Skip to content
This repository has been archived by the owner on Sep 16, 2021. It is now read-only.

Commit

Permalink
sitemap generation
Browse files Browse the repository at this point in the history
  • Loading branch information
ElectricMaxxx committed Feb 16, 2015
1 parent e488e32 commit b2e8b97
Show file tree
Hide file tree
Showing 34 changed files with 1,758 additions and 17 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Changelog
=========

* **2015-14-02**: implement sitemap generation
* **2015-14-02**: [BC BREAK] Changed method visibility from private to public of SeoPresentation#getSeoMetadata()
* **2014-10-04**: Custom exception controller for error handling

1.1.0-RC3
Expand Down
2 changes: 2 additions & 0 deletions CmfSeoBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;

use Symfony\Cmf\Bundle\SeoBundle\DependencyInjection\Compiler\RegisterUrlInformationProviderPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;

Expand All @@ -26,6 +27,7 @@ public function build(ContainerBuilder $container)
{
$container->addCompilerPass(new RegisterExtractorsPass());
$container->addCompilerPass(new RegisterSuggestionProviderPass());
$container->addCompilerPass(new RegisterUrlInformationProviderPass());

$this->buildPhpcrCompilerPass($container);
$this->buildOrmCompilerPass($container);
Expand Down
103 changes: 103 additions & 0 deletions Controller/SitemapController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

/*
* This file is part of the Symfony CMF package.
*
* (c) 2011-2014 Symfony CMF
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Cmf\Bundle\SeoBundle\Controller;

use Symfony\Cmf\Bundle\SeoBundle\Model\UrlInformation;
use Symfony\Cmf\Bundle\SeoBundle\Sitemap\UrlInformationProviderInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Templating\EngineInterface;

/**
* Controller to handle requests for sitemap.
*
* @author Maximilian Berghoff <[email protected]>
*/
class SitemapController
{
/**
* @var UrlInformationProviderInterface
*/
private $urlProvider;
/**
* @var EngineInterface
*/
private $templating;

/**
* @var array
*/
private $templates;

/**
* You should provide templates for html and xml.
*
* Json is serialized by default, but can be customized with a template
*
* @param UrlInformationProviderInterface $provider
* @param EngineInterface $templating
* @param array $templates Hash map with key being the format,
* value the name of the twig template
* to render the sitemap in that format
*/
public function __construct(
UrlInformationProviderInterface $provider,
EngineInterface $templating,
array $templates
) {
$this->urlProvider = $provider;
$this->templating = $templating;
$this->templates = $templates;
}

/**
* @param string $_format The format of the sitemap.
*
* @return Response
*/
public function indexAction($_format)
{
$supportedFormats = array_merge(array('json'), array_keys($this->templates));
if (!in_array($_format, $supportedFormats)) {
$text = sprintf(
'Unknown format %s, use one of %s.',
$_format,
implode(', ', $supportedFormats)
);

return new Response($text, 406);
}

$urls = $this->urlProvider->getUrlInformation();
if (isset($this->templates[$_format])) {
return new Response($this->templating->render($this->templates[$_format], array('urls' => $urls)));
}

return $this->createJsonResponse($urls);
}

/**
* @param array|UrlInformation[] $urls
*
* @return JsonResponse
*/
private function createJsonResponse($urls)
{
$result = array();

foreach ($urls as $url) {
$result[] = $url->toArray();
}

return new JsonResponse($result);
}
}
39 changes: 31 additions & 8 deletions DependencyInjection/CmfSeoExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Cmf\Bundle\RoutingBundle\Routing\DynamicRouter;
Expand Down Expand Up @@ -64,8 +65,6 @@ public function load(array $configs, ContainerBuilder $container)
$sonataBundles[] = 'SonataDoctrinePHPCRAdminBundle';

$this->loadPhpcr($config['persistence']['phpcr'], $loader, $container);

$loader->load('matcher_phpcr.xml');
}

if ($this->isConfigEnabled($container, $config['persistence']['orm'])) {
Expand All @@ -87,6 +86,10 @@ public function load(array $configs, ContainerBuilder $container)

$errorConfig = isset($config['error']) ? $config['error'] : array();
$this->loadErrorHandling($errorConfig, $container);

if ($this->isConfigEnabled($container, $config['sitemap'])) {
$this->loadSitemapHandling($config['sitemap'], $loader, $container);
}
}

