Good Day! I want to login my users and it's a trivial task. But issue is checking user by array of values!
For example I have entity user and phone. User have many phones. So I need to login user by all of phones which it has. How can I do it using default tool of security bundle?
I didn't find any question like my one and read all documentation about security in Symfony. The only thing which I thought to do is creating custom provider. But I don't think it solves my problem.
Any ides, dear symfoners? :)
You have to set a security provider in security.yml
security:
# http://symfony.com/doc/current/book/security.html#where-do-users-come-from-user-providers
...
providers:
my_db_provider:
entity:
class: AppBundle:User
...
Then your entity AppBundle:User
should implements the interface Symfony\Component\Security\Core\User\UserInterface
and have a custom repository for Example UserRepository
that implements the interface Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface
.
Your UserRepository
class should look like this:
<?php
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use AppBundle\Entity\User;
use Symfony\Bridge\Doctrine\Security\User\UserLoaderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
class UserRepository extends EntityRepository implements UserLoaderInterface
{
/**
* Loads the user for the given username.
*
* This method must return null if the user is not found.
*
* @param string $username The username
* @return null|Utilisateur
* @throws \Exception
*/
public function loadUserByUsername($username)
{
//Here you write a custom query to retrive the user base on the fields you require.
// Here I have used username, email and phone number
$q = $this
->createQueryBuilder('u')
->select('u')
->leftJoin('u.phones', 'p')
->where('u.username = :username or u.email= :email or p.phoneNumber= :phone')
->setParameter('username', $username)
->setParameter('email', $username)
->setParameter('phone ', $username)
->getQuery();
try {
$user = $q->getSingleResult();
} catch (NoResultException $e) {
throw new UsernameNotFoundException(sprintf('Unable to find an active user AppBundle:User object identified by "%s".', $username), 0, $e);
} catch (NonUniqueResultException $ex) {
throw new \Exception("The user you provided is not unique");
}
return $user;
}
}
Your AppByndle:User
entity class should look like this:
<?php
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Security\Core\User\UserInterface;
/**
* User
*
* @ORM\Table(name="user")
* @ORM\Entity(repositoryClass="AppBundle\Dao\UserRepository")
*/
class User implements UserInterface
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer", nullable=false)
* @ORM\Id
* @ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* @var string
*
* @ORM\Column(name="username", type="string", length=254, nullable=false, unique=true)
*/
private $username;
....
....
}