├── Exception
├── Exception.php
├── OutOfBoundsException.php
└── InvalidArgumentException.php
├── Sitemap
├── Provider.php
├── Storage
│ ├── Storage.php
│ ├── Memory.php
│ └── Doctrine
│ │ └── ODM
│ │ └── MongoDB.php
├── Sitemap.php
└── Url.php
├── Resources
├── config
│ ├── routing.yml
│ └── sitemap.xml
└── views
│ └── Sitemap
│ ├── siteindex.xml.twig
│ └── sitemap.xml.twig
├── Dumper
├── Dumper.php
└── Doctrine
│ └── ODM
│ └── MongoDB.php
├── composer.json
├── DependencyInjection
├── Compiler
│ └── SitemapProviderPass.php
└── OpenSkySitemapExtension.php
├── OpenSkySitemapBundle.php
├── Tests
├── Sitemap
│ ├── Storage
│ │ ├── MemoryTest.php
│ │ └── Doctrine
│ │ │ └── ODM
│ │ │ └── MongoDBTest.php
│ ├── UrlTest.php
│ └── SitemapTest.php
├── DependencyInjection
│ └── SitemapExtensionTest.php
└── Listener
│ └── SitemapListenerTest.php
├── Command
└── GenerateCommand.php
├── Listener
└── SitemapListener.php
├── Controller
└── SitemapController.php
└── README.md
/Exception/Exception.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2010 OpenSky Project Inc
10 | */
11 | interface Exception
12 | {
13 | }
--------------------------------------------------------------------------------
/Sitemap/Provider.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2010 OpenSky Project Inc
10 | */
11 | interface Provider
12 | {
13 | public function populate(Sitemap $sitemap);
14 | }
--------------------------------------------------------------------------------
/Resources/config/routing.yml:
--------------------------------------------------------------------------------
1 | sitemap:
2 | pattern: /sitemap.xml
3 | defaults: { _controller: OpenSkySitemapBundle:Sitemap:sitemap, _format: xml }
4 | requirements: { _method: GET }
5 | siteindex:
6 | pattern: /siteindex.xml
7 | defaults: { _controller: OpenSkySitemapBundle:Sitemap:siteindex, _format: xml }
8 | requirements: { _method: GET }
--------------------------------------------------------------------------------
/Dumper/Dumper.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | interface Dumper
14 | {
15 | public function dump(Sitemap $sitemap);
16 | }
--------------------------------------------------------------------------------
/Exception/OutOfBoundsException.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | class OutOfBoundsException extends BaseOutOfBoundsException implements Exception
14 | {
15 | }
--------------------------------------------------------------------------------
/Resources/views/Sitemap/siteindex.xml.twig:
--------------------------------------------------------------------------------
1 | {% spaceless %}
2 |
3 |
4 | {% for page in range(1, max(1, totalPages)) %}
5 |
6 | {{ url('sitemap', {'page': page}) }}
7 |
8 | {% endfor %}
9 |
10 | {% endspaceless %}
--------------------------------------------------------------------------------
/Exception/InvalidArgumentException.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | class InvalidArgumentException extends BaseInvalidArgumentException implements Exception
14 | {
15 | }
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "opensky/sitemap-bundle",
3 | "description": "Adds a sitemap.xml file!",
4 | "keywords": [ "sitemap" ],
5 | "homepage": "https://github.com/opensky/SitemapBundle",
6 | "type": "symfony-bundle",
7 | "license": "MIT",
8 | "require": {
9 | "php": ">=5.3.0",
10 | "symfony/framework-bundle": ">=2.1.0,<2.3-dev"
11 | },
12 | "autoload": {
13 | "psr-0": { "OpenSky\\Bundle\\SitemapBundle": "" }
14 | },
15 | "target-dir": "OpenSky/Bundle/SitemapBundle"
16 | }
17 |
--------------------------------------------------------------------------------
/Resources/views/Sitemap/sitemap.xml.twig:
--------------------------------------------------------------------------------
1 | {% spaceless %}
2 |
3 |
4 | {% for url in urls %}
5 |
6 | {% if url.loc %}{{ url.loc }}{% endif %}
7 | {% if url.lastmod %}{{ url.lastmod }}{% endif %}
8 | {% if url.changefreq %}{{ url.changefreq }}{% endif %}
9 | {% if url.priority %}{{ url.priority }}{% endif %}
10 |
11 | {% endfor %}
12 |
13 | {% endspaceless %}
--------------------------------------------------------------------------------
/DependencyInjection/Compiler/SitemapProviderPass.php:
--------------------------------------------------------------------------------
1 | findTaggedServiceIds('opensky.sitemap.provider') as $id => $attributes) {
15 | $providers[] = $id;
16 | }
17 |
18 | if (count($providers)) {
19 | $container->setParameter('opensky.sitemap.providers', $providers);
20 | }
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/OpenSkySitemapBundle.php:
--------------------------------------------------------------------------------
1 |
14 | * @copyright (c) 2010 OpenSky Project Inc
15 | */
16 | class OpenSkySitemapBundle extends Bundle
17 | {
18 | public function __construct()
19 | {
20 | $this->extension = new OpenSkySitemapExtension();
21 | }
22 |
23 | public function build(ContainerBuilder $container)
24 | {
25 | $container->addCompilerPass(new SitemapProviderPass());
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/Sitemap/Storage/Storage.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | interface Storage
14 | {
15 | const PAGE_LIMIT = 50000;
16 |
17 | /**
18 | * @return int
19 | */
20 | public function getTotalPages();
21 |
22 | /**
23 | * @param string loc
24 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Url|null
25 | */
26 | public function findOne($loc);
27 |
28 | /**
29 | * @param int page
30 | * @return \Traversable
31 | */
32 | public function find($page);
33 |
34 | /**
35 | * @param OpenSky\Bundle\SitemapBundle\Sitemap\Url
36 | */
37 | public function save(Url $url);
38 | }
--------------------------------------------------------------------------------
/Sitemap/Storage/Memory.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | class Memory implements Storage
14 | {
15 | public $urls = array();
16 |
17 | /**
18 | * @return int
19 | */
20 | public function getTotalPages()
21 | {
22 | return ceil(count($this->urls) / self::PAGE_LIMIT);
23 | }
24 |
25 | /**
26 | * @param string loc
27 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Url|null
28 | */
29 | public function findOne($loc)
30 | {
31 | return isset($this->urls[$loc]) ? $this->urls[$loc] : null;
32 | }
33 |
34 | /**
35 | * @param int page
36 | * @return \Traversable
37 | */
38 | public function find($page)
39 | {
40 | return array_slice($this->urls, ($page - 1) * self::PAGE_LIMIT, self::PAGE_LIMIT);
41 | }
42 |
43 | /**
44 | * @param OpenSky\Bundle\SitemapBundle\Sitemap\Url
45 | */
46 | public function save(Url $url)
47 | {
48 | $this->urls[$url->getLoc()] = $url;
49 | }
50 |
51 | }
--------------------------------------------------------------------------------
/Dumper/Doctrine/ODM/MongoDB.php:
--------------------------------------------------------------------------------
1 |
13 | * @copyright (c) 2010 OpenSky Project Inc
14 | */
15 | class MongoDB implements Dumper
16 | {
17 | /**
18 | * ${@inheritDoc}
19 | */
20 | public function dump(Sitemap $sitemap)
21 | {
22 | // remove the old ones first...
23 | $this->getDocumentCollection($sitemap)->remove(array());
24 |
25 | // now flush the new ones
26 | $dm = $this->getDocumentManager($sitemap);
27 | $dm->flush(null, array('safe' => true));
28 | }
29 |
30 | /**
31 | * @param Sitemap $sitemap
32 | * @return Doctrine\ODM\MongoDB\DocumentManager
33 | */
34 | protected function getDocumentManager(Sitemap $sitemap)
35 | {
36 | return $sitemap->getStorage()->getDocumentManager();
37 | }
38 |
39 | /**
40 | * @param Sitemap $sitemap
41 | * @return Doctrine\MongoDB\Collection
42 | */
43 | protected function getDocumentCollection(Sitemap $sitemap)
44 | {
45 | return $this->getDocumentManager($sitemap)->getDocumentCollection($sitemap->getUrlClass());
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/Tests/Sitemap/Storage/MemoryTest.php:
--------------------------------------------------------------------------------
1 |
14 | * @copyright (c) 2010 OpenSky Project Inc
15 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
16 | */
17 | class MemoryTest extends \PHPUnit_Framework_TestCase
18 | {
19 | protected $storage;
20 |
21 | public function setUp()
22 | {
23 | $this->storage = new Memory();
24 | }
25 |
26 | public function tearDown()
27 | {
28 | unset($this->storage);
29 | }
30 |
31 | public function testFindReturnsEmptyResult()
32 | {
33 | $this->assertEquals(0, count($this->storage->find(1)));
34 | }
35 |
36 | public function testFindOneReturnsNullForNonExistentResult()
37 | {
38 | $this->assertNull($this->storage->findOne('http://google.com'));
39 | }
40 |
41 | public function testHasUrlAfterAdding()
42 | {
43 | $location = 'http://www.twitter.com';
44 | $url = $this->getCreateUrl($location);
45 | $this->storage->save($url);
46 | $this->assertSame($url, $this->storage->findOne($location));
47 | $this->assertEquals(1, count($this->storage->find(1)));
48 | }
49 |
50 | public function testGetTotalPages()
51 | {
52 | $this->storage->urls = array_pad(array(), Memory::PAGE_LIMIT + 1, 'http://www.google.com');
53 | $this->assertEquals(2, $this->storage->getTotalPages());
54 | }
55 |
56 | protected function getCreateUrl($location)
57 | {
58 | return new Url($location);
59 | }
60 |
61 | }
--------------------------------------------------------------------------------
/Command/GenerateCommand.php:
--------------------------------------------------------------------------------
1 |
15 | * @copyright (c) 2010 OpenSky Project Inc
16 | */
17 | class GenerateCommand extends ContainerAwareCommand
18 | {
19 |
20 | /**
21 | * {@inheritDoc}
22 | */
23 | protected function configure()
24 | {
25 | $this
26 | ->setName('sitemap:generate')
27 | ->setDescription('Generate sitemap, using its data providers.');
28 | }
29 |
30 | /**
31 | * {@inheritDoc}
32 | */
33 | public function execute(InputInterface $input, OutputInterface $output)
34 | {
35 | $sitemap = $this->getSitemap();
36 | foreach ($this->getProviders() as $id) {
37 | $this->getContainer()->get($id)->populate($sitemap);
38 | }
39 | $this->getSitemapDumper()->dump($sitemap);
40 | }
41 |
42 | /**
43 | * @return Bundle\SitemapBundle\Sitemap\Sitemap
44 | */
45 | protected function getSitemap()
46 | {
47 | return $this->getContainer()->get('opensky.sitemap');
48 | }
49 |
50 | /**
51 | * @return Bundle\SitemapBundle\Dumper\Dumper
52 | */
53 | protected function getSitemapDumper()
54 | {
55 | return $this->getContainer()->get('opensky.sitemap.dumper');
56 | }
57 |
58 | /**
59 | * @return array Provider service ids
60 | */
61 | protected function getProviders()
62 | {
63 | return $this->getContainer()->getParameter('opensky.sitemap.providers');
64 | }
65 | }
--------------------------------------------------------------------------------
/DependencyInjection/OpenSkySitemapExtension.php:
--------------------------------------------------------------------------------
1 |
16 | * @copyright (c) 2010 OpenSky Project Inc
17 | */
18 | class OpenSkySitemapExtension extends Extension
19 | {
20 |
21 | /**
22 | * Loads OpenSky Sitemap configuration into the container:
23 | *
24 | * opensky_sitemap:
25 | * default_lastmod: 2010-06-01
26 | * default_changefreq: monthly
27 | * default_priority: 0.5
28 | *
29 | * @see Symfony\Component\DependencyInjection\Extension\ExtensionInterface::load()
30 | */
31 | public function load(array $configs, ContainerBuilder $container)
32 | {
33 | $loader = new XmlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
34 | $loader->load('sitemap.xml');
35 |
36 | $defaults = $container->getParameter('opensky.sitemap.defaults');
37 | foreach ($configs as $config) {
38 | foreach (array('changefreq', 'priority', 'lastmod') as $prop) {
39 | if (isset($config['default_' . $prop])) {
40 | $defaults[$prop] = $config['default_' . $prop];
41 | }
42 | }
43 | }
44 |
45 | $container->setParameter('opensky.sitemap.defaults', $defaults);
46 | }
47 |
48 | /**
49 | * @see Symfony\Component\DependencyInjection\Extension\ExtensionInterface::getAlias()
50 | * @codeCoverageIgnore
51 | */
52 | public function getAlias()
53 | {
54 | return 'opensky_sitemap';
55 | }
56 | }
--------------------------------------------------------------------------------
/Tests/Sitemap/UrlTest.php:
--------------------------------------------------------------------------------
1 |
13 | * @copyright (c) 2010 OpenSky Project Inc
14 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
15 | */
16 | class UrlTest extends \PHPUnit_Framework_TestCase
17 | {
18 |
19 | /**
20 | * @expectedException Bundle\SitemapBundle\Exception\InvalidArgumentException
21 | */
22 | public function testThrowsOnInvalidUrl()
23 | {
24 | new Url('somdasdasd');
25 | }
26 |
27 | public function testGetLoc()
28 | {
29 | $url = new Url('http://www.example.org/');
30 | $this->assertEquals('http://www.example.org/', $url->getLoc());
31 | }
32 |
33 | public function testSetLastmod()
34 | {
35 | $url = new Url('http://www.example.org/');
36 | $now = new \DateTime();
37 | $url->setLastmod($now);
38 | $this->assertEquals(date(Url::LASTMOD_FORMAT, $now->getTimestamp()), $url->getLastmod());
39 | }
40 |
41 | /**
42 | * @expectedException Bundle\SitemapBundle\Exception\InvalidArgumentException
43 | */
44 | public function testThrowsOnInvalidChangefreq()
45 | {
46 | $url = new Url('http://www.example.org/');
47 | $url->setChangefreq('somefreq');
48 | }
49 |
50 | public function testGetChangefreq()
51 | {
52 | $url = new Url('http://www.example.org/');
53 | $url->setChangefreq(Url::DAILY);
54 | $this->assertEquals(Url::DAILY, $url->getChangefreq());
55 | }
56 |
57 | public function testGetPriority()
58 | {
59 | $url = new Url('http://www.example.org/');
60 | $url->setPriority(1.0);
61 | $this->assertEquals(1.0, $url->getPriority());
62 | }
63 |
64 | /**
65 | * @expectedException Bundle\SitemapBundle\Exception\InvalidArgumentException
66 | */
67 | public function testThrowsOnInvalidPriority()
68 | {
69 | $url = new Url('http://www.example.org/');
70 | $url->setPriority(2.0);
71 | }
72 |
73 | }
--------------------------------------------------------------------------------
/Tests/DependencyInjection/SitemapExtensionTest.php:
--------------------------------------------------------------------------------
1 |
14 | * @copyright (c) 2010 OpenSky Project Inc
15 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
16 | */
17 | class SitemapExtensionTest extends \PHPUnit_Framework_TestCase
18 | {
19 |
20 | public function testSitemapLoad()
21 | {
22 | $configuration = new ContainerBuilder();
23 | $loader = new SitemapExtension('testkernel');
24 | $configuration = $loader->configLoad(array('driver' => 'odm.mongodb'), $configuration);
25 | $this->assertEquals('Bundle\SitemapBundle\Sitemap\Sitemap', $configuration->getParameter('sitemap.class'), '->sitemapLoad() merges default configration parameters');
26 | $this->assertHasDefinition('sitemap.sitemap', $configuration, '->sitemapLoad() defines sitemap service');
27 | }
28 |
29 | public function testSitemapLoadWithDefaults()
30 | {
31 | $configuration = new ContainerBuilder();
32 | $loader = new SitemapExtension('testkernel');
33 | $configuration = $loader->configLoad(array(
34 | 'driver' => 'odm.mongodb',
35 | 'default_changefreq' => 'daily',
36 | 'default_lastmod' => strtotime('2006-01-01'),
37 | 'default_priority' => 0.3,
38 | ), $configuration);
39 | $this->assertEquals(array(
40 | 'changefreq' => 'daily',
41 | 'lastmod' => strtotime('2006-01-01'),
42 | 'priority' => 0.3,
43 | ), $configuration->getParameter('sitemap.defaults'), '->sitemapLoad() merges default configration parameters');
44 | $this->assertHasDefinition('sitemap.dumper', $configuration, '->sitemapLoad() defines sitemap.dumper service');
45 | }
46 |
47 | public function assertHasDefinition($id, ContainerBuilder $configuration, $message = '')
48 | {
49 | $this->assertTrue(($configuration->hasDefinition($id) ? : $configuration->hasAlias($id)), $message);
50 | }
51 |
52 | }
--------------------------------------------------------------------------------
/Listener/SitemapListener.php:
--------------------------------------------------------------------------------
1 |
15 | * @copyright (c) 2010 OpenSky Project Inc
16 | */
17 | class SitemapListener
18 | {
19 | const DEFAULT_PRIORITY = '0.2';
20 |
21 | /**
22 | * @var OpenSky\Bundle\SitemapBundle\Sitemap\Sitemap
23 | */
24 | protected $sitemap;
25 | /**
26 | * @var OpenSky\Bundle\SitemapBundle\Dumper\Dumper
27 | */
28 | protected $dumper;
29 |
30 | /**
31 | * @param OpenSky\Bundle\SitemapBundle\Sitemap\Sitemap $sitemap
32 | */
33 | public function __construct(Sitemap $sitemap, Dumper $dumper)
34 | {
35 | $this->sitemap = $sitemap;
36 | $this->dumper = $dumper;
37 | }
38 |
39 | public function update(Event $event)
40 | {
41 | $urlLoc = $event->get('loc');
42 |
43 | if (!$this->sitemap->has($urlLoc)) {
44 | throw new Exception\OutOfBoundsException('Url ' . $urlLoc . ' could not be found.');
45 | }
46 |
47 | $url = $this->sitemap->get($urlLoc);
48 |
49 | $time = new \DateTime();
50 | $lastmod = $url->getLastmod();
51 |
52 | $url->setLastmod($time);
53 | $url->setChangefreq($this->getChangefreq($time->diff(\DateTime::createFromFormat(Url::LASTMOD_FORMAT, $lastmod))));
54 |
55 | $this->dump($this->sitemap);
56 | }
57 |
58 | public function create(Event $event)
59 | {
60 | $this->sitemap->add($event->get('loc'), array(
61 | 'changefreq' => ($event->has('changefreq') ? $event->get('changefreq') : Url::YEARLY),
62 | 'priority' => ($event->has('priority') ? $event->get('priority') : self::DEFAULT_PRIORITY),
63 | 'lastmod' => new \DateTime(),
64 | ));
65 |
66 | $this->dump($this->sitemap);
67 | }
68 |
69 | protected function getChangefreq(\DateInterval $interval)
70 | {
71 | return ($interval->y >= 1) ? Url::YEARLY : (($interval->m >= 1) ? Url::MONTHLY : (($interval->d >= 7) ? Url::WEEKLY : Url::DAILY));
72 | }
73 |
74 | protected function dump(Sitemap $sitemap)
75 | {
76 | $this->dumper->dump($sitemap);
77 | }
78 |
79 | }
--------------------------------------------------------------------------------
/Sitemap/Storage/Doctrine/ODM/MongoDB.php:
--------------------------------------------------------------------------------
1 |
16 | * @copyright (c) 2010 OpenSky Project Inc
17 | */
18 | class MongoDB implements Storage
19 | {
20 | /**
21 | * @var Doctrine\ODM\MongoDB\DocumentManager
22 | */
23 | protected $dm;
24 |
25 | /**
26 | * @var Doctrine\ODM\MongoDB\DocumentRepository
27 | */
28 | protected $repository;
29 |
30 | /**
31 | * Constructor.
32 | *
33 | * @param Doctrine\ODM\MongoDB\DocumentManager $dm
34 | */
35 | public function __construct(DocumentManager $dm, DocumentRepository $repository)
36 | {
37 | $this->dm = $dm;
38 | $this->repository = $repository;
39 | }
40 |
41 | /**
42 | * Finds one Url by location, returns null if not found
43 | *
44 | * @param string $loc
45 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Url|null
46 | */
47 | public function findOne($loc)
48 | {
49 | return $this->repository->find($loc);
50 | }
51 |
52 | /**
53 | * Finds all urls on specific page
54 | *
55 | * @param int $page
56 | * @return \Traversable
57 | */
58 | public function find($page)
59 | {
60 | return $this->repository->findAll()
61 | ->skip($this->getSkip($page))
62 | ->limit(self::PAGE_LIMIT);
63 | }
64 |
65 | /**
66 | * Returns total number of pages in the sitemap
67 | *
68 | * @return int
69 | */
70 | public function getTotalPages()
71 | {
72 | return ceil($this->repository->findAll()->count() / self::PAGE_LIMIT);
73 | }
74 |
75 | /**
76 | * Persists Url in DocumentManager, does not call flush
77 | *
78 | * @param OpenSky\Bundle\SitemapBundle\Sitemap\Url $url
79 | */
80 | public function save(Url $url)
81 | {
82 | $this->dm->persist($url);
83 | }
84 |
85 | /**
86 | * @return Doctrine\ODM\MongoDB\DocumentManager
87 | */
88 | public function getDocumentManager()
89 | {
90 | return $this->dm;
91 | }
92 |
93 | /**
94 | * @return Doctrine\ODM\MongoDB\DocumentRepository
95 | */
96 | public function getDocumentRepository()
97 | {
98 | return $this->repository;
99 | }
100 |
101 | private function getSkip($page)
102 | {
103 | return ((int) $page - 1) * self::PAGE_LIMIT;
104 | }
105 | }
--------------------------------------------------------------------------------
/Resources/config/sitemap.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 | OpenSky\Bundle\SitemapBundle\Listener\RequestParser
8 | OpenSky\Bundle\SitemapBundle\Listener\ResponseFilter
9 | OpenSky\Bundle\SitemapBundle\Document\Url
10 | OpenSky\Bundle\SitemapBundle\Sitemap\SitemapExporter
11 | OpenSky\Bundle\SitemapBundle\Dumper\Doctrine\ODM\MongoDB
12 | OpenSky\Bundle\SitemapBundle\Sitemap\Storage\Doctrine\ODM\MongoDB
13 | OpenSky\Bundle\SitemapBundle\Sitemap\Sitemap
14 | OpenSky\Bundle\SitemapBundle\Listener\SitemapListener
15 | twig
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | %opensky.sitemap.defaults%
25 |
26 | %opensky.sitemap.url.class%
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | %opensky.sitemap.url.class%
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/Controller/SitemapController.php:
--------------------------------------------------------------------------------
1 |
15 | * @copyright (c) 2010 OpenSky Project Inc
16 | */
17 | class SitemapController extends Controller
18 | {
19 |
20 | /**
21 | * @return Symfony\Component\HttpKernel\Response
22 | */
23 | public function siteindexAction()
24 | {
25 | return $this->generateResponse('siteindex', array(
26 | 'totalPages' => $this->getTotalPages(),
27 | 'router' => $this->getRouter(),
28 | ));
29 | }
30 |
31 | /**
32 | * @return Symfony\Component\HttpKernel\Response
33 | */
34 | public function sitemapAction()
35 | {
36 | $page = $this->getPage($this->get('request')->query);
37 | return $this->generateResponse('sitemap', array(
38 | 'urls' => $this->getUrls($page),
39 | 'page' => $page,
40 | ));
41 | }
42 |
43 | protected function generateResponse($view, array $args)
44 | {
45 | $template = sprintf(
46 | 'OpenSkySitemapBundle:Sitemap:%s.xml.%s',
47 | $view,
48 | $this->container->getParameter('opensky.sitemap.template.engine')
49 | );
50 |
51 | return $this->getTemplating()->renderResponse($template, $args, new Response('', 200, array(
52 | 'Content-Type' => 'application/xml',
53 | )));
54 | }
55 |
56 | /**
57 | * @return int
58 | */
59 | protected function getTotalPages()
60 | {
61 | return $this->getSitemap()->getTotalPages();
62 | }
63 |
64 | /**
65 | * @param int $page
66 | * @return Traversable
67 | */
68 | protected function getUrls($page)
69 | {
70 | return $this->getSitemap()->getUrls($page);
71 | }
72 |
73 | /**
74 | * @return Symfony\Component\Templating\Engine
75 | */
76 | protected function getTemplating()
77 | {
78 | return $this->get('templating');
79 | }
80 |
81 | /**
82 | *
83 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Sitemap
84 | */
85 | protected function getSitemap()
86 | {
87 | return $this->get('opensky.sitemap');
88 | }
89 |
90 | /**
91 | * @return Symfony\Component\Routing\Router
92 | */
93 | protected function getRouter()
94 | {
95 | return $this->get('router');
96 | }
97 |
98 | /**
99 | * @return int
100 | */
101 | protected function getPage($query)
102 | {
103 | return (int) max(array(1, $query->get('page', 1)));
104 | }
105 |
106 | /**
107 | * @return Symfony\Component\HttpKernel\Response
108 | */
109 | protected function getResponse()
110 | {
111 | return $this->get('response');
112 | }
113 |
114 | }
115 |
--------------------------------------------------------------------------------
/Sitemap/Sitemap.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | class Sitemap
14 | {
15 | const DEFAULT_URL_CLASS = 'OpenSky\Bundle\SitemapBundle\Sitemap\Url';
16 |
17 | /**
18 | * @var string
19 | */
20 | protected $urlClass = self::DEFAULT_URL_CLASS;
21 | /**
22 | * @var array
23 | */
24 | protected $defaults = array();
25 | /**
26 | * @var OpenSky\Bundle\SitemapBundle\Sitemap\Storage\Storage
27 | */
28 | protected $storage;
29 |
30 | /**
31 | * @param OpenSky\Bundle\SitemapBundle\Sitemap\Storage\Storage $storage
32 | * @param array $defaults
33 | */
34 | public function __construct(Storage $storage, array $defaults = array())
35 | {
36 | $this->storage = $storage;
37 | foreach (array('changefreq', 'priority', 'lastmod') as $prop) {
38 | if (isset($defaults[$prop])) {
39 | $this->defaults[$prop] = $defaults[$prop];
40 | }
41 | }
42 | }
43 |
44 | /**
45 | * @return int
46 | */
47 | public function getTotalPages()
48 | {
49 | return $this->storage->getTotalPages();
50 | }
51 |
52 | /**
53 | * @param int $page
54 | * @return \Traversable
55 | */
56 | public function getUrls($page = 1)
57 | {
58 | return $this->storage->find($page);
59 | }
60 |
61 | /**
62 | * @param string $loc
63 | * @param array $info
64 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Url
65 | */
66 | public function add($loc, array $info)
67 | {
68 | $info = array_merge($this->defaults, $info);
69 | $urlClass = $this->getUrlClass();
70 | $url = new $urlClass($loc);
71 | foreach (array('changefreq', 'priority', 'lastmod') as $prop) {
72 | if (isset($info[$prop])) {
73 | $url->{'set' . ucfirst($prop)}($info[$prop]);
74 | }
75 | }
76 | $this->storage->save($url);
77 | return $url;
78 | }
79 |
80 | /**
81 | * @param string $loc
82 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Url|null
83 | */
84 | public function get($loc)
85 | {
86 | return $this->storage->findOne($loc);
87 | }
88 |
89 | /**
90 | * @param string $loc
91 | * @return boolean
92 | */
93 | public function has($loc)
94 | {
95 | return ($this->get($loc) !== null);
96 | }
97 |
98 | /**
99 | * @param string $class
100 | */
101 | public function setUrlClass($class)
102 | {
103 | if ($class !== self::DEFAULT_URL_CLASS && (!class_exists($class) || !is_subclass_of($class, self::DEFAULT_URL_CLASS))) {
104 | throw new \InvalidArgumentException('Class ' . $class . ' doesn\'t exist or is not instance of ' . self::DEFAULT_URL_CLASS);
105 | }
106 | $this->urlClass = $class;
107 | }
108 |
109 | /**
110 | * @return string
111 | */
112 | public function getUrlClass()
113 | {
114 | return $this->urlClass;
115 | }
116 |
117 | /**
118 | * @return OpenSky\Bundle\SitemapBundle\Sitemap\Storage\Storage
119 | */
120 | public function getStorage()
121 | {
122 | return $this->storage;
123 | }
124 |
125 | }
--------------------------------------------------------------------------------
/Sitemap/Url.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2010 OpenSky Project Inc
12 | */
13 | class Url
14 | {
15 | const PATTERN = '~^
16 | (http|https):// # protocol
17 | (
18 | ([a-z0-9-]+\.)+[a-z]{2,6} # a domain name
19 | | # or
20 | \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3} # a IP address
21 | )
22 | (:[0-9]+)? # a port (optional)
23 | (/?|/\S+) # a /, nothing or a / with something
24 | $~ix';
25 | const DAILY = 'daily';
26 | const WEEKLY = 'weekly';
27 | const MONTHLY = 'monthly';
28 | const YEARLY = 'yearly';
29 | const LASTMOD_FORMAT = 'Y-m-d';
30 |
31 | /**
32 | * @var string
33 | */
34 | protected $loc;
35 | /**
36 | *
37 | * @var string
38 | */
39 | protected $lastmod;
40 | /**
41 | *
42 | * @var string
43 | */
44 | protected $changefreq;
45 | /**
46 | * @var float
47 | */
48 | protected $priority;
49 |
50 | /**
51 | * @param string $loc
52 | * @throws \InvalidArgumentException
53 | */
54 | public function __construct($loc)
55 | {
56 | if (!preg_match(self::PATTERN, $loc)) {
57 | throw new Exception\InvalidArgumentException($loc . ' is not valid url location');
58 | }
59 | $this->loc = $loc;
60 | }
61 |
62 | /**
63 | * @return string
64 | */
65 | public function getLoc()
66 | {
67 | return $this->loc;
68 | }
69 |
70 | /**
71 | * @param string|\DateTime $lastmod
72 | */
73 | public function setLastmod($lastmod)
74 | {
75 | if ($lastmod instanceof \DateTime) {
76 | $lastmod = $lastmod->getTimestamp();
77 | }
78 | $this->lastmod = date(self::LASTMOD_FORMAT, $lastmod);
79 | }
80 |
81 | /**
82 | * @return string
83 | */
84 | public function getLastmod()
85 | {
86 | if ($this->lastmod instanceof \DateTime) {
87 | $this->lastmod = $this->lastmod->format(self::LASTMOD_FORMAT);
88 | }
89 | return $this->lastmod;
90 | }
91 |
92 | /**
93 | * @param string $changefreq
94 | */
95 | public function setChangefreq($changefreq)
96 | {
97 | if (!in_array($changefreq, array(self::DAILY, self::MONTHLY, self::WEEKLY, self::YEARLY))) {
98 | throw new Exception\InvalidArgumentException('Change frequency ' . $changefreq . ' is invalid');
99 | }
100 | $this->changefreq = $changefreq;
101 | }
102 |
103 | /**
104 | * @return string
105 | */
106 | public function getChangefreq()
107 | {
108 | return $this->changefreq;
109 | }
110 |
111 | /**
112 | * @param float $priority
113 | */
114 | public function setPriority($priority)
115 | {
116 | if ($priority <= 0 || $priority > 1) {
117 | throw new Exception\InvalidArgumentException('Priority must be in between 0 and 1, ' . $priority . ' given');
118 | }
119 | $this->priority = $priority;
120 | }
121 |
122 | /**
123 | * @return string
124 | */
125 | public function getPriority()
126 | {
127 | return number_format($this->priority, 1);
128 | }
129 |
130 | }
--------------------------------------------------------------------------------
/Tests/Listener/SitemapListenerTest.php:
--------------------------------------------------------------------------------
1 |
17 | * @copyright (c) 2010 OpenSky Project Inc
18 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
19 | */
20 | class SitemapListenerTest extends \PHPUnit_Framework_TestCase
21 | {
22 | /**
23 | * @var Bundle\SitemapBundle\Listener\SitemapListener
24 | */
25 | protected $listener;
26 | /**
27 | * @var Bundle\SitemapBundle\Sitemap\Sitemap
28 | */
29 | protected $sitemap;
30 | /**
31 | * @var Bundle\SitemapBundle\Dumper\Dumper
32 | */
33 | protected $dumper;
34 |
35 | public function setUp()
36 | {
37 | $this->sitemap = $this->getSitemap();
38 | $this->dumper = $this->getDumper();
39 | $this->listener = new SitemapListener($this->sitemap, $this->dumper);
40 | }
41 |
42 | public function tearDown()
43 | {
44 | unset($this->sitemap, $this->dumper, $this->listener);
45 | }
46 |
47 | public function testRegister()
48 | {
49 | $connectedEvents = array();
50 |
51 | $eventDispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcher', array('connect'), array(), '', false, false);
52 | $eventDispatcher->expects($this->exactly(2))
53 | ->method('connect')
54 | ->will($this->returnCallback(function ($eventName, $callback) use (&$connectedEvents) {
55 | $connectedEvents[$eventName] = $callback;
56 | }));
57 |
58 | $this->listener->register($eventDispatcher);
59 |
60 | foreach (array('update', 'create') as $name) {
61 | $eventName = 'sitemap.' . $name;
62 | $this->assertArrayHasKey($eventName, $connectedEvents);
63 | $this->assertEquals(array($this->listener, $name), $connectedEvents[$eventName]);
64 | }
65 | }
66 |
67 | public function testCreate()
68 | {
69 | $this->dumper->expects($this->once())
70 | ->method('dump')
71 | ->with($this->sitemap);
72 |
73 | $urlData = array(
74 | 'loc' => 'http://google.com',
75 | 'changefreq' => 'monthly',
76 | 'priority' => '1',
77 | );
78 |
79 | $this->listener->create(new Event($this, 'sitemap.create', $urlData));
80 |
81 | $this->assertTrue($this->sitemap->has($urlData['loc']));
82 |
83 | $url = $this->sitemap->get($urlData['loc']);
84 |
85 | $this->assertEquals($urlData, array(
86 | 'loc' => $url->getLoc(),
87 | 'changefreq' => $url->getChangefreq(),
88 | 'priority' => $url->getPriority(),
89 | ));
90 | $this->assertEquals(date(Url::LASTMOD_FORMAT), $url->getLastmod());
91 | }
92 |
93 | public function testUpdate()
94 | {
95 | $url = 'http://google.com';
96 |
97 | $entry = $this->sitemap->add($url, array(
98 | 'lastmod' => new \DateTime('-2 months'),
99 | 'changefreq' => Url::YEARLY,
100 | 'priority' => '0.8',
101 | ));
102 |
103 | $this->dumper->expects($this->once())
104 | ->method('dump')
105 | ->with($this->sitemap);
106 |
107 | $this->listener->update(new Event($this, 'sitemap.update', array('loc' => $url)));
108 |
109 | $this->assertEquals(date(Url::LASTMOD_FORMAT), $entry->getLastmod());
110 | $this->assertEquals(Url::MONTHLY, $entry->getChangefreq());
111 | }
112 |
113 | /**
114 | * @expectedException Bundle\SitemapBundle\Exception\OutOfBoundsException
115 | */
116 | public function testUpdateThrowsException()
117 | {
118 | $this->listener->update(new Event($this, 'sitemap.update', array('loc' => 'http://www.example.com')));
119 | }
120 |
121 | /**
122 | * @return Bundle\SitemapBundle\Sitemap\Sitemap
123 | */
124 | protected function getSitemap()
125 | {
126 | return new Sitemap(new Memory());
127 | }
128 |
129 | /**
130 | * @return Bundle\SitemapBundle\Dumper\Dumper
131 | */
132 | protected function getDumper()
133 | {
134 | return $this->getMock('Bundle\SitemapBundle\Dumper\Dumper', array('dump'), array(), '', false, false);
135 | }
136 |
137 | }
--------------------------------------------------------------------------------
/Tests/Sitemap/SitemapTest.php:
--------------------------------------------------------------------------------
1 |
14 | * @copyright (c) 2010 OpenSky Project Inc
15 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
16 | */
17 | class SitemapTest extends \PHPUnit_Framework_TestCase
18 | {
19 |
20 | public function testNoUrls()
21 | {
22 | $sitemap = $this->getSitemap();
23 | $this->assertEquals(0, count($sitemap->getUrls()));
24 | }
25 |
26 | public function testAddUrl()
27 | {
28 | $sitemap = $this->getSitemap();
29 | $sitemap->add('http://www.example.org/', array(
30 | 'lastmod' => new \DateTime(),
31 | 'changefreq' => Url::DAILY,
32 | 'priority' => 1.0,
33 | ));
34 | $this->assertEquals(1, count($sitemap->getUrls()));
35 | }
36 |
37 | public function testAddGetsUrl()
38 | {
39 | $sitemap = $this->getSitemap();
40 | $lastMod = new \DateTime();
41 | $url = $sitemap->add('http://www.example.org/', array(
42 | 'lastmod' => $lastMod,
43 | 'changefreq' => Url::DAILY,
44 | 'priority' => 1.0,
45 | ));
46 | $this->assertUrlProperties(array(
47 | 'loc' => 'http://www.example.org/',
48 | 'lastmod' => date(Url::LASTMOD_FORMAT, $lastMod->getTimestamp()),
49 | 'changefreq' => 'daily',
50 | 'priority' => 1.0,
51 | ), $url);
52 | }
53 |
54 | /**
55 | * @expectedException InvalidArgumentException
56 | */
57 | public function testThrowsOnInvalidUrlClass()
58 | {
59 | $sitemap = $this->getSitemap();
60 | $sitemap->setUrlClass(get_class($this));
61 | }
62 |
63 | public function testGetUrlClass()
64 | {
65 | $sitemap = $this->getSitemap();
66 | $sitemap->setUrlClass('Bundle\SitemapBundle\Sitemap\Url');
67 | $this->assertEquals('Bundle\SitemapBundle\Sitemap\Url', $sitemap->getUrlClass());
68 | }
69 |
70 | public function testAddsDefaultInfo()
71 | {
72 | $sitemap = $this->getSitemap(array(
73 | 'changefreq' => 'monthly',
74 | 'lastmod' => new \DateTime('2006-01-01'),
75 | 'priority' => 0.1,
76 | ));
77 | $url = $sitemap->add('http://www.google.com/', array());
78 | $this->assertUrlProperties(array(
79 | 'loc' => 'http://www.google.com/',
80 | 'changefreq' => 'monthly',
81 | 'lastmod' => '2006-01-01',
82 | 'priority' => 0.1,
83 | ), $url);
84 | }
85 |
86 | public function testAppendsDefaultInfo()
87 | {
88 | $sitemap = $this->getSitemap(array(
89 | 'changefreq' => 'monthly',
90 | 'lastmod' => new \DateTime('2006-01-01'),
91 | 'priority' => 0.1,
92 | ));
93 | $url = $sitemap->add('http://www.google.com/', array(
94 | 'lastmod' => new \DateTime('2010-01-01'),
95 | 'priority' => 0.6,
96 | ));
97 | $this->assertUrlProperties(array(
98 | 'loc' => 'http://www.google.com/',
99 | 'changefreq' => 'monthly',
100 | 'lastmod' => '2010-01-01',
101 | 'priority' => 0.6,
102 | ), $url);
103 | }
104 |
105 | public function testGetUrl()
106 | {
107 | $now = new \DateTime();
108 | $sitemap = $this->getSitemap();
109 | $sitemap->add('http://www.example.org/', array(
110 | 'lastmod' => $now,
111 | 'changefreq' => Url::MONTHLY,
112 | 'priority' => 1.0,
113 | ));
114 | $sitemap->add('http://www.example.org/index', array(
115 | 'lastmod' => $now,
116 | 'changefreq' => Url::DAILY,
117 | 'priority' => 0.8,
118 | ));
119 | $this->assertUrlProperties(array(
120 | 'loc' => 'http://www.example.org/',
121 | 'lastmod' => date(Url::LASTMOD_FORMAT, $now->getTimestamp()),
122 | 'changefreq' => Url::MONTHLY,
123 | 'priority' => 1.0,
124 | ), $sitemap->get('http://www.example.org/'));
125 | }
126 |
127 | public function testGetUrlReturnsNullIfNoFound()
128 | {
129 | $sitemap = $this->getSitemap();
130 | $this->assertNull($sitemap->get('http://www.example.org'));
131 | }
132 |
133 | public function testHasReturnsFalseOnNonExistentRoute()
134 | {
135 | $this->assertFalse($this->getSitemap()->has('http://www.google.com/'));
136 | }
137 |
138 | public function testReturnsTrueOnExistentUrl()
139 | {
140 | $sitemap = $this->getSitemap();
141 | $sitemap->add('http://www.google.com/', array(
142 | 'lastmod' => new \DateTime('2010-01-01'),
143 | 'priority' => 0.6,
144 | ));
145 | $this->assertTrue($sitemap->has('http://www.google.com/'));
146 | }
147 |
148 | public function getSitemap(array $options = array())
149 | {
150 | return new Sitemap(new \Bundle\SitemapBundle\Sitemap\Storage\Memory(), $options);
151 | }
152 |
153 | protected function assertUrlProperties(array $properties, Url $url, $message = 'Url properties didn\'t match specification')
154 | {
155 | foreach (array('loc', 'lastmod', 'changefreq', 'priority') as $prop) {
156 | if (isset($properties[$prop]) && $properties[$prop] != $url->{'get' . ucfirst($prop)} ()) {
157 | $this->fail($message . PHP_EOL . 'property: ' . $prop . PHP_EOL . 'expected: ' . print_r($properties[$prop], true) . PHP_EOL . 'actual: ' . print_r($url->{'get' . ucfirst($prop)} (), true));
158 | }
159 | }
160 | }
161 |
162 | }
--------------------------------------------------------------------------------
/Tests/Sitemap/Storage/Doctrine/ODM/MongoDBTest.php:
--------------------------------------------------------------------------------
1 |
14 | * @copyright (c) 2010 OpenSky Project Inc
15 | * @license http://www.gnu.org/licenses/agpl.txt GNU Affero General Public License
16 | */
17 | class MongoDBTest extends \PHPUnit_Framework_TestCase
18 | {
19 | protected $storage;
20 | protected $dm;
21 | protected $repository;
22 |
23 | public function setUp()
24 | {
25 | $this->dm = $this->getDocumentManagerMock();
26 | $this->repository = $this->getDocumentRepositoryMock();
27 | $this->storage = new MongoDB($this->dm);
28 |
29 | $this->storage->setRepository($this->repository);
30 | }
31 |
32 | public function tearDown()
33 | {
34 | unset($this->storage, $this->repository, $this->dm);
35 | }
36 |
37 | public function testRegister()
38 | {
39 | $classMetadata = $this->getClassMetadataMock();
40 | $classMetadataFactory = $this->getClassMetadataFactoryMock();
41 |
42 | $classMetadataFactory->expects($this->once())
43 | ->method('setMetadataFor')
44 | ->with(MongoDB::URL_CLASS, $classMetadata);
45 |
46 | $this->storage->register($classMetadata, $classMetadataFactory);
47 | }
48 |
49 | /**
50 | * @dataProvider getUrls
51 | */
52 | public function testFindOne($location, $result)
53 | {
54 | $this->repository->expects($this->once())
55 | ->method('find')
56 | ->with($location)
57 | ->will($this->returnValue($result));
58 |
59 | $this->assertSame($result, $this->storage->findOne($location));
60 | }
61 |
62 | public function testFind()
63 | {
64 | $expectedNumberOfResults = 5;
65 | $page = 1;
66 | $cursor = $this->getMongoCursorMock();
67 |
68 | $cursor->expects($this->once())
69 | ->method('skip')
70 | ->with(($page - 1) * MongoDB::PAGE_LIMIT)
71 | ->will($this->returnValue($cursor));
72 | $cursor->expects($this->once())
73 | ->method('limit')
74 | ->with(MongoDB::PAGE_LIMIT)
75 | ->will($this->returnValue($cursor));
76 | $cursor->expects($this->once())
77 | ->method('count')
78 | ->will($this->returnValue($expectedNumberOfResults));
79 |
80 | $this->repository->expects($this->once())
81 | ->method('findAll')
82 | ->will($this->returnValue($cursor));
83 |
84 | $this->assertEquals($expectedNumberOfResults, count($this->storage->find($page)));
85 | }
86 |
87 | public function testSave()
88 | {
89 | $url = new Url('http://www.example.com');
90 |
91 | $this->dm->expects($this->once())
92 | ->method('persist')
93 | ->with($url);
94 |
95 | $this->storage->save($url);
96 | }
97 |
98 | public function testGetTotalPages()
99 | {
100 | $cursor = $this->getMongoCursorMock();
101 |
102 | $cursor->expects($this->once())
103 | ->method('count')
104 | ->will($this->returnValue(MongoDB::PAGE_LIMIT + 1));
105 |
106 | $this->repository->expects($this->once())
107 | ->method('findAll')
108 | ->will($this->returnValue($cursor));
109 |
110 | $this->assertEquals(2, $this->storage->getTotalPages());
111 | }
112 |
113 | public function testGetDocumentManager()
114 | {
115 | $this->assertSame($this->dm, $this->storage->getDocumentManager());
116 | }
117 |
118 | public function testGetDocumentRepository()
119 | {
120 | $this->assertSame($this->repository, $this->storage->getDocumentRepository());
121 | }
122 |
123 | public function getUrls()
124 | {
125 | return array(
126 | array('http://example.com/', null),
127 | array('http://example.com/', new Url('http://example.com/')),
128 | );
129 | }
130 |
131 | /**
132 | * @return Doctrine\ODM\MongoDB\Mapping\ClassMetadata
133 | */
134 | protected function getClassMetadataMock()
135 | {
136 | return $this->getMockBuilder('Doctrine\ODM\MongoDB\Mapping\ClassMetadata')
137 | ->disableOriginalConstructor()
138 | ->disableOriginalClone()
139 | ->getMock();
140 | }
141 |
142 | /**
143 | * @return Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory
144 | */
145 | protected function getClassMetadataFactoryMock()
146 | {
147 | return $this->getMockBuilder('Doctrine\ODM\MongoDB\Mapping\ClassMetadataFactory')
148 | ->disableOriginalConstructor()
149 | ->disableOriginalClone()
150 | ->getMock();
151 | }
152 |
153 | /**
154 | * @return Doctrine\ODM\MongoDB\DocumentManager
155 | */
156 | protected function getDocumentManagerMock()
157 | {
158 | return $this->getMockBuilder('Doctrine\ODM\MongoDB\DocumentManager')
159 | ->disableOriginalConstructor()
160 | ->disableOriginalClone()
161 | ->getMock();
162 | }
163 |
164 | /**
165 | * @return Doctrine\ODM\MongoDB\DocumentRepository
166 | */
167 | protected function getDocumentRepositoryMock()
168 | {
169 | return $this->getMockBuilder('Doctrine\ODM\MongoDB\DocumentRepository')
170 | ->disableOriginalConstructor()
171 | ->disableOriginalClone()
172 | ->getMock();
173 | }
174 |
175 | /**
176 | * @return Doctrine\ODM\MongoDB\Cursor
177 | */
178 | protected function getMongoCursorMock()
179 | {
180 | return $this->getMockBuilder('Doctrine\ODM\MongoDB\Cursor')
181 | ->disableOriginalConstructor()
182 | ->disableOriginalClone()
183 | ->getMock();
184 | }
185 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenSky SitemapBundle
2 |
3 | This bundle will help with sitemap generation in your Symfony2 based projects.
4 |
5 | ## Installation via Composer
6 |
7 | Add the following to the "repositories" section of composer.json:
8 | ```
9 | {
10 | "type": "vcs",
11 | "url": "https://github.com/opensky/SitemapBundle"
12 | }
13 | ```
14 |
15 | Add the following to the "require" section of composer.json:
16 |
17 | "opensky/sitemap-bundle": "dev-master"
18 |
19 | ## Adding the bundle to your kernel
20 |
21 | To enable the sitemap bundle, add it to your kernel registerBundles() method:
22 |
23 | use Symfony\Foundation\Kernel;
24 |
25 | class MyKernel extends Kernel {
26 | // ...
27 | public function registerBundles() {
28 | return array(
29 | // ...
30 | new OpenSky\Bundle\SitemapBundle\OpenSkySitemapBundle(),
31 | // ...
32 | );
33 | }
34 | }
35 |
36 |
37 | ## Enabling the services
38 |
39 | The second step is to enable its DependencyInjection extension in your `config.yml`:
40 |
41 | opensky_sitemap:
42 | default_lastmod: 2010-06-01
43 | default_changefreq: monthly
44 | default_priority: 0.5
45 |
46 | You will need a Doctrine ODM MongoDB connection for your sitemap. This means that you have to add `DoctrineMongoDBBundle` to your Kernel and register its configuration like so:
47 |
48 | doctrine_odm.mongodb:
49 | auto_generate_proxy_classes: true
50 | default_document_manager: default
51 | default_connection: mongodb
52 | cache_driver: array
53 | metadata_cache_driver: array
54 | default_database: opensky
55 | proxy_namespace: Proxies
56 | document_managers:
57 | default:
58 | connection: mongodb
59 | connections:
60 | mongodb:
61 | server: localhost:27017
62 |
63 |
64 | ## Defining a Url class
65 |
66 | You will need to add a URL document to your model. Most likely, you will want to save a class that looks like this to your `Document` directory:
67 |
68 | topicRepository = $topicRepository;
119 | $this->router = $router;
120 | }
121 |
122 | public function populate(Sitemap $sitemap)
123 | {
124 | foreach ($this->topicRepository->find() as $topic) {
125 | $sitemap->add($this->router->generate('topic_view', array(
126 | 'id' => $topic->getId(),
127 | ), true), array(
128 | 'changefreq' => \OpenSky\Bundle\SitemapBundle\Sitemap\Url::MONTHLY,
129 | 'lastmod' => $seller->getUpdatedAt(),
130 | 'priority' => '0.8',
131 | )
132 | );
133 | }
134 | }
135 | }
136 |
137 | **NOTE:** in the above example, we use router to generate absolute urls. Since you don't have knowledge of your current domain in the CLI mode (the mode, where commands are run), router will still generate relative urls. You have to make the host a container parameter, that you will then use inside of your sitemap provider.
138 |
139 | And register your provider in DIC like this:
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 | After providers are in place and registered, time to run the generation command:
148 |
149 | > php forum/console sitemap:generate
150 |
151 | or simply:
152 |
153 | > php forum/console sitemap:g
154 |
155 |
156 | ## Creating/Updating sitemap urls in the application
157 |
158 | After the three steps were completed, you can use Symfony2's native 'event_dispatcher'
159 | service to let the 'sitemap' know of new url:
160 |
161 | $eventDispatcher->notify(new Event($this, 'opensky.sitemap.create', array(
162 | 'loc' => $router->generate('user_view', array('id' => $user->getId())),
163 | 'changefreq' => 'daily',
164 | 'priority' => '0.8',
165 | )));
166 |
167 | or existing url updates:
168 |
169 | $eventDispatcher->notify(new Event($this, 'opensky.sitemap.update', array(
170 | 'loc' => $router->generate('user_view', array('id' => $user->getId())),
171 | 'priority' => '0.6',
172 | )));
173 |
174 |
175 | ## Enabling sitemap routes
176 |
177 | The last and most important step is to enable sitemap routing in your routing.yml:
178 |
179 | sitemap:
180 | resource: @OpenSkySitemapBundle/Resources/config/routing.yml
181 |
182 | After that is done, you can access your sitemap at /sitemap.xml and siteindex at /siteindex.xml
183 |
184 | Happy Coding
185 |
--------------------------------------------------------------------------------