Преглед на файлове

[DoctrineBundle] Added a way to register custom DQL functions through the configuration

Christophe Coevoet преди 14 години
родител
ревизия
5c2e0898d1

+ 32 - 0
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/Configuration.php

@@ -151,6 +151,38 @@ class Configuration
                         ->performNoDeepMerging()
                     ->end()
                 ->end()
+                ->arrayNode('dql')
+                    ->fixXmlConfig('string_function')
+                    ->arrayNode('string_functions')
+                        ->useAttributeAsKey('name')
+                        ->prototype('scalar')
+                            ->beforeNormalization()
+                                ->ifTrue(function($v) { return is_array($v) && isset($v['class']); })
+                                ->then(function($v) { return $v['class']; })
+                            ->end()
+                        ->end()
+                    ->end()
+                    ->fixXmlConfig('numeric_function')
+                    ->arrayNode('numeric_functions')
+                        ->useAttributeAsKey('name')
+                        ->prototype('scalar')
+                            ->beforeNormalization()
+                                ->ifTrue(function($v) { return is_array($v) && isset($v['class']); })
+                                ->then(function($v) { return $v['class']; })
+                            ->end()
+                        ->end()
+                    ->end()
+                    ->fixXmlConfig('datetime_function')
+                    ->arrayNode('datetime_functions')
+                        ->useAttributeAsKey('name')
+                        ->prototype('scalar')
+                            ->beforeNormalization()
+                                ->ifTrue(function($v) { return is_array($v) && isset($v['class']); })
+                                ->then(function($v) { return $v['class']; })
+                            ->end()
+                        ->end()
+                    ->end()
+                ->end()
             ->end()
         ;
 

+ 12 - 0
src/Symfony/Bundle/DoctrineBundle/DependencyInjection/DoctrineExtension.php

@@ -198,6 +198,18 @@ class DoctrineExtension extends AbstractDoctrineExtension
             $ormConfigDef->addMethodCall($method, array($arg));
         }
 
+        if (!empty($entityManager['dql'])) {
+            foreach ($entityManager['dql']['string_functions'] as $name => $function) {
+                $ormConfigDef->addMethodCall('addCustomStringFunction', array ($name, $function));
+            }
+            foreach ($entityManager['dql']['numeric_functions'] as $name => $function) {
+                $ormConfigDef->addMethodCall('addCustomNumericFunction', array ($name, $function));
+            }
+            foreach ($entityManager['dql']['datetime_functions'] as $name => $function) {
+                $ormConfigDef->addMethodCall('addCustomDatetimeFunction', array ($name, $function));
+            }
+        }
+
         $entityManagerService = sprintf('doctrine.orm.%s_entity_manager', $entityManager['name']);
         $connectionId = isset($entityManager['connection']) ? sprintf('doctrine.dbal.%s_connection', $entityManager['connection']) : 'database_connection';
         $eventManagerID = isset($entityManager['connection']) ? sprintf('doctrine.dbal.%s_connection.event_manager', $entityManager['connection']) : 'doctrine.dbal.event_manager';

+ 14 - 0
src/Symfony/Bundle/DoctrineBundle/Resources/config/schema/doctrine-1.0.xsd

@@ -92,6 +92,7 @@
         <xsd:choice minOccurs="0" maxOccurs="unbounded">
             <xsd:element name="mapping" type="mapping" />
             <xsd:element name="metadata-cache-driver" type="metadata_cache_driver" minOccurs="0" maxOccurs="1" />
+            <xsd:element name="dql" type="dql" minOccurs="0" maxOccurs="1" />
         </xsd:choice>
 
         <xsd:attribute name="connection" type="xsd:string" />
@@ -100,4 +101,17 @@
         <xsd:attribute name="metadata-cache-driver" type="xsd:string" />
         <xsd:attribute name="query-cache-driver" type="xsd:string" />
     </xsd:complexType>
+
+    <xsd:complexType name="dql">
+        <xsd:choice minOccurs="0" maxOccurs="unbounded">
+            <xsd:element name="string-function" type="dql_function" />
+            <xsd:element name="numeric-function" type="dql_function" />
+            <xsd:element name="datetime-function" type="dql_function" />
+        </xsd:choice>
+    </xsd:complexType>
+
+    <xsd:complexType name="dql_function">
+        <xsd:attribute name="name" type="xsd:string" use="required" />
+        <xsd:attribute name="class" type="xsd:string" use="required" />
+    </xsd:complexType>
 </xsd:schema>

