PHP code example of ecourty / sitemap-bundle

1. Go to this page and download the library: Download ecourty/sitemap-bundle library. Choose the download type require.

2. Extract the ZIP file and open the index.php.

3. Add this code to the index.php.
    
        
<?php
require_once('vendor/autoload.php');

/* Start to develop here. Best regards https://php-download.com/ */

    

ecourty / sitemap-bundle example snippets


return [
    // ...
    Ecourty\SitemapBundle\SitemapBundle::class => ['all' => true],
];

// src/Repository/PostRepository.php
use Doctrine\ORM\QueryBuilder;

class PostRepository extends ServiceEntityRepository
{
    public function getSitemapQueryBuilder(): QueryBuilder
    {
        return $this->createQueryBuilder('p')
            ->where('p.published = true')
            ->andWhere('p.deletedAt IS NULL')
            ->orderBy('p.updatedAt', 'DESC');
    }
}

// src/Service/PostSitemapService.php
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\QueryBuilder;

class PostSitemapService
{
    public function __construct(
        private EntityManagerInterface $em,
    ) {
    }
    
    public function getPublishedPostsQueryBuilder(): QueryBuilder
    {
        return $this->em->createQueryBuilder()
            ->select('p')
            ->from(Post::class, 'p')
            ->where('p.status = :published')
            ->setParameter('published', 'published')
            ->orderBy('p.publishedAt', 'DESC');
    }
}

// src/Service/ProductUrlProvider.php
namespace App\Service;

use Doctrine\ORM\EntityManagerInterface;
use Ecourty\SitemapBundle\Contract\UrlProviderInterface;
use Ecourty\SitemapBundle\Enum\ChangeFrequency;
use Ecourty\SitemapBundle\Model\SitemapUrl;
use App\Entity\Product;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

class ProductUrlProvider implements UrlProviderInterface
{
    // Inject dependencies

    public function getUrls(): iterable
    {
        // Join with Category to get both slugs in one query
        $qb = $this->em->createQueryBuilder()
            ->select('p', 'c') // Select both product and category
            ->from(Product::class, 'p')
            ->innerJoin('p.category', 'c')
            ->where('p.active = true')
            ->andWhere('c.active = true')
            ->orderBy('p.updatedAt', 'DESC');

        foreach ($qb->getQuery()->toIterable() as $product) {            
            // Generate URL with both category and product parameters
            $path = $this->urlGenerator->generate('product_show', [
                'categorySlug' => $product->getCategory()->getSlug(),
                'productSlug' => $product->getSlug(),
            ]);

            yield new SitemapUrl(
                loc: rtrim($this->baseUrl, '/') . $path,
                priority: 0.7,
                changefreq: ChangeFrequency::WEEKLY,
                lastmod: $product->getUpdatedAt(),
            );
        }
    }

    public function count(): int
    {
        // Implement the count efficiently
        // $qb = $this->em->createQueryBuilder()
        //    ->select('COUNT(p.id)')
        //    ...
    }

    public function getSourceName(): string
    {
        return 'products';
    }
}

// ✅ Automatic streaming - no memory issues with 100k+ entities
$query->toIterable();

// ❌ Would load all entities in memory at once
$query->getResult();

// ✅ Correct - return QueryBuilder
public function getSitemapQueryBuilder(): QueryBuilder
{
    return $this->createQueryBuilder('p')
        ->where('p.published = true');
}

// ❌ Wrong - don't call getQuery() or toIterable()
public function getSitemapData(): iterable
{
    return $this->createQueryBuilder('p')
        ->getQuery()
        ->toIterable();  // Bundle handles this automatically
}

// Repository method with filtering
public function getActiveProductsQueryBuilder(): QueryBuilder
{
    return $this->createQueryBuilder('p')
        ->where('p.active = true')
        ->andWhere('p.stock > 0')
        ->orderBy('p.updatedAt', 'DESC');
}
bash
php bin/console sitemap:dump # Generates public/sitemap.xml
bash
# Generate to public/ directory (default)
php bin/console sitemap:dump

# Generate to custom directory (relative to public/)
php bin/console sitemap:dump --output=sitemaps

# Generate to absolute directory path
php bin/console sitemap:dump --output=/var/www/public/sitemaps

# Force overwrite existing files without confirmation
php bin/console sitemap:dump --force