Completed
Pull Request — 2.x (#345)
by
unknown
13:55
created

SitemapGeneratorCommand::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 2
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\SeoBundle\Command;
15
16
use Sonata\Exporter\Handler;
17
use Sonata\Exporter\Writer\SitemapWriter;
18
use Sonata\SeoBundle\Sitemap\SourceManager;
19
use Symfony\Component\Console\Command\Command;
20
use Symfony\Component\Console\Input\InputArgument;
21
use Symfony\Component\Console\Input\InputInterface;
22
use Symfony\Component\Console\Input\InputOption;
23
use Symfony\Component\Console\Output\OutputInterface;
24
use Symfony\Component\Filesystem\Filesystem;
25
use Symfony\Component\Finder\Finder;
26
use Symfony\Component\Routing\RouterInterface;
27
28
/**
29
 * Create a sitemap.
30
 *
31
 * @author Thomas Rabaix <[email protected]>
32
 */
33
class SitemapGeneratorCommand extends Command
34
{
35
    /**
36
     * @var RouterInterface
37
     */
38
    private $router;
39
40
    /**
41
     * @var SourceManager
42
     */
43
    private $sitemapManager;
44
45
    public function __construct(RouterInterface $router, SourceManager $sitemapManager)
46
    {
47
        $this->router = $router;
48
        $this->sitemapManager = $sitemapManager;
49
50
        parent::__construct();
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56
    public function configure()
57
    {
58
        $this->setName('sonata:seo:sitemap');
59
60
        $this->addArgument('folder', InputArgument::REQUIRED, 'The folder to store the sitemap.xml file');
61
        $this->addArgument('host', InputArgument::REQUIRED, 'Set the host');
62
        $this->addOption('scheme', null, InputOption::VALUE_OPTIONAL, 'Set the scheme', 'http');
63
        $this->addOption('baseurl', null, InputOption::VALUE_OPTIONAL, 'Set the base url', '');
64
        $this->addOption('sitemap_path', null, InputOption::VALUE_OPTIONAL, 'Set the sitemap relative path (if in a specific folder)', '');
65
66
        $this->setDescription('Create a sitemap');
67
        $this->setHelp(<<<'EOT'
68
The <info>sonata:seo:sitemap</info> command create new sitemap files (index + sitemap).
69
70
EOT
71
        );
72
    }
73
74
    /**
75
     * {@inheritdoc}
76
     */
77
    public function execute(InputInterface $input, OutputInterface $output)
78
    {
79
        $this->router->getContext()->setHost($input->getArgument('host'));
0 ignored issues
show
Bug introduced by
It seems like $input->getArgument('host') targeting Symfony\Component\Consol...nterface::getArgument() can also be of type array<integer,string> or null; however, Symfony\Component\Routin...questContext::setHost() does only seem to accept string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
80
        $this->router->getContext()->setScheme($input->getOption('scheme'));
81
        $this->router->getContext()->setBaseUrl($input->getOption('baseurl'));
82
83
        $tempFolder = sys_get_temp_dir().'/sonata_sitemap_'.md5(__DIR__);
84
85
        $fs = new Filesystem();
86
87
        // step 1
88
        $output->writeln(sprintf('Creating temporary folder: %s', $tempFolder));
89
90
        if ($fs->exists($tempFolder)) {
91
            $output->writeln('<error>The temporary folder already exists</error>');
92
            $output->writeln('<error>If the task is not running please delete this folder</error>');
93
94
            return 1;
95
        }
96
97
        $fs->mkdir($tempFolder);
98
99
        // step 2
100
        $output->writeln(sprintf('Generating sitemap - this can take a while'));
101
        foreach ($this->sitemapManager as $group => $sitemap) {
102
            $write = new SitemapWriter($tempFolder, $group, $sitemap->types, false);
103
104
            try {
105
                Handler::create($sitemap->sources, $write)->export();
106
            } catch (\Exception $e) {
107
                $fs->remove($tempFolder);
108
109
                throw $e;
110
            }
111
        }
112
113
        // generate global sitemap index
114
        $appendPath = $input->hasOption('sitemap_path') ? $input->getOption('sitemap_path') : $input->getOption('baseurl');
115
        SitemapWriter::generateSitemapIndex($tempFolder, sprintf('%s://%s%s', $input->getOption('scheme'), $input->getArgument('host'), $appendPath), 'sitemap*.xml', 'sitemap.xml');
116
117
        // step 3
118
        $output->writeln(sprintf('Moving temporary file to %s ...', $input->getArgument('folder')));
119
120
        $oldFiles = Finder::create()->files()->name('sitemap*.xml')->in($input->getArgument('folder'));
0 ignored issues
show
Bug introduced by
It seems like $input->getArgument('folder') targeting Symfony\Component\Consol...nterface::getArgument() can also be of type null; however, Symfony\Component\Finder\Finder::in() does only seem to accept string|array<integer,string>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
121
        foreach ($oldFiles as $file) {
122
            $fs->remove($file->getRealPath());
123
        }
124
125
        $newFiles = Finder::create()->files()->name('sitemap*.xml')->in($tempFolder);
126
        foreach ($newFiles as $file) {
127
            $fs->rename($file->getRealPath(), sprintf('%s/%s', $input->getArgument('folder'), $file->getFilename()));
128
        }
129
130
        $fs->remove($tempFolder);
131
132
        $output->writeln('<info>done!</info>');
133
    }
134
}
135