Symfony Standard Edition Upgrade
================================

From Symfony 2.0 to Symfony 2.1
-------------------------------

### Project Dependencies

As of Symfony 2.1, project dependencies are managed by
[Composer](http://getcomposer.org/):

* The `bin/vendors` script can be removed as `composer.phar` does all the work
  now (it is recommended to install it globally on your machine).

* The `deps` file need to be replaced with the `composer.json` one.

* The `composer.lock` is the equivalent of the generated `deps.lock` file and
  it is automatically generated by Composer.

Download the default
[`composer.json`](https://raw.github.com/symfony/symfony-standard/2.1/composer.json)
and
[`composer.lock`](https://raw.github.com/symfony/symfony-standard/2.1/composer.lock)
files for Symfony 2.1 and put them into the main directory of your project. If
you have customized your `deps` file, move the added dependencies to the
`composer.json` file (many bundles and PHP libraries are already available as
Composer packages -- search for them on [Packagist](http://packagist.org/)).

Remove your current `vendor` directory.

Finally, run Composer:

    $ composer.phar install

Note: You must complete the upgrade steps below so composer can successfully generate the autoload files.

### `app/autoload.php`

The default `autoload.php` reads as follows (it has been simplified a lot as
autoloading for libraries and bundles declared in your `composer.json` file is
automatically managed by the Composer autoloader):

    <?php

    use Doctrine\Common\Annotations\AnnotationRegistry;

    $loader = include __DIR__.'/../vendor/autoload.php';

    // intl
    if (!function_exists('intl_get_error_code')) {
        require_once __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs/functions.php';

        $loader->add('', __DIR__.'/../vendor/symfony/symfony/src/Symfony/Component/Locale/Resources/stubs');
    }

    AnnotationRegistry::registerLoader(array($loader, 'loadClass'));

    return $loader;

### `app/config/config.yml`

The `framework.charset` setting must be removed. If you are not using `UTF-8`
for your application, override the `getCharset()` method in your `AppKernel`
class instead:

    class AppKernel extends Kernel
    {
        public function getCharset()
        {
            return 'ISO-8859-1';
        }

        // ...
    }

You might want to add the new `strict_requirements` parameter to
`framework.router` (it avoids fatal errors in the production environment when
a link cannot be generated):

    framework:
        router:
            strict_requirements: %kernel.debug%

You can even disable the requirements check on production with `null` as you should
know that the parameters for URL generation always pass the requirements, e.g. by
validating them beforehand. This additionally enhances performance. See
[config_prod.yml](https://github.com/symfony/symfony-standard/blob/master/app/config/config_prod.yml).

The `default_locale` parameter is now a setting of the main `framework`
configuration (it was under the `framework.session` in 2.0):

    framework:
        default_locale: %locale%

The `auto_start` setting under `framework.session` must be removed as it is
not used anymore (the session is now always started on-demand). If
`auto_start` was the only setting under the `framework.session` entry, don't
remove it entirely, but set its value to `~` (`~` means `null` in YAML)
instead:

    framework:
        session: ~

The `trust_proxy_headers` setting was added in the default configuration file
(as it should be set to `true` when you install your application behind a
reverse proxy):

    framework:
        trust_proxy_headers: false

An empty `bundles` entry was added to the `assetic` configuration:

    assetic:
        bundles: []

The default `swiftmailer` configuration now has the `spool` setting configured
to the `memory` type to defer email sending after the response is sent to the
user (recommended for better end-user performance):

    swiftmailer:
        spool: { type: memory }

The `jms_security_extra` configuration was moved to the `security.yml`
configuration file.

### `app/config/config_dev.yml`

An example of how to send all emails to a unique address was added:

    #swiftmailer:
    #    delivery_address: me@example.com

### `app/config/config_test.yml`

The `storage_id` setting must be changed to `session.storage.mock_file`:

    framework:
        session:
            storage_id: session.storage.mock_file

### `app/config/parameters.ini`

The file has been converted to a YAML file which reads as follows:

    parameters:
        database_driver:   pdo_mysql
        database_host:     localhost
        database_port:     ~
        database_name:     symfony
        database_user:     root
        database_password: ~

        mailer_transport:  smtp
        mailer_host:       localhost
        mailer_user:       ~
        mailer_password:   ~

        locale:            en
        secret:            ThisTokenIsNotSoSecretChangeIt

Note that if you convert your parameters file to YAML, you must also change
its reference in `app/config/config.yml`.

### `app/config/routing_dev.yml`

The `_assetic` entry was removed:

    #_assetic:
    #    resource: .
    #    type:     assetic

### `app/config/security.yml`

Under `security.access_control`, the default rule for internal routes was changed:

    security:
        access_control:
            #- { path: ^/_internal/secure, roles: IS_AUTHENTICATED_ANONYMOUSLY, ip: 127.0.0.1 }

Under `security.providers`, the `in_memory` example was updated to the following:

    security:
        providers:
                in_memory:
                    memory:
                        users:
                            user:  { password: userpass, roles: [ 'ROLE_USER' ] }
                            admin: { password: adminpass, roles: [ 'ROLE_ADMIN' ] }

### `app/AppKernel.php`

The following bundles have been added to the list of default registered bundles:

    new JMS\AopBundle\JMSAopBundle(),
    new JMS\DiExtraBundle\JMSDiExtraBundle($this),

You must also rename the DoctrineBundle from:

    new Symfony\Bundle\DoctrineBundle\DoctrineBundle(),

to:

    new Doctrine\Bundle\DoctrineBundle\DoctrineBundle(),

### `web/app.php`

The default `web/app.php` file now reads as follows:

    <?php

    use Symfony\Component\ClassLoader\ApcClassLoader;
    use Symfony\Component\HttpFoundation\Request;

    $loader = require_once __DIR__.'/../app/bootstrap.php.cache';

    // Use APC for autoloading to improve performance.
    // Change 'sf2' to a unique prefix in order to prevent cache key conflicts
    // with other applications also using APC.
    /*
    $loader = new ApcClassLoader('sf2', $loader);
    $loader->register(true);
    */

    require_once __DIR__.'/../app/AppKernel.php';
    //require_once __DIR__.'/../app/AppCache.php';

    $kernel = new AppKernel('prod', false);
    $kernel->loadClassCache();
    //$kernel = new AppCache($kernel);
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    $kernel->terminate($request, $response);

### `web/app_dev.php`

The default `web/app_dev.php` file now reads as follows:

    <?php

    use Symfony\Component\HttpFoundation\Request;

    // If you don't want to setup permissions the proper way, just uncomment the following PHP line
    // read http://symfony.com/doc/current/book/installation.html#configuration-and-setup for more information
    //umask(0000);

    // This check prevents access to debug front controllers that are deployed by accident to production servers.
    // Feel free to remove this, extend it, or make something more sophisticated.
    if (isset($_SERVER['HTTP_CLIENT_IP'])
        || isset($_SERVER['HTTP_X_FORWARDED_FOR'])
        || !in_array(@$_SERVER['REMOTE_ADDR'], array(
            '127.0.0.1',
            '::1',
        ))
    ) {
        header('HTTP/1.0 403 Forbidden');
        exit('You are not allowed to access this file. Check '.basename(__FILE__).' for more information.');
    }

    $loader = require_once __DIR__.'/../app/bootstrap.php.cache';
    require_once __DIR__.'/../app/AppKernel.php';

    $kernel = new AppKernel('dev', true);
    $kernel->loadClassCache();
    $request = Request::createFromGlobals();
    $response = $kernel->handle($request);
    $response->send();
    $kernel->terminate($request, $response);
