refactor config process using only xml config file
This commit is contained in:
@@ -27,6 +27,8 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Scope;
|
||||
|
||||
use Thelia\Core\DependencyInjection\Compiler\RegisterListenersPass;
|
||||
|
||||
/**
|
||||
* First Bundle use in Thelia
|
||||
* It initialize dependency injection container.
|
||||
@@ -49,76 +51,10 @@ class TheliaBundle extends Bundle
|
||||
|
||||
public function build(ContainerBuilder $container)
|
||||
{
|
||||
$container->addScope( new Scope('request'));
|
||||
parent::build($container);
|
||||
|
||||
$container->register('request', 'Symfony\Component\HttpFoundation\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->addScope(new Scope('request'));
|
||||
|
||||
$container->addCompilerPass(new RegisterListenersPass());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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.
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
@@ -150,7 +150,7 @@ class Parser implements ParserInterface
|
||||
|
||||
$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(
|
||||
$this->container->getParameter("Tpex.loop"),
|
||||
$this->container->getParameter("Tpex.filter"),
|
||||
|
||||
@@ -47,8 +47,9 @@ use Thelia\Core\Bundle;
|
||||
use Thelia\Log\Tlog;
|
||||
use Thelia\Config\DatabaseConfiguration;
|
||||
use Thelia\Config\DefinePropel;
|
||||
use Thelia\Config\Dumper\TpexConfigDumper;
|
||||
use Thelia\Core\TheliaContainerBuilder;
|
||||
use Thelia\Core\DependencyInjection\Loader\XmlFileLoader;
|
||||
use Symfony\Component\Config\FileLocator;
|
||||
|
||||
use Propel;
|
||||
use PropelConfiguration;
|
||||
@@ -101,106 +102,23 @@ class Thelia extends Kernel
|
||||
* 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();
|
||||
|
||||
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")));
|
||||
|
||||
$filterConfig = array_merge($filterConfig, $this->processConfig($dom->getElementsByTagName("filter")));
|
||||
|
||||
$baseParamConfig = array_merge(
|
||||
$baseParamConfig,
|
||||
$this->processConfig($dom->getElementsByTagName("baseParam"))
|
||||
);
|
||||
|
||||
$loopTestConfig = array_merge(
|
||||
$loopTestConfig,
|
||||
$this->processConfig($dom->getElementsByTagName("testLoop"))
|
||||
);
|
||||
try {
|
||||
$loader = new XmlFileLoader($container, new FileLocator(THELIA_PLUGIN_DIR . "/" . ucfirst($module->getCode()) . "/Config"));
|
||||
$loader->load("config.xml");
|
||||
} catch(\InvalidArgumentException $e) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$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 = $this->loadConfiguration($container);
|
||||
|
||||
$this->loadConfiguration($container);
|
||||
$container->customCompile();
|
||||
|
||||
return $container;
|
||||
|
||||
@@ -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>
|
||||
<testLoop name="equal" class="Test\TestLoop\Equal"/>
|
||||
</testLoops>
|
||||
|
||||
<loops>
|
||||
<loop name="foo" class="Foo\Bar"/>
|
||||
<loop name="fooz" class="Foo\Barz"/>
|
||||
</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>
|
||||
@@ -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>
|
||||
<loop name="foo" class="Test\Loop\Foo"/>
|
||||
<loop name="doobitch" class="Test\Loop\Doobitch"/>
|
||||
</loops>
|
||||
</plugin>
|
||||
|
||||
</config>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user