diff --git a/book/security.rst b/book/security.rst
index 2f3ed0f30a6..84e5647e655 100644
--- a/book/security.rst
+++ b/book/security.rst
@@ -280,6 +280,11 @@ But who can you login as? Where do users come from?
What other methods are supported? See the :doc:`Configuration Reference `
or :doc:`build your own `.
+.. tip::
+
+ If your application logs users in via a third-party service such as Google,
+ Facebook or Twitter, check out the `HWIOAuthBundle`_ community bundle.
+
.. _security-user-providers:
.. _where-do-users-come-from-user-providers:
@@ -485,7 +490,7 @@ else, you'll want to encode their passwords. The best algorithm to use is
-
+
@@ -1381,3 +1386,4 @@ Learn More from the Cookbook
.. _`online tool`: https://www.dailycred.com/blog/12/bcrypt-calculator
.. _`frameworkextrabundle documentation`: http://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/index.html
.. _`security advisories database`: https://github.com/FriendsOfPHP/security-advisories
+.. _`HWIOAuthBundle`: https://github.com/hwi/HWIOAuthBundle
diff --git a/components/class_loader/class_loader.rst b/components/class_loader/class_loader.rst
index 246ee38a68a..1bef3f652d9 100644
--- a/components/class_loader/class_loader.rst
+++ b/components/class_loader/class_loader.rst
@@ -12,8 +12,7 @@ load all of your project's classes.
You can use both the ``ApcClassLoader`` and the ``XcacheClassLoader`` to
:doc:`cache ` a ``ClassLoader``
- instance or the ``DebugClassLoader`` to :doc:`debug `
- it.
+ instance.
Usage
-----
diff --git a/components/class_loader/debug_class_loader.rst b/components/class_loader/debug_class_loader.rst
index 75bf66c707a..d41afe9d277 100644
--- a/components/class_loader/debug_class_loader.rst
+++ b/components/class_loader/debug_class_loader.rst
@@ -1,6 +1,3 @@
-.. index::
- single: ClassLoader; DebugClassLoader
-
Debugging a Class Loader
========================
diff --git a/components/class_loader/index.rst b/components/class_loader/index.rst
index 9808f59c6d8..5215b57291d 100644
--- a/components/class_loader/index.rst
+++ b/components/class_loader/index.rst
@@ -9,5 +9,9 @@ ClassLoader
psr4_class_loader
map_class_loader
cache_class_loader
- debug_class_loader
class_map_generator
+
+.. toctree::
+ :hidden:
+
+ debug_class_loader
diff --git a/components/class_loader/introduction.rst b/components/class_loader/introduction.rst
index 9db1e7f41fa..55ba19a3e53 100644
--- a/components/class_loader/introduction.rst
+++ b/components/class_loader/introduction.rst
@@ -23,12 +23,14 @@ the class. Symfony provides three autoloaders, which are able to load your class
* :doc:`/components/class_loader/map_class_loader`: loads classes using
a static map from class name to file path.
-Additionally, the Symfony ClassLoader component ships with a set of wrapper
-classes which can be used to add additional functionality on top of existing
-autoloaders:
-
-* :doc:`/components/class_loader/cache_class_loader`
-* :doc:`/components/class_loader/debug_class_loader`
+Additionally, the Symfony ClassLoader component ships with a wrapper class
+which makes it possible
+:doc:`to cache the results of a class loader `.
+
+When using the :doc:`Debug component `, you
+can also use a special :doc:`DebugClassLoader `
+that eases debugging by throwing more helpful exceptions when a class could
+not be found by a class loader.
Installation
------------
diff --git a/components/dependency_injection/advanced.rst b/components/dependency_injection/advanced.rst
index 507908ab350..5fe67adc70f 100644
--- a/components/dependency_injection/advanced.rst
+++ b/components/dependency_injection/advanced.rst
@@ -73,61 +73,6 @@ below) to access this service (via the alias).
Services are by default public.
-Synthetic Services
-------------------
-
-Synthetic services are services that are injected into the container instead
-of being created by the container.
-
-For example, if you're using the :doc:`HttpKernel `
-component with the DependencyInjection component, then the ``request``
-service is injected in the
-:method:`ContainerAwareHttpKernel::handle() `
-method when entering the request :doc:`scope `.
-The class does not exist when there is no request, so it can't be included in
-the container configuration. Also, the service should be different for every
-subrequest in the application.
-
-To create a synthetic service, set ``synthetic`` to ``true``:
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- services:
- request:
- synthetic: true
-
- .. code-block:: xml
-
-
-
-
-
-
-
-
-
- .. code-block:: php
-
- use Symfony\Component\DependencyInjection\Definition;
-
- $container
- ->setDefinition('request', new Definition())
- ->setSynthetic(true);
-
-As you see, only the ``synthetic`` option is set. All other options are only used
-to configure how a service is created by the container. As the service isn't
-created by the container, these options are omitted.
-
-Now, you can inject the class by using
-:method:`Container::set `::
-
- // ...
- $container->set('request', new MyRequest(...));
-
Aliasing
--------
@@ -183,47 +128,6 @@ service by asking for the ``bar`` service like this::
class: Example\Foo
bar: "@foo"
-
-Requiring Files
----------------
-
-There might be use cases when you need to include another file just before
-the service itself gets loaded. To do so, you can use the ``file`` directive.
-
-.. configuration-block::
-
- .. code-block:: yaml
-
- services:
- foo:
- class: Example\Foo\Bar
- file: "%kernel.root_dir%/src/path/to/file/foo.php"
-
- .. code-block:: xml
-
-
-
-
-
-
- %kernel.root_dir%/src/path/to/file/foo.php
-
-
-
-
- .. code-block:: php
-
- use Symfony\Component\DependencyInjection\Definition;
-
- $definition = new Definition('Example\Foo\Bar');
- $definition->setFile('%kernel.root_dir%/src/path/to/file/foo.php');
- $container->setDefinition('foo', $definition);
-
-Notice that Symfony will internally call the PHP statement ``require_once``,
-which means that your file will be included only once per request.
-
Decorating Services
-------------------
diff --git a/components/dependency_injection/definitions.rst b/components/dependency_injection/definitions.rst
index c9d1e72cb3d..9c9574c7b9b 100644
--- a/components/dependency_injection/definitions.rst
+++ b/components/dependency_injection/definitions.rst
@@ -125,3 +125,15 @@ You can also replace any existing method calls with an array of new ones with::
the container is compiled. Once the container is compiled you cannot
manipulate service definitions further. To learn more about compiling
the container see :doc:`/components/dependency_injection/compilation`.
+
+Requiring Files
+~~~~~~~~~~~~~~~
+
+There might be use cases when you need to include another file just before
+the service itself gets loaded. To do so, you can use the
+:method:`Symfony\\Component\\DependencyInjection\\Definition::setFile` method::
+
+ $definition->setFile('/src/path/to/file/foo.php');
+
+Notice that Symfony will internally call the PHP statement ``require_once``,
+which means that your file will be included only once per request.
diff --git a/components/dependency_injection/index.rst b/components/dependency_injection/index.rst
index 4261a0a7854..dfa2e1ef54b 100644
--- a/components/dependency_injection/index.rst
+++ b/components/dependency_injection/index.rst
@@ -8,6 +8,7 @@
types
parameters
definitions
+ synthetic_services
compilation
tags
factories
diff --git a/components/dependency_injection/synthetic_services.rst b/components/dependency_injection/synthetic_services.rst
new file mode 100644
index 00000000000..cbe32a8c60a
--- /dev/null
+++ b/components/dependency_injection/synthetic_services.rst
@@ -0,0 +1,50 @@
+.. index::
+ single: DependencyInjection; Synthetic Services
+
+How to Inject Instances into the Container
+------------------------------------------
+
+When using the container in your application, you sometimes need to inject an
+instance instead of configuring the container to create a new instance.
+
+For instance, if you're using the :doc:`HttpKernel `
+component with the DependencyInjection component, then the ``kernel``
+service is injected into the container from within the ``Kernel`` class::
+
+ // ...
+ abstract class Kernel implements KernelInterface, TerminableInterface
+ {
+ // ...
+ protected function initializeContainer()
+ {
+ // ...
+ $this->container->set('kernel', $this);
+
+ // ...
+ }
+ }
+
+The ``kernel`` service is called a synthetic service. This service has to be
+configured in the container, so the container knows the service does exist
+during compilation (otherwise, services depending on this ``kernel`` service
+will get a "service does not exists" error).
+
+In order to do so, you have to use
+:method:`Definition::setSynthetic() `::
+
+ use Symfony\Component\DependencyInjectino\Definition;
+
+ // synthetic services don't specify a class
+ $kernelDefinition = new Definition();
+ $kernelDefinition->setSynthetic(true);
+
+ $container->setDefinition('your_service', $kernelDefinition);
+
+Now, you can inject the instance in the container using
+:method:`Container::set() `::
+
+ $yourService = new YourObject();
+ $container->set('your_service', $yourService);
+
+``$container->get('your_service')`` will now return the same instance as
+``$yourService``.
diff --git a/components/map.rst.inc b/components/map.rst.inc
index 009284614ce..dfead75f62c 100644
--- a/components/map.rst.inc
+++ b/components/map.rst.inc
@@ -11,7 +11,6 @@
* :doc:`/components/class_loader/psr4_class_loader`
* :doc:`/components/class_loader/map_class_loader`
* :doc:`/components/class_loader/cache_class_loader`
- * :doc:`/components/class_loader/debug_class_loader`
* :doc:`/components/class_loader/class_map_generator`
* :doc:`/components/config/index`
@@ -47,6 +46,7 @@
* :doc:`/components/dependency_injection/types`
* :doc:`/components/dependency_injection/parameters`
* :doc:`/components/dependency_injection/definitions`
+ * :doc:`/components/dependency_injection/synthetic_services`
* :doc:`/components/dependency_injection/compilation`
* :doc:`/components/dependency_injection/tags`
* :doc:`/components/dependency_injection/factories`
diff --git a/cookbook/assetic/asset_management.rst b/cookbook/assetic/asset_management.rst
index 6db46608147..121a1e9ac46 100644
--- a/cookbook/assetic/asset_management.rst
+++ b/cookbook/assetic/asset_management.rst
@@ -183,6 +183,12 @@ To include an image you can use the ``image`` tag.
You can also use Assetic for image optimization. More information in
:doc:`/cookbook/assetic/jpeg_optimize`.
+.. tip::
+
+ Instead of using Assetic to include images, you may consider using the
+ `LiipImagineBundle`_ community bundle, which allows to compress and
+ manipulate images (rotate, resize, watermark, etc.) before serving them.
+
.. _cookbook-assetic-cssrewrite:
Fixing CSS Paths with the ``cssrewrite`` Filter
@@ -572,3 +578,5 @@ some isolated directory (e.g. ``/js/compiled``), to keep things organized:
) as $url): ?>
+
+.. _`LiipImagineBundle`: https://github.com/liip/LiipImagineBundle
diff --git a/cookbook/assetic/jpeg_optimize.rst b/cookbook/assetic/jpeg_optimize.rst
index d3aebeb9e94..295bc27dd3a 100644
--- a/cookbook/assetic/jpeg_optimize.rst
+++ b/cookbook/assetic/jpeg_optimize.rst
@@ -250,4 +250,10 @@ file:
),
));
+.. tip::
+
+ For uploaded images, you can compress and manipulate them using the
+ `LiipImagineBundle`_ community bundle.
+
.. _`Jpegoptim`: http://www.kokkonen.net/tjko/projects.html
+.. _`LiipImagineBundle`: http://knpbundles.com/liip/LiipImagineBundle
diff --git a/cookbook/bundles/best_practices.rst b/cookbook/bundles/best_practices.rst
index 6aa1701334a..2bcf2fec0dd 100644
--- a/cookbook/bundles/best_practices.rst
+++ b/cookbook/bundles/best_practices.rst
@@ -4,7 +4,7 @@
Best Practices for Reusable Bundles
===================================
-There are 2 types of bundles:
+There are two types of bundles:
* Application-specific bundles: only used to build your application;
* Reusable bundles: meant to be shared across many projects.
@@ -13,12 +13,8 @@ This article is all about how to structure your **reusable bundles** so that
they're easy to configure and extend. Many of these recommendations do not
apply to application bundles because you'll want to keep those as simple
as possible. For application bundles, just follow the practices shown throughout
-the book and cookbook.
-
-.. seealso::
-
- The best practices for application-specific bundles are discussed in
- :doc:`/best_practices/introduction`.
+the :doc:`book `, the :doc:`cookbook ` and the
+:doc:`best practices ` book.
.. index::
pair: Bundle; Naming conventions
@@ -38,7 +34,7 @@ bundle class name must follow these simple rules:
* Use only alphanumeric characters and underscores;
* Use a CamelCased name;
-* Use a descriptive and short name (no more than 2 words);
+* Use a descriptive and short name (no more than two words);
* Prefix the name with the concatenation of the vendor (and optionally the
category namespaces);
* Suffix the name with ``Bundle``.
@@ -112,7 +108,7 @@ The following files are mandatory:
structure to work.
The depth of sub-directories should be kept to the minimal for most used
-classes and files (2 levels at a maximum). More levels can be defined for
+classes and files (two levels at a maximum). More levels can be defined for
non-strategic, less-used files.
The bundle directory is read-only. If you need to write temporary files, store
@@ -158,7 +154,7 @@ instance, a ``HelloController`` controller is stored in
``Bundle/HelloBundle/Controller/HelloController.php`` and the fully qualified
class name is ``Bundle\HelloBundle\Controller\HelloController``.
-All classes and files must follow the Symfony coding :doc:`standards `.
+All classes and files must follow the :doc:`Symfony coding standards `.
Some classes should be seen as facades and should be as short as possible, like
Commands, Helpers, Listeners, and Controllers.
@@ -181,7 +177,7 @@ Tests
-----
A bundle should come with a test suite written with PHPUnit and stored under
-the ``Tests/`` directory. Tests should follow the following principles:
+the ``Tests/`` directory. Tests should follow these principles:
* The test suite must be executable with a simple ``phpunit`` command run from
a sample application;
@@ -190,13 +186,14 @@ the ``Tests/`` directory. Tests should follow the following principles:
* The tests should cover at least 95% of the code base.
.. note::
+
A test suite must not contain ``AllTests.php`` scripts, but must rely on the
existence of a ``phpunit.xml.dist`` file.
Documentation
-------------
-All classes and functions must come with full PHPDoc.
+All classes and functions must be fully documented using `PHPDoc`_ tags.
Extensive documentation should also be provided in the
:doc:`reStructuredText ` format, under
@@ -233,8 +230,8 @@ following standardized instructions in your ``README.md`` file.
Step 2: Enable the Bundle
-------------------------
- Then, enable the bundle by adding the following line in the `app/AppKernel.php`
- file of your project:
+ Then, enable the bundle by adding it to the list of registered bundles
+ in the `app/AppKernel.php` file of your project:
```php
` should be named
+after the bundle name (``bundle.hello``).
A bundle must not override existing messages from another bundle.
@@ -369,18 +370,12 @@ The end user can provide values in any configuration file:
// app/config/config.php
$container->setParameter('acme_hello.email.from', 'fabien@example.com');
- .. code-block:: ini
-
- ; app/config/config.ini
- [parameters]
- acme_hello.email.from = fabien@example.com
-
Retrieve the configuration parameters in your code from the container::
$container->getParameter('acme_hello.email.from');
Even if this mechanism is simple enough, you are highly encouraged to use the
-semantic configuration described in the cookbook.
+:doc:`semantic bundle configuration ` instead.
.. note::
@@ -442,3 +437,4 @@ Learn more from the Cookbook
* :doc:`/cookbook/bundles/extension`
.. _standards: http://www.php-fig.org/psr/psr-4/
+.. _`PHPDoc`: https://en.wikipedia.org/wiki/PHPDoc
diff --git a/cookbook/bundles/configuration.rst b/cookbook/bundles/configuration.rst
index a6505f481af..43c5242ed5c 100644
--- a/cookbook/bundles/configuration.rst
+++ b/cookbook/bundles/configuration.rst
@@ -6,13 +6,13 @@ How to Create Friendly Configuration for a Bundle
=================================================
If you open your application configuration file (usually ``app/config/config.yml``),
-you'll see a number of different configuration "namespaces", such as ``framework``,
+you'll see a number of different configuration sections, such as ``framework``,
``twig`` and ``doctrine``. Each of these configures a specific bundle, allowing
-you to configure things at a high level and then let the bundle make all the
+you to define options at a high level and then let the bundle make all the
low-level, complex changes based on your settings.
-For example, the following tells the FrameworkBundle to enable the form
-integration, which involves the definition of quite a few services as well
+For example, the following configuration tells the FrameworkBundle to enable the
+form integration, which involves the definition of quite a few services as well
as integration of other related components:
.. configuration-block::
diff --git a/cookbook/bundles/extension.rst b/cookbook/bundles/extension.rst
index 78092a3f3fd..1cc271212e2 100644
--- a/cookbook/bundles/extension.rst
+++ b/cookbook/bundles/extension.rst
@@ -6,7 +6,7 @@ How to Load Service Configuration inside a Bundle
=================================================
In Symfony, you'll find yourself using many services. These services can be
-registered in the `app/config` directory of your application. But when you
+registered in the ``app/config/`` directory of your application. But when you
want to decouple the bundle for use in other projects, you want to include the
service configuration in the bundle itself. This article will teach you how to
do that.
@@ -15,7 +15,7 @@ Creating an Extension Class
---------------------------
In order to load service configuration, you have to create a Dependency
-Injection Extension for your bundle. This class has some conventions in order
+Injection (DI) Extension for your bundle. This class has some conventions in order
to be detected automatically. But you'll later see how you can change it to
your own preferences. By default, the Extension has to comply with the
following conventions:
diff --git a/cookbook/bundles/inheritance.rst b/cookbook/bundles/inheritance.rst
index 25c29da67fc..90457f54320 100644
--- a/cookbook/bundles/inheritance.rst
+++ b/cookbook/bundles/inheritance.rst
@@ -12,16 +12,16 @@ things like controllers, templates, and other files in a bundle's
For example, suppose that you're installing the `FOSUserBundle`_, but you
want to override its base ``layout.html.twig`` template, as well as one of
-its controllers. Suppose also that you have your own AcmeUserBundle
-where you want the overridden files to live. Start by registering the FOSUserBundle
-as the "parent" of your bundle::
+its controllers. Suppose also that you have your own UserBundle where you want
+the overridden files to live. Start by registering the FOSUserBundle as the
+"parent" of your bundle::
- // src/Acme/UserBundle/AcmeUserBundle.php
- namespace Acme\UserBundle;
+ // src/UserBundle/UserBundle.php
+ namespace UserBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
- class AcmeUserBundle extends Bundle
+ class UserBundle extends Bundle
{
public function getParent()
{
@@ -45,8 +45,8 @@ Suppose you want to add some functionality to the ``registerAction`` of a
just create your own ``RegistrationController.php`` file, override the bundle's
original method, and change its functionality::
- // src/Acme/UserBundle/Controller/RegistrationController.php
- namespace Acme\UserBundle\Controller;
+ // src/UserBundle/Controller/RegistrationController.php
+ namespace UserBundle\Controller;
use FOS\UserBundle\Controller\RegistrationController as BaseController;
@@ -82,9 +82,9 @@ location as your parent bundle.
For example, it's very common to need to override the FOSUserBundle's
``layout.html.twig`` template so that it uses your application's base layout.
Since the file lives at ``Resources/views/layout.html.twig`` in the FOSUserBundle,
-you can create your own file in the same location of AcmeUserBundle.
-Symfony will ignore the file that lives inside the FOSUserBundle entirely,
-and use your file instead.
+you can create your own file in the same location of UserBundle. Symfony will
+ignore the file that lives inside the FOSUserBundle entirely, and use your file
+instead.
The same goes for routing files and some other resources.
@@ -92,7 +92,7 @@ The same goes for routing files and some other resources.
The overriding of resources only works when you refer to resources with
the ``@FOSUserBundle/Resources/config/routing/security.xml`` method.
- If you refer to resources without using the @BundleName shortcut, they
+ If you refer to resources without using the ``@BundleName`` shortcut, they
can't be overridden in this way.
.. caution::
diff --git a/cookbook/bundles/installation.rst b/cookbook/bundles/installation.rst
index c4ce4e7aab5..638dcdf12f5 100644
--- a/cookbook/bundles/installation.rst
+++ b/cookbook/bundles/installation.rst
@@ -15,16 +15,16 @@ A) Add Composer Dependencies
----------------------------
Dependencies are managed with Composer, so if Composer is new to you, learn
-some basics in `their documentation`_. This has 2 steps:
+some basics in `their documentation`_. This involves two steps:
1) Find out the Name of the Bundle on Packagist
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The README for a bundle (e.g. `FOSUserBundle`_) usually tells you its name
(e.g. ``friendsofsymfony/user-bundle``). If it doesn't, you can search for
-the library on the `Packagist.org`_ site.
+the bundle on the `Packagist.org`_ site.
-.. note::
+.. tip::
Looking for bundles? Try searching at `KnpBundles.com`_: the unofficial
archive of Symfony Bundles.
@@ -39,9 +39,12 @@ Now that you know the package name, you can install it via Composer:
$ composer require friendsofsymfony/user-bundle
This will choose the best version for your project, add it to ``composer.json``
-and download the library into the ``vendor/`` directory. If you need a specific
-version, add a ``:`` and the version right after the library name (see
-`composer require`_).
+and download its code into the ``vendor/`` directory. If you need a specific
+version, include it as the second argument of the `composer require`_ command:
+
+.. code-block:: bash
+
+ $ composer require friendsofsymfony/user-bundle "~2.0"
B) Enable the Bundle
--------------------
@@ -60,7 +63,7 @@ The only thing you need to do now is register the bundle in ``AppKernel``::
public function registerBundles()
{
$bundles = array(
- // ...,
+ // ...
new FOS\UserBundle\FOSUserBundle(),
);
@@ -68,22 +71,47 @@ The only thing you need to do now is register the bundle in ``AppKernel``::
}
}
+In a few rare cases, you may want a bundle to be *only* enabled in the development
+:doc:`environment `. For example,
+the DoctrineFixturesBundle helps load dummy data - something you probably
+only want to do while developing. To only load this bundle in the ``dev``
+and ``test`` environments, register the bundle in this way::
+
+ // app/AppKernel.php
+
+ // ...
+ class AppKernel extends Kernel
+ {
+ // ...
+
+ public function registerBundles()
+ {
+ $bundles = array(
+ // ...
+ );
+
+ if (in_array($this->getEnvironment(), array('dev', 'test'))) {
+ $bundles[] = new Doctrine\Bundle\FixturesBundle\DoctrineFixturesBundle();
+ }
+
+ // ...
+ }
+ }
+
C) Configure the Bundle
-----------------------
It's pretty common for a bundle to need some additional setup or configuration
in ``app/config/config.yml``. The bundle's documentation will tell you about
-the configuration, but you can also get a reference of the bundle's config
-via the ``config:dump-reference`` command.
-
-For instance, in order to look the reference of the ``assetic`` config you
-can use this:
+the configuration, but you can also get a reference of the bundle's configuration
+via the ``config:dump-reference`` command:
.. code-block:: bash
$ app/console config:dump-reference AsseticBundle
-or this:
+Instead of the full bundle name, you can also pass the short name used as the root
+of the bundle's configuration:
.. code-block:: bash
diff --git a/cookbook/doctrine/file_uploads.rst b/cookbook/doctrine/file_uploads.rst
index 64178d6dca2..0282086c165 100644
--- a/cookbook/doctrine/file_uploads.rst
+++ b/cookbook/doctrine/file_uploads.rst
@@ -4,6 +4,13 @@
How to Handle File Uploads with Doctrine
========================================
+.. note::
+
+ Instead of handling file uploading yourself, you may consider using the
+ `VichUploaderBundle`_ community bundle. This bundle provides all the common
+ operations (such as file renaming, saving and deleting) and it's tightly
+ integrated with Doctrine ORM, MongoDB ODM, PHPCR ODM and Propel.
+
Handling file uploads with Doctrine entities is no different than handling
any other file upload. In other words, you're free to move the file in your
controller after handling a form submission. For examples of how to do this,
@@ -99,6 +106,13 @@ file.
If you're using annotations to specify your validation rules (as shown
in this example), be sure that you've enabled validation by annotation
(see :ref:`validation configuration `).
+
+.. caution::
+
+ If you use the ``getUploadRootDir()`` method, be aware that this will save
+ the file inside the document root, which can be accessed by everyone.
+ Consider placing it out of the document root and adding custom viewing
+ logic when you need to secure the files.
To handle the actual file upload in the form, use a "virtual" ``file`` field.
For example, if you're building your form directly in a controller, it might
@@ -557,3 +571,4 @@ order to remove the file. Before it's removed, you must store the file path
from the database, you can safely delete the file (in ``PostRemove``).
.. _`preUpdate`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/events.html#preupdate
+.. _`VichUploaderBundle`: https://github.com/dustin10/VichUploaderBundle
diff --git a/cookbook/security/custom_authentication_provider.rst b/cookbook/security/custom_authentication_provider.rst
index b377b800f44..7be577ec97d 100644
--- a/cookbook/security/custom_authentication_provider.rst
+++ b/cookbook/security/custom_authentication_provider.rst
@@ -8,10 +8,12 @@ How to Create a custom Authentication Provider
Creating a custom authentication system is hard, and this entry will walk
you through that process. But depending on your needs, you may be able
- to solve your problem in a simpler way using these documents:
+ to solve your problem in a simpler, or via a community bundle:
* :doc:`/cookbook/security/custom_password_authenticator`
* :doc:`/cookbook/security/api_key_authentication`
+ * To authenticate via OAuth using a third-party service such as Google, Facebook
+ or Twitter, try using the `HWIOAuthBundle`_ community bundle.
If you have read the chapter on :doc:`/book/security`, you understand the
distinction Symfony makes between authentication and authorization in the
@@ -289,7 +291,7 @@ the ``PasswordDigest`` header value matches with the user's password.
.. note::
- The comparsion of the expected and the provided digests uses a constant
+ The comparison of the expected and the provided digests uses a constant
time comparison provided by the
:method:`Symfony\\Component\\Security\\Core\\Util\\StringUtils::equals`
method of the ``StringUtils`` class. It is used to mitigate possible
@@ -624,6 +626,7 @@ set to any desirable value per firewall.
The rest is up to you! Any relevant configuration items can be defined
in the factory and consumed or passed to the other classes in the container.
+.. _`HWIOAuthBundle`: https://github.com/hwi/HWIOAuthBundle
.. _`WSSE`: http://www.xml.com/pub/a/2003/12/17/dive.html
.. _`nonce`: http://en.wikipedia.org/wiki/Cryptographic_nonce
.. _`timing attacks`: http://en.wikipedia.org/wiki/Timing_attack
diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst
index 8efd450f9e8..8abd48f5823 100644
--- a/reference/constraints/Length.rst
+++ b/reference/constraints/Length.rst
@@ -116,6 +116,10 @@ min
This required option is the "min" length value. Validation will fail if
the given value's length is **less** than this min value.
+It is important to notice that NULL values and empty strings are considered
+valid no matter if the constraint required a minimum length. Validators are
+triggered only if the value is not blank.
+
max
~~~