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

Commit

Permalink
Moved most of the logic to a Factory extension
Browse files Browse the repository at this point in the history
Refs commit: KnpLabs/KnpMenu@5056422

Again, this allows us to have less duplication.
  • Loading branch information
wouterj committed Nov 1, 2014
1 parent ac32d60 commit 71a7011
Show file tree
Hide file tree
Showing 6 changed files with 134 additions and 148 deletions.
24 changes: 4 additions & 20 deletions Admin/AbstractMenuNodeAdmin.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,13 @@
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Sonata\DoctrinePHPCRAdminBundle\Admin\Admin;
use Symfony\Cmf\Bundle\MenuBundle\Model\MenuNode;
use Symfony\Cmf\Bundle\MenuBundle\Model\MenuNodeBase;
use Symfony\Cmf\Bundle\MenuBundle\ContentAwareFactory;

/**
* Common base admin for Menu and MenuNode
*/
abstract class AbstractMenuNodeAdmin extends Admin
{
/**
* @var ContentAwareFactory
*/
protected $contentAwareFactory;

/**
* @var string
*/
Expand Down Expand Up @@ -73,9 +66,10 @@ protected function configureFormFields(FormMapper $formMapper)
$formMapper
->with('form.group_general')
->add('linkType', 'choice_field_mask', array(
'choices' => array_combine(
$this->contentAwareFactory->getLinkTypes(),
$this->contentAwareFactory->getLinkTypes()
'choices' => array(
'route' => 'route',
'uri' => 'uri',
'content' => 'content',
),
'map' => array(
'route' => array('route'),
Expand Down Expand Up @@ -115,16 +109,6 @@ public function getExportFormats()
return array();
}

public function getContentAwareFactory()
{
return $this->contentAwareFactory;
}

public function setContentAwareFactory(ContentAwareFactory $contentAwareFactory)
{
$this->contentAwareFactory = $contentAwareFactory;
}

public function setContentRoot($contentRoot)
{
$this->contentRoot = $contentRoot;
Expand Down
109 changes: 0 additions & 109 deletions ContentAwareFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,6 @@ public function getLinkTypes()
return $this->linkTypes;
}

/**
* Whether to return a MenuItem without an URL or null when a MenuNode has
* no URL that can be found.
*
* @param boolean $allowEmptyItems
*/
public function setAllowEmptyItems($allowEmptyItems)
{
$this->allowEmptyItems = $allowEmptyItems;
}

/**
* Add a voter to decide on current item.
*
Expand Down Expand Up @@ -210,64 +199,6 @@ public function addChildrenFromNode($nodes, ItemInterface $item)
*/
public function createItem($name, array $options = array())
{
$options = array_merge(array(
'content' => null,
'routeParameters' => array(),
'routeAbsolute' => false,
'uri' => null,
'route' => null,
'linkType' => null,
), $options);

if (null === $options['linkType']) {
$options['linkType'] = $this->determineLinkType($options);
}

$this->validateLinkType($options['linkType']);

switch ($options['linkType']) {
case 'content':
try {
$options['uri'] = $this->contentRouter->generate(
$options['content'],
$options['routeParameters'],
$options['routeAbsolute']
);
} catch (RouteNotFoundException $e) {
if (!$this->allowEmptyItems) {
return null;
}
}
unset($options['route']);
break;
case 'uri':
unset($options['route']);
break;
case 'route':
unset($options['uri']);

try {
$options['uri'] = $this->generator->generate(
$options['route'],
$options['routeParameters'],
$options['routeAbsolute']
);

unset($options['route']);
} catch (RouteNotFoundException $e) {
$this->logger->error(sprintf('%s : %s', $name, $e->getMessage()));

if (!$this->allowEmptyItems) {
return null;
}
}
break;
default:
throw new \RuntimeException(sprintf('Internal error: unexpected linkType "%s"', $options['linkType']));
}

$item = parent::createItem($name, $options);
$item->setExtra('content', $options['content']);

$current = $this->isCurrentItem($item);

Expand All @@ -278,46 +209,6 @@ public function createItem($name, array $options = array())
return $item;
}

/**
* If linkType not specified, we can determine it from
* existing options
*/
protected function determineLinkType($options)
{
if (!empty($options['uri'])) {
return 'uri';
}

if (!empty($options['route'])) {
return 'route';
}

if (!empty($options['content'])) {
return 'content';
}

return 'uri';
}

/**
* Ensure that we have a valid link type.
*
* @param string $linkType
*
* @throws \InvalidArgumentException if $linkType is not one of the known
* link types
*/
protected function validateLinkType($linkType)
{
if (!in_array($linkType, $this->linkTypes)) {
throw new \InvalidArgumentException(sprintf(
'Invalid link type "%s". Valid link types are: "%s"',
$linkType,
implode(',', $this->linkTypes)
));
}
}

/**
* Cycle through all voters. If any votes true, this is the current item. If
* any votes false cycling stops. Continue cycling while we get null.
Expand Down
3 changes: 1 addition & 2 deletions DependencyInjection/CmfMenuExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ public function load(array $configs, ContainerBuilder $container)
);

$loader->load('menu.xml');
$factory = $container->getDefinition($this->getAlias().'.factory');
$factory->replaceArgument(1, new Reference($config['content_url_generator']));
$container->setAlias('cmf_menu.content_router', $config['content_url_generator']);
$container->setParameter($this->getAlias() . '.allow_empty_items', $config['allow_empty_items']);

$this->loadVoters($config, $loader, $container);
Expand Down
121 changes: 121 additions & 0 deletions Extension/ContentExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

namespace Symfony\Cmf\Bundle\MenuBundle\Extension;

use Knp\Menu\Factory\ExtensionInterface;
use Knp\Menu\ItemInterface;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;

/**
* An extension of the MenuFactory to generate URLs from the Content object.
*
* It has to be registered with a priority higher than the CoreExtension and
* RoutingExtension provided by the KnpMenuBundle.
*
* @author Wouter J <wouter@wouterj.nl>
*/
class ContentExtension implements ExtensionInterface
{
/**
* @var UrlGeneratorInterface
*/
private $contentRouter;

/**
* @param UrlGeneratorInterface $contentRouter A router to generate URLs based on the content object
*/
public function __construct(UrlGeneratorInterface $contentRouter)
{
$this->contentRouter = $contentRouter;
}

/**
* Builds the full option array used to configure the item.
*
* @param array $options The options processed by the previous extensions
*
* @return array
*/
public function buildOptions(array $options)
{
$options = array_merge(array(
'content' => null,
'linkType' => null,
'extras' => array(),
), $options);

if (null === $options['linkType']) {
$options['linkType'] = $this->determineLinkType($options);
}

$this->validateLinkType($options['linkType']);

if ('content' === $options['linkType']) {
$options['uri'] = $this->contentRouter->generate(
$options['content'],
$options['routeParameters'],
$options['routeAbsolute']
);
}

if (isset($options['route']) && 'route' !== $options['linkType']) {
unset($options['route']);
}

$options['extras']['content'] = $options['content'];

return $options;
}

/**
* Configures the item with the passed options
*
* @param ItemInterface $item
* @param array $options
*/
public function buildItem(ItemInterface $item, array $options)
{
}

/**
* If linkType not specified, we can determine it from
* existing options
*/
protected function determineLinkType($options)
{
if (!empty($options['uri'])) {
return 'uri';
}

if (!empty($options['route'])) {
return 'route';
}

if (!empty($options['content'])) {
return 'content';
}

return 'uri';
}

/**
* Ensure that we have a valid link type.
*
* @param string $linkType
*
* @throws \InvalidArgumentException if $linkType is not one of the known
* link types
*/
protected function validateLinkType($linkType)
{
$linkTypes = array('uri', 'route', 'content');
if (!in_array($linkType, $linkTypes)) {
throw new \InvalidArgumentException(sprintf(
'Invalid link type "%s", expected: "%s"',
$linkType,
implode(',', $linkTypes)
));
}
}
}
9 changes: 1 addition & 8 deletions Resources/config/admin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
</parameters>

<services>

<service id="cmf_menu.menu_admin" class="%cmf_menu.persistence.phpcr.menu_admin.class%">
<tag
name="sonata.admin"
Expand All @@ -35,10 +36,6 @@
<argument>%cmf_menu.persistence.phpcr.menu_basepath%</argument>
</call>

<call method="setContentAwareFactory">
<argument type="service" id="cmf_menu.factory" />
</call>

</service>

<service id="cmf_menu.node_admin" class="%cmf_menu.persistence.phpcr.node_admin.class%">
Expand Down Expand Up @@ -66,10 +63,6 @@
<argument>%cmf_menu.persistence.phpcr.menu_basepath%</argument>
</call>

<call method="setContentAwareFactory">
<argument type="service" id="cmf_menu.factory" />
</call>

<call method="setRecursiveBreadcrumbs">
<argument>%cmf_menu.persistence.phpcr.admin_recursive_breadcrumbs%</argument>
</call>
Expand Down
16 changes: 7 additions & 9 deletions Resources/config/menu.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,9 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

<parameters>
<parameter key="cmf_menu.factory.class">Symfony\Cmf\Bundle\MenuBundle\ContentAwareFactory</parameter>
</parameters>

<services>

<service id="cmf_menu.factory" class="%cmf_menu.factory.class%">
<argument type="service" id="router"/>
<argument/> <!-- content url generator -->
<argument type="service" id="event_dispatcher"/>
</service>
<service id="cmf_menu.content_router" alias="router"/>

<service id="cmf_menu.factory.quiet" class="Symfony\Cmf\Bundle\MenuBundle\QuietFactory"
decorates="knp_menu.factory" public="false">
Expand All @@ -23,6 +15,12 @@
<argument>%cmf_menu.allow_empty_items%</argument>
</service>

<service id="cmf_menu.factory_extension.content" class="Symfony\Cmf\Bundle\MenuBundle\Extension\ContentExtension">
<argument type="service" id="cmf_menu.content_router"/>

<tag name="knp_menu.factory_extension" priority="10"/>
</service>

<service id="cmf_menu.loader.node" class="Knp\Menu\Loader\NodeLoader">
<argument type="service" id="knp_menu.factory"/>
</service>
Expand Down

0 comments on commit 71a7011

Please sign in to comment.