setWidgetFactories($widgetFactories); * // will be used on next step * $this->container = $container; * } * * } * ``` * * * * 2. add widget config to your config * ----------------------------------- * * ``` * use Symfony\Component\DependencyInjection\ContainerBuilder; * use Chill\MainBundle\DependencyInjection\Widget\AddWidgetConfigurationTrait; * use Symfony\Component\Config\Definition\Builder\TreeBuilder; * * class MyConfig * { * * use addWidgetConfigurationTrait; * * private $container; * * public function __construct(array $widgetFactories = array(), ContainerBuilder $container) * { * $this->setWidgetFactories($widgetFactories); * $this->container; * } * * public function getConfigTreeBuilder() * { * $treeBuilder = new TreeBuilder(); * $root = $treeBuilder->root('my_root'); * * $root->children() * ->arrayNode('widgets') * ->canBeDisabled() * ->children() * ->append($this->addWidgetsConfiguration('homepage', $this->container)) * ->end() * ->end() * ; * * return $treeBuilder; * } * * } * ``` * * the above code will add to the config : * * ``` * widgets: * enabled: true * * # register widgets on place "homepage" * homepage: * order: ~ # Required * widget_alias: ~ # One of "person_list"; "add_person", Required * person_list: * # options for the person_list * ``` */ trait AddWidgetConfigurationTrait { /** * @param WidgetFactoryInterface[] */ private $widgetFactories; /** * @return WidgetFactoryInterface[] */ public function getWidgetFactories() { return $this->widgetFactories; } /** * @param WidgetFactoryInterface[] $widgetFactories */ public function setWidgetFactories(array $widgetFactories) { $this->widgetFactories = $widgetFactories; } /** * add configuration nodes for the widget at the given place. * * @param string $place */ protected function addWidgetsConfiguration(string $place, ContainerBuilder $containerBuilder) { $treeBuilder = new TreeBuilder($place); $root = $treeBuilder->getRootNode($place) ->canBeUnset() ->info('register widgets on place "' . $place . '"'); // if no childen, return the root if (count(iterator_to_array($this->filterWidgetByPlace($place))) === 0) { return $root; } $prototypeChildren = $root->prototype('array')->children(); $prototypeChildren ->floatNode(WidgetsCompilerPass::WIDGET_CONFIG_ORDER) ->isRequired() ->info('the ordering of the widget. May be a number with decimal') ->example('10.58') ->end() ->scalarNode(WidgetsCompilerPass::WIDGET_CONFIG_ALIAS) // this node is scalar: when the configuration is build, the // tagged services are not available. But when the config reference // is build, the services are avaialble => we add the possible aliases // in the info. ->info('the widget alias (see your installed bundles config). ' . 'Possible values are (maybe incomplete) : ' . implode(', ', $this->getWidgetAliasesbyPlace($place, $containerBuilder))) ->isRequired() ->end(); // adding the possible config on each widget under the widget_alias foreach ($this->filterWidgetByPlace($place) as $factory) { $builder = new TreeBuilder($factory->getWidgetAlias()); $widgetOptionsRoot = $builder->getRootNode($factory->getWidgetAlias()); $widgetOptionsRoot->canBeUnset() ->info(sprintf( 'the configuration for the widget "%s" (only required if this widget is set in widget_alias)', $factory->getWidgetAlias() )); $factory->configureOptions($place, $widgetOptionsRoot->children()); $prototypeChildren->append($widgetOptionsRoot); } return $root; } /** * get all widget factories for the given place. * * @param string $place * * @return Generator a generator containing a widget factory */ protected function filterWidgetByPlace($place) { foreach ($this->widgetFactories as $factory) { if (in_array($place, $factory->getAllowedPlaces(), true)) { yield $factory; } } } /** * get the all possible aliases for the given place. This method * search within service tags and widget factories. * * **Note** that services are not available when the config is build: the whole * aliases will be checked in compiler pass, or when the command * `config:dump-reference` is runned. * * @param type $place * * @throws InvalidConfigurationException if a service's tag does not have the "alias" key * * @return type */ protected function getWidgetAliasesbyPlace($place, ContainerBuilder $containerBuilder) { $result = []; foreach ($this->filterWidgetByPlace($place) as $factory) { $result[] = $factory->getWidgetAlias(); } // append the aliases added without factory foreach ($containerBuilder ->findTaggedServiceIds(WidgetsCompilerPass::WIDGET_SERVICE_TAG_NAME) as $serviceId => $tags) { foreach ($tags as $tag) { // throw an error if no alias in definition if (!array_key_exists(WidgetsCompilerPass::WIDGET_SERVICE_TAG_ALIAS, $tag)) { throw new InvalidConfigurationException(sprintf( 'The service with id %s does not have any %d key', $serviceId, WidgetsCompilerPass::WIDGET_SERVICE_TAG_ALIAS )); } // add the key to the possible results $result[] = $tag[WidgetsCompilerPass::WIDGET_SERVICE_TAG_ALIAS]; } } return $result; } }