Skip to content

cleaning #2753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions book/doctrine.rst
Original file line number Diff line number Diff line change
Expand Up @@ -363,6 +363,8 @@ see the :ref:`book-doctrine-field-types` section.
class Product
// ...

.. _book-doctrine-generating-getters-and-setters:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there should be an empty line after this one


Generating Getters and Setters
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -425,6 +427,8 @@ mapping information) of a bundle or an entire namespace:
The getters and setters are generated here only because you'll need them
to interact with your PHP object.

.. _book-doctrine-creating-the-database-tables-schema:

Creating the Database Tables/Schema
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand Down
6 changes: 3 additions & 3 deletions components/console/helpers/tablehelper.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ You can also control table rendering by setting custom rendering option values:
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPaddingChar`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setHorizontalBorderChar`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVerticalBorderChar`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVrossingChar`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellHeaderFormat`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setVellRowFormat`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCrossingChar`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellHeaderFormat`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setCellRowFormat`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setBorderFormat`
* :method:`Symfony\\Component\\Console\\Helper\\TableHelper::setPadType`
2 changes: 1 addition & 1 deletion components/intl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ expose them manually by adding the following lines to your autoload code::
but usually Composer does this for you automatically:

* 1.0.*: when the intl extension is not available
* 1.1.*: when intl is compiled with ICU 4.0 or higher
* 1.1.*: when intl is compiled with ICU 3.8 or higher
* 1.2.*: when intl is compiled with ICU 4.4 or higher

These versions are important when you deploy your application to a **server with
Expand Down
14 changes: 13 additions & 1 deletion contributing/community/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,18 +75,30 @@ Below is the schedule for the first few versions that use this release model:

This results in very predictable dates and maintenance periods:


+---------+---------+---------------------+-------------+
| Version | Release | End of Maintenance | End of Life |
| ------- | ------- | ------------------- | ----------- |
+=========+=========+=====================+=============+
| 2.0 | 07/2011 | 03/2013 (20 months) | 09/2013 |
+---------+---------+---------------------+-------------+
| 2.1 | 09/2012 | 05/2013 (9 months) | 11/2013 |
+---------+---------+---------------------+-------------+
| 2.2 | 03/2013 | 11/2013 (8 months) | 05/2014 |
+---------+---------+---------------------+-------------+
| **2.3** | 05/2013 | 05/2016 (36 months) | 05/2017 |
+---------+---------+---------------------+-------------+
| 2.4 | 11/2013 | 07/2014 (8 months) | 01/2015 |
+---------+---------+---------------------+-------------+
| 2.5 | 05/2014 | 01/2015 (8 months) | 07/2016 |
+---------+---------+---------------------+-------------+
| 2.6 | 11/2014 | 07/2015 (8 months) | 01/2016 |
+---------+---------+---------------------+-------------+
| **2.7** | 05/2015 | 05/2018 (36 months) | 05/2019 |
+---------+---------+---------------------+-------------+
| 2.8 | 11/2015 | 07/2016 (8 months) | 01/2017 |
+---------+---------+---------------------+-------------+
| ... | ... | ... | ... |
+---------+---------+---------------------+-------------+

.. tip::

Expand Down
172 changes: 87 additions & 85 deletions cookbook/security/entity_provider.rst
Original file line number Diff line number Diff line change
Expand Up @@ -167,21 +167,6 @@ interface forces the class to implement the five following methods:

For more details on each of these, see :class:`Symfony\\Component\\Security\\Core\\User\\UserInterface`.

.. code-block:: php

// src/Acme/UserBundle/Entity/User.php

namespace Acme\UserBundle\Entity;

use Symfony\Component\Security\Core\User\EquatableInterface;

// ...

public function isEqualTo(UserInterface $user)
{
return $this->id === $user->getId();
}

.. note::

