Skip to content

Latest commit

 

History

History
293 lines (232 loc) · 8.02 KB

README.md

File metadata and controls

293 lines (232 loc) · 8.02 KB

Latest Stable Version Build Status Coverage Status Scrutinizer Code Quality StyleCI License

sitemap.xml builder

This is a complex of services for build Sitemaps.xml and index of Sitemap.xml files.

See protocol for more details.

Example build sitemap.xml

Installation

Pretty simple with Composer, run:

composer require gpslab/sitemap

Simple usage

Create a service that will return a links to pages of your site.

use GpsLab\Component\Sitemap\Builder\Url\UrlBuilder;
use GpsLab\Component\Sitemap\Url\Url;

class MySiteUrlBuilder implements UrlBuilder
{
    private $urls;

    public function __construct()
    {
        // add URLs on your site
        $this->urls = new \ArrayIterator([
            new Url(
                'https://example.com/', // loc
                new \DateTimeImmutable('-10 minutes'), // lastmod
                Url::CHANGE_FREQ_ALWAYS, // changefreq
                '1.0' // priority
            ),
            new Url(
                'https://example.com/contacts.html',
                new \DateTimeImmutable('-1 month'),
                Url::CHANGE_FREQ_MONTHLY,
                '0.7'
            ),
            new Url(
                'https://example.com/about.html',
                new \DateTimeImmutable('-2 month'),
                Url::CHANGE_FREQ_MONTHLY,
                '0.7'
            ),
        ]);
    }

    public function getName()
    {
        return 'My Site';
    }

    public function count()
    {
        return count($this->urls);
    }

    public function getIterator()
    {
        return $this->urls;
    }
}

It was a simple builder. We add a builder more complicated.

use GpsLab\Component\Sitemap\Builder\Url\UrlBuilder;
use GpsLab\Component\Sitemap\Url\Url;

class ArticlesUrlBuilder implements UrlBuilder
{
    private $pdo;

    public function __construct(\PDO $pdo)
    {
        $this->pdo = $pdo;
    }

    public function getName()
    {
        return 'Articles on my site';
    }

    public function count()
    {
        $total = $this->pdo->query('SELECT COUNT(*) FROM article')->fetchColumn(); 
        $total++; // +1 for section
 
        return $total;
    }

    public function getIterator()
    {
        $section_update_at = null;
        $sth = $this->pdo->query('SELECT id, update_at FROM article');
        $sth->execute();

        $i = 0;
        while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
            $update_at = new \DateTimeImmutable($row['update_at']);
            $section_update_at = max($section_update_at, $update_at);

            // not forget free memory
            if (++$i % 100 === 0) {
                gc_collect_cycles();
            }

            // SmartUrl automatically fills fields that it can
            yield new SmartUrl(
                sprintf('https://example.com/article/%d', $row['id']),
                $update_at
            );
        }

        // link to section
        yield new Url(
            'https://example.com/article/',
            $section_update_at ?: new \DateTimeImmutable('-1 day'),
            Url::CHANGE_FREQ_DAILY,
            '0.9'
        );
    }
}

We take one of the exists builders and configure it.

// collect a collection of builders
$collection = new UrlBuilderCollection([
    new MySiteUrlBuilder(),
    new ArticlesUrlBuilder(/* $pdo */),
]);

// the file into which we will write our sitemap
$filename = __DIR__.'/sitemap.xml';

// configure streamer
$render = new PlainTextSitemapRender();
$stream = new RenderFileStream($render, $filename);

// configure sitemap builder
$builder = new SilentSitemapBuilder($collection, $stream);

// build sitemap.xml
$total_urls = $builder->build();

Sitemap index

You can create Sitemap index to group multiple sitemap files.

// collect a collection of builders
$collection = new UrlBuilderCollection([
    new MySiteUrlBuilder(),
    new ArticlesUrlBuilder(/* $pdo */),
]);

// the file into which we will write our sitemap
$filename_index = __DIR__.'/sitemap.xml';

// the file into which we will write sitemap part
// you must use the temporary directory if you don't want to overwrite the existing index file!!!
// the sitemap part file will be automatically moved to the directive with the sitemap index on close stream
$filename_part = sys_get_temp_dir().'/sitemap.xml';

// configure streamer
$render = new PlainTextSitemapRender();
$stream = new RenderFileStream($render, $filename_part)

// configure index streamer
$index_render = new PlainTextSitemapIndexRender();
$index_stream = new RenderFileStream($index_render, $stream, 'https://example.com/', $filename_index);

// configure sitemap builder
$builder = new SilentSitemapBuilder($collection, $index_stream);

// build sitemap.xml index file and sitemap1.xml, sitemap2.xml, sitemapN.xml with URLs
$total_urls = $builder->build();

Symfony sitemap builder

If you use Symfony, you can use SymfonySitemapBuilder in console.

class BuildSitemapCommand extends Command
{
    private $builder;

    public function __construct(SymfonySitemapBuilder $builder)
    {
        $this->builder = $builder;
    }


    protected function configure()
    {
        // ...
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        $io = new SymfonyStyle($input, $output);

        // build sitemap.xml
        $total_urls = $this->builder->build($io);

        $io->success(sprintf('Build "%d" urls.', $total_urls));
    }
}

Streams

  • LoggerStream - use PSR-3 for log added URLs
  • MultiStream - allows to use multiple streams as one
  • OutputStream - sends a Sitemap to the output buffer. You can use it in controllers.
  • RenderFileStream - writes a Sitemap to file
  • RenderIndexFileStream - writes a Sitemap index to file
  • RenderGzipFileStream - writes a Sitemap to Gzip file
  • RenderBzip2FileStream - writes a Sitemap to Bzip2 file
  • CompressFileStream - use gpslab/compressor for compress sitemap.xml

You can use a composition from streams.

$stream = new MultiStream(
    new LoggerStream(/* $logger */),
    new RenderIndexFileStream(
        new PlainTextSitemapIndexRender(),
        new RenderGzipFileStream(
            new PlainTextSitemapRender(),
            __DIR__.'/sitemap.xml.gz'
        ),
        'https://example.com/',
         __DIR__.'/sitemap.xml',
    )
);

Streaming to file and compress result without index

$stream = new MultiStream(
    new LoggerStream(/* $logger */),
    new CompressFileStream(
        new RenderFileStream(
            new PlainTextSitemapRender(),
            __DIR__.'/sitemap.xml'
        ),
        new GzipCompressor(),
        __DIR__.'/sitemap.xml.gz'
    )
);

Streaming to file and output buffer

$stream = new MultiStream(
    new LoggerStream(/* $logger */),
    new RenderFileStream(
        new PlainTextSitemapRender(),
        __DIR__.'/sitemap.xml'
    ),
    new OutputStream(
        new PlainTextSitemapRender()
    )
);

License

This bundle is under the MIT license. See the complete license in the file: LICENSE