diff --git a/book/security.rst b/book/security.rst index fa9958dca1e..3d7ef25896c 100644 --- a/book/security.rst +++ b/book/security.rst @@ -661,7 +661,7 @@ see :doc:`/cookbook/security/form_login`. ), ), - **3. Be sure ``/login_check`` is behind a firewall** + **3. Be sure /login_check is behind a firewall** Next, make sure that your ``check_path`` URL (e.g. ``/login_check``) is behind the firewall you're using for your form login (in this example, @@ -1098,7 +1098,7 @@ Thanks to the SensioFrameworkExtraBundle, you can also secure your controller us // ... } -For more information, see the +For more information, see the :doc:`FrameworkExtraBundle documentation `. Securing other Services @@ -1338,7 +1338,7 @@ in plain text (whether those users are stored in a configuration file or in a database somewhere). Of course, in a real application, you'll want to encode your users' passwords for security reasons. This is easily accomplished by mapping your User class to one of several built-in "encoders". For example, -to store your users in memory, but obscure their passwords via ``sha1``, +to store your users in memory, but obscure their passwords via ``bcrypt``, do the following: .. configuration-block:: @@ -1352,14 +1352,17 @@ do the following: in_memory: memory: users: - ryan: { password: bb87a29949f3a1ee0559f8a57357487151281386, roles: 'ROLE_USER' } - admin: { password: 74913f5cd5f61ec0bcfdb775414c2fb3d161b620, roles: 'ROLE_ADMIN' } + ryan: + password: $2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO + roles: 'ROLE_USER' + admin: + password: $2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW + roles: 'ROLE_ADMIN' encoders: Symfony\Component\Security\Core\User\User: - algorithm: sha1 - iterations: 1 - encode_as_base64: false + algorithm: bcrypt + cost: 12 .. code-block:: xml @@ -1369,18 +1372,18 @@ do the following: + algorithm="bcrypt" + cost="12" + /> .. code-block:: php @@ -1393,11 +1396,11 @@ do the following: 'memory' => array( 'users' => array( 'ryan' => array( - 'password' => 'bb87a29949f3a1ee0559f8a57357487151281386', + 'password' => '$2a$12$w/aHvnC/XNeDVrrl65b3dept8QcKqpADxUlbraVXXsC03Jam5hvoO', 'roles' => 'ROLE_USER', ), 'admin' => array( - 'password' => '74913f5cd5f61ec0bcfdb775414c2fb3d161b620', + 'password' => '$2a$12$HmOsqRDJK0HuMDQ5Fb2.AOLMQHyNHGD0seyjU3lEVusjT72QQEIpW', 'roles' => 'ROLE_ADMIN', ), ), @@ -1406,73 +1409,32 @@ do the following: ), 'encoders' => array( 'Symfony\Component\Security\Core\User\User' => array( - 'algorithm' => 'sha1', - 'iterations' => 1, - 'encode_as_base64' => false, + 'algorithm' => 'bcrypt', + 'iterations' => 12, ), ), )); -By setting the ``iterations`` to ``1`` and the ``encode_as_base64`` to false, -the password is simply run through the ``sha1`` algorithm one time and without -any extra encoding. You can now calculate the hashed password either programmatically -(e.g. ``hash('sha1', 'ryanpass')``) or via some online tool like `functions-online.com`_ +.. versionadded:: 2.2 + The BCrypt encoder was introduced in Symfony 2.2. -.. tip:: - - Supported algorithms for this method depend on your PHP version. - A full list is available calling the PHP function :phpfunction:`hash_algos`. - -If you're creating your users dynamically (and storing them in a database), -you can use even tougher hashing algorithms and then rely on an actual password -encoder object to help you encode passwords. For example, suppose your User -object is ``Acme\UserBundle\Entity\User`` (like in the above example). First, -configure the encoder for that user: - -.. configuration-block:: - - .. code-block:: yaml - - # app/config/security.yml - security: - # ... - - encoders: - Acme\UserBundle\Entity\User: sha512 - - .. code-block:: xml +You can now calculate the hashed password either programmatically +(e.g. ``password_hash('ryanpass', PASSWORD_BCRYPT, array('cost' => 12));``) +or via some online tool. - - - - - - +.. include:: /cookbook/security/_ircmaxwell_password-compat.rst.inc - .. code-block:: php - - // app/config/security.php - $container->loadFromExtension('security', array( - // ... - 'encoders' => array( - 'Acme\UserBundle\Entity\User' => 'sha512', - ), - )); - -In this case, you're using the stronger ``sha512`` algorithm. Also, since -you've simply specified the algorithm (``sha512``) as a string, the system -will default to hashing your password 5000 times in a row and then encoding -it as base64. In other words, the password has been greatly obfuscated so -that the hashed password can't be decoded (i.e. you can't determine the password -from the hashed password). +Supported algorithms for this method depend on your PHP version. A full list +is available by calling the PHP function :phpfunction:`hash_algos`. Determining the Hashed Password ............................... -If you have some sort of registration form for users, you'll need to be able -to determine the hashed password so that you can set it on your user. No -matter what algorithm you configure for your user object, the hashed password -can always be determined in the following way from a controller:: +If you're storing users in the database and you have some sort of registration +form for users, you'll need to be able to determine the hashed password so +that you can set it on your user before inserting it. No matter what algorithm +you configure for your user object, the hashed password can always be determined +in the following way from a controller:: $factory = $this->get('security.encoder_factory'); $user = new Acme\UserBundle\Entity\User(); @@ -1481,6 +1443,10 @@ can always be determined in the following way from a controller:: $password = $encoder->encodePassword('ryanpass', $user->getSalt()); $user->setPassword($password); +In order for this to work, just make sure that you have the encoder for your +user class (e.g. ``Acme\UserBundle\Entity\User``) configured under the ``encoders`` +key in ``app/config/security.yml``. + .. caution:: When you allow a user to submit a plaintext password (e.g. registration @@ -2157,8 +2123,8 @@ Learn more from the Cookbook * :doc:`Blacklist users by IP address with a custom voter ` * :doc:`Access Control Lists (ACLs) ` * :doc:`/cookbook/security/remember_me` +* :doc:`How to Restrict Firewalls to a Specific Host ` .. _`FOSUserBundle`: https://github.com/FriendsOfSymfony/FOSUserBundle .. _`implement the \Serializable interface`: http://php.net/manual/en/class.serializable.php -.. _`functions-online.com`: http://www.functions-online.com/sha1.html .. _`Timing attack`: http://en.wikipedia.org/wiki/Timing_attack diff --git a/components/config/introduction.rst b/components/config/introduction.rst index 047ff599cc0..89eb4beaec9 100644 --- a/components/config/introduction.rst +++ b/components/config/introduction.rst @@ -12,6 +12,13 @@ The Config component provides several classes to help you find, load, combine, autofill and validate configuration values of any kind, whatever their source may be (YAML, XML, INI files, or for instance a database). +.. caution:: + + The ``IniFileLoader`` parses the file contents using the + :phpfunction:`parse_ini_file` function, therefore, you can only set + parameters to string values. To set parameters to other data types + (e.g. boolean, integer, etc), the other loaders are recommended. + Installation ------------ diff --git a/components/http_foundation/trusting_proxies.rst b/components/http_foundation/trusting_proxies.rst index 591a58b09b7..fcd32d70b83 100644 --- a/components/http_foundation/trusting_proxies.rst +++ b/components/http_foundation/trusting_proxies.rst @@ -15,7 +15,7 @@ headers by default. If you are behind a proxy, you should manually whitelist your proxy. .. versionadded:: 2.3 - CIDR notation support was introduced, so you can whitelist whole + CIDR notation support was introduced in Symfony 2.3, so you can whitelist whole subnets (e.g. ``10.0.0.0/8``, ``fc00::/7``). .. code-block:: php diff --git a/contributing/code/patches.rst b/contributing/code/patches.rst index 7f0667ea960..040ad643170 100644 --- a/contributing/code/patches.rst +++ b/contributing/code/patches.rst @@ -200,7 +200,7 @@ When your patch is not about a bug fix (when you add a new feature or change an existing one for instance), it must also include the following: * An explanation of the changes in the relevant ``CHANGELOG`` file(s) (the - ``[BC BREAK]`` or the ``[DEPRECATION]`` prefix must be used when relevant); + ``[BC BREAK]`` or the ``[DEPRECATION]`` prefix must be used when relevant); * An explanation on how to upgrade an existing application in the relevant ``UPGRADE`` file(s) if the changes break backward compatibility or if you @@ -244,7 +244,7 @@ Check that all tests still pass and push your branch remotely: .. code-block:: bash - $ git push -f origin BRANCH_NAME + $ git push --force origin BRANCH_NAME Make a Pull Request ~~~~~~~~~~~~~~~~~~~ @@ -369,11 +369,11 @@ patch. Before re-submitting the patch, rebase with ``upstream/master`` or .. code-block:: bash $ git rebase -f upstream/master - $ git push -f origin BRANCH_NAME + $ git push --force origin BRANCH_NAME .. note:: - when doing a ``push --force``, always specify the branch name explicitly + When doing a ``push --force``, always specify the branch name explicitly to avoid messing other branches in the repo (``--force`` tells Git that you really want to mess with things so do it carefully). @@ -383,10 +383,9 @@ convert many commits to one commit. To do this, use the rebase command: .. code-block:: bash $ git rebase -i upstream/master - $ git push -f origin BRANCH_NAME + $ git push --force origin BRANCH_NAME -The number 3 here must equal the amount of commits in your branch. After you -type this command, an editor will popup showing a list of commits: +After you type this command, an editor will popup showing a list of commits: .. code-block:: text @@ -396,9 +395,9 @@ type this command, an editor will popup showing a list of commits: To squash all commits into the first one, remove the word ``pick`` before the second and the last commits, and replace it by the word ``squash`` or just - ``s``. When you save, Git will start rebasing, and if successful, will ask - you to edit the commit message, which by default is a listing of the commit - messages of all the commits. When you are finished, execute the push command. +``s``. When you save, Git will start rebasing, and if successful, will ask +you to edit the commit message, which by default is a listing of the commit +messages of all the commits. When you are finished, execute the push command. .. _ProGit: http://git-scm.com/book .. _GitHub: https://github.com/signup/free diff --git a/contributing/documentation/overview.rst b/contributing/documentation/overview.rst index da849040e48..695960bad64 100644 --- a/contributing/documentation/overview.rst +++ b/contributing/documentation/overview.rst @@ -135,7 +135,7 @@ tag and a short description: .. code-block:: text .. versionadded:: 2.3 - The ``askHiddenResponse`` method was added in Symfony 2.3. + The ``askHiddenResponse`` method was introduced in Symfony 2.3. You can also ask a question and hide the response. This is particularly... diff --git a/cookbook/doctrine/file_uploads.rst b/cookbook/doctrine/file_uploads.rst index 8b6b30c3b48..adb30e27e1f 100644 --- a/cookbook/doctrine/file_uploads.rst +++ b/cookbook/doctrine/file_uploads.rst @@ -300,6 +300,15 @@ object, which is what's returned after a ``file`` field is submitted:: Using Lifecycle Callbacks ------------------------- +.. caution:: + + Using lifecycle callbacks is a limited technique that has some drawbacks. + If you want to remove the hardcoded ``__DIR__`` reference inside + the ``Document::getUploadRootDir()`` method, the best way is to start + using explicit :doc:`doctrine listeners `. + There you will be able to inject kernel parameters such as ``kernel.root_dir`` + to be able to build absolute paths. + Even if this implementation works, it suffers from a major flaw: What if there is a problem when the entity is persisted? The file would have already moved to its final location even though the entity's ``path`` property didn't diff --git a/cookbook/routing/service_container_parameters.rst b/cookbook/routing/service_container_parameters.rst index 8eaa7d524f8..9ac05c48e60 100644 --- a/cookbook/routing/service_container_parameters.rst +++ b/cookbook/routing/service_container_parameters.rst @@ -18,16 +18,17 @@ inside your routing configuration: .. code-block:: yaml + # app/config/routing.yml contact: path: /{_locale}/contact defaults: { _controller: AcmeDemoBundle:Main:contact } requirements: - _locale: %acme_demo.locales% + _locale: "%acme_demo.locales%" .. code-block:: xml + - @@ -40,6 +41,7 @@ inside your routing configuration: .. code-block:: php + // app/config/routing.php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; @@ -82,14 +84,15 @@ path): .. code-block:: yaml + # app/config/routing.yml some_route: path: /%acme_demo.route_prefix%/contact defaults: { _controller: AcmeDemoBundle:Main:contact } .. code-block:: xml + - @@ -101,6 +104,7 @@ path): .. code-block:: php + // app/config/routing.php use Symfony\Component\Routing\RouteCollection; use Symfony\Component\Routing\Route; @@ -116,7 +120,7 @@ path): Just like in normal service container configuration files, if you actually need a ``%`` in your route, you can escape the percent sign by doubling it, e.g. ``/score-50%%``, which would resolve to ``/score-50%``. - + However, as the ``%`` characters included in any URL are automatically encoded, the resulting URL of this example would be ``/score-50%25`` (``%25`` is the result of encoding the ``%`` character). diff --git a/cookbook/security/_ircmaxwell_password-compat.rst.inc b/cookbook/security/_ircmaxwell_password-compat.rst.inc new file mode 100644 index 00000000000..3f96c454488 --- /dev/null +++ b/cookbook/security/_ircmaxwell_password-compat.rst.inc @@ -0,0 +1,13 @@ +.. caution:: + + If you're using PHP 5.4 or lower, you'll need to install the ``ircmaxell/password-compat`` + library via Composer in order to be able to use the ``bcrypt`` encoder: + + .. code-block:: json + + { + "require": { + ... + "ircmaxell/password-compat": "~1.0.3" + } + } diff --git a/cookbook/security/entity_provider.rst b/cookbook/security/entity_provider.rst index 3fb489c819d..8ba616eb481 100644 --- a/cookbook/security/entity_provider.rst +++ b/cookbook/security/entity_provider.rst @@ -32,7 +32,7 @@ The Data Model -------------- For the purpose of this cookbook, the ``AcmeUserBundle`` bundle contains a -``User`` entity class with the following fields: ``id``, ``username``, ``salt``, +``User`` entity class with the following fields: ``id``, ``username``, ``password``, ``email`` and ``isActive``. The ``isActive`` field tells whether or not the user account is active. @@ -77,11 +77,6 @@ focus on the most important methods that come from the */ private $username; - /** - * @ORM\Column(type="string", length=32) - */ - private $salt; - /** * @ORM\Column(type="string", length=64) */ @@ -100,7 +95,8 @@ focus on the most important methods that come from the public function __construct() { $this->isActive = true; - $this->salt = md5(uniqid(null, true)); + // may not be needed, see section on salt below + // $this->salt = md5(uniqid(null, true)); } /** @@ -116,7 +112,9 @@ focus on the most important methods that come from the */ public function getSalt() { - return $this->salt; + // you *may* need a real salt depending on your encoder + // see section on salt below + return null; } /** @@ -150,8 +148,9 @@ focus on the most important methods that come from the return serialize(array( $this->id, $this->username, - $this->salt, $this->password, + // see section on salt below + // $this->salt, )); } @@ -163,8 +162,9 @@ focus on the most important methods that come from the list ( $this->id, $this->username, - $this->salt, $this->password, + // see section on salt below + // $this->salt ) = unserialize($serialized); } } @@ -226,17 +226,31 @@ user records and encode their password, see :ref:`book-security-encoding-user-pa .. code-block:: bash - $ mysql> SELECT * FROM acme_users; - +----+----------+------+------------------------------------------+--------------------+-----------+ - | id | username | salt | password | email | is_active | - +----+----------+------+------------------------------------------+--------------------+-----------+ - | 1 | admin | | d033e22ae348aeb5660fc2140aec35850c4da997 | admin@example.com | 1 | - +----+----------+------+------------------------------------------+--------------------+-----------+ + $ mysql> select * from acme_users; + +----+----------+------------------------------------------+--------------------+-----------+ + | id | username | password | email | is_active | + +----+----------+------------------------------------------+--------------------+-----------+ + | 1 | admin | d033e22ae348aeb5660fc2140aec35850c4da997 | admin@example.com | 1 | + +----+----------+------------------------------------------+--------------------+-----------+ The next part will focus on how to authenticate one of these users thanks to the Doctrine entity user provider and a couple of lines of configuration. +.. sidebar:: Do you need to use a Salt? + + Yes. Hashing a password with a salt is a necessary step so that encoded + passwords can't be decoded. However, some encoders - like Bcrypt - have + a built-in salt mechanism. If you configure ``bcrypt`` as your encoder + in ``security.yml`` (see the next section), then ``getSalt()`` should + return ``null``, so that Bcrypt generates the salt itself. + + However, if you use an encoder that does *not* have a built-in salting + ability (e.g. ``sha512``), you *must* (from a security perspective) generate + your own, random salt, store it on a ``salt`` property that is saved to + the database, and return it from ``getSalt()``. Some of the code needed + is commented out in the above example. + Authenticating Someone against a Database ----------------------------------------- @@ -257,9 +271,7 @@ then be checked against your User entity records in the database: security: encoders: Acme\UserBundle\Entity\User: - algorithm: sha1 - encode_as_base64: false - iterations: 1 + algorithm: bcrypt role_hierarchy: ROLE_ADMIN: ROLE_USER @@ -282,9 +294,7 @@ then be checked against your User entity records in the database: ROLE_USER @@ -307,9 +317,7 @@ then be checked against your User entity records in the database: $container->loadFromExtension('security', array( 'encoders' => array( 'Acme\UserBundle\Entity\User' => array( - 'algorithm' => 'sha1', - 'encode_as_base64' => false, - 'iterations' => 1, + 'algorithm' => 'bcrypt', ), ), 'role_hierarchy' => array( @@ -335,12 +343,14 @@ then be checked against your User entity records in the database: ), )); -The ``encoders`` section associates the ``sha1`` password encoder to the entity +The ``encoders`` section associates the ``bcrypt`` password encoder to the entity class. This means that Symfony will expect the password that's stored in -the database to be encoded using this algorithm. For details on how to create +the database to be encoded using this encoder. For details on how to create a new User object with a properly encoded password, see the :ref:`book-security-encoding-user-password` section of the security chapter. +.. include:: /cookbook/security/_ircmaxwell_password-compat.rst.inc + The ``providers`` section defines an ``administrators`` user provider. A user provider is a "source" of where users are loaded during authentication. In this case, the ``entity`` keyword means that Symfony will use the Doctrine @@ -749,3 +759,45 @@ fetch the user and their associated roles with a single query:: The ``QueryBuilder::leftJoin()`` method joins and fetches related roles from the ``AcmeUserBundle:User`` model class when a user is retrieved by their email address or username. + +.. _`cookbook-security-serialize-equatable`: + +Understanding serialize and how a User is Saved in the Session +-------------------------------------------------------------- + +If you're curious about the importance of the ``serialize()`` method inside +the ``User`` class or how the User object is serialized or deserialized, then +this section is for you. If not, feel free to skip this. + +Once the user is logged in, the entire User object is serialized into the +session. On the next request, the User object is deserialized. Then, value +of the ``id`` property is used to re-query for a fresh User object from the +database. Finally, the fresh User object is compared in some way to the deserialized +User object to make sure that they represent the same user. For example, if +the ``username`` on the 2 User objects doesn't match for some reason, then +the user will be logged out for security reasons. + +Even though this all happens automatically, there are a few important side-effects. + +First, the :phpclass:`Serializable` interface and its ``serialize`` and ``unserialize`` +methods have been added to allow the ``User`` class to be serialized +to the session. This may or may not be needed depending on your setup, +but it's probably a good idea. In theory, only the ``id`` needs to be serialized, +because the :method:`Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider::refreshUser` +method refreshes the user on each request by using the ``id`` (as explained +above). However in practice, this means that the User object is reloaded from +the database on each request using the ``id`` from the serialized object. +This makes sure all of the User's data is fresh. + +Symfony also uses the ``username``, ``salt``, and ``password`` to verify +that the User has not changed between requests. Failing to serialize +these may cause you to be logged out on each request. If your User implements +the :class:`Symfony\\Component\\Security\\Core\\User\\EquatableInterface`, +then instead of these properties being checked, your ``isEqualTo`` method +is simply called, and you can check whatever properties you want. Unless +you understand this, you probably *won't* need to implement this interface +or worry about it. + +.. versionadded:: 2.1 + In Symfony 2.1, the ``equals`` method was removed from ``UserInterface`` + and the ``EquatableInterface`` was added in its place. diff --git a/cookbook/security/host_restriction.rst b/cookbook/security/host_restriction.rst index 232f1cd5ff6..b5b2e529d95 100644 --- a/cookbook/security/host_restriction.rst +++ b/cookbook/security/host_restriction.rst @@ -5,7 +5,7 @@ How to Restrict Firewalls to a Specific Host ============================================ .. versionadded:: 2.4 - Support for restricting security firewalls to a specific host was added in + Support for restricting security firewalls to a specific host was introduced in Symfony 2.4. When using the Security component, you can create firewalls that match certain diff --git a/cookbook/session/sessions_directory.rst b/cookbook/session/sessions_directory.rst index ad662846f82..974764df923 100644 --- a/cookbook/session/sessions_directory.rst +++ b/cookbook/session/sessions_directory.rst @@ -4,23 +4,86 @@ Configuring the Directory Where Sessions Files are Saved ======================================================== -By default, Symfony stores the session data in files in the cache -directory ``%kernel.cache_dir%/sessions``. This means that when you clear -the cache, any current sessions will also be deleted. +By default, the Symfony Standard Edition uses the global ``php.ini`` values +for ``session.save_handler`` and ``session.save_path`` to determine where +to store session data. This is because of the following configuration: -.. note:: +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + framework: + session: + # handler_id set to null will use default session handler from php.ini + handler_id: ~ + + .. code-block:: xml + + + + + + + + + - If the ``session`` configuration key is set to ``~``, Symfony will use the - global PHP ini values for ``session.save_handler`` and associated - ``session.save_path`` from ``php.ini``. + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('framework', array( + 'session' => array( + // handler_id set to null will use default session handler from php.ini + 'handler-id' => null, + ), + )); -.. note:: +With this configuration, changing *where* your session metadata is stored +is entirely up to your ``php.ini`` configuration. - While the Symfony Full Stack Framework defaults to using the - ``session.handler.native_file``, the Symfony Standard Edition is - configured to use PHP's global session settings by default and therefor - sessions will be stored according to the ``session.save_path`` location - and will not be deleted when clearing the cache. +However, if you have the following configuration, Symfony will store the session +data in files in the cache directory ``%kernel.cache_dir%/sessions``. This +means that when you clear the cache, any current sessions will also be deleted: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + framework: + session: ~ + + .. code-block:: xml + + + + + + + + + + .. code-block:: php + + // app/config/config.php + $container->loadFromExtension('framework', array( + 'session' => array(), + )); Using a different directory to save session data is one method to ensure that your current sessions aren't lost when you clear Symfony's cache. diff --git a/cookbook/testing/database.rst b/cookbook/testing/database.rst index 6d290b733df..ab869fa3a62 100644 --- a/cookbook/testing/database.rst +++ b/cookbook/testing/database.rst @@ -49,7 +49,7 @@ Suppose the class you want to test looks like this:: public function calculateTotalSalary($id) { $employeeRepository = $this->entityManager->getRepository('AcmeDemoBundle::Employee'); - $employee = $userRepository->find($id); + $employee = $employeeRepository->find($id); return $employee->getSalary() + $employee->getBonus(); } @@ -62,7 +62,6 @@ it's easy to pass a mock object within a test:: class SalaryCalculatorTest extends \PHPUnit_Framework_TestCase { - public function testCalculateTotalSalary() { // First, mock the object to be used in the test diff --git a/cookbook/testing/profiling.rst b/cookbook/testing/profiling.rst index 2ee70f00eae..3d3e660e4b7 100644 --- a/cookbook/testing/profiling.rst +++ b/cookbook/testing/profiling.rst @@ -11,7 +11,7 @@ various things and enforce some metrics. The Symfony2 :ref:`Profiler ` gathers a lot of data for each request. Use this data to check the number of database calls, the time -spent in the framework, ... But before writing assertions, enable the profiler +spent in the framework, etc. But before writing assertions, enable the profiler and check that the profiler is indeed available (it is enabled by default in the ``test`` environment):: diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index 6d9a6010ea7..fb58717c916 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -128,7 +128,7 @@ Configures the IP addresses that should be trusted as proxies. For more details, see :doc:`/components/http_foundation/trusting_proxies`. .. versionadded:: 2.3 - CIDR notation support was introduced, so you can whitelist whole + CIDR notation support was introduced in Symfony 2.3, so you can whitelist whole subnets (e.g. ``10.0.0.0/8``, ``fc00::/7``). .. configuration-block:: diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index 8eda298cdc6..accbbd97cbd 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -13,6 +13,10 @@ Full Default Configuration The following is the full default configuration for the security system. Each part will be explained in the next section. +.. versionadded:: 2.4 + Support for restricting security firewalls to a specific host was introduced in + Symfony 2.4. + .. configuration-block:: .. code-block:: yaml @@ -98,6 +102,8 @@ Each part will be explained in the next section. # Examples: somename: pattern: .* + # restrict the firewall to a specific host + host: admin\.example\.com request_matcher: some.service.id access_denied_url: /foo/error403 access_denied_handler: some.service.id diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index fc529e3a7d9..159ef755c30 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -42,17 +42,7 @@ Example Usage Field Options ------------- -value -~~~~~ - -**type**: ``mixed`` **default**: ``1`` - -The value that's actually used as the value for the checkbox. This does -not affect the value that's set on your object. - -.. caution:: - - To make a checkbox checked by default, set the `data`_ option to ``true``. +.. include:: /reference/forms/types/options/value.rst.inc Inherited options ----------------- diff --git a/reference/forms/types/form.rst b/reference/forms/types/form.rst index fc630baa1b1..dfe67119f6c 100644 --- a/reference/forms/types/form.rst +++ b/reference/forms/types/form.rst @@ -45,8 +45,17 @@ on all fields. .. include:: /reference/forms/types/options/max_length.rst.inc -inherit_data ------------- +.. include:: /reference/forms/types/options/empty_data.rst.inc + +.. include:: /reference/forms/types/options/by_reference.rst.inc + +.. include:: /reference/forms/types/options/error_bubbling.rst.inc + +.. include:: /reference/forms/types/options/inherit_data.rst.inc + +.. include:: /reference/forms/types/options/error_mapping.rst.inc + +.. include:: /reference/forms/types/options/invalid_message.rst.inc -See :doc:`/cookbook/form/inherit_data_option`. +.. include:: /reference/forms/types/options/invalid_message_parameters.rst.inc diff --git a/reference/forms/types/options/_error_bubbling_body.rst.inc b/reference/forms/types/options/_error_bubbling_body.rst.inc index 32f5ad33401..5fd93614456 100644 --- a/reference/forms/types/options/_error_bubbling_body.rst.inc +++ b/reference/forms/types/options/_error_bubbling_body.rst.inc @@ -1,3 +1,3 @@ -If true, any errors for this field will be passed to the parent field -or form. For example, if set to true on a normal field, any errors for +If ``true``, any errors for this field will be passed to the parent field +or form. For example, if set to ``true`` on a normal field, any errors for that field will be attached to the main form, not to the specific field. \ No newline at end of file diff --git a/reference/forms/types/options/by_reference.rst.inc b/reference/forms/types/options/by_reference.rst.inc index 26dbd65a020..8f7fffab0fe 100644 --- a/reference/forms/types/options/by_reference.rst.inc +++ b/reference/forms/types/options/by_reference.rst.inc @@ -3,8 +3,8 @@ by_reference **type**: ``Boolean`` **default**: ``true`` -In most cases, if you have a ``name`` field, then you expect ``setName`` -to be called on the underlying object. In some cases, however, ``setName`` +In most cases, if you have a ``name`` field, then you expect ``setName()`` +to be called on the underlying object. In some cases, however, ``setName()`` may *not* be called. Setting ``by_reference`` ensures that the setter is called in all cases. @@ -20,13 +20,13 @@ To explain this further, here's a simple example:: ) If ``by_reference`` is true, the following takes place behind the scenes -when you call ``submit`` (or ``handleRequest``) on the form:: +when you call ``submit()`` (or ``handleRequest()``) on the form:: $article->setTitle('...'); $article->getAuthor()->setName('...'); $article->getAuthor()->setEmail('...'); -Notice that ``setAuthor`` is not called. The author is modified by reference. +Notice that ``setAuthor()`` is not called. The author is modified by reference. If you set ``by_reference`` to false, submitting looks like this:: @@ -42,4 +42,4 @@ call the setter on the parent object. Similarly, if you're using the :doc:`collection` form type where your underlying collection data is an object (like with Doctrine's ``ArrayCollection``), then ``by_reference`` must be set to ``false`` if you -need the setter (e.g. ``setAuthors``) to be called. +need the setter (e.g. ``setAuthors()``) to be called. diff --git a/reference/forms/types/options/empty_data.rst.inc b/reference/forms/types/options/empty_data.rst.inc index d62ddabc470..1e150b4b503 100644 --- a/reference/forms/types/options/empty_data.rst.inc +++ b/reference/forms/types/options/empty_data.rst.inc @@ -1,20 +1,23 @@ empty_data ~~~~~~~~~~ -**type**: ``mixed`` **default**: ``array()`` if ``multiple`` or ``expanded``, ``''`` otherwise +**type**: ``mixed`` **default**: depends on other field options, see below -This option determines what value the field will return when the ``empty_value`` -choice is selected. +This option determines what value the field will return when the submitted +value is empty. This may happen when the ``empty_value`` choice in a +``choice`` field is selected or when an ``input`` field of some type is not +required and left empty by the user. -The true default value of this option depends on the field options: +The true default value of this option depends on other field options: -* If ``data_class`` is set and ``required`` is ``true``, then ``new $data_class()``; -* If ``data_class`` is set and ``required`` is ``false``, then ``null``; -* If ``data_class`` is not set and ``compound`` is ``true``, then ``array()``; -* If ``data_class`` is not set and ``compound`` is ``false``, then ``null``. +* If ``data_class`` is set and ``required`` is ``true``, then ``new $data_class()``; +* If ``data_class`` is set and ``required`` is ``false``, then ``null``; +* If ``data_class`` is not set and ``compound`` is ``true``, then ``array()``; +* If ``data_class`` is not set and ``compound`` is ``false``, then ``''`` (empty string). -But you can customize this to your needs. For example, if you want the ``gender`` field to be -explicitly set to ``null`` when no value is selected, you can do it like this: +But you can customize this to your needs. For example, if you want the +``gender`` choice field to be explicitly set to ``null`` when no value is +selected, you can do it like this: .. code-block:: php diff --git a/reference/forms/types/options/error_mapping.rst.inc b/reference/forms/types/options/error_mapping.rst.inc index d570147a931..7b3c1359871 100644 --- a/reference/forms/types/options/error_mapping.rst.inc +++ b/reference/forms/types/options/error_mapping.rst.inc @@ -24,14 +24,14 @@ field so that it displays above it:: Here are the rules for the left and the right side of the mapping: -* The left side contains property paths. +* The left side contains property paths; * If the violation is generated on a property or method of a class, its path - is simply "propertyName". + is simply ``propertyName``; * If the violation is generated on an entry of an ``array`` or ``ArrayAccess`` - object, the property path is ``[indexName]``. + object, the property path is ``[indexName]``; * You can construct nested property paths by concatenating them, separating - properties by dots. For example: ``addresses[work].matchingCityAndZipCode`` + properties by dots. For example: ``addresses[work].matchingCityAndZipCode``; * The left side of the error mapping also accepts a dot ``.``, which refers to the field itself. That means that any error added to the field is added - to the given nested field instead. + to the given nested field instead; * The right side contains simply the names of fields in the form. diff --git a/reference/forms/types/options/value.rst.inc b/reference/forms/types/options/value.rst.inc new file mode 100644 index 00000000000..6c94904764f --- /dev/null +++ b/reference/forms/types/options/value.rst.inc @@ -0,0 +1,12 @@ +value +~~~~~ + +**type**: ``mixed`` **default**: ``1`` + +The value that's actually used as the value for the checkbox or radio button. +This does not affect the value that's set on your object. + +.. caution:: + + To make a checkbox or radio button checked by default, use the `data`_ + option. diff --git a/reference/forms/types/radio.rst b/reference/forms/types/radio.rst index 6d29555f3fa..0cf937db3bb 100644 --- a/reference/forms/types/radio.rst +++ b/reference/forms/types/radio.rst @@ -15,10 +15,9 @@ If you want to have a Boolean field, use :doc:`checkbox ` | +| Parent type | :doc:`checkbox ` | +-------------+---------------------------------------------------------------------+ | Class | :class:`Symfony\\Component\\Form\\Extension\\Core\\Type\\RadioType` | +-------------+---------------------------------------------------------------------+ -Field Options -------------- - -value -~~~~~ - -**type**: ``mixed`` **default**: ``1`` - -The value that's actually used as the value for the radio button. This does -not affect the value that's set on your object. - -.. caution:: - - To make a radio button checked by default, use the `data`_ option. - Inherited Options ----------------- +These options inherit from the :doc:`checkbox ` +type: + +.. include:: /reference/forms/types/options/value.rst.inc + These options inherit from the :doc:`form ` type: .. include:: /reference/forms/types/options/data.rst.inc