refactor config process using only xml config file

This commit is contained in:
Manuel Raynaud
2013-04-03 12:47:49 +02:00
parent d4b87cca52
commit d8c4f3eeb8
8 changed files with 638 additions and 167 deletions

View File

@@ -27,6 +27,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Scope; use Symfony\Component\DependencyInjection\Scope;
use Thelia\Core\DependencyInjection\Compiler\RegisterListenersPass;
/** /**
* First Bundle use in Thelia * First Bundle use in Thelia
* It initialize dependency injection container. * It initialize dependency injection container.
@@ -49,76 +51,10 @@ class TheliaBundle extends Bundle
public function build(ContainerBuilder $container) public function build(ContainerBuilder $container)
{ {
$container->addScope( new Scope('request')); parent::build($container);
$container->register('request', 'Symfony\Component\HttpFoundation\Request') $container->addScope(new Scope('request'));
->setSynthetic(true);
$container->register('controller.default','Thelia\Controller\DefaultController');
$container->register('matcher.default','Thelia\Routing\Matcher\DefaultMatcher')
->addArgument(new Reference('controller.default'));
$container->register('matcher.action', 'Thelia\Routing\Matcher\ActionMatcher');
$container->register('matcher','Thelia\Routing\TheliaMatcherCollection')
->addMethodCall('add', array(new Reference('matcher.default'), -255))
->addMethodCall('add', array(new Reference('matcher.action'), -200))
//->addMethodCall('add','a matcher class (instance or class name)
;
$container->register('resolver', 'Symfony\Component\HttpKernel\Controller\ControllerResolver');
$container->register('parser','Thelia\Core\Template\Parser')
->addArgument(new Reference('service_container'))
;
/**
* RouterListener implements EventSubscriberInterface and listen for kernel.request event
*/
$container->register('listener.router', 'Symfony\Component\HttpKernel\EventListener\RouterListener')
->addArgument(new Reference('matcher'))
;
/**
* @TODO add an other listener on kernel.request for checking some params Like check if User is log in, set the language and other.
*
* $container->register()
*
*
* $container->register('listener.request', 'Thelia\Core\EventListener\RequestListener')
* ->addArgument(new Reference('');
* ;
*/
$container->register('thelia.listener.view','Thelia\Core\EventListener\ViewListener')
->addArgument(new Reference('service_container'))
;
$container->register('dispatcher','Symfony\Component\EventDispatcher\EventDispatcher')
->addArgument(new Reference('service_container'))
->addMethodCall('addSubscriber', array(new Reference('listener.router')))
->addMethodCall('addSubscriber', array(new Reference('thelia.listener.view')))
;
// TODO : save listener from plugins
$container->getDefinition('matcher.action')->addMethodCall("setDispatcher", array(new Reference('dispatcher')));
$container->register('http_kernel','Thelia\Core\TheliaHttpKernel')
->addArgument(new Reference('dispatcher'))
->addArgument(new Reference('service_container'))
->addArgument(new Reference('resolver'))
;
// DEFINE DEFAULT PARAMETER LIKE
/**
* @TODO learn about container compilation
*/
$container->addCompilerPass(new RegisterListenersPass());
} }
} }

View File

@@ -0,0 +1,72 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
class RegisterListenersPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('event_dispatcher')) {
return;
}
$definition = $container->getDefinition('event_dispatcher');
foreach ($container->findTaggedServiceIds('kernel.event_listener') as $id => $events) {
foreach ($events as $event) {
$priority = isset($event['priority']) ? $event['priority'] : 0;
if (!isset($event['event'])) {
throw new \InvalidArgumentException(sprintf('Service "%s" must define the "event" attribute on "kernel.event_listener" tags.', $id));
}
if (!isset($event['method'])) {
$event['method'] = 'on'.preg_replace(array(
'/(?<=\b)[a-z]/ie',
'/[^a-z0-9]/i'
), array('strtoupper("\\0")', ''), $event['event']);
}
$definition->addMethodCall('addListenerService', array($event['event'], array($id, $event['method']), $priority));
}
}
foreach ($container->findTaggedServiceIds('kernel.event_subscriber') as $id => $attributes) {
// We must assume that the class value has been correctly filled, even if the service is created by a factory
$class = $container->getDefinition($id)->getClass();
$refClass = new \ReflectionClass($class);
$interface = 'Symfony\Component\EventDispatcher\EventSubscriberInterface';
if (!$refClass->implementsInterface($interface)) {
throw new \InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, $interface));
}
$definition->addMethodCall('addSubscriberService', array($id, $class));
}
}
}

