diff --git a/components/console/helpers/tablehelper.rst b/components/console/helpers/tablehelper.rst index 04301af5048..1145dd7b603 100644 --- a/components/console/helpers/tablehelper.rst +++ b/components/console/helpers/tablehelper.rst @@ -48,8 +48,8 @@ You can also control table rendering by setting custom rendering option values: * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPaddingChar` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setHorizontalBorderChar` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVerticalBorderChar` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVrossingChar` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellHeaderFormat` -* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellRowFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCrossingChar` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellHeaderFormat` +* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellRowFormat` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setBorderFormat` * :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPadType` diff --git a/components/dependency_injection/index.rst b/components/dependency_injection/index.rst index e1d6b0eab8d..b3960eb8e00 100644 --- a/components/dependency_injection/index.rst +++ b/components/dependency_injection/index.rst @@ -14,5 +14,6 @@ configurators parentservices advanced + lazy_services workflow diff --git a/components/dependency_injection/lazy_services.rst b/components/dependency_injection/lazy_services.rst new file mode 100644 index 00000000000..88ad0c51f59 --- /dev/null +++ b/components/dependency_injection/lazy_services.rst @@ -0,0 +1,92 @@ +.. index:: + single: Dependency Injection; Lazy Services + +Lazy Services +============= + +.. versionadded:: 2.3 + Lazy services were added in Symfony 2.3. + +Why Lazy Services? +------------------ + +In some cases, you may want to inject a service that is a bit heavy to instantiate, +but is not always used inside your object. For example, imagine you have +a ``NewsletterManager`` and you inject a ``mailer`` service into it. Only +a few methods on your ``NewsletterManager`` actually use the ``mailer``, +but even when you don't need it, a ``mailer`` service is always instantiated +in order to construct your ``NewsletterManager``. + +Configuring lazy services is one answer to this. With a lazy service, a "proxy" +of the ``mailer`` service is actually injected. It looks and acts just like +the ``mailer``, except that the ``mailer`` isn't actually instantiated until +you interact with the proxy in some way. + +Installation +------------ + +In order to use the lazy service instantiation, you will first need to install +the `ProxyManager bridge`_: + +.. code-block:: bash + + $ php composer.phar require symfony/proxy-manager-bridge:2.3.* + +.. note:: + + If you're using the full-stack framework, this package is not included + and needs to be added to ``composer.json`` and installed (which is what + the above command does). + +Configuration +------------- + +You can mark the service as ``lazy`` by manipulating its definition: + +.. configuration-block:: + + .. code-block:: yaml + + services: + foo: + class: Acme\Foo + lazy: true + + .. code-block:: xml + + + + .. code-block:: php + + $definition = new Definition('Acme\Foo'); + $definition->setLazy(true); + $container->setDefinition('foo', $definition); + +You can then require the service from the container:: + + $service = $container->get('foo'); + +At this point the retrieved ``$service`` should be a virtual `proxy`_ with +the same signature of the class representing the service. You can also inject +the service just like normal into other services. The object that's actually +injected will be the proxy. + +.. note:: + + If you don't install the `ProxyManager bridge`_, the container will just + skip over the ``lazy`` flag and simply instantiate the service as it would + normally do. + +The proxy gets initialized and the actual service is instantiated as soon +as you interact in any way with this object. + +Additional Resources +-------------------- + +You can read more about how proxies are instantiated, generated and initialized +in the `documentation of ProxyManager`_. + + +.. _`ProxyManager bridge`: https://github.com/symfony/symfony/tree/master/src/Symfony/Bridge/ProxyManager +.. _`proxy`: http://en.wikipedia.org/wiki/Proxy_pattern +.. _`documentation of ProxyManager`: https://github.com/Ocramius/ProxyManager/blob/master/docs/lazy-loading-value-holder.md \ No newline at end of file diff --git a/components/intl.rst b/components/intl.rst index cf42b9778d5..e9c5028d4c2 100644 --- a/components/intl.rst +++ b/components/intl.rst @@ -72,7 +72,7 @@ expose them manually by adding the following lines to your autoload code:: but usually Composer does this for you automatically: * 1.0.*: when the intl extension is not available - * 1.1.*: when intl is compiled with ICU 4.0 or higher + * 1.1.*: when intl is compiled with ICU 3.8 or higher * 1.2.*: when intl is compiled with ICU 4.4 or higher These versions are important when you deploy your application to a **server with diff --git a/components/map.rst.inc b/components/map.rst.inc index e29df506e55..d360c65a706 100644 --- a/components/map.rst.inc +++ b/components/map.rst.inc @@ -39,6 +39,7 @@ * :doc:`/components/dependency_injection/configurators` * :doc:`/components/dependency_injection/parentservices` * :doc:`/components/dependency_injection/advanced` + * :doc:`/components/dependency_injection/lazy_services` * :doc:`/components/dependency_injection/workflow` * **DOM Crawler** diff --git a/cookbook/doctrine/mapping_model_classes.rst b/cookbook/doctrine/mapping_model_classes.rst index 48529cc2e26..60322bccad5 100644 --- a/cookbook/doctrine/mapping_model_classes.rst +++ b/cookbook/doctrine/mapping_model_classes.rst @@ -17,13 +17,25 @@ register the mappings for your model classes. just to get the auto mapping, use the compiler pass. .. versionadded:: 2.3 + The base mapping compiler pass was added in Symfony 2.3. The doctrine bundles - support it from DoctrineBundle >= 1.2.1, MongoDBBundle >= 3.0.0 + support it from DoctrineBundle >= 1.2.1, MongoDBBundle >= 3.0.0, + PHPCRBundle >= 1.0.0-alpha2 and the (unversioned) CouchDBBundle supports the + compiler pass since the `CouchDB Mapping Compiler Pass pull request`_ + was merged. + + If you want your bundle to support older versions of Symfony and + Doctrine, you can provide a copy of the compiler pass in your bundle. + See for example the `FOSUserBundle mapping configuration`_ + ``addRegisterMappingsPass``. + In your bundle class, write the following code to register the compiler pass:: use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass; use Doctrine\Bundle\MongoDBBundle\DependencyInjection\Compiler\DoctrineMongoDBMappingsPass; + use Doctrine\Bundle\CouchDBBundle\DependencyInjection\Compiler\DoctrineCouchDBMappingsPass; + use Doctrine\Bundle\PHPCRBundle\DependencyInjection\Compiler\DoctrinePhpcrMappingsPass; class FOSUserBundle extends Bundle { @@ -55,10 +67,64 @@ In your bundle class, write the following code to register the compiler pass:: )); } - // TODO: couch + $couchCompilerClass = 'Doctrine\Bundle\CouchDBBundle\DependencyInjection' + . '\Compiler\DoctrineCouchDBMappingsPass'; + if (class_exists($couchCompilerClass)) { + $container->addCompilerPass( + DoctrinCouchDBMappingsPass::createXmlMappingDriver( + $mappings, 'fos_user.backend_type_couchdb' + )); + } + + $phpcrCompilerClass = 'Doctrine\Bundle\PHPCRBundle\DependencyInjection' + . '\Compiler\DoctrinePhpcrMappingsPass'; + if (class_exists($phpcrCompilerClass)) { + $container->addCompilerPass( + DoctrinePhpcrMappingsPass::createXmlMappingDriver( + $mappings, 'fos_user.backend_type_phpcr' + )); + } } } -The compiler pass provides factory methods for all drivers provided by the -bundle: Annotations, XML, Yaml, PHP and StaticPHP for Doctrine ORM, the ODM -bundles sometimes do not have all of those drivers. +Note the ``class_exists`` check. This is crucial, as you do not want your +bundle to have a hard dependency on all doctrine bundles but let the user +decide which to use. + +The compiler pass provides factory methods for all drivers provided by doctrine: +Annotations, XML, Yaml, PHP and StaticPHP. The arguments are + +* a map of absolute directory path to namespace; +* an array of container parameters that your bundle uses to specify the name of + the doctrine manager that it is using. The compiler pass will append the + parameter doctrine is using to specify the name of the default manager. The + first parameter found is used and the mappings are registered with that + manager; +* an optional container parameter name that will be used by the compiler + pass to determine if this doctrine type is used at all (this is relevant if + your user has more than one type of doctrine bundle installed, but your + bundle is only used with one type of doctrine. + +.. note:: + + The factory method is using the ``SymfonyFileLocator`` of doctrine, meaning + it will only see XML and YML mapping files if they do not contain the + namespace. If you also need to map a base class, you can register a + compiler pass with the ``DefaultFileLocator`` like this:: + + private function buildMappingCompilerPass() + { + $arguments = array(array(realpath(__DIR__ . '/Resources/config/doctrine')), '.orm.xml'); + $locator = new Definition('Doctrine\Common\Persistence\Mapping\Driver\DefaultFileLocator', $arguments); + $driver = new Definition('Doctrine\ORM\Mapping\Driver\XmlDriver', array($locator)); + + return new DoctrineOrmMappingsPass( + $driver, + array('Full\Namespace'), + array('your_bundle.manager_name'), + 'your_bundle.orm_enabled' + ); + } + +.. _`CouchDB Mapping Compiler Pass pull request`: https://github.com/doctrine/DoctrineCouchDBBundle/pull/27 +.. _`FOSUserBundle mapping configuration`: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/FOSUserBundle.php