Skip to content
sitemap.xml and index for sitemap.xml builder
PHP
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
src
tests
.coveralls.yml
.editorconfig
.gitignore
.scrutinizer.yml
.sensiolabs.yml
.styleci.yml
.travis.yml
LICENSE
README.md
build.png
composer.json
phpunit.xml.dist

README.md

Latest Stable Version PHP from Travis config Build Status Coverage Status Scrutinizer Code Quality SensioLabs Insight 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

You can’t perform that action at this time.