-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathSitemap.php
More file actions
118 lines (98 loc) · 4.35 KB
/
Sitemap.php
File metadata and controls
118 lines (98 loc) · 4.35 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
<?php
declare(strict_types=1);
namespace MatchBot\Application\Actions;
use JetBrains\PhpStorm\Pure;
use MatchBot\Application\Environment;
use MatchBot\Application\HttpModels\MetaCampaign;
use MatchBot\Domain\CampaignRepository;
use MatchBot\Domain\MetaCampaignRepository;
use Psr\Clock\ClockInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Log\LoggerInterface;
use SimpleXMLElement;
use Symfony\Contracts\Cache\CacheInterface;
use Symfony\Contracts\Cache\ItemInterface;
/**
* Creates a sitemap for the Big Give public facing site. See spec at https://www.sitemaps.org/protocol.html#prioritydef
*/
class Sitemap extends Action
{
#[Pure]
public function __construct(
private CampaignRepository $campaignRepository,
private MetaCampaignRepository $metaCampaignRepository,
private Environment $environment,
private ClockInterface $clock,
LoggerInterface $logger,
) {
parent::__construct($logger);
}
#[\Override]
protected function action(Request $request, Response $response, array $args): Response
{
// initial implementation of sitemap - following spec from https://www.sitemaps.org/protocol.html#prioritydef
// which is what Google uses.
$xml = new SimpleXMLElement('<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
$campaigns = $this->campaignRepository->search(
sortField: 'amountRaised',
sortDirection: 'asc',
offset: 0,
limit: 100_000,
metaCampaignSlug: null,
fundSlug: null,
jsonMatchInListConditions: [],
term:null,
);
foreach ($campaigns as $campaign) {
$endsInFuture = $campaign->getEndDate() > $this->clock->now();
$changefreq = $endsInFuture ? 'daily' : 'monthly';
if ($campaign->isOpen($this->clock->now())) {
$changefreq = 'hourly';
}
$this->addUrl(
xml: $xml,
url: $this->environment->publicDonateURLPrefix() . 'campaign/' . $campaign->getSalesforceId(),
changefreq: $changefreq,
priority: $endsInFuture ? '0.5' : '0.25',
);
if ($campaign->isOpen($this->clock->now()) && ! $campaign->isRegularGiving()) {
// regular giving donate pages are at a different address and in any case behind a login-wall,
// so not worth listing in sitemap.
$this->addUrl(
xml: $xml,
url: $this->environment->publicDonateURLPrefix() . 'donate/' . $campaign->getSalesforceId(),
changefreq: $changefreq,
priority: '0.5'
);
}
}
$metaCampaigns = $this->metaCampaignRepository->allToIncludeInSitemap($this->clock->now());
foreach ($metaCampaigns as $metaCampaign) {
if ($metaCampaign->isOpen($this->clock->now())) {
$changefreq = 'always';
} elseif ($metaCampaign->getEndDate() > $this->clock->now()->sub(new \DateInterval("P1D"))) {
$changefreq = 'hourly';
} else {
$changefreq = 'monthly';
}
$this->addUrl(
xml: $xml,
url: $this->environment->publicDonateURLPrefix() . $metaCampaign->getSlug()->slug,
changefreq: $changefreq,
priority: ($metaCampaign->getEndDate() > $this->clock->now()->add(new \DateInterval("P14D"))) ? '0.75' : '0.5',
);
}
$sitemapXml = $xml->asXML();
\assert(\is_string($sitemapXml));
$response->getBody()->write($sitemapXml);
return $response->withHeader('Content-Type', 'application/xml');
}
private function addUrl(SimpleXMLElement $xml, string $url, string $changefreq, string $priority): void
{
$urlElement = $xml->addChild('url') ?? throw new \LogicException('Expected child element not returned');
$urlElement->addChild('loc', $url);
$urlElement->addChild('changefreq', $changefreq); // options: always, hourly, daily, weekly, monthly, yearly, never
$urlElement->addChild('priority', $priority); // value betweeon 0 and 1 sets relative priority to other content on same site.
}
}