/**
Expand Down Expand Up @@ -169,6 +172,9 @@ private function loadPhpcr($config, XmlFileLoader $loader, ContainerBuilder $con
$this->defaultAlternateLocaleProviderId = 'cmf_seo.alternate_locale.provider_phpcr';
}
}

$loader->load('matcher_phpcr.xml');
$loader->load('phpcr-sitemap.xml');
}

/**
Expand All @@ -189,13 +195,19 @@ private function loadAlternateLocaleProvider($config, ContainerBuilder $containe


if ($alternateLocaleProvider) {
$definition = $container->getDefinition('cmf_seo.event_listener.seo_content');
$definition
$alternateLocaleProviderDefinition = $container->findDefinition($alternateLocaleProvider);
$container
->findDefinition('cmf_seo.event_listener.seo_content')
->addMethodCall(
'setAlternateLocaleProvider',
array($alternateLocaleProviderDefinition)
);
$container
->findDefinition('cmf_seo.sitemap.phpcr_provider')
->addMethodCall(
'setAlternateLocaleProvider',
array($container->getDefinition($alternateLocaleProvider))
)
;
array($alternateLocaleProviderDefinition)
);
}
}

Expand All @@ -210,10 +222,21 @@ private function loadAlternateLocaleProvider($config, ContainerBuilder $containe
private function loadErrorHandling($config, ContainerBuilder $container)
{
foreach (array('parent', 'sibling') as $group) {
$remove = isset($config['enable_'.$group.'_provider']) && !$config['enable_'.$group.'_provider'] ? true : false;
$remove = isset($config['enable_'.$group.'_provider'])
&& !$config['enable_'.$group.'_provider'] ? true : false;
if ($container->has('cmf_seo.error.suggestion_provider.'.$group) && $remove) {
$container->removeDefinition('cmf_seo.error.suggestion_provider.'.$group);
}
}
}

private function loadSitemapHandling($config, XmlFileLoader $loader, ContainerBuilder $container)
{
$loader->load('sitemap.xml');

$container->setParameter(
$this->getAlias().'.sitemap.default_change_frequency',
$config['default_chan_frequency']
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

/*
* This file is part of the Symfony CMF package.
*
* (c) 2011-2014 Symfony CMF
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/

namespace Symfony\Cmf\Bundle\SeoBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Reference;

/**
* Compiler adds custom url information provider to the phpcr chain provider.
*
* To do so you need to tag them with "cmf_seo.sitemap.url_information_provider".
*
* @author Maximilian Berghoff <[email protected]>
*/
class RegisterUrlInformationProviderPass implements CompilerPassInterface
{
/**
* {@inheritDoc}
*
* @throws LogicException If a tagged service is not public.
*/
public function process(ContainerBuilder $container)
{
// feature not activated means nothing to add
if (!$container->hasDefinition('cmf_seo.sitemap.url_information_provider')) {
return;
}

$chainProviderDefinition = $container->getDefinition('cmf_seo.sitemap.url_information_provider');
$taggedServices = $container->findTaggedServiceIds('cmf_seo.sitemap.url_information_provider');

foreach ($taggedServices as $id => $attributes) {
$priority = null;
foreach ($attributes as $attribute) {
if (isset($attribute['priority'])) {
$priority = $attribute['priority'];
break;
}
}
$priority = $priority ?: 0;

$chainProviderDefinition->addMethodCall('addProvider', array(new Reference($id), $priority));
}
}
}
9 changes: 8 additions & 1 deletion DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ public function getConfigTreeBuilder()
->addDefaultsIfNotSet()
->beforeNormalization()
->ifTrue( function ($v) { return is_scalar($v); })
->then( function ($v) {
->then(function ($v) {
return array('enabled' => $v);
})
->end()
Expand All @@ -85,6 +85,13 @@ public function getConfigTreeBuilder()
->scalarNode('enable_sibling_provider')->defaultValue(false)->end()
->end()
->end()
->arrayNode('sitemap')
->addDefaultsIfNotSet()
->canBeEnabled()
->children()
->scalarNode('default_chan_frequency')->defaultValue('always')->end()
->end()
->end()
->end()
;

Expand Down
Loading

0 comments on commit b2e8b97

Please sign in to comment.