The :phpclass:`Serializable` interface and its ``serialize`` and ``unserialize``
Expand All @@ -191,24 +176,32 @@ For more details on each of these, see :class:`Symfony\\Component\\Security\\Cor
because the :method:`Symfony\\Bridge\\Doctrine\\Security\\User\\EntityUserProvider::refreshUser`
method reloads the user on each request by using the ``id``.

Below is an export of my ``User`` table from MySQL. For details on how to
create user records and encode their password, see :ref:`book-security-encoding-user-password`.
.. tip::

To generate missing setters and getters for your ``User`` entity, you
can use ``php app/console doctrine:generate:entities Acme/UserBundle/Entity/User``.
For more details, see Doctrine's :ref:`book-doctrine-generating-getters-and-setters`.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK, this code is stil relevant. But an explanation/introduction should be placed before this snippet

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

totally agree. i personally dont know what is this code good for and it was not needed to make functionality covered by this tutorial to work, so from my perspective it is useless, unless ofc the explanation will be added. i would suggest remove the code for now, and once someone decide to add explanation, the code can be attached again.


Below is an export of my ``User`` table from MySQL with user `admin`
and password `admin`. For details on how to create user records and
encode their password, see :ref:`book-security-encoding-user-password`.

.. code-block:: bash

$ mysql> select * from user;
+----+----------+----------------------------------+------------------------------------------+--------------------+-----------+
| id | username | salt | password | email | is_active |
+----+----------+----------------------------------+------------------------------------------+--------------------+-----------+
| 1 | hhamon | 7308e59b97f6957fb42d66f894793079 | 09610f61637408828a35d7debee5b38a8350eebe | hhamon@example.com | 1 |
| 2 | jsmith | ce617a6cca9126bf4036ca0c02e82dee | 8390105917f3a3d533815250ed7c64b4594d7ebf | jsmith@example.com | 1 |
| 3 | maxime | cd01749bb995dc658fa56ed45458d807 | 9764731e5f7fb944de5fd8efad4949b995b72a3c | maxime@example.com | 0 |
| 4 | donald | 6683c2bfd90c0426088402930cadd0f8 | 5c3bcec385f59edcc04490d1db95fdb8673bf612 | donald@example.com | 1 |
+----+----------+----------------------------------+------------------------------------------+--------------------+-----------+
4 rows in set (0.00 sec)

The database now contains four users with different usernames, emails and
statuses. The next part will focus on how to authenticate one of these users
$ mysql> select * from acme_users;
+----+----------+------+------------------------------------------+--------------------+-----------+
| id | username | salt | password | email | is_active |
+----+----------+------+------------------------------------------+--------------------+-----------+
| 1 | admin | | d033e22ae348aeb5660fc2140aec35850c4da997 | admin@example.com | 1 |
+----+----------+------+------------------------------------------+--------------------+-----------+

.. tip::

To generate database table from your ``User`` entity, you can run
``php app/console doctrine:schema:update --force``.
For mor details, see Doctrine's :ref:`book-doctrine-creating-the-database-tables-schema`.

The next part will focus on how to authenticate one of these users
thanks to the Doctrine entity user provider and a couple of lines of
configuration.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why did you remove the rows?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because the data are irrelevant. as mentioned here #2756 there is no explanation how they were created, what are the raw passwords = not usable for testing.

Expand Down Expand Up @@ -323,9 +316,8 @@ entity user provider to load User entity objects from the database by using
the ``username`` unique field. In other words, this tells Symfony how to
fetch the user from the database before checking the password validity.

This code and configuration works but it's not enough to secure the application
for **active** users. As of now, you can still authenticate with ``maxime``. The
next section explains how to forbid non active users.
This code is not enough to secure the application for **active** users.
The next section explains how to forbid non active users.

Forbid non Active Users
-----------------------
Expand Down Expand Up @@ -355,10 +347,10 @@ For this example, the first three methods will return ``true`` whereas the
// src/Acme/UserBundle/Entity/User.php
namespace Acme\UserBundle\Entity;

// ...
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\AdvancedUserInterface;

class User implements AdvancedUserInterface
class User implements AdvancedUserInterface, \Serializable
{
// ...

Expand All @@ -383,10 +375,8 @@ For this example, the first three methods will return ``true`` whereas the
}
}

If you try to authenticate as ``maxime``, the access is now forbidden as this
user does not have an enabled account. The next session will focus on how
to write a custom entity provider to authenticate a user with his username
or his email address.
The next session will focus on how to write a custom entity provider
to authenticate a user with his username or his email address.

Authenticating Someone with a Custom Entity Provider
----------------------------------------------------
Expand Down Expand Up @@ -428,8 +418,7 @@ The code below shows the implementation of the
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
->getQuery()
;
->getQuery();

try {
// The Query::getSingleResult() method throws an exception
Expand Down Expand Up @@ -537,10 +526,11 @@ about in this section.
authenticated at all.

In this example, the ``AcmeUserBundle:User`` entity class defines a
many-to-many relationship with a ``AcmeUserBundle:Group`` entity class. A user
can be related to several groups and a group can be composed of one or
more users. As a group is also a role, the previous ``getRoles()`` method now
returns the list of related groups::
many-to-many relationship with a ``AcmeUserBundle:Role`` entity class.
A user can be related to several roles and a role can be composed of
one or more users. The previous ``getRoles()`` method now returns
the list of related roles.
Notice that methods ``__construcotor()`` and ``getRoles()`` had changed::

// src/Acme/UserBundle/Entity/User.php
namespace Acme\UserBundle\Entity;
Expand All @@ -550,63 +540,46 @@ returns the list of related groups::

class User implements AdvancedUserInterface, \Serializable
{
//...

/**
* @ORM\ManyToMany(targetEntity="Group", inversedBy="users")
* @ORM\ManyToMany(targetEntity="Role", inversedBy="users")
*
*/
private $groups;
private $roles;

public function __construct()
{
$this->groups = new ArrayCollection();
$this->roles = new ArrayCollection();
}

// ...

public function getRoles()
{
return $this->groups->toArray();
}

/**
* @see \Serializable::serialize()
*/
public function serialize()
{
return serialize(array(
$this->id,
));
return $this->roles->toArray();
}

// ...

/**
* @see \Serializable::unserialize()
*/
public function unserialize($serialized)
{
list (
$this->id,
) = unserialize($serialized);
}
}

The ``AcmeUserBundle:Group`` entity class defines three table fields (``id``,
The ``AcmeUserBundle:Role`` entity class defines three table fields (``id``,
``name`` and ``role``). The unique ``role`` field contains the role name used by
the Symfony security layer to secure parts of the application. The most
important thing to notice is that the ``AcmeUserBundle:Group`` entity class
important thing to notice is that the ``AcmeUserBundle:Role`` entity class
extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::

// src/Acme/Bundle/UserBundle/Entity/Group.php
// src/Acme/Bundle/UserBundle/Entity/Role.php
namespace Acme\UserBundle\Entity;

use Symfony\Component\Security\Core\Role\Role;
use Symfony\Component\Security\Core\Role\RoleInterface;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;

/**
* @ORM\Table(name="acme_groups")
* @ORM\Table(name="acme_roles")
* @ORM\Entity()
*/
class Group extends Role
class Role implements RoleInterface
{
/**
* @ORM\Column(name="id", type="integer")
Expand All @@ -626,7 +599,7 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::
private $role;

/**
* @ORM\ManyToMany(targetEntity="User", mappedBy="groups")
* @ORM\ManyToMany(targetEntity="User", mappedBy="roles")
*/
private $users;

Expand All @@ -635,21 +608,27 @@ extends the :class:`Symfony\\Component\\Security\\Core\\Role\\Role`::
$this->users = new ArrayCollection();
}

// ... getters and setters for each property

/**
* @see RoleInterface
*/
public function getRole()
{
return $this->role;
}

// ... getters and setters for each property
}

To improve performances and avoid lazy loading of groups when retrieving a user
from the custom entity provider, the best solution is to join the groups
.. tip::

To generate missing setters and getters for your ``Role`` entity, you
can use ``php app/console doctrine:generate:entities Acme/UserBundle/Entity/User``.
For more details, see Doctrine's :ref:`book-doctrine-generating-getters-and-setters`.

To improve performances and avoid lazy loading of roles when retrieving a user
from the custom entity provider, the best solution is to join the roles
relationship in the ``UserRepository::loadUserByUsername()`` method. This will
fetch the user and his associated roles / groups with a single query::
fetch the user and his associated roles with a single query::

// src/Acme/UserBundle/Entity/UserRepository.php
namespace Acme\UserBundle\Entity;
Expand All @@ -662,8 +641,8 @@ fetch the user and his associated roles / groups with a single query::
{
$q = $this
->createQueryBuilder('u')
->select('u, g')
->leftJoin('u.groups', 'g')
->select('u, r')
->leftJoin('u.roles', 'r')
->where('u.username = :username OR u.email = :email')
->setParameter('username', $username)
->setParameter('email', $username)
Expand All @@ -675,6 +654,29 @@ fetch the user and his associated roles / groups with a single query::
// ...
}

The ``QueryBuilder::leftJoin()`` method joins and fetches related groups from
The ``QueryBuilder::leftJoin()`` method joins and fetches related roles from
the ``AcmeUserBundle:User`` model class when a user is retrieved with his email
address or username.

To re-generate all database tables, you can run ``php app/console doctrine:schema:update --force``.
This will also create additional table ``user_role`` what holds
relations between users and roles.
For mor details, see Doctrine's :ref:`book-doctrine-creating-the-database-tables-schema`.

Below is an export of my ``Roles`` and ``user_role`` tables from MySQL:

.. code-block:: bash

$ mysql> select * from acme_users;
+----+-------+------------+
| id | name | role |
+----+-------+------------+
| 1 | admin | ROLE_ADMIN |
+----+-------+------------+

mysql> select * from user_role;
+---------+---------+
| user_id | role_id |
+---------+---------+
| 1 | 1 |
+---------+---------+