diff --git a/book/security.rst b/book/security.rst index dc788c6536b..327ee93c7da 100644 --- a/book/security.rst +++ b/book/security.rst @@ -67,7 +67,7 @@ configuration looks like this: + security="false" /> @@ -81,7 +81,7 @@ configuration looks like this: $container->loadFromExtension('security', array( 'providers' => array( 'in_memory' => array( - 'memory' => array(), + 'memory' => null, ), ), 'firewalls' => array( @@ -214,6 +214,8 @@ user to be logged in to access this URL: # ... firewalls: # ... + default: + # ... access_control: # require ROLE_ADMIN for /admin* @@ -236,10 +238,8 @@ user to be logged in to access this URL: - - - - + + @@ -546,13 +546,14 @@ like this: http://symfony.com/schema/dic/services/services-1.0.xsd"> + + - @@ -560,6 +561,8 @@ like this: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'providers' => array( 'in_memory' => array( 'memory' => array( @@ -699,8 +702,11 @@ URL pattern. You saw this earlier, where anything matching the regular expressio # app/config/security.yml security: # ... + firewalls: # ... + default: + # ... access_control: # require ROLE_ADMIN for /admin* @@ -723,10 +729,8 @@ URL pattern. You saw this earlier, where anything matching the regular expressio - - - - + + @@ -735,6 +739,7 @@ URL pattern. You saw this earlier, where anything matching the regular expressio // app/config/security.php $container->loadFromExtension('security', array( // ... + 'firewalls' => array( // ... 'default' => array( @@ -763,6 +768,7 @@ matches the URL. # app/config/security.yml security: # ... + access_control: - { path: ^/admin/users, roles: ROLE_SUPER_ADMIN } - { path: ^/admin, roles: ROLE_ADMIN } @@ -779,10 +785,9 @@ matches the URL. - - - - + + + @@ -791,6 +796,7 @@ matches the URL. // app/config/security.php $container->loadFromExtension('security', array( // ... + 'access_control' => array( array('path' => '^/admin/users', 'role' => 'ROLE_SUPER_ADMIN'), array('path' => '^/admin', 'role' => 'ROLE_ADMIN'), @@ -1106,13 +1112,14 @@ the firewall can handle this automatically for you when you activate the # app/config/security.yml security: + # ... + firewalls: secured_area: # ... logout: path: /logout target: / - # ... .. code-block:: xml @@ -1125,11 +1132,12 @@ the firewall can handle this automatically for you when you activate the http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + + - @@ -1137,13 +1145,14 @@ the firewall can handle this automatically for you when you activate the // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'secured_area' => array( // ... - 'logout' => array('path' => 'logout', 'target' => '/'), + 'logout' => array('path' => '/logout', 'target' => '/'), ), ), - // ... )); Next, you'll need to create a route for this URL (but not a controller): @@ -1154,7 +1163,7 @@ Next, you'll need to create a route for this URL (but not a controller): # app/config/routing.yml logout: - path: /logout + path: /logout .. code-block:: xml @@ -1175,7 +1184,7 @@ Next, you'll need to create a route for this URL (but not a controller): use Symfony\Component\Routing\Route; $collection = new RouteCollection(); - $collection->add('logout', new Route('/logout', array())); + $collection->add('logout', new Route('/logout')); return $collection; @@ -1243,6 +1252,8 @@ rules by creating a role hierarchy: # app/config/security.yml security: + # ... + role_hierarchy: ROLE_ADMIN: ROLE_USER ROLE_SUPER_ADMIN: [ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH] @@ -1258,6 +1269,8 @@ rules by creating a role hierarchy: http://symfony.com/schema/dic/services/services-1.0.xsd"> + + ROLE_USER ROLE_ADMIN, ROLE_ALLOWED_TO_SWITCH @@ -1267,6 +1280,8 @@ rules by creating a role hierarchy: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'role_hierarchy' => array( 'ROLE_ADMIN' => 'ROLE_USER', 'ROLE_SUPER_ADMIN' => array( @@ -1296,6 +1311,8 @@ cookie will be ever created by Symfony): # app/config/security.yml security: + # ... + firewalls: main: http_basic: ~ @@ -1312,7 +1329,9 @@ cookie will be ever created by Symfony): http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + + @@ -1322,8 +1341,10 @@ cookie will be ever created by Symfony): // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( - 'main' => array('http_basic' => array(), 'stateless' => true), + 'main' => array('http_basic' => null, 'stateless' => true), ), )); diff --git a/components/console/introduction.rst b/components/console/introduction.rst index 4a55cc29dbe..d4566925b10 100644 --- a/components/console/introduction.rst +++ b/components/console/introduction.rst @@ -504,8 +504,8 @@ Calling a command from another one is straightforward:: '--yell' => true, ); - $input = new ArrayInput($arguments); - $returnCode = $command->run($input, $output); + $greetInput = new ArrayInput($arguments); + $returnCode = $command->run($greetInput, $output); // ... } diff --git a/components/expression_language/caching.rst b/components/expression_language/caching.rst index 4961d76bd6c..9c60ecc67bf 100644 --- a/components/expression_language/caching.rst +++ b/components/expression_language/caching.rst @@ -65,7 +65,7 @@ Both ``evaluate()`` and ``compile()`` can handle ``ParsedExpression`` and $expression = new SerializedParsedExpression( '1 + 4', - serialize($language->parse('1 + 4', array())) + serialize($language->parse('1 + 4', array())->getNodes()) ); var_dump($language->evaluate($expression)); // prints 5 diff --git a/cookbook/configuration/index.rst b/cookbook/configuration/index.rst index 35b87ef0f2e..8bac5cf43be 100644 --- a/cookbook/configuration/index.rst +++ b/cookbook/configuration/index.rst @@ -13,3 +13,4 @@ Configuration apache_router web_server_configuration configuration_organization + mongodb_session_storage \ No newline at end of file diff --git a/cookbook/configuration/mongodb_session_storage.rst b/cookbook/configuration/mongodb_session_storage.rst new file mode 100644 index 00000000000..c2f912e8b9e --- /dev/null +++ b/cookbook/configuration/mongodb_session_storage.rst @@ -0,0 +1,171 @@ +How to Use MongoDbSessionHandler to Store Sessions in a MongoDB Database +======================================================================== + +The default Symfony session storage writes the session information to files. +Some medium to large websites use a NoSQL database called MongoDB to store the +session values instead of files, because databases are easier to use and scale +in a multi-webserver environment. + +Symfony has a built-in solution for NoSQL database session storage called +:class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\MongoDbSessionHandler`. +MongoDB is an open-source document database that provides high performance, +high availability and automatic scaling. This article assumes that you have +already `installed and configured a MongoDB server`_. To use it, you just +need to change/add some parameters in the main configuration file: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/config.yml + framework: + session: + # ... + handler_id: session.handler.mongo + cookie_lifetime: 2592000 # optional, it is set to 30 days here + gc_maxlifetime: 2592000 # optional, it is set to 30 days here + + services: + # ... + mongo_client: + class: MongoClient + # if using a username and password + arguments: [mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017] + # if not using a username and password + arguments: [mongodb://%mongodb_host%:27017] + session.handler.mongo: + class: Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler + arguments: [@mongo_client, %mongo.session.options%] + + .. code-block:: xml + + + + + + + + + + + + + + + mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017 + + + mongodb://%mongodb_host%:27017 + + + + mongo_client + %mongo.session.options% + + + + .. code-block:: php + + use Symfony\Component\DependencyInjection\Reference; + use Symfony\Component\DependencyInjection\Definition; + + $container->loadFromExtension('framework', array( + 'session' => array( + // ... + 'handler_id' => 'session.handler.mongo', + 'cookie_lifetime' => 2592000, // optional, it is set to 30 days here + 'gc_maxlifetime' => 2592000, // optional, it is set to 30 days here + ), + )); + + $container->setDefinition('mongo_client', new Definition('MongoClient', array( + // if using a username and password + array('mongodb://%mongodb_username%:%mongodb_password%@%mongodb_host%:27017'), + // if not using a username and password + array('mongodb://%mongodb_host%:27017'), + ))); + + $container->setDefinition('session.handler.mongo', new Definition( + 'Symfony\Component\HttpFoundation\Session\Storage\Handler\MongoDbSessionHandler', + array(new Reference('mongo_client'), '%mongo.session.options%') + )); + +The parameters used above should be defined somewhere in your application, often in your main +parameters configuration: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/parameters.yml + parameters: + # ... + mongo.session.options: + database: session_db # your MongoDB database name + collection: session # your MongoDB collection name + mongodb_host: 1.2.3.4 # your MongoDB server's IP + mongodb_username: my_username + mongodb_password: my_password + + .. code-block:: xml + + + + + + + + session_db + + session + + + 1.2.3.4 + my_username + my_password + + + + .. code-block:: php + + use Symfony\Component\DependencyInjection\Reference; + use Symfony\Component\DependencyInjection\Definition; + + $container->setParameter('mongo.session.options', array( + 'database' => 'session_db', // your MongoDB database name + 'collection' => 'session', // your MongoDB collection name + )); + $container->setParameter('mongodb_host', '1.2.3.4'); // your MongoDB server's IP + $container->setParameter('mongodb_username', 'my_username'); + $container->setParameter('mongodb_password', 'my_password'); + +Setting Up the MongoDB Collection +--------------------------------- + +Because MongoDB uses dynamic collection schemas, you do not need to do anything to initialize your +session collection. However, you may want to add an index to improve garbage collection performance. +From the `MongoDB shell`_: + +.. code-block:: sql + + use session_db + db.session.ensureIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } ) + +.. _installed and configured a MongoDB server: http://docs.mongodb.org/manual/installation/ +.. _MongoDB shell: http://docs.mongodb.org/v2.2/tutorial/getting-started-with-the-mongo-shell/ \ No newline at end of file diff --git a/cookbook/configuration/pdo_session_storage.rst b/cookbook/configuration/pdo_session_storage.rst index 6d62b4b878e..90789b119e8 100644 --- a/cookbook/configuration/pdo_session_storage.rst +++ b/cookbook/configuration/pdo_session_storage.rst @@ -13,7 +13,7 @@ How to Use PdoSessionHandler to Store Sessions in the Database The default Symfony session storage writes the session information to files. Most medium to large websites use a database to store the session values instead of files, because databases are easier to use and scale in a -multi webserver environment. +multiple web server environment. Symfony has a built-in solution for database session storage called :class:`Symfony\\Component\\HttpFoundation\\Session\\Storage\\Handler\\PdoSessionHandler`. @@ -184,8 +184,14 @@ of your project's data, you can use the connection settings from the array('db_username' => '%database_user%', 'db_password' => '%database_password%') )); -Example SQL Statements ----------------------- +.. _example-sql-statements: + +Preparing the Database to Store Sessions +---------------------------------------- + +Before storing sessions in the database, you must create the table that stores +the information. The following sections contain some examples of the SQL statements +you may use for your specific database engine. .. _pdo-session-handle-26-changes: @@ -208,9 +214,6 @@ Example SQL Statements MySQL ~~~~~ -The SQL statement for creating the needed database table might look like the -following (MySQL): - .. code-block:: sql CREATE TABLE `sessions` ( @@ -230,8 +233,6 @@ following (MySQL): PostgreSQL ~~~~~~~~~~ -For PostgreSQL, the statement should look like this: - .. code-block:: sql CREATE TABLE sessions ( @@ -244,8 +245,6 @@ For PostgreSQL, the statement should look like this: Microsoft SQL Server ~~~~~~~~~~~~~~~~~~~~ -For MSSQL, the statement might look like the following: - .. code-block:: sql CREATE TABLE [dbo].[sessions]( @@ -263,3 +262,16 @@ For MSSQL, the statement might look like the following: ALLOW_PAGE_LOCKS = ON ) ON [PRIMARY] ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY] + +.. caution:: + + If the session data doesn't fit in the data column, it might get truncated + by the database engine. To make matters worse, when the session data gets + corrupted, PHP ignores the data without giving a warning. + + If the application stores large amounts of session data, this problem can + be solved by increasing the column size (use ``BLOB`` or even ``MEDIUMBLOB``). + When using MySQL as the database engine, you can also enable the `strict SQL mode`_ + to get noticed when such an error happens. + +.. _`strict SQL mode`: https://dev.mysql.com/doc/refman/5.7/en/sql-mode.html diff --git a/cookbook/deployment/tools.rst b/cookbook/deployment/tools.rst index 322154ba9f2..c53ed2fa6a5 100644 --- a/cookbook/deployment/tools.rst +++ b/cookbook/deployment/tools.rst @@ -66,9 +66,10 @@ Using Build Scripts and other Tools There are also tools to help ease the pain of deployment. Some of them have been specifically tailored to the requirements of Symfony. -`Capifony`_ - This Ruby-based tool provides a specialized set of tools on top of - `Capistrano`_, tailored specifically to Symfony projects. +`Capistrano`_ with `Symfony plugin`_ + `Capistrano`_ is a remote server automation and deployment tool written in Ruby. + `Symfony plugin`_ is a plugin to ease Symfony related tasks, inspired by `Capifony`_ + (which works only with Capistrano 2 ) `sf2debpkg`_ Helps you build a native Debian package for your Symfony project. @@ -198,3 +199,5 @@ other potential things like pushing assets to a CDN (see `Common Post-Deployment .. _`bundles that add deployment features`: http://knpbundles.com/search?q=deploy .. _`Memcached`: http://memcached.org/ .. _`Redis`: http://redis.io/ +.. _`Symfony plugin`: https://github.com/capistrano/symfony/ + diff --git a/cookbook/map.rst.inc b/cookbook/map.rst.inc index 8f5803c797e..aff2feb33d0 100644 --- a/cookbook/map.rst.inc +++ b/cookbook/map.rst.inc @@ -38,6 +38,7 @@ * :doc:`/cookbook/configuration/apache_router` * :doc:`/cookbook/configuration/web_server_configuration` * :doc:`/cookbook/configuration/configuration_organization` + * :doc:`/cookbook/configuration/mongodb_session_storage` * :doc:`/cookbook/console/index` @@ -201,6 +202,7 @@ * :doc:`/cookbook/session/php_bridge` * :doc:`/cookbook/session/limit_metadata_writes` * (configuration) :doc:`/cookbook/configuration/pdo_session_storage` + * (configuration) :doc:`/cookbook/configuration/mongodb_session_storage` * :doc:`/cookbook/session/avoid_session_start` * **PSR-7** diff --git a/cookbook/security/access_control.rst b/cookbook/security/access_control.rst index 2849d03125c..00b73837be6 100644 --- a/cookbook/security/access_control.rst +++ b/cookbook/security/access_control.rst @@ -54,12 +54,10 @@ Take the following ``access_control`` entries as an example: - - - - - - + + + + @@ -82,7 +80,7 @@ Take the following ``access_control`` entries as an example: array( 'path' => '^/admin', 'role' => 'ROLE_USER_METHOD', - 'method' => 'POST, PUT', + 'methods' => 'POST, PUT', ), array( 'path' => '^/admin', @@ -195,11 +193,12 @@ pattern so that it is only accessible by requests from the local server itself: - - - - + + + @@ -210,12 +209,12 @@ pattern so that it is only accessible by requests from the local server itself: // ... 'access_control' => array( array( - 'path' => '^/esi', + 'path' => '^/internal', 'role' => 'IS_AUTHENTICATED_ANONYMOUSLY', 'ips' => '127.0.0.1, ::1' ), array( - 'path' => '^/esi', + 'path' => '^/internal', 'role' => 'ROLE_NO_ACCESS' ), ), @@ -321,11 +320,10 @@ the user will be redirected to ``https``: xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - + .. code-block:: php diff --git a/cookbook/security/acl.rst b/cookbook/security/acl.rst index 5f1618e658e..5d3d5553a3b 100644 --- a/cookbook/security/acl.rst +++ b/cookbook/security/acl.rst @@ -52,20 +52,34 @@ First, you need to configure the connection the ACL system is supposed to use: # app/config/security.yml security: + # ... + acl: connection: default .. code-block:: xml - - default - + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', 'acl', array( + // ... + 'connection' => 'default', )); diff --git a/cookbook/security/csrf_in_login_form.rst b/cookbook/security/csrf_in_login_form.rst index 0e14196db02..ef45d4f237c 100644 --- a/cookbook/security/csrf_in_login_form.rst +++ b/cookbook/security/csrf_in_login_form.rst @@ -26,6 +26,8 @@ provider available in the Security component: # app/config/security.yml security: + # ... + firewalls: secured_area: # ... @@ -35,17 +37,19 @@ provider available in the Security component: .. code-block:: xml - + + xsi:schemaLocation="http://symfony.com/schema/dic/services + http://symfony.com/schema/dic/services/services-1.0.xsd"> + + - @@ -55,15 +59,17 @@ provider available in the Security component: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'secured_area' => array( // ... 'form_login' => array( // ... 'csrf_provider' => 'security.csrf.token_manager', - ) - ) - ) + ), + ), + ), )); The Security component can be configured further, but this is all information @@ -124,6 +130,8 @@ After this, you have protected your login form against CSRF attacks. # app/config/security.yml security: + # ... + firewalls: secured_area: # ... @@ -134,19 +142,22 @@ After this, you have protected your login form against CSRF attacks. .. code-block:: xml - + + xsi:schemaLocation="http://symfony.com/schema/dic/services + http://symfony.com/schema/dic/services/services-1.0.xsd"> + + - + intention="a_private_string" + /> @@ -155,6 +166,8 @@ After this, you have protected your login form against CSRF attacks. // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'secured_area' => array( // ... @@ -162,9 +175,9 @@ After this, you have protected your login form against CSRF attacks. // ... 'csrf_parameter' => '_csrf_security_token', 'intention' => 'a_private_string', - ) - ) - ) + ), + ), + ), )); .. _`Cross-site request forgery`: http://en.wikipedia.org/wiki/Cross-site_request_forgery diff --git a/cookbook/security/custom_authentication_provider.rst b/cookbook/security/custom_authentication_provider.rst index 7be577ec97d..1db7c384a77 100644 --- a/cookbook/security/custom_authentication_provider.rst +++ b/cookbook/security/custom_authentication_provider.rst @@ -403,32 +403,41 @@ to service ids that do not exist yet: ``wsse.security.authentication.provider`` .. code-block:: yaml - # src/AppBundle/Resources/config/services.yml + # app/config/services.yml services: wsse.security.authentication.provider: class: AppBundle\Security\Authentication\Provider\WsseProvider - arguments: ["", "%kernel.cache_dir%/security/nonces"] + arguments: + - "" # User Provider + - "%kernel.cache_dir%/security/nonces" + public: false wsse.security.authentication.listener: class: AppBundle\Security\Firewall\WsseListener arguments: ["@security.token_storage", "@security.authentication.manager"] + public: false .. code-block:: xml - + + + class="AppBundle\Security\Authentication\Provider\WsseProvider" + public="false" + > %kernel.cache_dir%/security/nonces + class="AppBundle\Security\Firewall\WsseListener" + public="false" + > @@ -437,27 +446,29 @@ to service ids that do not exist yet: ``wsse.security.authentication.provider`` .. code-block:: php - // src/AppBundle/Resources/config/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; - $container->setDefinition('wsse.security.authentication.provider', - new Definition( - 'AppBundle\Security\Authentication\Provider\WsseProvider', array( - '', - '%kernel.cache_dir%/security/nonces', - ) + $definition = new Definition( + 'AppBundle\Security\Authentication\Provider\WsseProvider', + array( + '', // User Provider + '%kernel.cache_dir%/security/nonces', ) ); - - $container->setDefinition('wsse.security.authentication.listener', - new Definition( - 'AppBundle\Security\Firewall\WsseListener', array( - new Reference('security.token_storage'), - new Reference('security.authentication.manager'), - ) + $definition->setPublic(false); + $container->setDefinition('wsse.security.authentication.provider', $definition) + + $definition = new Definition( + 'AppBundle\Security\Firewall\WsseListener', + array( + new Reference('security.token_storage'), + new Reference('security.authentication.manager'), ) ); + $definition->setPublic(false); + $container->setDefinition('wsse.security.authentication.listener', $definition); Now that your services are defined, tell your security context about your factory in your bundle class: @@ -488,30 +499,49 @@ You are finished! You can now define parts of your app as under WSSE protection. .. code-block:: yaml + # app/config/security.yml security: + # ... + firewalls: wsse_secured: - pattern: /api/.* + pattern: ^/api/ stateless: true wsse: true .. code-block:: xml - - - - - - + + + + + + + + + + .. code-block:: php + // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'wsse_secured' => array( - 'pattern' => '/api/.*', - 'stateless' => true, - 'wsse' => true, + 'pattern' => '^/api/', + 'stateless' => true, + 'wsse' => true, ), ), )); @@ -591,32 +621,46 @@ set to any desirable value per firewall. .. code-block:: yaml + # app/config/security.yml security: + # ... + firewalls: wsse_secured: - pattern: /api/.* + pattern: ^/api/ stateless: true wsse: { lifetime: 30 } .. code-block:: xml - - - - - - + + + + + + + + + + + + .. code-block:: php + // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'wsse_secured' => array( - 'pattern' => '/api/.*', + 'pattern' => '^/api/', 'stateless' => true, - 'wsse' => array( + 'wsse' => array( 'lifetime' => 30, ), ), diff --git a/cookbook/security/custom_provider.rst b/cookbook/security/custom_provider.rst index 5ba3ac7c986..60a53517bbe 100644 --- a/cookbook/security/custom_provider.rst +++ b/cookbook/security/custom_provider.rst @@ -175,21 +175,30 @@ Now you make the user provider available as a service: .. code-block:: yaml - # src/Acme/WebserviceUserBundle/Resources/config/services.yml + # app/config/services.yml services: webservice_user_provider: class: Acme\WebserviceUserBundle\Security\User\WebserviceUserProvider .. code-block:: xml - - - - + + + + + + + + .. code-block:: php - // src/Acme/WebserviceUserBundle/Resources/config/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; $container->setDefinition( @@ -221,6 +230,8 @@ to the list of providers in the "security" section. Choose a name for the user p # app/config/security.yml security: + # ... + providers: webservice: id: webservice_user_provider @@ -228,14 +239,26 @@ to the list of providers in the "security" section. Choose a name for the user p .. code-block:: xml - - - + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'providers' => array( 'webservice' => array( 'id' => 'webservice_user_provider', @@ -253,20 +276,36 @@ users, e.g. by filling in a login form. You can do this by adding a line to the # app/config/security.yml security: + # ... + encoders: Acme\WebserviceUserBundle\Security\User\WebserviceUser: sha512 .. code-block:: xml - - sha512 - + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'encoders' => array( 'Acme\WebserviceUserBundle\Security\User\WebserviceUser' => 'sha512', ), @@ -305,6 +344,8 @@ options, the password may be encoded multiple times and encoded to base64. # app/config/security.yml security: + # ... + encoders: Acme\WebserviceUserBundle\Security\User\WebserviceUser: algorithm: sha512 @@ -314,18 +355,30 @@ options, the password may be encoded multiple times and encoded to base64. .. code-block:: xml - - - + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'encoders' => array( 'Acme\WebserviceUserBundle\Security\User\WebserviceUser' => array( 'algorithm' => 'sha512', diff --git a/cookbook/security/entity_provider.rst b/cookbook/security/entity_provider.rst index d52d9d4b529..58acf646245 100644 --- a/cookbook/security/entity_provider.rst +++ b/cookbook/security/entity_provider.rst @@ -226,23 +226,31 @@ the username and then check the password (more on passwords in a moment): .. code-block:: xml - - + + - + + - - - + - - - + + + + - - + + + + + + + .. code-block:: php @@ -253,7 +261,9 @@ the username and then check the password (more on passwords in a moment): 'algorithm' => 'bcrypt', ), ), + // ... + 'providers' => array( 'our_db_provider' => array( 'entity' => array( @@ -264,11 +274,12 @@ the username and then check the password (more on passwords in a moment): ), 'firewalls' => array( 'default' => array( - 'pattern' => '^/', + 'pattern' => '^/', 'http_basic' => null, - 'provider' => 'our_db_provider', + 'provider' => 'our_db_provider', ), ), + // ... )); @@ -487,30 +498,37 @@ To finish this, just remove the ``property`` key from the user provider in # app/config/security.yml security: # ... + providers: our_db_provider: entity: class: AppBundle:User - # ... .. code-block:: xml - - - - - - - - - + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( - ..., + // ... + 'providers' => array( 'our_db_provider' => array( 'entity' => array( @@ -518,7 +536,6 @@ To finish this, just remove the ``property`` key from the user provider in ), ), ), - ..., )); This tells Symfony to *not* query automatically for the User. Instead, when diff --git a/cookbook/security/force_https.rst b/cookbook/security/force_https.rst index 63bb7b2e2b2..eba38055b34 100644 --- a/cookbook/security/force_https.rst +++ b/cookbook/security/force_https.rst @@ -13,24 +13,44 @@ to use HTTPS then you could use the following configuration: .. code-block:: yaml - access_control: - - { path: ^/secure, roles: ROLE_ADMIN, requires_channel: https } + # app/config/security.yml + security: + # ... + + access_control: + - { path: ^/secure, roles: ROLE_ADMIN, requires_channel: https } .. code-block:: xml - - - + + + + + + + + + + .. code-block:: php - 'access_control' => array( - array( - 'path' => '^/secure', - 'role' => 'ROLE_ADMIN', - 'requires_channel' => 'https', + // app/config/security.php + $container->loadFromExtension('security', array( + // ... + + 'access_control' => array( + array( + 'path' => '^/secure', + 'role' => 'ROLE_ADMIN', + 'requires_channel' => 'https', + ), ), - ), + )); The login form itself needs to allow anonymous access, otherwise users will be unable to authenticate. To force it to use HTTPS you can still use @@ -39,20 +59,40 @@ role: .. configuration-block:: - .. code-block:: yaml + .. code-block:: yaml + + # app/config/security.yml + security: + # ... access_control: - { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY, requires_channel: https } - .. code-block:: xml + .. code-block:: xml + + + + + + + - - + role="IS_AUTHENTICATED_ANONYMOUSLY" + requires_channel="https" + /> + + - .. code-block:: php + .. code-block:: php + + // app/config/security.php + $container->loadFromExtension('security', array( + // ... 'access_control' => array( array( @@ -61,6 +101,7 @@ role: 'requires_channel' => 'https', ), ), + )); It is also possible to specify using HTTPS in the routing configuration, see :doc:`/cookbook/routing/scheme` for more details. diff --git a/cookbook/security/form_login.rst b/cookbook/security/form_login.rst index 337d02a2fdf..e05e6067e58 100644 --- a/cookbook/security/form_login.rst +++ b/cookbook/security/form_login.rst @@ -52,6 +52,8 @@ if no previous page was stored in the session). To set it to the # app/config/security.yml security: + # ... + firewalls: main: form_login: @@ -61,18 +63,28 @@ if no previous page was stored in the session). To set it to the .. code-block:: xml - - - - - + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main' => array( // ... @@ -101,6 +113,8 @@ of what URL they had requested previously by setting the # app/config/security.yml security: + # ... + firewalls: main: form_login: @@ -110,18 +124,29 @@ of what URL they had requested previously by setting the .. code-block:: xml - - - - - + + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main' => array( // ... @@ -147,31 +172,44 @@ this by setting ``use_referer`` to true (it defaults to false): # app/config/security.yml security: + # ... + firewalls: main: + # ... form_login: # ... - use_referer: true + use_referer: true .. code-block:: xml - - - - - + + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main' => array( // ... - 'form_login' => array( // ... 'use_referer' => true, @@ -238,30 +276,45 @@ option to another value. # app/config/security.yml security: + # ... + firewalls: main: + # ... form_login: target_path_parameter: redirect_url .. code-block:: xml - - - - - + + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main' => array( + // ... 'form_login' => array( - 'target_path_parameter' => redirect_url, + 'target_path_parameter' => 'redirect_url', ), ), ), @@ -282,8 +335,11 @@ back to the login form itself. You can set this to a different route (e.g. # app/config/security.yml security: + # ... + firewalls: main: + # ... form_login: # ... failure_path: login_failure @@ -291,22 +347,32 @@ back to the login form itself. You can set this to a different route (e.g. .. code-block:: xml - - - - - + + + + + + + + + + + + .. code-block:: php // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main' => array( // ... - 'form_login' => array( // ... 'failure_path' => 'login_failure', diff --git a/cookbook/security/form_login_setup.rst b/cookbook/security/form_login_setup.rst index 228e09b9457..1cefa8b7b0f 100644 --- a/cookbook/security/form_login_setup.rst +++ b/cookbook/security/form_login_setup.rst @@ -45,8 +45,9 @@ First, enable form login under your firewall: http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + @@ -57,8 +58,9 @@ First, enable form login under your firewall: // app/config/security.php $container->loadFromExtension('security', array( 'firewalls' => array( - 'main' => array( - 'anonymous' => array(), + 'default' => array( + 'anonymous' => null, + 'http_basic' => null, 'form_login' => array( 'login_path' => '/login', 'check_path' => '/login_check', @@ -160,7 +162,7 @@ under your ``form_login`` configuration (``/login`` and ``/login_check``): '_controller' => 'AppBundle:Security:login', ))); - $collection->add('login_check', new Route('/login_check', array())); + $collection->add('login_check', new Route('/login_check')); // no controller is bound to this route // as it's handled by the Security system @@ -350,11 +352,18 @@ all URLs (including the ``/login`` URL), will cause a redirect loop: .. code-block:: xml + + - - - - + + + + + .. code-block:: php @@ -382,12 +391,19 @@ fixes the problem: .. code-block:: xml + + - - - - - + + + + + + .. code-block:: php @@ -422,14 +438,24 @@ for the login page: .. code-block:: xml + + - - - - - - - + + + + + + + + + + + .. code-block:: php @@ -439,11 +465,11 @@ for the login page: 'firewalls' => array( 'login_firewall' => array( 'pattern' => '^/login$', - 'anonymous' => array(), + 'anonymous' => null, ), 'secured_area' => array( 'pattern' => '^/', - 'form_login' => array(), + 'form_login' => null, ), ), diff --git a/cookbook/security/impersonating_user.rst b/cookbook/security/impersonating_user.rst index 505d19d408e..b104bd6b449 100644 --- a/cookbook/security/impersonating_user.rst +++ b/cookbook/security/impersonating_user.rst @@ -15,6 +15,8 @@ done by activating the ``switch_user`` firewall listener: # app/config/security.yml security: + # ... + firewalls: main: # ... @@ -29,8 +31,11 @@ done by activating the ``switch_user`` firewall listener: xmlns:srv="http://symfony.com/schema/dic/services" xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> + - + + + @@ -41,10 +46,12 @@ done by activating the ``switch_user`` firewall listener: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main'=> array( // ... - 'switch_user' => true + 'switch_user' => true, ), ), )); @@ -116,6 +123,8 @@ setting: # app/config/security.yml security: + # ... + firewalls: main: # ... @@ -131,7 +140,9 @@ setting: xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"> - + + + @@ -142,6 +153,8 @@ setting: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'main'=> array( // ... @@ -152,7 +165,7 @@ setting: ), ), )); - + Events ------ @@ -179,9 +192,23 @@ how to change the sticky locale: .. code-block:: xml - - - + + + + + + + + .. code-block:: php @@ -201,13 +228,13 @@ how to change the sticky locale: namespace AppBundle\EventListener; use Symfony\Component\Security\Http\Event\SwitchUserEvent; - + class SwitchUserListener { public function onSwitchUser(SwitchUserEvent $event) { $event->getRequest()->getSession()->set( - '_locale', + '_locale', $event->getTargetUser()->getLocale() ); } diff --git a/cookbook/security/multiple_user_providers.rst b/cookbook/security/multiple_user_providers.rst index 4766ed92e44..14940627057 100644 --- a/cookbook/security/multiple_user_providers.rst +++ b/cookbook/security/multiple_user_providers.rst @@ -41,11 +41,13 @@ a new provider that chains the two together: user_db + + @@ -132,6 +134,7 @@ the first provider is always used: 'provider' => 'user_db', 'http_basic' => array( // ... + 'realm' => 'Secured Demo Area', 'provider' => 'in_memory', ), 'form_login' => array(), diff --git a/cookbook/security/pre_authenticated.rst b/cookbook/security/pre_authenticated.rst index 7a0775a8ab8..183fe9e91ca 100644 --- a/cookbook/security/pre_authenticated.rst +++ b/cookbook/security/pre_authenticated.rst @@ -26,6 +26,8 @@ Enable the x509 authentication for a particular firewall in the security configu # app/config/security.yml security: + # ... + firewalls: secured_area: pattern: ^/ @@ -35,13 +37,18 @@ Enable the x509 authentication for a particular firewall in the security configu .. code-block:: xml - + + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns:srv="http://symfony.com/schema/dic/services" + xsi:schemaLocation="http://symfony.com/schema/dic/services + http://symfony.com/schema/dic/services/services-1.0.xsd"> + + - + @@ -50,9 +57,11 @@ Enable the x509 authentication for a particular firewall in the security configu // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'secured_area' => array( - 'pattern' => '^/' + 'pattern' => '^/', 'x509' => array( 'provider' => 'your_user_provider', ), diff --git a/cookbook/security/remember_me.rst b/cookbook/security/remember_me.rst index 4c0d40f5554..a3acf6f5472 100644 --- a/cookbook/security/remember_me.rst +++ b/cookbook/security/remember_me.rst @@ -15,17 +15,20 @@ the session lasts using a cookie with the ``remember_me`` firewall option: .. code-block:: yaml # app/config/security.yml - firewalls: - default: - # ... - remember_me: - key: "%secret%" - lifetime: 604800 # 1 week in seconds - path: / - # by default, the feature is enabled by checking a - # checkbox in the login form (see below), uncomment the - # below lines to always enable it. - #always_remember_me: true + security: + # ... + + firewalls: + default: + # ... + remember_me: + key: "%secret%" + lifetime: 604800 # 1 week in seconds + path: / + # by default, the feature is enabled by checking a + # checkbox in the login form (see below), uncomment the + # following line to always enable it. + #always_remember_me: true .. code-block:: xml @@ -38,17 +41,19 @@ the session lasts using a cookie with the ``remember_me`` firewall option: http://symfony.com/schema/dic/services/services-1.0.xsd"> + + + + - - path = "/" - /> @@ -57,6 +62,8 @@ the session lasts using a cookie with the ``remember_me`` firewall option: // app/config/security.php $container->loadFromExtension('security', array( + // ... + 'firewalls' => array( 'default' => array( // ... @@ -66,7 +73,7 @@ the session lasts using a cookie with the ``remember_me`` firewall option: 'path' => '/', // by default, the feature is enabled by checking a // checkbox in the login form (see below), uncomment - // the below lines to always enable it. + // the following line to always enable it. //'always_remember_me' => true, ), ), diff --git a/cookbook/security/securing_services.rst b/cookbook/security/securing_services.rst index 0b37720654a..e8781d63c78 100644 --- a/cookbook/security/securing_services.rst +++ b/cookbook/security/securing_services.rst @@ -80,11 +80,18 @@ Then in your service configuration, you can inject the service: .. code-block:: xml - - - - - + + + + + + + + + .. code-block:: php @@ -146,30 +153,32 @@ the :ref:`sidebar ` below): .. code-block:: yaml - # app/services.yml - - # ... + # app/config/services.yml services: newsletter_manager: - # ... + class: AppBundle\Newsletter\NewsletterManager tags: - { name: security.secure_service } .. code-block:: xml - - - - - - - - - + + + + + + + + + + .. code-block:: php - // app/services.php + // app/config/services.php use Symfony\Component\DependencyInjection\Definition; use Symfony\Component\DependencyInjection\Reference; @@ -225,28 +234,28 @@ documentation. .. code-block:: yaml - # app/config/config.yml + # app/config/services.yml jms_security_extra: # ... secure_all_services: true .. code-block:: xml - + + xsi:schemaLocation="http://symfony.com/schema/dic/services + http://symfony.com/schema/dic/services/services-1.0.xsd"> - - - + + .. code-block:: php - // app/config/config.php + // app/config/services.php $container->loadFromExtension('jms_security_extra', array( // ... 'secure_all_services' => true, diff --git a/cookbook/security/voters.rst b/cookbook/security/voters.rst index 59f40dbc48c..f02b5083733 100644 --- a/cookbook/security/voters.rst +++ b/cookbook/security/voters.rst @@ -155,25 +155,28 @@ and tag it with ``security.voter``: .. code-block:: yaml - # src/AppBundle/Resources/config/services.yml + # app/config/services.yml services: security.access.post_voter: class: AppBundle\Security\Authorization\Voter\PostVoter public: false tags: - - { name: security.voter } + - { name: security.voter } .. code-block:: xml - + + + @@ -181,16 +184,17 @@ and tag it with ``security.voter``: .. code-block:: php - // src/AppBundle/Resources/config/services.php - $container - ->register( - 'security.access.post_voter', - 'AppBundle\Security\Authorization\Voter\PostVoter' - ) + // app/config/services.php + use Symfony\Component\DependencyInjection\Definition; + + $definition = new Definition('AppBundle\Security\Authorization\Voter\PostVoter'); + $definition ->setPublic(false) ->addTag('security.voter') ; + $container->setDefinition('security.access.post_voter', $definition); + How to Use the Voter in a Controller ------------------------------------ @@ -273,10 +277,9 @@ security configuration: xmlns:srv="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://symfony.com/schema/dic/services - http://symfony.com/schema/dic/services/services-1.0.xsd - http://symfony.com/schema/dic/security - http://symfony.com/schema/dic/security/security-1.0.xsd" + http://symfony.com/schema/dic/services/services-1.0.xsd" > + diff --git a/cookbook/session/sessions_directory.rst b/cookbook/session/sessions_directory.rst index 61922ec6fcd..5ecc133ae9f 100644 --- a/cookbook/session/sessions_directory.rst +++ b/cookbook/session/sessions_directory.rst @@ -93,8 +93,9 @@ that your current sessions aren't lost when you clear Symfony's cache. Using a different session save handler is an excellent (yet more complex) method of session management available within Symfony. See :doc:`/components/http_foundation/session_configuration` for a - discussion of session save handlers. There is also an entry in the cookbook - about storing sessions in the :doc:`database `. + discussion of session save handlers. There are also entries in the cookbook + about storing sessions in a :doc:`relational database ` + or a :doc:`NoSQL database `. To change the directory in which Symfony saves session data, you only need change the framework configuration. In this example, you will change the diff --git a/cookbook/web_server/built_in.rst b/cookbook/web_server/built_in.rst index 33289907614..e182601e4a2 100644 --- a/cookbook/web_server/built_in.rst +++ b/cookbook/web_server/built_in.rst @@ -39,6 +39,18 @@ can change the socket passing an IP address and a port as a command-line argumen $ php app/console server:run 192.168.0.1:8080 +.. note:: + + You can use the ``--force`` option to force the web server start + if the process wasn't correctly stopped (without using the ``server:stop`` command). + + .. code-block:: bash + + $ php app/console server:start --force + + .. versionadded:: 2.8 + The ``--force`` option was introduced in Symfony 2.8. + .. note:: You can use the ``server:status`` command to check if a web server is diff --git a/create_framework/event-dispatcher.rst b/create_framework/event-dispatcher.rst index fce91ac59bd..9d6b8c1ba89 100644 --- a/create_framework/event-dispatcher.rst +++ b/create_framework/event-dispatcher.rst @@ -13,7 +13,7 @@ needs. Many software have a similar concept like Drupal or Wordpress. In some languages, there is even a standard like `WSGI`_ in Python or `Rack`_ in Ruby. As there is no standard for PHP, we are going to use a well-known design -pattern, the *Observer*, to allow any kind of behaviors to be attached to our +pattern, the *Mediator*, to allow any kind of behaviors to be attached to our framework; the Symfony EventDispatcher Component implements a lightweight version of this pattern: diff --git a/create_framework/http-foundation.rst b/create_framework/http-foundation.rst index a0e0183ba58..e7d4c41646b 100644 --- a/create_framework/http-foundation.rst +++ b/create_framework/http-foundation.rst @@ -121,6 +121,19 @@ To use this component, add it as a dependency of the project: Running this command will also automatically download the Symfony HttpFoundation component and install it under the ``vendor/`` directory. +A ``composer.json`` and a ``composer.lock`` file will be generated as well, +containing the new requirement: + +.. code-block:: json + + { + "require": { + "symfony/http-foundation": "^2.7" + } + } + +The code block shows the content of the ``composer.json`` file (the actual +version may vary). .. sidebar:: Class Autoloading @@ -221,7 +234,7 @@ Last but not the least, these classes, like every other class in the Symfony code, have been `audited`_ for security issues by an independent company. And being an Open-Source project also means that many other developers around the world have read the code and have already fixed potential security problems. -When was the last you ordered a professional security audit for your home-made +When was the last time you ordered a professional security audit for your home-made framework? Even something as simple as getting the client IP address can be insecure:: diff --git a/create_framework/index.rst b/create_framework/index.rst index 10517e1565c..b6a70f5e264 100644 --- a/create_framework/index.rst +++ b/create_framework/index.rst @@ -1,5 +1,5 @@ -Create your PHP Framework -========================= +Create your own PHP Framework +============================= .. toctree:: diff --git a/create_framework/separation-of-concerns.rst b/create_framework/separation-of-concerns.rst index 5f8384f23b0..d7bb049970c 100644 --- a/create_framework/separation-of-concerns.rst +++ b/create_framework/separation-of-concerns.rst @@ -150,7 +150,8 @@ To sum up, here is the new file layout: example.com ├── composer.json - │ src + ├── composer.lock + ├── src │ ├── app.php │ └── Simplex │ └── Framework.php @@ -160,6 +161,7 @@ To sum up, here is the new file layout: │ └── Model │ └── LeapYear.php ├── vendor + │ └── autoload.php └── web └── front.php diff --git a/create_framework/unit-testing.rst b/create_framework/unit-testing.rst index de26e202570..5dcf1ca89ec 100644 --- a/create_framework/unit-testing.rst +++ b/create_framework/unit-testing.rst @@ -178,7 +178,7 @@ coverage feature (you need to enable `XDebug`_ first): $ phpunit --coverage-html=cov/ -Open ``example.com/cov/src_Simplex_Framework.php.html`` in a browser and check +Open ``example.com/cov/src/Simplex/Framework.php.html`` in a browser and check that all the lines for the Framework class are green (it means that they have been visited when the tests were executed). diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst index 88e83838ba1..1a329f7aa57 100644 --- a/reference/configuration/doctrine.rst +++ b/reference/configuration/doctrine.rst @@ -324,8 +324,8 @@ you can control. The following configuration options exist for a mapping: type .... -One of ``annotation``, ``xml``, ``yml``, ``php`` or ``staticphp``. This specifies -which type of metadata type your mapping uses. +One of ``annotation``, ``xml``, ``yml``, ``php`` or ``staticphp``. This +specifies which type of metadata type your mapping uses. dir ... @@ -339,18 +339,18 @@ that exist in the DIC (for example ``%kernel.root_dir%``). prefix ...... -A common namespace prefix that all entities of this mapping share. This prefix -should never conflict with prefixes of other defined mappings otherwise some -of your entities cannot be found by Doctrine. This option defaults to the -bundle namespace + ``Entity``, for example for an application bundle called -AcmeHelloBundle prefix would be ``Acme\HelloBundle\Entity``. +A common namespace prefix that all entities of this mapping share. This +prefix should never conflict with prefixes of other defined mappings otherwise +some of your entities cannot be found by Doctrine. This option defaults +to the bundle namespace + ``Entity``, for example for an application bundle +called AcmeHelloBundle prefix would be ``Acme\HelloBundle\Entity``. alias ..... Doctrine offers a way to alias entity namespaces to simpler, shorter names -to be used in DQL queries or for Repository access. When using a bundle the -alias defaults to the bundle name. +to be used in DQL queries or for Repository access. When using a bundle +the alias defaults to the bundle name. is_bundle ......... @@ -358,8 +358,8 @@ is_bundle This option is a derived value from ``dir`` and by default is set to ``true`` if dir is relative proved by a ``file_exists()`` check that returns ``false``. It is ``false`` if the existence check returns ``true``. In this case an -absolute path was specified and the metadata files are most likely in a directory -outside of a bundle. +absolute path was specified and the metadata files are most likely in a +directory outside of a bundle. .. index:: single: Configuration; Doctrine DBAL @@ -448,14 +448,15 @@ The following block shows all possible configuration keys: .. note:: - The ``server_version`` option was added in Doctrine DBAL 2.5, which is used - by DoctrineBundle 1.3. The value of this option should match your database - server version (use ``postgres -V`` or ``psql -V`` command to find - your PostgreSQL version and ``mysql -V`` to get your MySQL version). + The ``server_version`` option was added in Doctrine DBAL 2.5, which + is used by DoctrineBundle 1.3. The value of this option should match + your database server version (use ``postgres -V`` or ``psql -V`` command + to find your PostgreSQL version and ``mysql -V`` to get your MySQL + version). - If you don't define this option and you haven't created your database yet, - you may get ``PDOException`` errors because Doctrine will try to guess the - database server version automatically and none is available. + If you don't define this option and you haven't created your database + yet, you may get ``PDOException`` errors because Doctrine will try to + guess the database server version automatically and none is available. If you want to configure multiple connections in YAML, put them under the ``connections`` key and give them a unique name: @@ -524,24 +525,26 @@ Keep in mind that you can't use both syntaxes at the same time. Custom Mapping Entities in a Bundle ----------------------------------- -Doctrine's ``auto_mapping`` feature loads annotation configuration from the -``Entity/`` directory of each bundle *and* looks for other formats (e.g. YAML, XML) -in the ``Resources/config/doctrine`` directory. +Doctrine's ``auto_mapping`` feature loads annotation configuration from +the ``Entity/`` directory of each bundle *and* looks for other formats (e.g. +YAML, XML) in the ``Resources/config/doctrine`` directory. -If you store metadata somewhere else in your bundle, you can define your own mappings, -where you tell Doctrine exactly *where* to look, along with some other configurations. +If you store metadata somewhere else in your bundle, you can define your +own mappings, where you tell Doctrine exactly *where* to look, along with +some other configurations. -If you're using the ``auto_mapping`` configuration, you just need to overwrite the -configurations you want. In this case it's important that the key of the mapping -configurations corresponds to the name of the bundle. +If you're using the ``auto_mapping`` configuration, you just need to overwrite +the configurations you want. In this case it's important that the key of +the mapping configurations corresponds to the name of the bundle. -For example, suppose you decide to store your ``XML`` configuration for ``AppBundle`` entities -in the ``@AppBundle/SomeResources/config/doctrine`` directory instead: +For example, suppose you decide to store your ``XML`` configuration for +``AppBundle`` entities in the ``@AppBundle/SomeResources/config/doctrine`` +directory instead: .. configuration-block:: .. code-block:: yaml - + doctrine: # ... orm: @@ -552,22 +555,22 @@ in the ``@AppBundle/SomeResources/config/doctrine`` directory instead: AppBundle: type: xml dir: SomeResources/config/doctrine - + .. code-block:: xml - + - + - + .. code-block:: php - + $container->loadFromExtension('doctrine', array( 'orm' => array( 'auto_mapping' => true, @@ -582,13 +585,14 @@ Mapping Entities Outside of a Bundle You can also create new mappings, for example outside of the Symfony folder. -For example, the following looks for entity classes in the ``App\Entity`` namespace in the -``src/Entity`` directory and gives them an ``App`` alias (so you can say things like ``App:Post``): +For example, the following looks for entity classes in the ``App\Entity`` +namespace in the ``src/Entity`` directory and gives them an ``App`` alias +(so you can say things like ``App:Post``): .. configuration-block:: .. code-block:: yaml - + doctrine: # ... orm: @@ -601,16 +605,16 @@ For example, the following looks for entity classes in the ``App\Entity`` namesp is_bundle: false prefix: App\Entity alias: App - + .. code-block:: xml - + - + - - + .. code-block:: php - + $container->loadFromExtension('doctrine', array( 'orm' => array( 'auto_mapping' => true, @@ -641,31 +645,33 @@ For example, the following looks for entity classes in the ``App\Entity`` namesp Detecting a Mapping Configuration Format ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -If the ``type`` on the bundle configuration isn't set, -the DoctrineBundle will try to detect the correct mapping configuration format for -the bundle. +If the ``type`` on the bundle configuration isn't set, the DoctrineBundle +will try to detect the correct mapping configuration format for the bundle. -DoctrineBundle will look for files matching ``*.orm.[FORMAT]`` (e.g. ``Post.orm.yml``) -in the configured ``dir`` of your mapping (if you're mapping a bundle, then ``dir`` is -relative to the bundle's directory). +DoctrineBundle will look for files matching ``*.orm.[FORMAT]`` (e.g. +``Post.orm.yml``) in the configured ``dir`` of your mapping (if you're mapping +a bundle, then ``dir`` is relative to the bundle's directory). The bundle looks for (in this order) XML, YAML and PHP files. -Using the ``auto_mapping`` feature, every bundle can have only one configuration format. -The bundle will stop as soon as it locates one. +Using the ``auto_mapping`` feature, every bundle can have only one +configuration format. The bundle will stop as soon as it locates one. If it wasn't possible to determine a configuration format for a bundle, -the DoctrineBundle will check if there is an ``Entity`` folder in the bundle's root directory. -If the folder exist, Doctrine will fall back to using an annotation driver. +the DoctrineBundle will check if there is an ``Entity`` folder in the bundle's +root directory. If the folder exist, Doctrine will fall back to using an +annotation driver. -Default Value of dir +Default Value of Dir ~~~~~~~~~~~~~~~~~~~~ -If ``dir`` is not specified, then its default value depends on which configuration driver is being used. -For drivers that rely on the PHP files (annotation, staticphp) it will -be ``[Bundle]/Entity``. For drivers that are using configuration -files (XML, YAML, ...) it will be ``[Bundle]/Resources/config/doctrine``. +If ``dir`` is not specified, then its default value depends on which configuration +driver is being used. For drivers that rely on the PHP files (annotation, +staticphp) it will be ``[Bundle]/Entity``. For drivers that are using +configuration files (XML, YAML, ...) it will be +``[Bundle]/Resources/config/doctrine``. -If the ``dir`` configuration is set and the ``is_bundle`` configuration is ``true``, -the DoctrineBundle will prefix the ``dir`` configuration with the path of the bundle. +If the ``dir`` configuration is set and the ``is_bundle`` configuration +is ``true``, the DoctrineBundle will prefix the ``dir`` configuration with +the path of the bundle. .. _`DQL User Defined Functions`: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/dql-user-defined-functions.html diff --git a/reference/configuration/security.rst b/reference/configuration/security.rst index d4097719811..9010b357350 100644 --- a/reference/configuration/security.rst +++ b/reference/configuration/security.rst @@ -4,10 +4,10 @@ SecurityBundle Configuration ("security") ========================================= -The security system is one of the most powerful parts of Symfony, and can +The security system is one of the most powerful parts of Symfony and can largely be controlled via its configuration. -Full default Configuration +Full Default Configuration -------------------------- The following is the full default configuration for the security system. @@ -316,8 +316,8 @@ post_only **type**: ``boolean`` **default**: ``true`` By default, you must submit your login form to the ``check_path`` URL as -a POST request. By setting this option to ``false``, you can send a GET request -to the ``check_path`` URL. +a POST request. By setting this option to ``false``, you can send a GET +request to the ``check_path`` URL. Redirecting after Login ~~~~~~~~~~~~~~~~~~~~~~~ @@ -335,7 +335,8 @@ Using the PBKDF2 Encoder: Security and Speed The `PBKDF2`_ encoder provides a high level of Cryptographic security, as recommended by the National Institute of Standards and Technology (NIST). -You can see an example of the ``pbkdf2`` encoder in the YAML block on this page. +You can see an example of the ``pbkdf2`` encoder in the YAML block on this +page. But using PBKDF2 also warrants a warning: using it (with a high number of iterations) slows down the process. Thus, PBKDF2 should be used with @@ -393,10 +394,11 @@ Using the BCrypt Password Encoder )); The ``cost`` can be in the range of ``4-31`` and determines how long a password -will be encoded. Each increment of ``cost`` *doubles* the time it takes to -encode a password. +will be encoded. Each increment of ``cost`` *doubles* the time it takes +to encode a password. -If you don't provide the ``cost`` option, the default cost of ``13`` is used. +If you don't provide the ``cost`` option, the default cost of ``13`` is +used. .. note:: @@ -422,8 +424,8 @@ Firewall Context Most applications will only need one :ref:`firewall `. But if your application *does* use multiple firewalls, you'll notice that if you're authenticated in one firewall, you're not automatically authenticated -in another. In other words, the systems don't share a common "context": each -firewall acts like a separate security system. +in another. In other words, the systems don't share a common "context": +each firewall acts like a separate security system. However, each firewall has an optional ``context`` key (which defaults to the name of the firewall), which is used when storing and retrieving security diff --git a/reference/configuration/swiftmailer.rst b/reference/configuration/swiftmailer.rst index ccadb7dcb69..bae46b9ba33 100644 --- a/reference/configuration/swiftmailer.rst +++ b/reference/configuration/swiftmailer.rst @@ -11,8 +11,9 @@ options, see `Full Default Configuration`_ The ``swiftmailer`` key configures Symfony's integration with Swift Mailer, which is responsible for creating and delivering email messages. -The following section lists all options that are available to configure a -mailer. It is also possible to configure several mailers (see `Using Multiple Mailers`_). +The following section lists all options that are available to configure +a mailer. It is also possible to configure several mailers (see +`Using Multiple Mailers`_). Configuration ------------- @@ -121,9 +122,9 @@ sender_address **type**: ``string`` -If set, all messages will be delivered with this address as the "return path" -address, which is where bounced messages should go. This is handled internally -by Swift Mailer's ``Swift_Plugins_ImpersonatePlugin`` class. +If set, all messages will be delivered with this address as the "return +path" address, which is where bounced messages should go. This is handled +internally by Swift Mailer's ``Swift_Plugins_ImpersonatePlugin`` class. antiflood ~~~~~~~~~ @@ -149,10 +150,10 @@ delivery_address **type**: ``string`` -If set, all email messages will be sent to this address instead of being sent -to their actual recipients. This is often useful when developing. For example, -by setting this in the ``config_dev.yml`` file, you can guarantee that all -emails sent during development go to a single account. +If set, all email messages will be sent to this address instead of being +sent to their actual recipients. This is often useful when developing. For +example, by setting this in the ``config_dev.yml`` file, you can guarantee +that all emails sent during development go to a single account. This uses ``Swift_Plugins_RedirectingPlugin``. Original recipients are available on the ``X-Swift-To``, ``X-Swift-Cc`` and ``X-Swift-Bcc`` headers. @@ -162,16 +163,17 @@ delivery_whitelist **type**: ``array`` -Used in combination with ``delivery_address``. If set, emails matching any of these -patterns will be delivered like normal, instead of being sent to ``delivery_address``. -For details, see :ref:`the cookbook entry. ` +Used in combination with ``delivery_address``. If set, emails matching any +of these patterns will be delivered like normal, instead of being sent to +``delivery_address``. For details, see +:ref:`the cookbook entry `. disable_delivery ~~~~~~~~~~~~~~~~ **type**: ``boolean`` **default**: ``false`` -If true, the ``transport`` will automatically be set to ``null``, and no +If true, the ``transport`` will automatically be set to ``null`` and no emails will actually be delivered. logging @@ -179,10 +181,10 @@ logging **type**: ``boolean`` **default**: ``%kernel.debug%`` -If true, Symfony's data collector will be activated for Swift Mailer and the -information will be available in the profiler. +If true, Symfony's data collector will be activated for Swift Mailer and +the information will be available in the profiler. -Full default Configuration +Full Default Configuration -------------------------- .. configuration-block:: @@ -240,7 +242,7 @@ Full default Configuration -Using multiple Mailers +Using Multiple Mailers ---------------------- You can configure multiple mailers by grouping them under the ``mailers`` diff --git a/reference/configuration/twig.rst b/reference/configuration/twig.rst index 3ef62ab3ddd..0cc02ba58a5 100644 --- a/reference/configuration/twig.rst +++ b/reference/configuration/twig.rst @@ -60,11 +60,22 @@ TwigBundle Configuration ("twig") xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd http://symfony.com/schema/dic/twig http://symfony.com/schema/dic/twig/twig-1.0.xsd"> - + form_div_layout.html.twig MyBundle::form.html.twig + 3.14 + AcmeFooBundle:Exception:showException %kernel.root_dir%/../vendor/acme/foo-bar/templates @@ -107,7 +118,7 @@ Configuration .. _config-twig-exception-controller: exception_controller -.................... +~~~~~~~~~~~~~~~~~~~~ **type**: ``string`` **default**: ``twig.controller.exception:showAction`` diff --git a/reference/configuration/web_profiler.rst b/reference/configuration/web_profiler.rst index 700732c7afa..fc9e9ee8a0c 100644 --- a/reference/configuration/web_profiler.rst +++ b/reference/configuration/web_profiler.rst @@ -4,7 +4,7 @@ WebProfilerBundle Configuration ("web_profiler") ================================================ -Full default Configuration +Full Default Configuration -------------------------- .. configuration-block:: @@ -13,14 +13,17 @@ Full default Configuration web_profiler: - # DEPRECATED, it is not useful anymore and can be removed safely from your configuration + # DEPRECATED, it is not useful anymore and can be removed + # safely from your configuration verbose: true - # display the web debug toolbar at the bottom of pages with a summary of profiler info + # display the web debug toolbar at the bottom of pages with + # a summary of profiler info toolbar: false position: bottom - # gives you the opportunity to look at the collected data before following the redirect + # gives you the opportunity to look at the collected data + # before following the redirect intercept_redirects: false # Exclude AJAX requests in the web debug toolbar for specified paths diff --git a/reference/constraints/Length.rst b/reference/constraints/Length.rst index 8abd48f5823..f88b54610c7 100644 --- a/reference/constraints/Length.rst +++ b/reference/constraints/Length.rst @@ -116,9 +116,9 @@ 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. +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 ~~~ diff --git a/reference/constraints/NotBlank.rst b/reference/constraints/NotBlank.rst index fd9b44acc3f..fac3089574c 100644 --- a/reference/constraints/NotBlank.rst +++ b/reference/constraints/NotBlank.rst @@ -1,10 +1,10 @@ NotBlank ======== -Validates that a value is not blank, defined as not strictly ``false``, not -equal to a blank string and also not equal to ``null``. To force that a value -is simply not equal to ``null``, see the :doc:`/reference/constraints/NotNull` -constraint. +Validates that a value is not blank, defined as not strictly ``false``, +not equal to a blank string and also not equal to ``null``. To force that +a value is simply not equal to ``null``, see the +:doc:`/reference/constraints/NotNull` constraint. +----------------+------------------------------------------------------------------------+ | Applies to | :ref:`property or method ` | diff --git a/reference/dic_tags.rst b/reference/dic_tags.rst index f3097e577b5..68d601b4cf3 100644 --- a/reference/dic_tags.rst +++ b/reference/dic_tags.rst @@ -645,8 +645,8 @@ cookbook entry. Core Event Listener Reference ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -For the reference of Event Listeners associated with each kernel event, see the -:doc:`Symfony Events Reference `. +For the reference of Event Listeners associated with each kernel event, +see the :doc:`Symfony Events Reference `. .. _dic-tags-kernel-event-subscriber: diff --git a/reference/events.rst b/reference/events.rst index 60740ac9fe0..dc32e2266b0 100644 --- a/reference/events.rst +++ b/reference/events.rst @@ -2,20 +2,20 @@ Symfony Framework Events ======================== When the Symfony Framework (or anything using the :class:`Symfony\\Component\\HttpKernel\\HttpKernel`) -handles a request, a few core events are dispatched so that you can add listeners -throughout the process. These are called the "kernel events". For a larger -explanation, see :doc:`/components/http_kernel/introduction`. +handles a request, a few core events are dispatched so that you can add +listeners throughout the process. These are called the "kernel events". +For a larger explanation, see :doc:`/components/http_kernel/introduction`. Kernel Events ------------- Each event dispatched by the kernel is a subclass of -:class:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent`. This means that -each event has access to the following information: +:class:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent`. This means +that each event has access to the following information: :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::getRequestType` - Returns the *type* of the request (``HttpKernelInterface::MASTER_REQUEST`` or - ``HttpKernelInterface::SUB_REQUEST``). + Returns the *type* of the request (``HttpKernelInterface::MASTER_REQUEST`` + or ``HttpKernelInterface::SUB_REQUEST``). :method:`Symfony\\Component\\HttpKernel\\Event\\KernelEvent::getKernel` Returns the Kernel handling the request. @@ -87,8 +87,8 @@ Listener Class Name This event is not used by the FrameworkBundle, but it can be used to implement a view sub-system. This event is called *only* if the Controller does *not* -return a ``Response`` object. The purpose of the event is to allow some other -return value to be converted into a ``Response``. +return a ``Response`` object. The purpose of the event is to allow some +other return value to be converted into a ``Response``. The value returned by the Controller is accessible via the ``getControllerResult`` method:: @@ -115,8 +115,8 @@ method:: **Event Class**: :class:`Symfony\\Component\\HttpKernel\\Event\\FilterResponseEvent` -The purpose of this event is to allow other systems to modify or replace the -``Response`` object after its creation:: +The purpose of this event is to allow other systems to modify or replace +the ``Response`` object after its creation:: public function onKernelResponse(FilterResponseEvent $event) { @@ -137,8 +137,8 @@ The FrameworkBundle registers several listeners: Fixes the Response ``Content-Type`` based on the request format. :class:`Symfony\\Component\\HttpKernel\\EventListener\\EsiListener` - Adds a ``Surrogate-Control`` HTTP header when the Response needs to be parsed - for ESI tags. + Adds a ``Surrogate-Control`` HTTP header when the Response needs to + be parsed for ESI tags. .. seealso:: diff --git a/reference/forms/twig_reference.rst b/reference/forms/twig_reference.rst index 5ee8243c908..008bee33e00 100644 --- a/reference/forms/twig_reference.rst +++ b/reference/forms/twig_reference.rst @@ -4,15 +4,17 @@ Twig Template Form Function and Variable Reference ================================================== -When working with forms in a template, there are two powerful things at your -disposal: +When working with forms in a template, there are two powerful things at +your disposal: -* :ref:`Functions ` for rendering each part of a form -* :ref:`Variables ` for getting *any* information about any field +* :ref:`Functions ` for rendering each part + of a form; +* :ref:`Variables ` for getting *any* information + about any field. You'll use functions often to render your fields. Variables, on the other hand, are less commonly-used, but infinitely powerful since you can access -a fields label, id attribute, errors, and anything else about the field. +a fields label, id attribute, errors and anything else about the field. .. _reference-form-twig-functions: @@ -20,9 +22,9 @@ Form Rendering Functions ------------------------ This reference manual covers all the possible Twig functions available for -rendering forms. There are several different functions available, and each -is responsible for rendering a different part of a form (e.g. labels, errors, -widgets, etc). +rendering forms. There are several different functions available and +each is responsible for rendering a different part of a form (e.g. labels, +errors, widgets, etc). .. _reference-forms-twig-form: @@ -76,8 +78,8 @@ Renders the end tag of a form. {{ form_end(form) }} -This helper also outputs ``form_rest()`` unless you set ``render_rest`` to -false: +This helper also outputs ``form_rest()`` unless you set ``render_rest`` +to false: .. code-block:: jinja @@ -98,7 +100,11 @@ label you want to display as the second argument. {# The two following syntaxes are equivalent #} {{ form_label(form.name, 'Your Name', {'label_attr': {'class': 'foo'}}) }} - {{ form_label(form.name, null, {'label': 'Your name', 'label_attr': {'class': 'foo'}}) }} + + {{ form_label(form.name, null, { + 'label': 'Your name', + 'label_attr': {'class': 'foo'} + }) }} See ":ref:`twig-reference-form-variables`" to learn about the ``variables`` argument. @@ -122,8 +128,8 @@ Renders any errors for the given field. form_widget(view, variables) ---------------------------- -Renders the HTML widget of a given field. If you apply this to an entire form -or collection of fields, each underlying form row will be rendered. +Renders the HTML widget of a given field. If you apply this to an entire +form or collection of fields, each underlying form row will be rendered. .. code-block:: jinja @@ -181,8 +187,8 @@ form_enctype(view) .. note:: - This helper was deprecated in Symfony 2.3 and will be removed in Symfony 3.0. - You should use ``form_start()`` instead. + This helper was deprecated in Symfony 2.3 and will be removed in Symfony + 3.0. You should use ``form_start()`` instead. If the form contains at least one file upload field, this will render the required ``enctype="multipart/form-data"`` form attribute. It's always a @@ -204,7 +210,8 @@ selectedchoice(selected_value) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This test will check if the current choice is equal to the ``selected_value`` -or if the current choice is in the array (when ``selected_value`` is an array). +or if the current choice is in the array (when ``selected_value`` is an +array). .. code-block:: jinja @@ -221,7 +228,7 @@ More about Form Variables In almost every Twig function above, the final argument is an array of "variables" that are used when rendering that one part of the form. For example, the -following would render the "widget" for a field, and modify its attributes +following would render the "widget" for a field and modify its attributes to include a special class: .. code-block:: jinja @@ -242,41 +249,52 @@ Look at the ``form_label`` as an example: {% if not compound %} {% set label_attr = label_attr|merge({'for': id}) %} {% endif %} + {% if required %} - {% set label_attr = label_attr|merge({'class': (label_attr.class|default('') ~ ' required')|trim}) %} + {% set label_attr = label_attr|merge({ + 'class': (label_attr.class|default('') ~ ' required')|trim + }) %} {% endif %} + {% if label is empty %} {% set label = name|humanize %} {% endif %} - {{ label|trans({}, translation_domain) }} + + {% endblock form_label %} -This block makes use of several variables: ``compound``, ``label_attr``, ``required``, -``label``, ``name`` and ``translation_domain``. -These variables are made available by the form rendering system. But more -importantly, these are the variables that you can override when calling ``form_label`` -(since in this example, you're rendering the label). +This block makes use of several variables: ``compound``, ``label_attr``, +``required``, ``label``, ``name`` and ``translation_domain``. These variables +are made available by the form rendering system. But more importantly, these +are the variables that you can override when calling ``form_label`` (since +in this example, you're rendering the label). The exact variables available to override depends on which part of the form you're rendering (e.g. label versus widget) and which field you're rendering -(e.g. a ``choice`` widget has an extra ``expanded`` option). If you get comfortable -with looking through `form_div_layout.html.twig`_, you'll always be able -to see what options you have available. +(e.g. a ``choice`` widget has an extra ``expanded`` option). If you get +comfortable with looking through `form_div_layout.html.twig`_, you'll always +be able to see what options you have available. .. tip:: Behind the scenes, these variables are made available to the ``FormView`` - object of your form when the Form component calls ``buildView`` and ``finishView`` - on each "node" of your form tree. To see what "view" variables a particular - field has, find the source code for the form field (and its parent fields) - and look at the above two functions. + object of your form when the Form component calls ``buildView`` and + ``finishView`` on each "node" of your form tree. To see what "view" + variables a particular field has, find the source code for the form + field (and its parent fields) and look at the above two functions. .. note:: If you're rendering an entire form at once (or an entire embedded form), the ``variables`` argument will only be applied to the form itself and - not its children. In other words, the following will **not** pass a "foo" - class attribute to all of the child fields in the form: + not its children. In other words, the following will **not** pass a + "foo" class attribute to all of the child fields in the form: .. code-block:: jinja @@ -292,10 +310,10 @@ The following variables are common to every field type. Certain field types may have even more variables and some variables here only really apply to certain types. -Assuming you have a ``form`` variable in your template, and you want to reference -the variables on the ``name`` field, accessing the variables is done by using -a public ``vars`` property on the :class:`Symfony\\Component\\Form\\FormView` -object: +Assuming you have a ``form`` variable in your template and you want to +reference the variables on the ``name`` field, accessing the variables is +done by using a public ``vars`` property on the +:class:`Symfony\\Component\\Form\\FormView` object: .. configuration-block:: diff --git a/reference/forms/types/checkbox.rst b/reference/forms/types/checkbox.rst index 3e04856ac4a..3b45e55c582 100644 --- a/reference/forms/types/checkbox.rst +++ b/reference/forms/types/checkbox.rst @@ -4,9 +4,9 @@ checkbox Field Type =================== -Creates a single input checkbox. This should always be used for a field that -has a boolean value: if the box is checked, the field will be set to true, -if the box is unchecked, the value will be set to false. +Creates a single input checkbox. This should always be used for a field +that has a boolean value: if the box is checked, the field will be set to +true, if the box is unchecked, the value will be set to false. +-------------+------------------------------------------------------------------------+ | Rendered as | ``input`` ``checkbox`` field | diff --git a/reference/forms/types/choice.rst b/reference/forms/types/choice.rst index b8c4a12a89a..69079e4168d 100644 --- a/reference/forms/types/choice.rst +++ b/reference/forms/types/choice.rst @@ -102,6 +102,11 @@ is the item value and the array value is the item's label:: choice_list ~~~~~~~~~~~ +.. caution:: + + The ``choice_list`` option of ChoiceType was deprecated in Symfony 2.7. + You should use ``choices`` or ``choice_loader`` now. + **type**: :class:`Symfony\\Component\\Form\\Extension\\Core\\ChoiceList\\ChoiceListInterface` This is one way of specifying the options to be used for this field. @@ -109,15 +114,17 @@ The ``choice_list`` option must be an instance of the ``ChoiceListInterface``. For more advanced cases, a custom class that implements the interface can be created to supply the choices. -With this option you can also allow float values to be selected as data. For example: - -.. code-block:: php +With this option you can also allow float values to be selected as data. +For example:: use Symfony\Component\Form\Extension\Core\ChoiceList\ChoiceList; // ... $builder->add('status', 'choice', array( - 'choice_list' => new ChoiceList(array(1, 0.5, 0.1), array('Full', 'Half', 'Almost empty')) + 'choice_list' => new ChoiceList( + array(1, 0.5, 0.1), + array('Full', 'Half', 'Almost empty') + ) )); The ``status`` field created by the code above will be rendered as: @@ -130,9 +137,9 @@ The ``status`` field created by the code above will be rendered as: -But don't be confused! If ``Full`` is selected (value ``0`` in HTML), ``1`` will -be returned in your form. If ``Almost empty`` is selected (value ``2`` in HTML), -``0.1`` will be returned. +But don't be confused! If ``Full`` is selected (value ``0`` in HTML), ``1`` +will be returned in your form. If ``Almost empty`` is selected (value ``2`` +in HTML), ``0.1`` will be returned. .. include:: /reference/forms/types/options/placeholder.rst.inc diff --git a/reference/forms/types/entity.rst b/reference/forms/types/entity.rst index 9114bb19845..58faabc5ea2 100644 --- a/reference/forms/types/entity.rst +++ b/reference/forms/types/entity.rst @@ -12,11 +12,11 @@ objects from the database. +-------------+------------------------------------------------------------------+ | Rendered as | can be various tags (see :ref:`forms-reference-choice-tags`) | +-------------+------------------------------------------------------------------+ -| Options | - `class`_ | +| Options | - `choice_label`_ | +| | - `class`_ | | | - `data_class`_ | | | - `em`_ | | | - `group_by`_ | -| | - `property`_ | | | - `query_builder`_ | +-------------+------------------------------------------------------------------+ | Overridden | - `choice_list`_ | @@ -55,13 +55,13 @@ be listed inside the choice field:: $builder->add('users', 'entity', array( 'class' => 'AcmeHelloBundle:User', - 'property' => 'username', + 'choice_label' => 'username', )); In this case, all ``User`` objects will be loaded from the database and rendered as either a ``select`` tag, a set or radio buttons or a series of checkboxes (this depends on the ``multiple`` and ``expanded`` values). -If the entity object does not have a ``__toString()`` method the ``property`` +If the entity object does not have a ``__toString()`` method the ``choice_label`` option is needed. Using a Custom Query for the Entities @@ -103,6 +103,33 @@ then you can supply the ``choices`` option directly:: Field Options ------------- +choice_label +~~~~~~~~~~~~ + +.. versionadded:: 2.7 + The ``choice_label`` option was introduced in Symfony 2.7. Prior to Symfony + 2.7, it was called ``property`` (which has the same functionality). + +**type**: ``string`` + +This is the property that should be used for displaying the entities +as text in the HTML element. If left blank, the entity object will be +cast into a string and so must have a ``__toString()`` method. + +.. note:: + + The ``choice_label`` option is the property path used to display the option. + So you can use anything supported by the + :doc:`PropertyAccessor component ` + + For example, if the translations property is actually an associative + array of objects, each with a name property, then you could do this:: + + $builder->add('gender', 'entity', array( + 'class' => 'MyBundle:Gender', + 'choice_label' => 'translations[en].name', + )); + class ~~~~~ @@ -133,29 +160,6 @@ and does so by adding ``optgroup`` elements around options. Choices that do not return a value for this property path are rendered directly under the select tag, without a surrounding optgroup. -property -~~~~~~~~ - -**type**: ``string`` - -This is the property that should be used for displaying the entities -as text in the HTML element. If left blank, the entity object will be -cast into a string and so must have a ``__toString()`` method. - -.. note:: - - The ``property`` option is the property path used to display the option. - So you can use anything supported by the - :doc:`PropertyAccessor component ` - - For example, if the translations property is actually an associative - array of objects, each with a name property, then you could do this:: - - $builder->add('gender', 'entity', array( - 'class' => 'MyBundle:Gender', - 'property' => 'translations[en].name', - )); - query_builder ~~~~~~~~~~~~~ diff --git a/reference/forms/types/integer.rst b/reference/forms/types/integer.rst index e8296bbe765..b2d4348861e 100644 --- a/reference/forms/types/integer.rst +++ b/reference/forms/types/integer.rst @@ -4,10 +4,10 @@ integer Field Type ================== -Renders an input "number" field. Basically, this is a text field that's good -at handling data that's in an integer form. The input ``number`` field looks -like a text box, except that - if the user's browser supports HTML5 - it will -have some extra front-end functionality. +Renders an input "number" field. Basically, this is a text field that's +good at handling data that's in an integer form. The input ``number`` field +looks like a text box, except that - if the user's browser supports HTML5 +- it will have some extra front-end functionality. This field has different options on how to handle input values that aren't integers. By default, all non-integer values (e.g. 6.78) will round down diff --git a/reference/map.rst.inc b/reference/map.rst.inc index 0bf22aa3b44..174cdd908cc 100644 --- a/reference/map.rst.inc +++ b/reference/map.rst.inc @@ -1,9 +1,9 @@ * **Configuration Options** - Ever wondered what configuration options you have available to you in files - such as ``app/config/config.yml``? In this section, all the available configuration - is broken down by the key (e.g. ``framework``) that defines each possible - section of your Symfony configuration. + Ever wondered what configuration options you have available to you in + files such as ``app/config/config.yml``? In this section, all the available + configuration is broken down by the key (e.g. ``framework``) that defines + each possible section of your Symfony configuration. * :doc:`framework ` * :doc:`doctrine `