diff --git a/best_practices/creating-the-project.rst b/best_practices/creating-the-project.rst index d5b3a48766a..7e658fdae59 100644 --- a/best_practices/creating-the-project.rst +++ b/best_practices/creating-the-project.rst @@ -35,6 +35,11 @@ to create files and execute the following commands: c:\> cd projects/ c:\projects\> php symfony new blog +.. note:: + + If the installer doesn't work for you or doesn't output anything, make sure + that the `Phar extension`_ is installed and enabled on your computer. + This command creates a new directory called ``blog`` that contains a fresh new project based on the most recent stable Symfony version available. In addition, the installer checks if your system meets the technical requirements to execute @@ -178,3 +183,4 @@ the Symfony directory structure. .. _`Composer download page`: https://getcomposer.org/download/ .. _`public checksums repository`: https://github.com/sensiolabs/checksums .. _`these steps`: http://fabien.potencier.org/signing-project-releases.html +.. _`Phar extension`: http://php.net/manual/en/intro.phar.php diff --git a/book/controller.rst b/book/controller.rst index c53b897d24d..13a19afb334 100644 --- a/book/controller.rst +++ b/book/controller.rst @@ -116,8 +116,10 @@ Controllers are also called *actions*. This controller is pretty straightforward: -* *line 4*: Symfony takes advantage of PHP's namespace functionality to - namespace the entire controller class. The ``use`` keyword imports the +* *line 2*: Symfony takes advantage of PHP's namespace functionality to + namespace the entire controller class. + +* *line 4*: Symfony again takes advantage of PHP's namespace functionality: the ``use`` keyword imports the ``Response`` class, which the controller must return. * *line 6*: The class name is the concatenation of a name for the controller diff --git a/book/from_flat_php_to_symfony2.rst b/book/from_flat_php_to_symfony2.rst index 99a7dc6ea27..e168f6b93a0 100644 --- a/book/from_flat_php_to_symfony2.rst +++ b/book/from_flat_php_to_symfony2.rst @@ -554,7 +554,7 @@ them for you. Here's the same sample application, now built in Symfony:: { $posts = $this->get('doctrine') ->getManager() - ->createQuery('SELECT p FROM AcmeBlogBundle:Post p') + ->createQuery('SELECT p FROM AppBundle:Post p') ->execute(); return $this->render('Blog/list.html.php', array('posts' => $posts)); diff --git a/book/includes/_service_container_my_mailer.rst.inc b/book/includes/_service_container_my_mailer.rst.inc index 5b9fc68d5d4..f14c2fbe282 100644 --- a/book/includes/_service_container_my_mailer.rst.inc +++ b/book/includes/_service_container_my_mailer.rst.inc @@ -4,8 +4,8 @@ # app/config/services.yml services: - my_mailer: - class: Acme\HelloBundle\Mailer + app.mailer: + class: AppBundle\Mailer arguments: [sendmail] .. code-block:: xml @@ -15,10 +15,10 @@ + http://symfony.com/schema/dic/services/services-1.0.xsd"> + - + sendmail @@ -29,7 +29,7 @@ // app/config/services.php use Symfony\Component\DependencyInjection\Definition; - $container->setDefinition('my_mailer', new Definition( - 'Acme\HelloBundle\Mailer', + $container->setDefinition('app.mailer', new Definition( + 'AppBundle\Mailer', array('sendmail') )); diff --git a/book/installation.rst b/book/installation.rst index ed6bc171fc3..5a5204288c9 100644 --- a/book/installation.rst +++ b/book/installation.rst @@ -81,6 +81,11 @@ to meet those requirements. distributing them. If you want to verify the integrity of any Symfony version, follow the steps `explained in this post`_. +.. note:: + + If the installer doesn't work for you or doesn't output anything, make sure + that the `Phar extension`_ is installed and enabled on your computer. + Basing your Project on a Specific Symfony Version ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -417,3 +422,4 @@ a wide variety of articles about solving specific problems with Symfony. .. _`Symfony REST Edition`: https://github.com/gimler/symfony-rest-edition .. _`FOSRestBundle`: https://github.com/FriendsOfSymfony/FOSRestBundle .. _`Git`: http://git-scm.com/ +.. _`Phar extension`: http://php.net/manual/en/intro.phar.php diff --git a/book/page_creation.rst b/book/page_creation.rst index 7c1d83fa9c7..4a762d61478 100644 --- a/book/page_creation.rst +++ b/book/page_creation.rst @@ -191,7 +191,7 @@ at the end: .. code-block:: xml - + ``BlogController``) and ``Action`` to the method name (``show`` => ``showAction``). You could also refer to this controller using its fully-qualified class name -and method: ``AppBundle\Controller\BlogController::showAction``. -But if you follow some simple conventions, the logical name is more concise -and allows more flexibility. +and method: ``AppBundle\Controller\BlogController::showAction``. But if you +follow some simple conventions, the logical name is more concise and allows +more flexibility. .. note:: diff --git a/book/service_container.rst b/book/service_container.rst index 0fe4d37a234..22c33eca89e 100644 --- a/book/service_container.rst +++ b/book/service_container.rst @@ -79,7 +79,7 @@ For example, suppose you have a simple PHP class that delivers email messages. Without a service container, you must manually create the object whenever you need it:: - use Acme\HelloBundle\Mailer; + use AppBundle\Mailer; $mailer = new Mailer('sendmail'); $mailer->send('ryan@example.com', ...); @@ -116,10 +116,10 @@ be specified in YAML, XML or PHP: ``config_dev.yml`` for the ``dev`` environment or ``config_prod.yml`` for ``prod``). -An instance of the ``Acme\HelloBundle\Mailer`` object is now available via -the service container. The container is available in any traditional Symfony -controller where you can access the services of the container via the ``get()`` -shortcut method:: +An instance of the ``AppBundle\Mailer`` class is now available via the service +container. The container is available in any traditional Symfony controller +where you can access the services of the container via the ``get()`` shortcut +method:: class HelloController extends Controller { @@ -128,12 +128,12 @@ shortcut method:: public function sendEmailAction() { // ... - $mailer = $this->get('my_mailer'); + $mailer = $this->get('app.mailer'); $mailer->send('ryan@foobar.net', ...); } } -When you ask for the ``my_mailer`` service from the container, the container +When you ask for the ``app.mailer`` service from the container, the container constructs the object and returns it. This is another major advantage of using the service container. Namely, a service is *never* constructed until it's needed. If you define a service and never use it on a request, the service @@ -151,7 +151,7 @@ later how you can configure a service that has multiple instances in the In this example, the controller extends Symfony's base Controller, which gives you access to the service container itself. You can then use the - ``get`` method to locate and retrieve the ``my_mailer`` service from + ``get`` method to locate and retrieve the ``app.mailer`` service from the service container. You can also define your :doc:`controllers as services `. This is a bit more advanced and not necessary, but it allows you to inject only the services you need into your controller. @@ -168,18 +168,18 @@ straightforward. Parameters make defining services more organized and flexible: .. code-block:: yaml - # app/config/config.yml + # app/config/services.yml parameters: - my_mailer.transport: sendmail + app.mailer.transport: sendmail services: - my_mailer: - class: Acme\HelloBundle\Mailer - arguments: ['%my_mailer.transport%'] + app.mailer: + class: AppBundle\Mailer + arguments: ['%app.mailer.transport%'] .. code-block:: xml - + - sendmail + sendmail - - %my_mailer.transport% + + %app.mailer.transport% .. code-block:: php - // app/config/config.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; - $container->setParameter('my_mailer.transport', 'sendmail'); + $container->setParameter('app.mailer.transport', 'sendmail'); - $container->setDefinition('my_mailer', new Definition( - 'Acme\HelloBundle\Mailer', - array('%my_mailer.transport%') + $container->setDefinition('app.mailer', new Definition( + 'AppBundle\Mailer', + array('%app.mailer.transport%') )); The end result is exactly the same as before - the difference is only in -*how* you defined the service. By surrounding the ``my_mailer.transport`` -string in percent (``%``) signs, the container knows to look for a parameter +*how* you defined the service. By enclosing the ``app.mailer.transport`` +string with percent (``%``) signs, the container knows to look for a parameter with that name. When the container is built, it looks up the value of each parameter and uses it in the service definition. @@ -290,13 +290,13 @@ configuration. Read on to learn more about both methods. Importing Configuration with ``imports`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -So far, you've placed your ``my_mailer`` service container definition directly +So far, you've placed your ``app.mailer`` service container definition directly in the application configuration file (e.g. ``app/config/config.yml``). Of course, since the ``Mailer`` class itself lives inside the AcmeHelloBundle, it -makes more sense to put the ``my_mailer`` container definition inside the +makes more sense to put the ``app.mailer`` container definition inside the bundle as well. -First, move the ``my_mailer`` container definition into a new container resource +First, move the ``app.mailer`` container definition into a new container resource file inside AcmeHelloBundle. If the ``Resources`` or ``Resources/config`` directories don't exist, create them. @@ -306,12 +306,12 @@ directories don't exist, create them. # src/Acme/HelloBundle/Resources/config/services.yml parameters: - my_mailer.transport: sendmail + app.mailer.transport: sendmail services: - my_mailer: - class: Acme\HelloBundle\Mailer - arguments: ['%my_mailer.transport%'] + app.mailer: + class: AppBundle\Mailer + arguments: ['%app.mailer.transport%'] .. code-block:: xml @@ -323,12 +323,12 @@ directories don't exist, create them. http://symfony.com/schema/dic/services/services-1.0.xsd"> - sendmail + sendmail - - %my_mailer.transport% + + %app.mailer.transport% @@ -338,11 +338,11 @@ directories don't exist, create them. // src/Acme/HelloBundle/Resources/config/services.php use Symfony\Component\DependencyInjection\Definition; - $container->setParameter('my_mailer.transport', 'sendmail'); + $container->setParameter('app.mailer.transport', 'sendmail'); - $container->setDefinition('my_mailer', new Definition( - 'Acme\HelloBundle\Mailer', - array('%my_mailer.transport%') + $container->setDefinition('app.mailer', new Definition( + 'AppBundle\Mailer', + array('%app.mailer.transport%') )); The definition itself hasn't changed, only its location. Of course the service @@ -512,22 +512,22 @@ If you want to expose user friendly configuration in your own bundles, read the Referencing (Injecting) Services -------------------------------- -So far, the original ``my_mailer`` service is simple: it takes just one argument +So far, the original ``app.mailer`` service is simple: it takes just one argument in its constructor, which is easily configurable. As you'll see, the real power of the container is realized when you need to create a service that depends on one or more other services in the container. As an example, suppose you have a new service, ``NewsletterManager``, that helps to manage the preparation and delivery of an email message to -a collection of addresses. Of course the ``my_mailer`` service is already +a collection of addresses. Of course the ``app.mailer`` service is already really good at delivering email messages, so you'll use it inside ``NewsletterManager`` to handle the actual delivery of the messages. This pretend class might look something like this:: - // src/Acme/HelloBundle/Newsletter/NewsletterManager.php - namespace Acme\HelloBundle\Newsletter; + // src/AppBundle/Newsletter/NewsletterManager.php + namespace AppBundle\Newsletter; - use Acme\HelloBundle\Mailer; + use AppBundle\Mailer; class NewsletterManager { @@ -544,13 +544,13 @@ something like this:: Without using the service container, you can create a new ``NewsletterManager`` fairly easily from inside a controller:: - use Acme\HelloBundle\Newsletter\NewsletterManager; + use AppBundle\Newsletter\NewsletterManager; // ... public function sendNewsletterAction() { - $mailer = $this->get('my_mailer'); + $mailer = $this->get('app.mailer'); $newsletter = new NewsletterManager($mailer); // ... } @@ -565,18 +565,18 @@ the service container gives you a much more appealing option: .. code-block:: yaml - # src/Acme/HelloBundle/Resources/config/services.yml + # app/config/services.yml services: - my_mailer: + app.mailer: # ... - newsletter_manager: - class: Acme\HelloBundle\Newsletter\NewsletterManager - arguments: ['@my_mailer'] + app.newsletter_manager: + class: AppBundle\Newsletter\NewsletterManager + arguments: ['@app.mailer'] .. code-block:: xml - + - + - - + + .. code-block:: php - // src/Acme/HelloBundle/Resources/config/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; - $container->setDefinition('my_mailer', ...); + $container->setDefinition('app.mailer', ...); - $container->setDefinition('newsletter_manager', new Definition( - 'Acme\HelloBundle\Newsletter\NewsletterManager', - array(new Reference('my_mailer')) + $container->setDefinition('app.newsletter_manager', new Definition( + 'AppBundle\Newsletter\NewsletterManager', + array(new Reference('app.mailer')) )); -In YAML, the special ``@my_mailer`` syntax tells the container to look for -a service named ``my_mailer`` and to pass that object into the constructor -of ``NewsletterManager``. In this case, however, the specified service ``my_mailer`` +In YAML, the special ``@app.mailer`` syntax tells the container to look for +a service named ``app.mailer`` and to pass that object into the constructor +of ``NewsletterManager``. In this case, however, the specified service ``app.mailer`` must exist. If it does not, an exception will be thrown. You can mark your dependencies as optional - this will be discussed in the next section. Using references is a very powerful tool that allows you to create independent service -classes with well-defined dependencies. In this example, the ``newsletter_manager`` -service needs the ``my_mailer`` service in order to function. When you define +classes with well-defined dependencies. In this example, the ``app.newsletter_manager`` +service needs the ``app.mailer`` service in order to function. When you define this dependency in the service container, the container takes care of all the work of instantiating the classes. @@ -736,9 +736,9 @@ dependencies for a class, then "setter injection" may be a better option. This means injecting the dependency using a method call rather than through the constructor. The class would look like this:: - namespace Acme\HelloBundle\Newsletter; + namespace AppBundle\Newsletter; - use Acme\HelloBundle\Mailer; + use AppBundle\Mailer; class NewsletterManager { @@ -758,19 +758,19 @@ Injecting the dependency by the setter method just needs a change of syntax: .. code-block:: yaml - # src/Acme/HelloBundle/Resources/config/services.yml + # app/config/services.yml services: - my_mailer: + app.mailer: # ... - newsletter_manager: - class: Acme\HelloBundle\Newsletter\NewsletterManager + app.newsletter_manager: + class: AppBundle\Newsletter\NewsletterManager calls: - - [setMailer, ['@my_mailer']] + - [setMailer, ['@app.mailer']] .. code-block:: xml - + - + - + - + @@ -792,16 +792,16 @@ Injecting the dependency by the setter method just needs a change of syntax: .. code-block:: php - // src/Acme/HelloBundle/Resources/config/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; - $container->setDefinition('my_mailer', ...); + $container->setDefinition('app.mailer', ...); - $container->setDefinition('newsletter_manager', new Definition( - 'Acme\HelloBundle\Newsletter\NewsletterManager' + $container->setDefinition('app.newsletter_manager', new Definition( + 'AppBundle\Newsletter\NewsletterManager' ))->addMethodCall('setMailer', array( - new Reference('my_mailer'), + new Reference('app.mailer'), )); .. note:: @@ -910,8 +910,8 @@ Making References optional Sometimes, one of your services may have an optional dependency, meaning that the dependency is not required for your service to work properly. In -the example above, the ``my_mailer`` service *must* exist, otherwise an exception -will be thrown. By modifying the ``newsletter_manager`` service definition, +the example above, the ``app.mailer`` service *must* exist, otherwise an exception +will be thrown. By modifying the ``app.newsletter_manager`` service definition, you can make this reference optional. The container will then inject it if it exists and do nothing if it doesn't: @@ -919,15 +919,15 @@ it exists and do nothing if it doesn't: .. code-block:: yaml - # src/Acme/HelloBundle/Resources/config/services.yml + # app/config/services.yml services: - newsletter_manager: - class: Acme\HelloBundle\Newsletter\NewsletterManager - arguments: ['@?my_mailer'] + app.newsletter_manager: + class: AppBundle\Newsletter\NewsletterManager + arguments: ['@?app.mailer'] .. code-block:: xml - + - + - - + + .. code-block:: php - // src/Acme/HelloBundle/Resources/config/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ContainerInterface; - $container->setDefinition('my_mailer', ...); + $container->setDefinition('app.mailer', ...); - $container->setDefinition('newsletter_manager', new Definition( - 'Acme\HelloBundle\Newsletter\NewsletterManager', + $container->setDefinition('app.newsletter_manager', new Definition( + 'AppBundle\Newsletter\NewsletterManager', array( new Reference( - 'my_mailer', + 'app.mailer', ContainerInterface::IGNORE_ON_INVALID_REFERENCE ) ) @@ -998,11 +998,12 @@ sending emails (``mailer``), or accessing information on the request (``request` You can take this a step further by using these services inside services that you've created for your application. Beginning by modifying the ``NewsletterManager`` -to use the real Symfony ``mailer`` service (instead of the pretend ``my_mailer``). +to use the real Symfony ``mailer`` service (instead of the pretend ``app.mailer``). Also pass the templating engine service to the ``NewsletterManager`` so that it can generate the email content via a template:: - namespace Acme\HelloBundle\Newsletter; + // src/AppBundle/Newsletter/NewsletterManager.php + namespace AppBundle\Newsletter; use Symfony\Component\Templating\EngineInterface; @@ -1029,22 +1030,22 @@ Configuring the service container is easy: .. code-block:: yaml - # src/Acme/HelloBundle/Resources/config/services.yml + # app/config/services.yml services: - newsletter_manager: - class: Acme\HelloBundle\Newsletter\NewsletterManager + app.newsletter_manager: + class: AppBundle\Newsletter\NewsletterManager arguments: ['@mailer', '@templating'] .. code-block:: xml - + - + @@ -1052,16 +1053,16 @@ Configuring the service container is easy: .. code-block:: php - // src/Acme/HelloBundle/Resources/config/services.php - $container->setDefinition('newsletter_manager', new Definition( - 'Acme\HelloBundle\Newsletter\NewsletterManager', + // app/config/services.php + $container->setDefinition('app.newsletter_manager', new Definition( + 'AppBundle\Newsletter\NewsletterManager', array( new Reference('mailer'), new Reference('templating'), ) )); -The ``newsletter_manager`` service now has access to the core ``mailer`` +The ``app.newsletter_manager`` service now has access to the core ``mailer`` and ``templating`` services. This is a common way to create services specific to your application that leverage the power of different services within the framework. @@ -1090,7 +1091,7 @@ to be used for a specific purpose. Take the following example: # app/config/services.yml services: foo.twig.extension: - class: Acme\HelloBundle\Extension\FooExtension + class: AppBundle\Extension\FooExtension public: false tags: - { name: twig.extension } @@ -1107,7 +1108,7 @@ to be used for a specific purpose. Take the following example: @@ -1120,7 +1121,7 @@ to be used for a specific purpose. Take the following example: // app/config/services.php use Symfony\Component\DependencyInjection\Definition; - $definition = new Definition('Acme\HelloBundle\Extension\FooExtension'); + $definition = new Definition('AppBundle\Extension\FooExtension'); $definition->setPublic(false); $definition->addTag('twig.extension'); $container->setDefinition('foo.twig.extension', $definition); @@ -1170,7 +1171,7 @@ its id: .. code-block:: bash - $ php app/console debug:container my_mailer + $ php app/console debug:container app.mailer Learn more ---------- diff --git a/components/console/console_arguments.rst b/components/console/console_arguments.rst index 894680b684a..fd3474c8ca2 100644 --- a/components/console/console_arguments.rst +++ b/components/console/console_arguments.rst @@ -49,18 +49,18 @@ is required. It can be separated from the option name either by spaces or except that it doesn't require a value. Have a look at the following table to get an overview of the possible ways to pass options: -===================== ========= =========== ============ -Input ``foo`` ``bar`` ``cat`` -===================== ========= =========== ============ -``--bar=Hello`` ``false`` ``"Hello"`` ``null`` -``--bar Hello`` ``false`` ``"Hello"`` ``null`` -``-b=Hello`` ``false`` ``"Hello"`` ``null`` -``-b Hello`` ``false`` ``"Hello"`` ``null`` -``-bHello`` ``false`` ``"Hello"`` ``null`` -``-fcWorld -b Hello`` ``true`` ``"Hello"`` ``"World"`` -``-cfWorld -b Hello`` ``false`` ``"Hello"`` ``"fWorld"`` -``-cbWorld`` ``false`` ``null`` ``"bWorld"`` -===================== ========= =========== ============ +===================== ========= ============ ============ +Input ``foo`` ``bar`` ``cat`` +===================== ========= ============ ============ +``--bar=Hello`` ``false`` ``"Hello"`` ``null`` +``--bar Hello`` ``false`` ``"Hello"`` ``null`` +``-b=Hello`` ``false`` ``"=Hello"`` ``null`` +``-b Hello`` ``false`` ``"Hello"`` ``null`` +``-bHello`` ``false`` ``"Hello"`` ``null`` +``-fcWorld -b Hello`` ``true`` ``"Hello"`` ``"World"`` +``-cfWorld -b Hello`` ``false`` ``"Hello"`` ``"fWorld"`` +``-cbWorld`` ``false`` ``null`` ``"bWorld"`` +===================== ========= ============ ============ Things get a little bit more tricky when the command also accepts an optional argument:: @@ -77,15 +77,15 @@ arguments. Have a look at the fifth example in the following table where it is used to tell the command that ``World`` is the value for ``arg`` and not the value of the optional ``cat`` option: -============================== ================= =========== =========== -Input ``bar`` ``cat`` ``arg`` -============================== ================= =========== =========== -``--bar Hello`` ``"Hello"`` ``null`` ``null`` -``--bar Hello World`` ``"Hello"`` ``null`` ``"World"`` -``--bar "Hello World"`` ``"Hello World"`` ``null`` ``null`` -``--bar Hello --cat World`` ``"Hello"`` ``"World"`` ``null`` -``--bar Hello --cat -- World`` ``"Hello"`` ``null`` ``"World"`` -``-b Hello -c World`` ``"Hello"`` ``"World"`` ``null`` -============================== ================= =========== =========== +============================== ================= =========== =========== +Input ``bar`` ``cat`` ``arg`` +============================== ================= =========== =========== +``--bar Hello`` ``"Hello"`` ``null`` ``null`` +``--bar Hello World`` ``"Hello"`` ``null`` ``"World"`` +``--bar "Hello World"`` ``"Hello World"`` ``null`` ``null`` +``--bar Hello --cat World`` ``"Hello"`` ``"World"`` ``null`` +``--bar Hello --cat -- World`` ``"Hello"`` ``null`` ``"World"`` +``-b Hello -c World`` ``"Hello"`` ``"World"`` ``null`` +============================== ================= =========== =========== .. _docopt: http://docopt.org/ diff --git a/components/dependency_injection/synthetic_services.rst b/components/dependency_injection/synthetic_services.rst index aba2c6d5710..a950acbbc4f 100644 --- a/components/dependency_injection/synthetic_services.rst +++ b/components/dependency_injection/synthetic_services.rst @@ -32,7 +32,7 @@ service will get a "service does not exist" error). In order to do so, you have to use :method:`Definition::setSynthetic() `:: - use Symfony\Component\DependencyInjectino\Definition; + use Symfony\Component\DependencyInjection\Definition; // synthetic services don't specify a class $kernelDefinition = new Definition(); diff --git a/contributing/code/standards.rst b/contributing/code/standards.rst index c989356a01d..c6030ba3ee1 100644 --- a/contributing/code/standards.rst +++ b/contributing/code/standards.rst @@ -200,6 +200,10 @@ Documentation * Add PHPDoc blocks for all classes, methods, and functions; +* Group annotations together so that annotations of the same type immediately + follow each other, and annotations of a different type are separated by a + single blank line; + * Omit the ``@return`` tag if the method does not return anything; * The ``@package`` and ``@subpackage`` annotations are not used. diff --git a/cookbook/form/unit_testing.rst b/cookbook/form/unit_testing.rst index e27d944cb7e..2ffcc4b5d4d 100644 --- a/cookbook/form/unit_testing.rst +++ b/cookbook/form/unit_testing.rst @@ -158,60 +158,45 @@ before creating the parent form using the ``PreloadedExtension`` class:: be getting errors that are not related to the form you are currently testing but to its children. -Adding custom Extensions +Adding Custom Extensions ------------------------ It often happens that you use some options that are added by :doc:`form extensions `. One of the cases may be the ``ValidatorExtension`` with its ``invalid_message`` option. -The ``TypeTestCase`` loads only the core form extension so an "Invalid option" -exception will be raised if you try to use it for testing a class that depends -on other extensions. You need to add those extensions to the factory object:: +The ``TypeTestCase`` only loads the core form extension, which means an +"Invalid option" exception will be raised if you try to test a class that +depends on other extensions. The +:method:`Symfony\\Component\\Form\\Test\\TypeTestCase::getExtensions` allows you to +return a list of extensions to register:: // src/AppBundle/Tests/Form/Type/TestedTypeTests.php namespace AppBundle\Tests\Form\Type; use AppBundle\Form\Type\TestedType; use AppBundle\Model\TestObject; - use Symfony\Component\Form\Test\TypeTestCase; + use Symfony\Component\Form\Extension\Validator\ValidatorExtension; use Symfony\Component\Form\Forms; use Symfony\Component\Form\FormBuilder; - use Symfony\Component\Form\Extension\Validator\Type\FormTypeValidatorExtension; + use Symfony\Component\Form\Test\TypeTestCase; use Symfony\Component\Validator\ConstraintViolationList; class TestedTypeTest extends TypeTestCase { - protected function setUp() + protected function getExtensions() { - parent::setUp(); - $validator = $this->getMock('\Symfony\Component\Validator\Validator\ValidatorInterface'); $validator->method('validate')->will($this->returnValue(new ConstraintViolationList())); - $this->factory = Forms::createFormFactoryBuilder() - ->addExtensions($this->getExtensions()) - ->addTypeExtension( - new FormTypeValidatorExtension( - $validator - ) - ) - ->addTypeGuesser( - $this->getMockBuilder( - 'Symfony\Component\Form\Extension\Validator\ValidatorTypeGuesser' - ) - ->disableOriginalConstructor() - ->getMock() - ) - ->getFormFactory(); - - $this->dispatcher = $this->getMock('Symfony\Component\EventDispatcher\EventDispatcherInterface'); - $this->builder = new FormBuilder(null, null, $this->dispatcher, $this->factory); + return array( + new ValidatorExtension($validator), + ); } // ... your tests } -Testing against different Sets of Data +Testing against Different Sets of Data -------------------------------------- If you are not familiar yet with PHPUnit's `data providers`_, this might be diff --git a/cookbook/routing/custom_route_loader.rst b/cookbook/routing/custom_route_loader.rst index 2e644464416..f762c4c4203 100644 --- a/cookbook/routing/custom_route_loader.rst +++ b/cookbook/routing/custom_route_loader.rst @@ -12,13 +12,9 @@ conventions or patterns. A great example for this use-case is the `FOSRestBundle`_ where routes are generated based on the names of the action methods in a controller. -A custom route loader does not enable your bundle to inject routes -without the need to modify the routing configuration -(e.g. ``app/config/routing.yml``) manually. -If your bundle provides routes, whether via a configuration file, like -the `WebProfilerBundle` does, or via a custom route loader, like the -`FOSRestBundle`_ does, an entry in the routing configuration is always -necessary. +You still need to modify your routing configuration (e.g. +``app/config/routing.yml``) manually, even when using a custom route +loader. .. note:: @@ -57,6 +53,12 @@ its :method:`Symfony\\Component\\Config\\Loader\\LoaderInterface::load` method will be called, which should return a :class:`Symfony\\Component\\Routing\\RouteCollection` containing :class:`Symfony\\Component\\Routing\\Route` objects. +.. note:: + + Routes loaded this way will be cached by the Router the same way as + when they are defined in one of the default formats (e.g. XML, YML, + PHP file). + Creating a custom Loader ------------------------ @@ -64,13 +66,14 @@ To load routes from some custom source (i.e. from something other than annotatio YAML or XML files), you need to create a custom route loader. This loader has to implement :class:`Symfony\\Component\\Config\\Loader\\LoaderInterface`. -In most cases it's better not to implement -:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` -yourself, but extend from :class:`Symfony\\Component\\Config\\Loader\\Loader`. +In most cases it is easier to extend from +:class:`Symfony\\Component\\Config\\Loader\\Loader` instead of implementing +:class:`Symfony\\Component\\Config\\Loader\\LoaderInterface` yourself. The sample loader below supports loading routing resources with a type of -``extra``. The type ``extra`` isn't important - you can just invent any resource -type you want. The resource name itself is not actually used in the example:: +``extra``. The type name should not clash with other loaders that might +support the same type of resource. Just make up a name specific to what +you do. The resource name itself is not actually used in the example:: // src/AppBundle/Routing/ExtraLoader.php namespace AppBundle\Routing; @@ -182,7 +185,7 @@ Using the custom Loader ~~~~~~~~~~~~~~~~~~~~~~~ If you did nothing else, your custom routing loader would *not* be called. -Instead, you only need to add a few extra lines to the routing configuration: +What remains to do is adding a few lines to the routing configuration: .. configuration-block::