Passed
Push — master ( 338607...6bed5d )
by Jeroen
02:58
created

SitemapGenerator::setUrl()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace JeroenDesloovere\SitemapBundle\Generator;
4
5
use JeroenDesloovere\SitemapBundle\Exception\SitemapException;
6
use JeroenDesloovere\SitemapBundle\Item\SitemapItem;
7
use JeroenDesloovere\SitemapBundle\Provider\SitemapProviderInterface;
8
use JeroenDesloovere\SitemapBundle\Provider\SitemapProviders;
9
use Symfony\Component\Routing\RequestContext;
10
use Symfony\Component\Routing\RouterInterface;
11
12
class SitemapGenerator
13
{
14
    /** @var RouterInterface */
15
    private $router;
16
17
    /** @var string - The path where we must save all the sitemaps.*/
18
    private $path;
19
20
    /** @var SitemapProviders */
21
    private $providers;
22
23
    /**
24
     * @param RouterInterface $router
25
     * @param string $path
26
     * @param SitemapProviders $providers
27
     * @throws \Exception
28
     */
29
    public function __construct(RouterInterface $router, string $path, SitemapProviders $providers)
30
    {
31
        $this->router = $router;
32
        $this->providers = $providers;
33
        $this->setPath($path);
34
    }
35
36
    public function generate(): void
37
    {
38
        $providers = $this->providers->getAll();
39
40
        if (empty($providers)) {
41
            return;
42
        }
43
44
        foreach ($providers as $provider) {
45
            $this->saveSitemapForProvider($provider);
46
        }
47
48
        $this->saveSitemapIndex();
49
    }
50
51
    private function generateSitemapForProvider(SitemapProviderInterface $provider): string
52
    {
53
        $provider->createItems();
54
        $rootNode = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></urlset>');
55
56
        /** @var SitemapItem $item */
57
        foreach ($provider->getItems()->getAll() as $item) {
58
            $itemNode = $rootNode->addChild('url');
59
            $itemNode->addChild('loc', $this->getUrl() . $item->getUrl());
60
            $itemNode->addChild('changefreq', $item->getChangeFrequency()->__toString());
61
            $itemNode->addChild('lastmod', $item->getLastModifiedOn()->format('Y-m-d'));
62
            $itemNode->addChild('priority', $item->getPriority()/10);
63
        }
64
65
        return $rootNode->asXML();
66
    }
67
68
    private function generateSitemapIndex(): string
69
    {
70
        $rootNode = new \SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?><sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"></sitemapindex>');
71
72
        /** @var string $key */
73
        foreach ($this->providers->getKeys() as $key) {
74
            $itemNode = $rootNode->addChild('sitemap');
75
            $itemNode->addChild('loc', $this->getUrl() . '/sitemap_' . $key . '.xml');
76
            // @todo: lastmod
77
            $itemNode->addChild('lastmod', (new \DateTime())->format('Y-m-d'));
78
        }
79
80
        return $rootNode->asXML();
81
    }
82
83
    public function getPath(): string
84
    {
85
        return $this->path;
86
    }
87
88
    private function getUrl(): string
89
    {
90
        /** @var RequestContext $context */
91
        $context = $this->router->getContext();
92
        $url = $context->getScheme() . '://' . $context->getHost();
93
94
        if ($context->getBaseUrl() !== '') {
95
            $url .= '/' . $context->getBaseUrl();
96
        }
97
98
        return $context->getScheme() . '://' . $context->getHost();
99
    }
100
101
    public function regenerateForSitemapProvider(SitemapProviderInterface $provider): void
102
    {
103
        $this->saveSitemapForProvider($provider);
104
        $this->saveSitemapIndex();
105
    }
106
107
    private function saveSitemapForProvider(SitemapProviderInterface $provider): void
108
    {
109
        file_put_contents(
110
            $this->getPath() . '/sitemap_' . $provider->getKey() . '.xml',
111
            $this->generateSitemapForProvider($provider)
112
        );
113
    }
114
115
    private function saveSitemapIndex(): void
116
    {
117
        file_put_contents(
118
            $this->getPath() . '/sitemap.xml',
119
            $this->generateSitemapIndex()
120
        );
121
    }
122
123
    /**
124
     * Set the path where whe must save all the sitemaps.
125
     *
126
     * @param string $path
127
     * @throws \Exception
128
     */
129
    public function setPath(string $path): void
130
    {
131
        if ($path === '') {
132
            throw SitemapException::forEmptyPath();
133
        }
134
135
        $this->path = $path;
136
    }
137
}
138