View File

@@ -0,0 +1,314 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace Thelia\Core\DependencyInjection\Loader;
use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader as XmlLoader;
use Symfony\Component\Config\Util\XmlUtils;
use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\SimpleXMLElement;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Loader\FileLoader;
class XmlFileLoader extends FileLoader
{
/**
* Loads an XML file.
*
* @param mixed $file The resource
* @param string $type The resource type
*/
public function load($file, $type = null)
{
$path = $this->locator->locate($file);
$xml = $this->parseFile($path);
$xml->registerXPathNamespace('config', 'http://thelia.net/schema/dic/config');
$this->container->addResource(new FileResource($path));
$this->parseDefinitions($xml, $path);
$this->parseLoops($xml);
$this->parseFilters($xml);
$this->parseBaseParams($xml);
$this->parseTestLoops($xml);
}
protected function parseLoops(SimpleXMLElement $xml)
{
if (false === $loops = $xml->xpath('//config:loops/config:loop')) {
return;
}
try {
$loopConfig = $this->container->getParameter("Tpex.loop");
} catch (\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException $e) {
$loopConfig = array();
}
foreach ($loops as $loop) {
$loopConfig[$loop->getAttributeAsPhp("name")] = $loop->getAttributeAsPhp("class");
}
$this->container->setParameter("Tpex.loop", $loopConfig);
}
protected function parseFilters(SimpleXMLElement $xml)
{
if (false === $filters = $xml->xpath('//config:filters/config:filter')) {
return;
}
try {
$filterConfig = $this->container->getParameter("Tpex.filter");
} catch (\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException $e) {
$filterConfig = array();
}
foreach ($filters as $filter) {
$filterConfig[$filter->getAttributeAsPhp("name")] = $filter->getAttributeAsPhp("class");
}
$this->container->setParameter("Tpex.filter", $filterConfig);
}
protected function parseBaseParams(SimpleXMLElement $xml)
{
if (false === $baseParams = $xml->xpath('//config:baseParams/config:baseParam')) {
return;
}
try {
$baseParamConfig = $this->container->getParameter("Tpex.baseParam");
} catch (\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException $e) {
$baseParamConfig = array();
}
foreach ($baseParams as $baseParam) {
$baseParamConfig[$baseParam->getAttributeAsPhp("name")] = $baseParam->getAttributeAsPhp("class");
}
$this->container->setParameter("Tpex.baseParam", $baseParamConfig);
}
protected function parseTestLoops(SimpleXMLElement $xml)
{
if (false === $testLoops = $xml->xpath('//config:testLoops/config:testLoop')) {
return;
}
try {
$baseParamConfig = $this->container->getParameter("Tpex.baseParam");
} catch (\Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException $e) {
$baseParamConfig = array();
}
foreach ($testLoops as $testLoop) {
$baseParamConfig[$testLoop->getAttributeAsPhp("name")] = $testLoop->getAttributeAsPhp("class");
}
$this->container->setParameter("Tpex.testLoop", $baseParamConfig);
}
/**
* Parses multiple definitions
*
* @param SimpleXMLElement $xml
* @param string $file
*/
protected function parseDefinitions(SimpleXMLElement $xml, $file)
{
if (false === $services = $xml->xpath('//config:services/config:service')) {
return;
}
foreach ($services as $service) {
$this->parseDefinition((string) $service['id'], $service, $file);
}
}
/**
* Parses an individual Definition
*
* @param string $id
* @param SimpleXMLElement $service
* @param string $file
*/
protected function parseDefinition($id, $service, $file)
{
if ((string) $service['alias']) {
$public = true;
if (isset($service['public'])) {
$public = $service->getAttributeAsPhp('public');
}
$this->container->setAlias($id, new Alias((string) $service['alias'], $public));
return;
}
if (isset($service['parent'])) {
$definition = new DefinitionDecorator((string) $service['parent']);
} else {
$definition = new Definition();
}
foreach (array('class', 'scope', 'public', 'factory-class', 'factory-method', 'factory-service', 'synthetic', 'abstract') as $key) {
if (isset($service[$key])) {
$method = 'set'.str_replace('-', '', $key);
$definition->$method((string) $service->getAttributeAsPhp($key));
}
}
if ($service->file) {
$definition->setFile((string) $service->file);
}
$definition->setArguments($service->getArgumentsAsPhp('argument'));
$definition->setProperties($service->getArgumentsAsPhp('property'));
if (isset($service->configurator)) {
if (isset($service->configurator['function'])) {
$definition->setConfigurator((string) $service->configurator['function']);
} else {
if (isset($service->configurator['service'])) {
$class = new Reference((string) $service->configurator['service'], ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE, false);
} else {
$class = (string) $service->configurator['class'];
}
$definition->setConfigurator(array($class, (string) $service->configurator['method']));
}
}
foreach ($service->call as $call) {
$definition->addMethodCall((string) $call['method'], $call->getArgumentsAsPhp('argument'));
}
foreach ($service->tag as $tag) {
$parameters = array();
foreach ($tag->attributes() as $name => $value) {
if ('name' === $name) {
continue;
}
$parameters[$name] = SimpleXMLElement::phpize($value);
}
$definition->addTag((string) $tag['name'], $parameters);
}
$this->container->setDefinition($id, $definition);
}
/**
* Parses a XML file.
*
* @param string $file Path to a file
*
* @return SimpleXMLElement
*
* @throws InvalidArgumentException When loading of XML file returns error
*/
protected function parseFile($file)
{
try {
$dom = XmlUtils::loadFile($file, array($this, 'validateSchema'));
} catch (\InvalidArgumentException $e) {
throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e);
}
return simplexml_import_dom($dom, 'Symfony\\Component\\DependencyInjection\\SimpleXMLElement');
}
/**
* Validates a documents XML schema.
*
* @param \DOMDocument $dom
*
* @return Boolean
*
* @throws RuntimeException When extension references a non-existent XSD file
*/
public function validateSchema(\DOMDocument $dom)
{
$schemaLocations = array('http://thelia.net/schema/dic/config' => str_replace('\\', '/',__DIR__.'/schema/dic/config/thelia-1.0.xsd'));
$tmpfiles = array();
$imports = '';
foreach ($schemaLocations as $namespace => $location) {
$parts = explode('/', $location);
if (0 === stripos($location, 'phar://')) {
$tmpfile = tempnam(sys_get_temp_dir(), 'sf2');
if ($tmpfile) {
copy($location, $tmpfile);
$tmpfiles[] = $tmpfile;
$parts = explode('/', str_replace('\\', '/', $tmpfile));
}
}
$drive = '\\' === DIRECTORY_SEPARATOR ? array_shift($parts).'/' : '';
$location = 'file:///'.$drive.implode('/', array_map('rawurlencode', $parts));
$imports .= sprintf(' <xsd:import namespace="%s" schemaLocation="%s" />'."\n", $namespace, $location);
}
$source = <<<EOF
<?xml version="1.0" encoding="utf-8" ?>
<xsd:schema xmlns="http://symfony.com/schema"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema"
elementFormDefault="qualified">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace"/>
$imports
</xsd:schema>
EOF
;
$valid = @$dom->schemaValidateSource($source);
foreach ($tmpfiles as $tmpfile) {
@unlink($tmpfile);
}
return $valid;
}
/**
* Returns true if this class supports the given resource.
*
* @param mixed $resource A resource
* @param string $type The resource type
*
* @return Boolean true if this class supports the given resource, false otherwise
*/
public function supports($resource, $type = null)
{
// TODO: Implement supports() method.
}
}