+ 17 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/AbstractDoctrineExtensionTest.php

@@ -652,6 +652,23 @@ abstract class AbstractDoctrineExtensionTest extends TestCase
         );
     }
 
+    public function testSetCustomFunctions()
+    {
+        $container = $this->getContainer(array('YamlBundle'));
+
+        $loader = new DoctrineExtension();
+        $container->registerExtension($loader);
+        $this->loadFromFile($container, 'orm_functions');
+        $container->getCompilerPassConfig()->setOptimizationPasses(array());
+        $container->getCompilerPassConfig()->setRemovingPasses(array());
+        $container->compile();
+
+        $definition = $container->getDefinition('doctrine.orm.default_configuration');
+        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomStringFunction', array('test_string', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction'));
+        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomNumericFunction', array('test_numeric', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction'));
+        $this->assertDICDefinitionMethodCallOnce($definition, 'addCustomDatetimeFunction', array('test_datetime', 'Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction'));
+    }
+
     protected function getContainer($bundles = 'YamlBundle', $vendor = null)
     {
         if (!is_array($bundles)) {

+ 22 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/xml/orm_functions.xml

@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+
+<srv:container xmlns="http://symfony.com/schema/dic/doctrine"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:srv="http://symfony.com/schema/dic/services"
+    xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
+                        http://symfony.com/schema/dic/doctrine http://symfony.com/schema/dic/doctrine/doctrine-1.0.xsd">
+
+    <config>
+        <dbal />
+        <orm default-entity-manager="default">
+            <entity-manager name="default">
+                <mapping name="YamlBundle" />
+                <dql>
+                    <string-function name="test_string" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction" />
+                    <numeric-function name="test_numeric" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction" />
+                    <datetime-function name="test_datetime" class="Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction" />
+                </dql>
+            </entity-manager>
+        </orm>
+    </config>
+</srv:container>

+ 14 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/Fixtures/config/yml/orm_functions.yml

@@ -0,0 +1,14 @@
+doctrine:
+    dbal: ~
+    orm:
+        entity_managers:
+            default:
+                mappings:
+                    YamlBundle: ~
+                dql:
+                    string_functions:
+                        test_string: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestStringFunction
+                    numeric_functions:
+                        test_numeric: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestNumericFunction
+                    datetime_functions:
+                        test_datetime: Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection\TestDatetimeFunction

+ 29 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/TestDatetimeFunction.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection;
+
+use Doctrine\ORM\Query\AST\Functions\FunctionNode;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+
+class TestStringFunction extends FunctionNode
+{
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        return '';
+    }
+
+    public function parse(Parser $parser)
+    {
+        return '';
+    }
+}

+ 29 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/TestNumericFunction.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection;
+
+use Doctrine\ORM\Query\AST\Functions\FunctionNode;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+
+class TestStringFunction extends FunctionNode
+{
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        return '';
+    }
+
+    public function parse(Parser $parser)
+    {
+        return '';
+    }
+}

+ 29 - 0
src/Symfony/Bundle/DoctrineBundle/Tests/DependencyInjection/TestStringFunction.php

@@ -0,0 +1,29 @@
+<?php
+
+/*
+ * This file is part of the Symfony package.
+ *
+ * (c) Fabien Potencier <fabien@symfony.com>
+ *
+ * For the full copyright and license information, please view the LICENSE
+ * file that was distributed with this source code.
+ */
+
+namespace Symfony\Bundle\DoctrineBundle\Tests\DependencyInjection;
+
+use Doctrine\ORM\Query\AST\Functions\FunctionNode;
+use Doctrine\ORM\Query\SqlWalker;
+use Doctrine\ORM\Query\Parser;
+
+class TestStringFunction extends FunctionNode
+{
+    public function getSql(SqlWalker $sqlWalker)
+    {
+        return '';
+    }
+
+    public function parse(Parser $parser)
+    {
+        return '';
+    }
+}