Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split big sitemaps & generate proper index #253

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions src/Builder/SitemapIndexBuilder.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ final class SitemapIndexBuilder implements SitemapIndexBuilderInterface
/** @var IndexUrlProviderInterface[] */
private array $indexProviders = [];

/** @var array */
private array $paths = [];

public function __construct(SitemapIndexFactoryInterface $sitemapIndexFactory)
{
$this->sitemapIndexFactory = $sitemapIndexFactory;
Expand All @@ -38,12 +41,22 @@ public function addIndexProvider(IndexUrlProviderInterface $indexProvider): void
$this->indexProviders[] = $indexProvider;
}

public function addPath(UrlProviderInterface $provider, string $path): void
{
if (!array_key_exists($provider->getName(), $this->paths)) {
$this->paths[$provider->getName()] = [];
}

$this->paths[$provider->getName()][] = $path;
}

public function build(): SitemapInterface
{
$sitemap = $this->sitemapIndexFactory->createNew();
$urls = [];

foreach ($this->indexProviders as $indexProvider) {
$indexProvider->addPaths($this->paths);
$urls[] = $indexProvider->generate();
}

Expand Down
3 changes: 3 additions & 0 deletions src/Builder/SitemapIndexBuilderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@

use SitemapPlugin\Model\SitemapInterface;
use SitemapPlugin\Provider\IndexUrlProviderInterface;
use SitemapPlugin\Provider\UrlProviderInterface;

interface SitemapIndexBuilderInterface extends BuilderInterface
{
public function addIndexProvider(IndexUrlProviderInterface $indexProvider): void;

public function addPath(UrlProviderInterface $provider, string $path): void;

public function build(): SitemapInterface;
}
37 changes: 22 additions & 15 deletions src/Command/GenerateSitemapCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,18 +55,19 @@ public function __construct(
protected function configure(): void
{
$this->addOption('channel', 'c', InputOption::VALUE_IS_ARRAY | InputOption::VALUE_OPTIONAL, 'Channel codes to generate. If none supplied, all channels will generated.');
$this->addOption('limit', 'l', InputOption::VALUE_OPTIONAL, 'Limit amount of URLs per sitemap', 50000);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
foreach ($this->channels($input) as $channel) {
$this->executeChannel($channel, $output);
$this->executeChannel($channel, $input, $output);
}

return 0;
}

private function executeChannel(ChannelInterface $channel, OutputInterface $output): void
private function executeChannel(ChannelInterface $channel, InputInterface $input, OutputInterface $output): void
{
$output->writeln(\sprintf('Start generating sitemaps for channel "%s"', $channel->getName()));

Expand All @@ -76,27 +77,33 @@ private function executeChannel(ChannelInterface $channel, OutputInterface $outp
$output->writeln(\sprintf('Start generating sitemap "%s" for channel "%s"', $provider->getName(), $channel->getCode()));

$sitemap = $this->sitemapBuilder->build($provider, $channel); // TODO use provider instance, not the name
$xml = $this->sitemapRenderer->render($sitemap);
$path = $this->path($channel, \sprintf('%s.xml', $provider->getName()));

$this->writer->write(
$path,
$xml
);

$output->writeln(\sprintf('Finished generating sitemap "%s" for channel "%s" at path "%s"', $provider->getName(), $channel->getCode(), $path));
$xml = $this->sitemapRenderer->render($sitemap, (int)$input->getOption('limit'));
foreach($xml as $index => $data) {
$path = $this->path($channel, \sprintf('%s_%d.xml', $provider->getName(), $index));
$this->writer->write($path, $data);
$output->writeln(
\sprintf(
'Finished generating sitemap "%s" (%d) for channel "%s" at path "%s"',
$provider->getName(),
$index,
$channel->getCode(),
$path
)
);
$provider->addPath($path);
}
}

$output->writeln(\sprintf('Start generating sitemap index for channel "%s"', $channel->getCode()));

$sitemap = $this->sitemapIndexBuilder->build();
$xml = $this->sitemapIndexRenderer->render($sitemap);
$path = $this->path($channel, 'sitemap_index.xml');

$this->writer->write(
$path,
$xml
);
foreach($xml as $index => $data) {
$path = $this->path($channel, 'sitemap_index.xml');
$this->writer->write($path, $data);
}

$output->writeln(\sprintf('Finished generating sitemap index for channel "%s" at path "%s"', $channel->getCode(), $path));
}
Expand Down
4 changes: 2 additions & 2 deletions src/Controller/SitemapController.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ public function __construct(
parent::__construct($reader);
}

public function showAction(string $name): Response
public function showAction(string $name, int $index): Response
{
$path = \sprintf('%s/%s', $this->channelContext->getChannel()->getCode(), \sprintf('%s.xml', $name));
$path = \sprintf('%s/%s', $this->channelContext->getChannel()->getCode(), \sprintf('%s_%d.xml', $name, $index));

return $this->createResponse($path);
}
Expand Down
16 changes: 14 additions & 2 deletions src/Provider/IndexUrlProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ final class IndexUrlProvider implements IndexUrlProviderInterface

private IndexUrlFactoryInterface $sitemapIndexUrlFactory;

/** @var array */
private array $paths = [];

public function __construct(
RouterInterface $router,
IndexUrlFactoryInterface $sitemapIndexUrlFactory
Expand All @@ -29,12 +32,21 @@ public function addProvider(UrlProviderInterface $provider): void
$this->providers[] = $provider;
}

public function addPaths(array $paths): void
{
$this->paths = $paths;
}

public function generate(): iterable
{
$urls = [];
foreach ($this->providers as $provider) {
$location = $this->router->generate('sylius_sitemap_' . $provider->getName());
$urls[] = $this->sitemapIndexUrlFactory->createNew($location);
$pathCount = count($this->paths[$provider->getName()]);
for ($i = 0; $i < $pathCount; $i++) {
$params = ['index' => $i];
$location = $this->router->generate('sylius_sitemap_'.$provider->getName(), $params);
$urls[] = $this->sitemapIndexUrlFactory->createNew($location);
}
}

return $urls;
Expand Down
2 changes: 2 additions & 0 deletions src/Provider/IndexUrlProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,6 @@ interface IndexUrlProviderInterface
public function generate(): iterable;

public function addProvider(UrlProviderInterface $provider): void;

public function addPaths(array $paths): void;
}
15 changes: 13 additions & 2 deletions src/Renderer/SitemapRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,19 @@ public function __construct(RendererAdapterInterface $adapter)
$this->adapter = $adapter;
}

public function render(SitemapInterface $sitemap): string
public function render(SitemapInterface $sitemap, ?int $limit = null): iterable
{
return $this->adapter->render($sitemap);
$urls = $sitemap->getUrls();
$total = count($urls);

if (null === $limit || $limit < 0) {
$limit = $total;
}

foreach(array_chunk($urls, $limit) as $slice) {
$sitemap->setUrls($slice);

yield $this->adapter->render($sitemap);
}
}
}
5 changes: 4 additions & 1 deletion src/Renderer/SitemapRendererInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,8 @@

interface SitemapRendererInterface
{
public function render(SitemapInterface $sitemap): string;
/**
* @return string[]
*/
public function render(SitemapInterface $sitemap, ?int $limit = null): iterable;
}
6 changes: 4 additions & 2 deletions src/Routing/SitemapLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ public function load($resource, $type = null)
$routes->add(
$name,
new Route(
'/sitemap/' . $provider->getName() . '.xml',
'/sitemap/' . $provider->getName() . '/{index}.xml',
[
'_controller' => 'sylius.controller.sitemap::showAction',
'name' => $provider->getName(),
],
[],
[
'index' => '\d+',
],
[],
'',
[],
Expand Down