diff --git a/book/forms.rst b/book/forms.rst index 33ac67e0806..0ff9231e4c2 100644 --- a/book/forms.rst +++ b/book/forms.rst @@ -167,16 +167,19 @@ helper functions: That's it! Just three lines are needed to render the complete form: -* ``form_start(form)`` - Renders the start tag of the form, including the - correct enctype attribute when using file uploads; +``form_start(form)`` + Renders the start tag of the form, including the correct enctype attribute + when using file uploads. -* ``form_widget(form)`` - Renders all the fields, which includes the field - element itself, a label and any validation error messages for the field; +``form_widget(form)`` + Renders all the fields, which includes the field element itself, a label + and any validation error messages for the field. -* ``form_end()`` - Renders the end tag of the form and any fields that have not - yet been rendered, in case you rendered each field yourself. This is useful - for rendering hidden fields and taking advantage of the automatic - :ref:`CSRF Protection `. +``form_end()`` + Renders the end tag of the form and any fields that have not + yet been rendered, in case you rendered each field yourself. This is useful + for rendering hidden fields and taking advantage of the automatic + :ref:`CSRF Protection `. .. seealso:: @@ -262,7 +265,7 @@ possible paths: .. note:: You can use the method :method:`Symfony\\Component\\Form\\FormInterface::isSubmitted` - to check whether a form was submitted, regardless of whether the + to check whether a form was submitted, regardless of whether or not the submitted data is actually valid. #. When the user submits the form with valid data, the submitted data is again @@ -330,9 +333,9 @@ Form Validation In the previous section, you learned how a form can be submitted with valid or invalid data. In Symfony, validation is applied to the underlying object (e.g. ``Task``). In other words, the question isn't whether the "form" is -valid, but whether the ``$task`` object is valid after the form has +valid, but whether or not the ``$task`` object is valid after the form has applied the submitted data to it. Calling ``$form->isValid()`` is a shortcut -that asks the ``$task`` object whether it has valid data. +that asks the ``$task`` object whether or not it has valid data. Validation is done by adding a set of rules (called constraints) to a class. To see this in action, add validation constraints so that the ``task`` field cannot @@ -639,7 +642,7 @@ the documentation for each type. option on your field to ``false`` or :ref:`disable HTML5 validation `. - Also, note that setting the ``required`` option to ``true`` will **not** + Also note that setting the ``required`` option to ``true`` will **not** result in server-side validation to be applied. In other words, if a user submits a blank value for the field (either with an old browser or web service, for example), it will be accepted as a valid value unless @@ -1486,7 +1489,7 @@ In Twig, every block needed is defined in a single template file (e.g. file, you can see every block needed to render a form and every default field type. -In PHP, the fragments are individual template files. By default, they are located in +In PHP, the fragments are individual template files. By default they are located in the `Resources/views/Form` directory of the framework bundle (`view on GitHub`_). Each fragment name follows the same basic pattern and is broken up into two pieces, diff --git a/book/translation.rst b/book/translation.rst index ba2ef11e5d1..d6094a3a5d7 100644 --- a/book/translation.rst +++ b/book/translation.rst @@ -394,13 +394,13 @@ Imagine that the user's locale is ``fr_FR`` and that you're translating the key ``Symfony is great``. To find the French translation, Symfony actually checks translation resources for several locales: -1. First, Symfony looks for the translation in a ``fr_FR`` translation resource +#. First, Symfony looks for the translation in a ``fr_FR`` translation resource (e.g. ``messages.fr_FR.xliff``); -2. If it wasn't found, Symfony looks for the translation in a ``fr`` translation +#. If it wasn't found, Symfony looks for the translation in a ``fr`` translation resource (e.g. ``messages.fr.xliff``); -3. If the translation still isn't found, Symfony uses the ``fallback`` configuration +#. If the translation still isn't found, Symfony uses the ``fallback`` configuration parameter, which defaults to ``en`` (see `Configuration`_). .. _book-translation-user-locale: diff --git a/components/console/introduction.rst b/components/console/introduction.rst index add481437d3..a2b3c52b7fd 100644 --- a/components/console/introduction.rst +++ b/components/console/introduction.rst @@ -88,6 +88,8 @@ an ``Application`` and adds commands to it:: value pair; + Sets multiple attributes at once: takes a keyed array and sets each key => value pair. :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::remove` - Deletes an attribute by key; + Deletes an attribute by key. :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::clear` Clear all attributes. @@ -123,7 +123,7 @@ an array. A few methods exist for "Bag" management: :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getBag` Gets a :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` by - bag name; + bag name. :method:`Symfony\\Component\\HttpFoundation\\Session\\Session::getFlashBag` Gets the :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface`. @@ -157,16 +157,16 @@ bag types if necessary. :class:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface` has the following API which is intended mainly for internal purposes: -* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getStorageKey`: - Returns the key which the bag will ultimately store its array under in ``$_SESSION``. - Generally this value can be left at its default and is for internal use. +:method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getStorageKey` + Returns the key which the bag will ultimately store its array under in ``$_SESSION``. + Generally this value can be left at its default and is for internal use. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::initialize`: - This is called internally by Symfony session storage classes to link bag data - to the session. +:method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::initialize` + This is called internally by Symfony session storage classes to link bag data + to the session. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getName`: - Returns the name of the session bag. +:method:`Symfony\\Component\\HttpFoundation\\Session\\SessionBagInterface::getName` + Returns the name of the session bag. Attributes ~~~~~~~~~~ @@ -175,11 +175,11 @@ The purpose of the bags implementing the :class:`Symfony\\Component\\HttpFoundat is to handle session attribute storage. This might include things like user ID, and remember me login settings or other user based state information. -* :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBag` - This is the standard default implementation. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBag` + This is the standard default implementation. -* :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag` - This implementation allows for attributes to be stored in a structured namespace. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\NamespacedAttributeBag` + This implementation allows for attributes to be stored in a structured namespace. Any plain key-value storage system is limited in the extent to which complex data can be stored since each key must be unique. You can achieve @@ -210,29 +210,29 @@ This way you can easily access a key within the stored array directly and easily :class:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface` has a simple API -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::set`: - Sets an attribute by key; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::set` + Sets an attribute by key. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::get`: - Gets an attribute by key; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::get` + Gets an attribute by key. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::all`: - Gets all attributes as an array of key => value; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::all` + Gets all attributes as an array of key => value. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::has`: - Returns true if the attribute exists; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::has` + Returns true if the attribute exists. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::keys`: - Returns an array of stored attribute keys; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::keys` + Returns an array of stored attribute keys. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::replace`: - Sets multiple attributes at once: takes a keyed array and sets each key => value pair. +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::replace` + Sets multiple attributes at once: takes a keyed array and sets each key => value pair. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::remove`: - Deletes an attribute by key; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::remove` + Deletes an attribute by key. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::clear`: - Clear the bag; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Attribute\\AttributeBagInterface::clear` + Clear the bag. Flash Messages ~~~~~~~~~~~~~~ @@ -246,49 +246,49 @@ updated page or an error page. Flash messages set in the previous page request would be displayed immediately on the subsequent page load for that session. This is however just one application for flash messages. -* :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\AutoExpireFlashBag` - In this implementation, messages set in one page-load will - be available for display only on the next page load. These messages will auto - expire regardless of if they are retrieved or not. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\AutoExpireFlashBag` + In this implementation, messages set in one page-load will + be available for display only on the next page load. These messages will auto + expire regardless of if they are retrieved or not. -* :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBag` - In this implementation, messages will remain in the session until - they are explicitly retrieved or cleared. This makes it possible to use ESI - caching. +:class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBag` + In this implementation, messages will remain in the session until + they are explicitly retrieved or cleared. This makes it possible to use ESI + caching. :class:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface` has a simple API -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::add`: - Adds a flash message to the stack of specified type; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::add` + Adds a flash message to the stack of specified type. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::set`: - Sets flashes by type; This method conveniently takes both single messages as - a ``string`` or multiple messages in an ``array``. +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::set` + Sets flashes by type; This method conveniently takes both single messages as + a ``string`` or multiple messages in an ``array``. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::get`: - Gets flashes by type and clears those flashes from the bag; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::get` + Gets flashes by type and clears those flashes from the bag. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::setAll`: - Sets all flashes, accepts a keyed array of arrays ``type => array(messages)``; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::setAll` + Sets all flashes, accepts a keyed array of arrays ``type => array(messages)``. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::all`: - Gets all flashes (as a keyed array of arrays) and clears the flashes from the bag; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::all` + Gets all flashes (as a keyed array of arrays) and clears the flashes from the bag. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peek`: - Gets flashes by type (read only); +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peek` + Gets flashes by type (read only). -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peekAll`: - Gets all flashes (read only) as keyed array of arrays; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::peekAll` + Gets all flashes (read only) as keyed array of arrays. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::has`: - Returns true if the type exists, false if not; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::has` + Returns true if the type exists, false if not. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::keys`: - Returns an array of the stored flash types; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::keys` + Returns an array of the stored flash types. -* :method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::clear`: - Clears the bag; +:method:`Symfony\\Component\\HttpFoundation\\Session\\Flash\\FlashBagInterface::clear` + Clears the bag. For simple applications it is usually sufficient to have one flash message per type, for example a confirmation notice after a form is submitted. However, diff --git a/components/routing/introduction.rst b/components/routing/introduction.rst index e751b0a36d2..85bcd1065de 100644 --- a/components/routing/introduction.rst +++ b/components/routing/introduction.rst @@ -72,25 +72,25 @@ Defining Routes A full route definition can contain up to seven parts: -1. The URL path route. This is matched against the URL passed to the `RequestContext`, +#. The URL path route. This is matched against the URL passed to the `RequestContext`, and can contain named wildcard placeholders (e.g. ``{placeholders}``) to match dynamic parts in the URL. -2. An array of default values. This contains an array of arbitrary values +#. An array of default values. This contains an array of arbitrary values that will be returned when the request matches the route. -3. An array of requirements. These define constraints for the values of the +#. An array of requirements. These define constraints for the values of the placeholders as regular expressions. -4. An array of options. These contain internal settings for the route and +#. An array of options. These contain internal settings for the route and are the least commonly needed. -5. A host. This is matched against the host of the request. See +#. A host. This is matched against the host of the request. See :doc:`/components/routing/hostname_pattern` for more details. -6. An array of schemes. These enforce a certain HTTP scheme (``http``, ``https``). +#. An array of schemes. These enforce a certain HTTP scheme (``http``, ``https``). -7. An array of methods. These enforce a certain HTTP request method (``HEAD``, +#. An array of methods. These enforce a certain HTTP request method (``HEAD``, ``GET``, ``POST``, ...). .. versionadded:: 2.2 diff --git a/components/security/authorization.rst b/components/security/authorization.rst index c5b357e5118..9c3000a429e 100644 --- a/components/security/authorization.rst +++ b/components/security/authorization.rst @@ -40,13 +40,13 @@ itself depends on multiple voters, and makes a final verdict based on all the votes (either positive, negative or neutral) it has received. It recognizes several strategies: -* ``affirmative`` (default) +``affirmative`` (default) grant access as soon as any voter returns an affirmative response; -* ``consensus`` +``consensus`` grant access if there are more voters granting access than there are denying; -* ``unanimous`` +``unanimous`` only grant access if none of the voters has denied access; .. code-block:: php @@ -85,14 +85,14 @@ of :class:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterf which means they have to implement a few methods which allows the decision manager to use them: -* ``supportsAttribute($attribute)`` +``supportsAttribute($attribute)`` will be used to check if the voter knows how to handle the given attribute; -* ``supportsClass($class)`` +``supportsClass($class)`` will be used to check if the voter is able to grant or deny access for an object of the given class; -* ``vote(TokenInterface $token, $object, array $attributes)`` +``vote(TokenInterface $token, $object, array $attributes)`` this method will do the actual voting and return a value equal to one of the class constants of :class:`Symfony\\Component\\Security\\Core\\Authorization\\Voter\\VoterInterface`, i.e. ``VoterInterface::ACCESS_GRANTED``, ``VoterInterface::ACCESS_DENIED`` diff --git a/components/serializer.rst b/components/serializer.rst index aeaabeb6067..472de02aa02 100644 --- a/components/serializer.rst +++ b/components/serializer.rst @@ -144,9 +144,9 @@ of the ``Person`` class would be encoded in XML format:: In this case, :method:`Symfony\\Component\\Serializer\\Serializer::deserialize` needs three parameters: -1. The information to be decoded -2. The name of the class this information will be decoded to -3. The encoder used to convert that information into an array +#. The information to be decoded +#. The name of the class this information will be decoded to +#. The encoder used to convert that information into an array Using Camelized Method Names for Underscored Attributes ------------------------------------------------------- diff --git a/components/translation/introduction.rst b/components/translation/introduction.rst index 5810fe5e770..c637dce0b5a 100644 --- a/components/translation/introduction.rst +++ b/components/translation/introduction.rst @@ -159,12 +159,12 @@ If the message is not located in the catalog of the specific locale, the translator will look into the catalog of one or more fallback locales. For example, assume you're trying to translate into the ``fr_FR`` locale: -1. First, the translator looks for the translation in the ``fr_FR`` locale; +#. First, the translator looks for the translation in the ``fr_FR`` locale; -2. If it wasn't found, the translator looks for the translation in the ``fr`` +#. If it wasn't found, the translator looks for the translation in the ``fr`` locale; -3. If the translation still isn't found, the translator uses the one or more +#. If the translation still isn't found, the translator uses the one or more fallback locales set explicitly on the translator. For (3), the fallback locales can be set by calling diff --git a/conf.py b/conf.py index 46f9687837f..291205d1d73 100644 --- a/conf.py +++ b/conf.py @@ -101,12 +101,10 @@ lexers['php-annotations'] = PhpLexer(startinline=True) lexers['php-standalone'] = PhpLexer(startinline=True) lexers['php-symfony'] = PhpLexer(startinline=True) -lexers['varnish2'] = CLexer() lexers['varnish3'] = CLexer() lexers['varnish4'] = CLexer() config_block = { - 'varnish2': 'Varnish 2', 'varnish3': 'Varnish 3', 'varnish4': 'Varnish 4' } diff --git a/contributing/code/patches.rst b/contributing/code/patches.rst index 033d19765a3..1f9bf7000e5 100644 --- a/contributing/code/patches.rst +++ b/contributing/code/patches.rst @@ -15,7 +15,7 @@ software: * Git; * PHP version 5.3.3 or above; -* PHPUnit 3.6.4 or above. +* `PHPUnit`_ 4.2 or above. Configure Git ~~~~~~~~~~~~~ @@ -415,3 +415,4 @@ messages of all the commits. When you are finished, execute the push command. .. _`fabbot`: http://fabbot.io .. _`PSR-1`: http://www.php-fig.org/psr/psr-1/ .. _`PSR-2`: http://www.php-fig.org/psr/psr-2/ +.. _PHPUnit: https://phpunit.de/manual/current/en/installation.html diff --git a/contributing/code/security.rst b/contributing/code/security.rst index 49a6ff35e30..51acb3f1adf 100644 --- a/contributing/code/security.rst +++ b/contributing/code/security.rst @@ -19,10 +19,10 @@ Resolving Process For each report, we first try to confirm the vulnerability. When it is confirmed, the core-team works on a solution following these steps: -1. Send an acknowledgement to the reporter; -2. Work on a patch; -3. Get a CVE identifier from mitre.org; -4. Write a security announcement for the official Symfony `blog`_ about the +#. Send an acknowledgement to the reporter; +#. Work on a patch; +#. Get a CVE identifier from mitre.org; +#. Write a security announcement for the official Symfony `blog`_ about the vulnerability. This post should contain the following information: * a title that always include the "Security release" string; @@ -32,12 +32,12 @@ confirmed, the core-team works on a solution following these steps: * how to patch/upgrade/workaround affected applications; * the CVE identifier; * credits. -5. Send the patch and the announcement to the reporter for review; -6. Apply the patch to all maintained versions of Symfony; -7. Package new versions for all affected versions; -8. Publish the post on the official Symfony `blog`_ (it must also be added to +#. Send the patch and the announcement to the reporter for review; +#. Apply the patch to all maintained versions of Symfony; +#. Package new versions for all affected versions; +#. Publish the post on the official Symfony `blog`_ (it must also be added to the "`Security Advisories`_" category); -9. Update the security advisory list (see below). +#. Update the security advisory list (see below). .. note:: @@ -61,23 +61,23 @@ As Symfony is used by many large Open-Source projects, we standardized the way the Symfony security team collaborates on security issues with downstream projects. The process works as follows: -1. After the Symfony security team has acknowledged a security issue, it -immediately sends an email to the downstream project security teams to inform -them of the issue; +#. After the Symfony security team has acknowledged a security issue, it + immediately sends an email to the downstream project security teams to + inform them of the issue; -2. The Symfony security team creates a private Git repository to ease the -collaboration on the issue and access to this repository is given to the -Symfony security team, to the Symfony contributors that are impacted by the -issue, and to one representative of each downstream projects; +#. The Symfony security team creates a private Git repository to ease the + collaboration on the issue and access to this repository is given to the + Symfony security team, to the Symfony contributors that are impacted by + the issue, and to one representative of each downstream projects; -3. All people with access to the private repository work on a solution to -solve the issue via pull requests, code reviews, and comments; +#. All people with access to the private repository work on a solution to + solve the issue via pull requests, code reviews, and comments; -4. Once the fix is found, all involved projects collaborate to find the best -date for a joint release (there is no guarantee that all releases will be at -the same time but we will try hard to make them at about the same time). When -the issue is not known to be exploited in the wild, a period of two weeks -seems like a reasonable amount of time. +#. Once the fix is found, all involved projects collaborate to find the best + date for a joint release (there is no guarantee that all releases will + be at the same time but we will try hard to make them at about the same + time). When the issue is not known to be exploited in the wild, a period + of two weeks seems like a reasonable amount of time. The list of downstream projects participating in this process is kept as small as possible in order to better manage the flow of confidential information diff --git a/contributing/code/tests.rst b/contributing/code/tests.rst index c876a00d559..ebec01f3d3e 100644 --- a/contributing/code/tests.rst +++ b/contributing/code/tests.rst @@ -112,5 +112,5 @@ browser. The code coverage only works if you have Xdebug enabled and all dependencies installed. -.. _install PHPUnit: http://www.phpunit.de/manual/current/en/installation.html +.. _install PHPUnit: https://phpunit.de/manual/current/en/installation.html .. _`Composer`: http://getcomposer.org/ diff --git a/cookbook/cache/varnish.rst b/cookbook/cache/varnish.rst index 8be11c7f098..6c53138fdd9 100644 --- a/cookbook/cache/varnish.rst +++ b/cookbook/cache/varnish.rst @@ -7,27 +7,91 @@ How to Use Varnish to Speed up my Website Because Symfony's cache uses the standard HTTP cache headers, the :ref:`symfony-gateway-cache` can easily be replaced with any other reverse proxy. `Varnish`_ is a powerful, open-source, HTTP accelerator capable of serving -cached content quickly and including support for :ref:`Edge Side Includes `. +cached content fast and including support for :ref:`Edge Side Includes `. -Trusting Reverse Proxies ------------------------- +.. index:: + single: Varnish; configuration + +Make Symfony Trust the Reverse Proxy +------------------------------------ For ESI to work correctly and for the :ref:`X-FORWARDED ` headers to be used, you need to configure Varnish as a :doc:`trusted proxy `. -.. index:: - single: Varnish; configuration +.. _varnish-x-forwarded-headers: + +Routing and X-FORWARDED Headers +------------------------------- + +To ensure that the Symfony Router generates URLs correctly with Varnish, +a ``X-Forwarded-Port`` header must be present for Symfony to use the +correct port number. -Configuration -------------- +This port depends on your setup. Lets say that external connections come in +on the default HTTP port 80. For HTTPS connections, there is another proxy +(as Varnish does not do HTTPS itself) on the default HTTPS port 443 that +handles the SSL termination and forwards the requests as HTTP requests to +Varnish with a ``X-Forwarded-Proto`` header. In this case, you need to add +the following configuration snippet: -As seen previously, Symfony is smart enough to detect whether it talks to a -reverse proxy that understands ESI or not. It works out of the box when you -use the Symfony reverse proxy, but you need a special configuration to make -it work with Varnish. Thankfully, Symfony relies on yet another standard -written by Akamai (`Edge Architecture`_), so the configuration tips in this -chapter can be useful even if you don't use Symfony. +.. code-block:: varnish4 + + sub vcl_recv { + if (req.http.X-Forwarded-Proto == "https" ) { + set req.http.X-Forwarded-Port = "443"; + } else { + set req.http.X-Forwarded-Port = "80"; + } + } + +.. note:: + + Remember to configure :ref:`framework.trusted_proxies ` + in the Symfony configuration so that Varnish is seen as a trusted proxy + and the ``X-Forwarded-*`` headers are used. + + Varnish automatically forwards the IP as ``X-Forwarded-For`` and leaves + the ``X-Forwarded-Proto`` header in the request. If you do not configure + Varnish as trusted proxy, Symfony will see all requests as coming through + insecure HTTP connections from the Varnish host instead of the real client. + +If the ``X-Forwarded-Port`` header is not set correctly, Symfony will append +the port where the PHP application is running when generating absolute URLs, +e.g. ``http://example.com:8080/my/path``. + +Ensure Consistent Caching Behaviour +----------------------------------- + +Varnish uses the cache headers sent by your application to determine how +to cache content. However, versions prior to Varnish 4 did not respect +``Cache-Control: no-cache``. To ensure consistent behaviour, use the following +configuration if you are still using Varnish 3: + +.. configuration-block:: + + .. code-block:: varnish3 + + sub vcl_fetch { + /* By default, Varnish3 ignores Cache-Control: no-cache and private + https://www.varnish-cache.org/docs/3.0/tutorial/increasing_your_hitrate.html#cache-control + */ + if (beresp.http.Cache-Control ~ "no-cache" || + beresp.http.Cache-Control ~ "private" + ) { + return (hit_for_pass); + } + } + +Enable Edge Side Includes (ESI) +------------------------------- + +As explained in the :ref:`Edge Side Includes section`, +Symfony detects whether it talks to a reverse proxy that understands ESI or +not. When you use the Symfony reverse proxy, you don't need to do anything. +But to make Varnish instead of Symfony resolve the ESI tags, you need some +configuration in Varnish. Symfony uses the ``Surrogate-Capability`` header +from the `Edge Architecture`_ described by Akamai. .. note:: @@ -58,22 +122,12 @@ Symfony adds automatically: .. code-block:: varnish4 - /* (https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#req-not-available-in-vcl-backend-response) */ sub vcl_backend_response { // Check for ESI acknowledgement and remove Surrogate-Control header if (beresp.http.Surrogate-Control ~ "ESI/1.0") { unset beresp.http.Surrogate-Control; set beresp.do_esi = true; } - /* By default Varnish ignores Pragma: nocache - (https://www.varnish-cache.org/docs/4.0/users-guide/increasing-your-hitrate.html#cache-control) - so in order avoid caching it has to be done explicitly */ - if (beresp.http.Pragma ~ "no-cache") { - // https://www.varnish-cache.org/docs/4.0/whats-new/upgrading.html#hit-for-pass-objects-are-created-using-beresp-uncacheable - set beresp.uncacheable = true; - set beresp.ttl = 120s; - return (deliver); - } } .. code-block:: varnish3 @@ -84,38 +138,13 @@ Symfony adds automatically: unset beresp.http.Surrogate-Control; set beresp.do_esi = true; } - /* By default Varnish ignores Cache-Control: nocache - (https://www.varnish-cache.org/docs/3.0/tutorial/increasing_your_hitrate.html#cache-control), - so in order avoid caching it has to be done explicitly */ - if (beresp.http.Pragma ~ "no-cache" || - beresp.http.Cache-Control ~ "no-cache" || - beresp.http.Cache-Control ~ "private") { - return (hit_for_pass); - } } - .. code-block:: varnish2 - - sub vcl_fetch { - // Check for ESI acknowledgement and remove Surrogate-Control header - if (beresp.http.Surrogate-Control ~ "ESI/1.0") { - unset beresp.http.Surrogate-Control; - esi; - } - /* By default Varnish ignores Cache-Control: nocache - so in order avoid caching it has to be done explicitly */ - if (beresp.http.Pragma ~ "no-cache" || - beresp.http.Cache-Control ~ "no-cache" || - beresp.http.Cache-Control ~ "private") { - return (hit_for_pass); - } - } - -.. caution:: +.. tip:: - Compression with ESI was not supported in Varnish until version 3.0 - (read `GZIP and Varnish`_). If you're not using Varnish 3.0, put a web - server in front of Varnish to perform the compression. + If you followed the advice about ensuring a consistent caching + behaviour, those vcl functions already exist. Just append the code + to the end of the function, they won't interfere with each other. .. index:: single: Varnish; Invalidation @@ -134,139 +163,8 @@ proxy before it has expired, it adds complexity to your caching setup. invalidation by helping you to organize your caching and invalidation setup. -Varnish can be configured to accept a special HTTP ``PURGE`` method -that will invalidate the cache for a given resource: - -.. code-block:: varnish4 - - /* - Connect to the backend server - on the local machine on port 8080 - */ - backend default { - .host = "127.0.0.1"; - .port = "8080"; - } - - sub vcl_recv { - /* - Varnish default behavior doesn't support PURGE. - Match the PURGE request and immediately do a cache lookup, - otherwise Varnish will directly pipe the request to the backend - and bypass the cache - */ - if (req.request == "PURGE") { - return(lookup); - } - } - - sub vcl_hit { - // Match PURGE request - if (req.request == "PURGE") { - // Force object expiration for Varnish < 3.0 - set obj.ttl = 0s; - // Do an actual purge for Varnish >= 3.0 - // purge; - error 200 "Purged"; - } - } - - sub vcl_miss { - /* - Match the PURGE request and - indicate the request wasn't stored in cache. - */ - if (req.request == "PURGE") { - error 404 "Not purged"; - } - } - -.. caution:: - - You must protect the ``PURGE`` HTTP method somehow to avoid random people - purging your cached data. You can do this by setting up an access list: - - .. code-block:: varnish4 - - /* - Connect to the backend server - on the local machine on port 8080 - */ - backend default { - .host = "127.0.0.1"; - .port = "8080"; - } - - // ACL's can contain IP's, subnets and hostnames - acl purge { - "localhost"; - "192.168.55.0"/24; - } - - sub vcl_recv { - // Match PURGE request to avoid cache bypassing - if (req.request == "PURGE") { - // Match client IP to the ACL - if (!client.ip ~ purge) { - // Deny access - error 405 "Not allowed."; - } - // Perform a cache lookup - return(lookup); - } - } - - sub vcl_hit { - // Match PURGE request - if (req.request == "PURGE") { - // Force object expiration for Varnish < 3.0 - set obj.ttl = 0s; - // Do an actual purge for Varnish >= 3.0 - // purge; - error 200 "Purged"; - } - } - - sub vcl_miss { - // Match PURGE request - if (req.request == "PURGE") { - // Indicate that the object isn't stored in cache - error 404 "Not purged"; - } - } - -.. _varnish-x-forwarded-headers: - -Routing and X-FORWARDED Headers -------------------------------- - -To ensure that the Symfony Router generates URLs correctly with Varnish, -proper ```X-Forwarded``` headers must be added so that Symfony is aware of -the original port number of the request. Exactly how this is done depends -on your setup. As a simple example, Varnish and your web server are on the -same machine and that Varnish is listening on one port (e.g. 80) and Apache -on another (e.g. 8080). In this situation, Varnish should add the ``X-Forwarded-Port`` -header so that the Symfony application knows that the original port number -is 80 and not 8080. - -If this header weren't set properly, Symfony may append ``8080`` when generating -absolute URLs: - -.. code-block:: varnish4 - - sub vcl_recv { - if (req.http.X-Forwarded-Proto == "https" ) { - set req.http.X-Forwarded-Port = "443"; - } else { - set req.http.X-Forwarded-Port = "80"; - } - } - -.. note:: - - Remember to configure :ref:`framework.trusted_proxies ` - in the Symfony configuration so that Varnish is seen as a trusted proxy - and the ``X-Forwarded-`` headers are used. + The documentation of the `FOSHttpCacheBundle`_ explains how to configure + Varnish and other reverse proxies for cache invalidation. .. _`Varnish`: https://www.varnish-cache.org .. _`Edge Architecture`: http://www.w3.org/TR/edge-arch diff --git a/cookbook/configuration/environments.rst b/cookbook/configuration/environments.rst index c3fd907859f..b658b16f360 100644 --- a/cookbook/configuration/environments.rst +++ b/cookbook/configuration/environments.rst @@ -212,6 +212,39 @@ environment by using this code and changing the environment string. mode. You'll need to enable that in your front controller by calling :method:`Symfony\\Component\\Debug\\Debug::enable`. +Selecting the Environment for Console Commands +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, Symfony commands are executed in the ``dev`` environment and with the +debug mode enabled. Use the ``--env`` and ``--no-debug`` options to modify this +behavior: + +.. code-block:: bash + + # 'dev' environment and debug enabled + $ php app/console command_name + + # 'prod' environment (debug is always disabled for 'prod') + $ php app/console command_name --env=prod + + # 'test' environment and debug disabled + $ php app/console command_name --env=test --no-debug + +In addition to the ``--env`` and ``--debug`` options, the behavior of Symfony +commands can also be controlled with environment variables. The Symfony console +application checks the existence and value of these environment variables before +executing any command: + +``SYMFONY_ENV`` + Sets the execution environment of the command to the value of this variable + (``dev``, ``prod``, ``test``, etc.); +``SYMFONY_DEBUG`` + If ``0``, debug mode is disabled. Otherwise, debug mode is enabled. + +These environment variables are very useful for production servers because they +allow you to ensure that commands always run in the ``prod`` environment without +having to add any command option. + .. index:: single: Environments; Creating a new environment diff --git a/cookbook/deployment/heroku.rst b/cookbook/deployment/heroku.rst index 5525e7ffce5..44f33b46362 100644 --- a/cookbook/deployment/heroku.rst +++ b/cookbook/deployment/heroku.rst @@ -81,9 +81,9 @@ Creating a Procfile By default, Heroku will launch an Apache web server together with PHP to serve applications. However, two special circumstances apply to Symfony applications: -1. The document root is in the ``web/`` directory and not in the root directory +#. The document root is in the ``web/`` directory and not in the root directory of the application; -2. The Composer ``bin-dir``, where vendor binaries (and thus Heroku's own boot +#. The Composer ``bin-dir``, where vendor binaries (and thus Heroku's own boot scripts) are placed, is ``bin/`` , and not the default ``vendor/bin``. .. note:: diff --git a/cookbook/form/create_custom_field_type.rst b/cookbook/form/create_custom_field_type.rst index 3cb5f33c265..891a274f7a8 100644 --- a/cookbook/form/create_custom_field_type.rst +++ b/cookbook/form/create_custom_field_type.rst @@ -60,20 +60,23 @@ all of the logic and rendering of that field type. To see some of the logic, check out the `ChoiceType`_ class. There are three methods that are particularly important: -* ``buildForm()`` - Each field type has a ``buildForm`` method, which is where - you configure and build any field(s). Notice that this is the same method - you use to setup *your* forms, and it works the same here. - -* ``buildView()`` - This method is used to set any extra variables you'll - need when rendering your field in a template. For example, in `ChoiceType`_, - a ``multiple`` variable is set and used in the template to set (or not - set) the ``multiple`` attribute on the ``select`` field. See `Creating a Template for the Field`_ - for more details. - -* ``setDefaultOptions()`` - This defines options for your form type that - can be used in ``buildForm()`` and ``buildView()``. There are a lot of - options common to all fields (see :doc:`/reference/forms/types/form`), - but you can create any others that you need here. +``buildForm()`` + Each field type has a ``buildForm`` method, which is where + you configure and build any field(s). Notice that this is the same method + you use to setup *your* forms, and it works the same here. + +``buildView()`` + This method is used to set any extra variables you'll + need when rendering your field in a template. For example, in `ChoiceType`_, + a ``multiple`` variable is set and used in the template to set (or not + set) the ``multiple`` attribute on the ``select`` field. See `Creating a Template for the Field`_ + for more details. + +``setDefaultOptions()`` + This defines options for your form type that + can be used in ``buildForm()`` and ``buildView()``. There are a lot of + options common to all fields (see :doc:`/reference/forms/types/form`), + but you can create any others that you need here. .. tip:: diff --git a/cookbook/security/custom_authentication_provider.rst b/cookbook/security/custom_authentication_provider.rst index be18a236549..c2baec636d3 100644 --- a/cookbook/security/custom_authentication_provider.rst +++ b/cookbook/security/custom_authentication_provider.rst @@ -20,9 +20,9 @@ The following chapter demonstrates how to create a custom authentication provider for WSSE authentication. The security protocol for WSSE provides several security benefits: -1. Username / Password encryption -2. Safe guarding against replay attacks -3. No web server configuration required +#. Username / Password encryption +#. Safe guarding against replay attacks +#. No web server configuration required WSSE is very useful for the securing of web services, may they be SOAP or REST. @@ -333,18 +333,22 @@ create a class which implements The :class:`Symfony\\Bundle\\SecurityBundle\\DependencyInjection\\Security\\Factory\\SecurityFactoryInterface` requires the following methods: -* ``create`` method, which adds the listener and authentication provider - to the DI container for the appropriate security context; +``create`` + Method which adds the listener and authentication provider + to the DI container for the appropriate security context. -* ``getPosition`` method, which must be of type ``pre_auth``, ``form``, ``http``, - and ``remember_me`` and defines the position at which the provider is called; +``getPosition`` + Method which must be of type ``pre_auth``, ``form``, ``http``, + and ``remember_me`` and defines the position at which the provider is called. -* ``getKey`` method which defines the configuration key used to reference - the provider in the firewall configuration; +``getKey`` + Method which defines the configuration key used to reference + the provider in the firewall configuration. -* ``addConfiguration`` method, which is used to define the configuration - options underneath the configuration key in your security configuration. - Setting configuration options are explained later in this chapter. +``addConfiguration`` + Method which is used to define the configuration + options underneath the configuration key in your security configuration. + Setting configuration options are explained later in this chapter. .. note:: diff --git a/reference/configuration/doctrine.rst b/reference/configuration/doctrine.rst index b91aee5422f..2a04200b361 100644 --- a/reference/configuration/doctrine.rst +++ b/reference/configuration/doctrine.rst @@ -26,9 +26,6 @@ Full Default Configuration #schema_filter: ^sf2_ connections: - default: - dbname: database - # A collection of different named connections (e.g. default, conn2, etc) default: dbname: ~