View File

@@ -0,0 +1,157 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://thelia.net/schema/dic/config"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://thelia.net/schema/dic/config"
elementFormDefault="qualified">
<xsd:element name="config" type="config" />
<xsd:complexType name="config">
<xsd:choice minOccurs="0" maxOccurs="unbounded">
<xsd:element name="loops" type="loops" />
<xsd:element name="filters" type="filter" />
<xsd:element name="baseParams" type="baseParams" />
<xsd:element name="testLoops" type="testLoops" />
<xsd:element name="services" type="services" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="loops">
<xsd:choice minOccurs="1" maxOccurs="unbounded" >
<xsd:element name="loop" type="loop"/>
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="loop">
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="filters">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="filter" type="filter" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="filter">
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="baseParams">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="baseParam" type="baseParam" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="baseParam">
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="testLoops">
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="testLoop" type="testLoop" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="testLoop">
<xsd:attribute name="class" type="xsd:string" use="required" />
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
<xsd:complexType name="services">
<xsd:annotation>
<xsd:documentation><![CDATA[
Enclosing element for the definition of all services
]]></xsd:documentation>
</xsd:annotation>
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element name="service" type="service" />
</xsd:choice>
</xsd:complexType>
<xsd:complexType name="service">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="file" type="xsd:string" minOccurs="0" maxOccurs="1" />
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="configurator" type="configurator" minOccurs="0" maxOccurs="1" />
<xsd:element name="call" type="call" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="tag" type="tag" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="property" type="property" minOccurs="0" maxOccurs="unbounded" />
</xsd:choice>
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="class" type="xsd:string" />
<xsd:attribute name="scope" type="xsd:string" />
<xsd:attribute name="public" type="boolean" />
<xsd:attribute name="synthetic" type="boolean" />
<xsd:attribute name="abstract" type="boolean" />
<xsd:attribute name="factory-class" type="xsd:string" />
<xsd:attribute name="factory-method" type="xsd:string" />
<xsd:attribute name="factory-service" type="xsd:string" />
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="parent" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="tag">
<xsd:attribute name="name" type="xsd:string" />
<xsd:anyAttribute namespace="##any" processContents="lax" />
</xsd:complexType>
<xsd:complexType name="property" mixed="true">
<xsd:choice minOccurs="0" maxOccurs="1">
<xsd:element name="service" type="service" />
</xsd:choice>
<xsd:attribute name="type" type="argument_type" />
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
<xsd:attribute name="on-invalid" type="xsd:string" />
<xsd:attribute name="strict" type="boolean" />
</xsd:complexType>
<xsd:complexType name="argument" mixed="true">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="service" type="service" />
</xsd:choice>
<xsd:attribute name="type" type="argument_type" />
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="key" type="xsd:string" />
<xsd:attribute name="index" type="xsd:integer" />
<xsd:attribute name="on-invalid" type="xsd:string" />
<xsd:attribute name="strict" type="boolean" />
</xsd:complexType>
<xsd:complexType name="call" mixed="true">
<xsd:choice maxOccurs="unbounded">
<xsd:element name="argument" type="argument" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="service" type="service" />
</xsd:choice>
<xsd:attribute name="method" type="xsd:string" />
</xsd:complexType>
<xsd:simpleType name="argument_type">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="collection" />
<xsd:enumeration value="service" />
<xsd:enumeration value="string" />
<xsd:enumeration value="constant" />
</xsd:restriction>
</xsd:simpleType>
<xsd:simpleType name="boolean">
<xsd:restriction base="xsd:string">
<xsd:pattern value="(%.+%|true|false)" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="configurator">
<xsd:attribute name="id" type="xsd:string" />
<xsd:attribute name="service" type="xsd:string" />
<xsd:attribute name="class" type="xsd:string" />
<xsd:attribute name="method" type="xsd:string" />
<xsd:attribute name="function" type="xsd:string" />
</xsd:complexType>
</xsd:schema>

View File

@@ -150,7 +150,7 @@ class Parser implements ParserInterface
$tpex = new Tpex(); $tpex = new Tpex();
$tpex->init($this->container->get("request"), $this->container->get("dispatcher"), $content, THELIA_TEMPLATE_DIR . rtrim($this->template, "/") . "/"); $tpex->init($this->container->get("request"), $this->container->get("event_dispatcher"), $content, THELIA_TEMPLATE_DIR . rtrim($this->template, "/") . "/");
$tpex->configure( $tpex->configure(
$this->container->getParameter("Tpex.loop"), $this->container->getParameter("Tpex.loop"),
$this->container->getParameter("Tpex.filter"), $this->container->getParameter("Tpex.filter"),

View File

@@ -47,8 +47,9 @@ use Thelia\Core\Bundle;
use Thelia\Log\Tlog; use Thelia\Log\Tlog;
use Thelia\Config\DatabaseConfiguration; use Thelia\Config\DatabaseConfiguration;
use Thelia\Config\DefinePropel; use Thelia\Config\DefinePropel;
use Thelia\Config\Dumper\TpexConfigDumper;
use Thelia\Core\TheliaContainerBuilder; use Thelia\Core\TheliaContainerBuilder;
use Thelia\Core\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\Config\FileLocator;
use Propel; use Propel;
use PropelConfiguration; use PropelConfiguration;
@@ -101,106 +102,23 @@ class Thelia extends Kernel
* Initialize all plugins * Initialize all plugins
* *
*/ */
public function loadConfiguration(ContainerBuilder $container) protected function loadConfiguration(ContainerBuilder $container)
{ {
/**
* TODO :
* - Retrieve all actives plugins
* - load config (create a cache and use this cache
*/
/**
* Set all listener here.
* Use $dispatcher->addSubscriber or addListener ?
*/
$dispatcher = $container->get("dispatcher");
/**
* manage Tpex configuration here
*/
$container = $this->generateTpexConfig($container);
return $container;
}
protected function generateTpexConfig(ContainerBuilder $container)
{
$loopConfig = array();
$filterConfig = array();
$baseParamConfig = array();
$loopTestConfig = array();
$resources = array();
//load master config, can be overload using modules
$masterConfigFile = THELIA_ROOT . "/core/lib/Thelia/config.xml";
if (file_exists($masterConfigFile)) {
$container->addResource(new FileResource($masterConfigFile));
$dom = XmlUtils::loadFile($masterConfigFile);
$loopConfig = $this->processConfig($dom->getElementsByTagName("loop"));
$filterConfig = $this->processConfig($dom->getElementsByTagName("filter"));
$baseParamConfig = $this->processConfig($dom->getElementsByTagName("baseParam"));
$loopTestConfig = $this->processConfig($dom->getElementsByTagName("testLoop"));
}
$loader = new XmlFileLoader($container, new FileLocator(THELIA_ROOT . "/core/lib/Thelia"));
$loader->load("config.xml");
$modules = \Thelia\Model\ModuleQuery::getActivated(); $modules = \Thelia\Model\ModuleQuery::getActivated();
foreach ($modules as $module) { foreach ($modules as $module) {
$configFile = THELIA_PLUGIN_DIR . "/" . ucfirst($module->getCode()) . "/Config/config.xml";
if (file_exists($configFile)) {
$container->addResource(new FileResource($configFile));
$dom = XmlUtils::loadFile($configFile);
$loopConfig = array_merge($loopConfig, $this->processConfig($dom->getElementsByTagName("loop"))); try {
$loader = new XmlFileLoader($container, new FileLocator(THELIA_PLUGIN_DIR . "/" . ucfirst($module->getCode()) . "/Config"));
$filterConfig = array_merge($filterConfig, $this->processConfig($dom->getElementsByTagName("filter"))); $loader->load("config.xml");
} catch(\InvalidArgumentException $e) {
$baseParamConfig = array_merge(
$baseParamConfig,
$this->processConfig($dom->getElementsByTagName("baseParam"))
);
$loopTestConfig = array_merge(
$loopTestConfig,
$this->processConfig($dom->getElementsByTagName("testLoop"))
);
} }
} }
$container->setParameter("Tpex.loop", $loopConfig);
$container->setParameter("Tpex.filter", $filterConfig);
$container->setParameter("Tpex.baseParam", $baseParamConfig);
$container->setParameter("Tpex.testLoop", $loopTestConfig);
return $container;
}
protected function processConfig(\DOMNodeList $elements)
{
$result = array();
for ($i = 0; $i < $elements->length; $i ++) {
$element = XmlUtils::convertDomElementToArray($elements->item($i));
$result[$element["name"]] = $element["class"];
}
return $result;
} }
/** /**
@@ -233,8 +151,7 @@ class Thelia extends Kernel
{ {
$container = parent::buildContainer(); $container = parent::buildContainer();
$container = $this->loadConfiguration($container); $this->loadConfiguration($container);
$container->customCompile(); $container->customCompile();
return $container; return $container;

View File

@@ -1,8 +1,72 @@
<root> <?xml version="1.0" encoding="UTF-8" ?>
<config xmlns="http://thelia.net/schema/dic/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<testLoops> <testLoops>
<testLoop name="equal" class="Test\TestLoop\Equal"/> <testLoop name="equal" class="Test\TestLoop\Equal"/>
</testLoops> </testLoops>
<loops> <loops>
<loop name="foo" class="Foo\Bar"/> <loop name="foo" class="Foo\Bar"/>
<loop name="fooz" class="Foo\Barz"/>
</loops> </loops>
</root> <services>
<service id="event_dispatcher" class="Symfony\Component\EventDispatcher\ContainerAwareEventDispatcher">
<argument type="service" id="service_container" />
</service>
<service id="thelia.listener.view" class="Thelia\Core\EventListener\ViewListener">
<tag name="kernel.event_subscriber"/>
<argument type="service" id="service_container"/>
</service>
<service id="controller.default" class="Thelia\Controller\DefaultController"/>
<service id="matcher.default" class="Thelia\Routing\Matcher\DefaultMatcher">
<argument type="service" id="controller.default"/>
</service>
<service id="matcher.action" class="Thelia\Routing\Matcher\ActionMatcher">
<call method="setDispatcher">
<argument type="service" id="event_dispatcher"/>
</call>
</service>
<service id="matcher" class="Thelia\Routing\TheliaMatcherCollection">
<call method="add">
<argument type="service" id="matcher.default"/>
<argument>-255</argument>
</call>
<call method="add">
<argument type="service" id="matcher.action"/>
<argument>-200</argument>
</call>
</service>
<service id="listener.router" class="Symfony\Component\HttpKernel\EventListener\RouterListener">
<tag name="kernel.event_subscriber"/>
<argument type="service" id="matcher"/>
</service>
<service id="controller_resolver" class="Symfony\Component\HttpKernel\Controller\ControllerResolver"/>
<service id="parser" class="Thelia\Core\Template\Parser">
<argument type="service" id="service_container"/>
</service>
<service id="http_kernel" class="Thelia\Core\TheliaHttpKernel">
<argument type="service" id="event_dispatcher" />
<argument type="service" id="service_container" />
<argument type="service" id="controller_resolver" />
</service>
<service id="request" scope="request" synthetic="true" />
<service id="service_container" synthetic="true" />
<service id="kernel" synthetic="true" />
</services>
</config>

View File

@@ -1,6 +1,17 @@
<plugin> <?xml version="1.0" encoding="UTF-8" ?>
<config xmlns="http://thelia.net/schema/dic/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://thelia.net/schema/dic/config http://thelia.net/schema/dic/config/thelia-1.0.xsd">
<testLoops>
<testLoop name="equal" class="Test\TestLoop\Equal"/>
</testLoops>
<loops> <loops>
<loop name="foo" class="Test\Loop\Foo"/> <loop name="foo" class="Test\Loop\Foo"/>
<loop name="doobitch" class="Test\Loop\Doobitch"/> <loop name="doobitch" class="Test\Loop\Doobitch"/>
</loops> </loops>
</plugin>
</config>