I've loaded up the Doctrine MongoODM Module for zf2. I have got the document manager inside my controller, and all was going well until I tried to persist a document. It fails with this error:
"[Semantical Error] The annotation "#Document" in class SdsCore\Document\User was never imported."
It seems to fail on this line of DocParser.php
if ('\\' !== $name[0] && !$this->classExists($name)) {
It fails because $name = 'Document', and the imported annotation class is 'Doctrine\ODM\MongoDB\Mapping\Annotations\Doctrine'
Here is my document class:
namespace SdsCore\Document;
/** #Document */
class User
{
/**
* #Id(strategy="UUID")
*/
private $id;
/**
* #Field(type="string")
*/
private $name;
/**
* #Field(type="string")
*/
private $firstname;
public function get($property)
{
$method = 'get'.ucfirst($property);
if (method_exists($this, $method))
{
return $this->$method();
} else {
$propertyName = $property;
return $this->$propertyName;
}
}
public function set($property, $value)
{
$method = 'set'.ucfirst($property);
if (method_exists($this, $method))
{
$this->$method($value);
} else {
$propertyName = $property;
$this->$propertyName = $value;
}
}
}
Here is my action controller:
public function indexAction()
{
$dm = $this->documentManager;
$user = new User();
$user->set('name', 'testname');
$user->set('firstname', 'testfirstname');
$dm->persist($user);
$dm->flush;
return new ViewModel();
}
I didn't yet work on the DoctrineMongoODMModule, but I'll get to it next week. Anyway, you are still using the "old way" of loading annotations. Most of the doctrine projects are now using Doctrine\Common\Annotations\AnnotationReader, while your #AnnotationName tells me that you were using the Doctrine\Common\Annotations\SimpeAnnotationReader. You can read more about it at the Doctrine\Common documentation
So here's how to fix your document:
<?php
namespace SdsCore\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/** #ODM\Document */
class User
{
/**
* #ODM\Id(strategy="UUID")
*/
private $id;
/**
* #ODM\Field(type="string")
*/
private $name;
/**
* #ODM\Field(type="string")
*/
private $firstname;
/* etc */
}
Related
I'm currently working with Symfony and Doctrine and I'm having a little bit of trouble to reference two entity.
I have a entity called cinema and another one called theater. It's a relation of OneToMany, where one cinema can have many theater.
I create a cinema_id into theater so I can relate cinema and theater.
I have create a controller to consume data from an API and store the data into a Postgres database. Here is the controller:
TheaterController
namespace App\Controller;
use GuzzleHttp\Client;
use App\Entity\Cinema;
use App\Entity\Theater;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
class TheaterController extends AbstractController
{
/**
* #Route("/theater", name="theater")
*/
public function Theater(Request $request)
{
$client = new Client();
$res = $client->request('GET','api-content');
$arrayContent = json_decode($res->getBody());
foreach ($arrayContent as $value)
{
$entityManager = $this->getDoctrine()->getManager();
$theater_cinema_id = $entityManager->getReference(Cinema::Cinema, $id);
$theater->addId($theater_cinema_id);
$theater_booking_cinema = 'value';
$theater_booking_id = $value->id;
$theater = new theater();
$theater->setId($theater_cinema_id);
$theater->setBookingCinema($theater_booking_cinema);
$theater->setBookingId($theater_booking_id);
//echo $theater;
$entityManager->persist($theater);
$entityManager->flush();
}
}
}
My problem here is, how can I reference the id from cinema to the cinema_id from theater? What am I doing wrong?
The two entities are:
Cinema
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\CinemaRepository")
*/
class Cinema
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string", length=255)
*/
private $name;
/**
* #ORM\Column(type="integer")
*/
private $is_active;
/**
* #ORM\Column(type="datetime")
*/
private $created_at;
/**
* #ORM\Column(type="datetime")
*/
private $updated_at;
public function getId(): ?int
{
return $this->id;
}
public function getName(): ?string
{
return $this->name;
}
public function setName(string $name): self
{
$this->name = $name;
return $this;
}
public function getIsActive(): ?int
{
return $this->is_active;
}
public function setIsActive(int $is_active): self
{
$this->is_active = $is_active;
return $this;
}
public function getCreatedAt(): ?\DateTimeInterface
{
return $this->created_at;
}
public function setCreatedAt(\DateTimeInterface $created_at): self
{
$this->created_at = $created_at;
return $this;
}
public function getUpdatedAt(): ?\DateTimeInterface
{
return $this->updated_at;
}
public function setUpdatedAt(\DateTimeInterface $updated_at): self
{
$this->updated_at = $updated_at;
return $this;
}
}
Theater
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\TheaterRepository")
*/
class Theater
{
/**
* #ORM\Id()
* #ORM\GeneratedValue()
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Cinema")
* #ORM\JoinColumn(nullable=false)
*/
private $cinema;
/**
* #ORM\Column(type="string", length=255)
*/
private $booking_cinema;
/**
* #ORM\Column(type="integer")
*/
private $booking_id;
public function getId(): ?int
{
return $this->id;
}
public function getCinema(): ?cinema
{
return $this->cinema;
}
public function setCinema(?cinema $cinema): self
{
$this->cinema = $cinema;
return $this;
}
public function getBookingCinema(): ?string
{
return $this->booking_cinema;
}
public function setBookingCinema(string $booking_cinema): self
{
$this->booking_cinema = $booking_cinema;
return $this;
}
public function getBookingId(): ?int
{
return $this->booking_id;
}
public function setBookingId(int $booking_id): self
{
$this->booking_id = $booking_id;
return $this;
}
}
As I understood, you have many cinemas in one theater. So, you have add the following code to your Theater entity:
// ...
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
// ...
/**
* #var ArrayCollection $cinemas
* #ORM\OneToMany(targetEntity="App\Entity\Theater", mappedBy="theater")
*/
public $cinemas;
// ...
/**
* Theater constructor.
*/
public function __construct()
{
$this->cinemas = new ArrayCollection();
}
// ...
/**
* #return array
*/
public function getCinemas(): array
{
return $this->cinemas->toArray()
}
/**
* #return Theater
*/
public function addCinema(Cinema $cinema): self
{
$this->cinemas->add($cinema);
return $this;
}
// ...
And the following code to your Cinema entity:
// ...
use Doctrine\ORM\Mapping as ORM;
// ...
/**
* #ORM\ManyToOne(targetEntity="App\Entity\Theater", inversedBy="cinemas")
* #ORM\JoinColumn(name="theater_id", referencedColumnName="id", nullable=FALSE)
*/
private $theater;
// ...
Then you can access to your cinemas entities from Theater entity:
$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);
$cinemas = $theater->getCinemas(); // array
/** #var Cinema $cinema */
foreach($cinemas as $cinema) {
// ...
}
Or add new Cinema to your Theater:
$theaterRepository = $this->getDoctrine()->getManager()->getRepository(Theater::class);
$theater = $theaterRepository->findBy(['id' => 1]);
$cinema = new Cinema();
// ...
$theater->addCinema($cinema)
// Persist, flush, e.t.c
About the ArrayCollection you can read here
And you can access to your Theater entity from any Cinema entity:
$cinemaRepository = $this->getDoctrine()->getManager()->getRepository(Cinema::class);
$cinema = $cinemaRepository->findBy(['id' => 1]);
$theater = $cinema->getTheater(); // Theater object
Or add the Theater to your Cinema:
$cinema = new Cinema();
$theater = new Theater();
// ...
$cinema->setTheater($theater);
// ...
// Persist, flush, e.t.c
Doctrine is an ORM, which means you don't have to think about tables, but entities. You don't think about foreign keys, but relations between entities.
Your API is giving you the cinema ID, or you can access it another way? You can retrieve the cinema using this :
$cinema = $entityManager->getRepository('App:Cinema')->findOneById($cinema_id);
You want to tell what cinema the theater belongs to? Use this :
$theater->setCinema($cinema);
Doctrine will itself build and execute the queries to get the desired datas.
I'm writing a REST API client and I am trying to unit test the user creation process which let a user to upload an image.
I am using Symfony 2.7, Doctrine Extension Bundle (Uploadable extension) and FOS Rest Bundle
The unit tests are working well excepted when I try to upload a file, it triggers me the following error when I error_log the 500 HTTP Reponse :
The class 'Symfony\\Component\\HttpFoundation\\File\\UploadedFile' was not found in the chain configured namespaces
Please find the relevant code :
UsersControllerTest.php
<?php
namespace Acme\Bundle\UserBundle\Tests\Controller;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\HttpFoundation\File\MimeType\MimeTypeGuesser;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class UsersControllerTest extends WebTestCase
{
public function testAvatar(){
$client = static::createClient();
$shortImage = tempnam(sys_get_temp_dir(), 'upl');
imagepng(imagecreatetruecolor(10, 10), $shortImage);
$file = new UploadedFile(
$shortImage,
basename($shortImage),
MimeTypeGuesser::getInstance()->guess($shortImage),
filesize($shortImage)
);
$crawler = $client->request(
"POST",
"/api/users",
array(
"user_registration" => array(
"firstName" => "test",
"lastName" => "test"
),
),
array(
'user_registration'=>array('avatar'=>$file)
),
array(
'Content-Type' => 'multipart/formdata'
)
);
error_log($client->getResponse()); //Here I see the Uploadable class namespace error
$this->assertEquals(200, $client->getResponse()->getStatusCode());
}
}
UserRegistrationType.php
<?php
namespace Acme\Bundle\UserBundle\Form\Type;
use Acme\Bundle\UserBundle\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormBuilderInterface;
class UserRegistrationType extends AbstractType{
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\Bundle\UserBundle\Entity\User',
'cascade_validation' => true,
'csrf_protection' => false
));
}
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('firstName', 'text');
$builder->add('lastName', 'text');
$builder->add('avatar', 'file', array(
'required' => false
));
}
public function getParent()
{
return 'form';
}
public function getName()
{
return 'user_registration';
}
}
UsersController.php
<?php
namespace Acme\Bundle\UserBundle\Controller;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Controller\Annotations\View;
use Acme\Bundle\UserBundle\Entity\User;
use Acme\Bundle\UserBundle\Entity\Avatar;
use Acme\Bundle\UserBundle\Form\Type\UserRegistrationType;
use Symfony\Component\HttpFoundation\Request;
use FOS\RestBundle\Controller\Annotations\RouteResource;
use JMS\SecurityExtraBundle\Annotation as JMSSecurity;
class UsersController extends FOSRestController
{
/**
* #View(serializerGroups={"Registration"})
*/
public function postUsersAction(Request $request){
$user = new User();
$form = $this->createForm(new UserRegistrationType(), $user);
$form->submit($request);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($user);
if(null !== $user->getAvatar()){
$uploadableManager = $this->get('stof_doctrine_extensions.uploadable.manager');
$uploadableManager->markEntityToUpload($user, $user->getAvatar());
}
$em->flush();
return $user;
}
else {
$validator = $this->get('validator');
$errors = $validator->validate($user, array('Default','Registration'));
$view = $this->view($errors, 400);
return $this->handleView($view);
}
}
}
Avatar.php
<?php
namespace Acme\Bundle\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Gedmo\Mapping\Annotation as Gedmo;
/**
* Avatar
*
* #ORM\Table("avatar")
* #ORM\Entity
* #Gedmo\Uploadable(pathMethod="getPath", callback="postUploadAction", filenameGenerator="SHA1", allowOverwrite=true, appendNumber=true)
*/
class Avatar
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\Column(name="path", type="string")
* #Gedmo\UploadableFilePath
*/
private $path;
/**
* #ORM\Column(name="name", type="string")
* #Gedmo\UploadableFileName
*/
private $name;
/**
* #ORM\Column(name="mime_type", type="string")
* #Gedmo\UploadableFileMimeType
*/
private $mimeType;
/**
* #ORM\Column(name="size", type="decimal")
* #Gedmo\UploadableFileSize
*/
private $size;
public function postUploadAction(array $info)
{
// Do some stuff with the file..
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
public function getPath(){
return __DIR__.'../../web/avatars/';
}
/**
* Set path
*
* #param string $path
* #return Image
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Set mimeType
*
* #param string $mimeType
* #return Image
*/
public function setMimeType($mimeType)
{
$this->mimeType = $mimeType;
return $this;
}
/**
* Get mimeType
*
* #return string
*/
public function getMimeType()
{
return $this->mimeType;
}
/**
* Set size
*
* #param string $size
* #return Image
*/
public function setSize($size)
{
$this->size = $size;
return $this;
}
/**
* Get size
*
* #return string
*/
public function getSize()
{
return $this->size;
}
}
User.php
class User{
...
/**
* Avatar
*
* #ORM\OneToOne(targetEntity="Acme\Bundle\UserBundle\Entity\Avatar", cascade={"all"})
* #ORM\JoinColumn(nullable=true)
* #Assert\Valid
*/
private $avatar;
public function getAvatar(){
return $this->avatar;
}
public function setAvatar($avatar = null){
$this->avatar = $avatar;
return $this;
}
}
Error stack (JSON)
For full stack please see here : http://pastebin.com/sgPE4Uh1
{
"error":{
"code":500,
"message":"Internal Server Error",
"exception":[
{
"message":"The class 'Symfony\\Component\\HttpFoundation\\File\\UploadedFile' was not found in the chain configured namespaces Acme\\Bundle\\UserBundle\\Entity",
"class":"Doctrine\\Common\\Persistence\\Mapping\\MappingException",
"trace":[
{
"namespace":"",
"short_class":"",
"class":"",
"type":"",
"function":"",
"file":"D:\\xampp\\htdocs\\RestApi\\vendor\\doctrine\\common\\lib\\Doctrine\\Common\\Persistence\\Mapping\\MappingException.php",
"line":37,
"args":[
]
}]
}
}
}
I really don't know the origin of the error, On my config.yml the doctrine mapping is set to auto
Thank you in advance for any help
EDIT 1
I have completely refactored the code with this scenario :
The upload request is now independant, it has it own isolated request with a Content-Type set to multipart/form-data
This time it would not have any problem, but..the same error is still here :
{
code: 500
message: "The class 'Symfony\Component\HttpFoundation\File\UploadedFile' was not found in the chain configured namespaces Sowq\Bundle\UserBundle\Entity"
}
I am wondering if that's not a bug or a compatibility issue between Symfony 2.7 and the doctrine Uploadable extension, any idea?
I think the problem is that you or (uploadableManager extension - I don't know this) try set an object file (of type "UploadedFile Class")
$Avatar is a file object if you want save to DataBase, you need a datatype blob.
Usually, before save the file on File System and then save $Avatar on DB, where $Avatar is just file path or file name o link to File System resource
see https://github.com/Atlantic18/DoctrineExtensions/issues/1353
I'm trying to play with MongoDB. But I've got some problems.
# src/Controller/DefaultController.php
public function editCategoryAction(Category $category) {
echo $category->getName();
die();
}
With "entity" this is ok but not with MongoDB.
It displays this error message :
Controller "Site\StoreBundle\Controller\DefaultController::editCategoryAction()" requires that you provide a value for the "$category" argument (because there is no default value or because there is a non optional argument after this one).
My Category Document :
namespace Site\StoreBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document
*/
class Category
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $name;
/**
* #MongoDB\ReferenceMany(targetDocument="Product")
*/
private $products = array();
public function __contructor() {
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Get id
*
* #return id $id
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return self
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string $name
*/
public function getName()
{
return $this->name;
}
public function getProducts() {
return $this->products;
}
public function __construct()
{
$this->products = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add product
*
* #param Site\StoreBundle\Document\Product $product
*/
public function addProduct(\Site\StoreBundle\Document\Product $product)
{
$this->products[] = $product;
}
/**
* Remove product
*
* #param Site\StoreBundle\Document\Product $product
*/
public function removeProduct(\Site\StoreBundle\Document\Product $product)
{
$this->products->removeElement($product);
}
}
My Route
editCategory:
path: /editCategory/{id}
defaults: { _controller: SiteStoreBundle:Default:editCategory }
How can I solve this ?
Edit:
I found this article : http://php-and-symfony.matthiasnoback.nl/2012/10/symfony2-mongodb-odm-adding-the-missing-paramconverter/
I changed my src/Site/StoreBundle/Resources/config/services.yml to this :
parameters:
# site_store.example.class: Site\StoreBundle\Example
services:
doctrine_mongo_db_param_converter:
class: Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter
arguments: ['#doctrine_mongodb']
But same error :/
I think you missed to tag your service:
services:
doctrine_mongo_db_param_converter:
class: Sensio\Bundle\FrameworkExtraBundle\Request\ParamConverter\DoctrineParamConverter
arguments: ['#doctrine_mongodb']
tags:
- { name: request.param_converter, priority: -2, converter: doctrine_mongo_db_param_converter}
he guys,
i want to make a simple reference on mongodb documents using symfony2.
i have this two documents and want to store picture references into the requests document. it works for me, if i have only the picture ids in the requests document.
so i need the follow:
can everyone change the document files and make and extends the custum call to get all pictures as object from the requests (picture array)?
my original files:
Document Pictures:
<?php
namespace TestBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(repositoryClass="TestBundle\Repository\RequestsRepository")
*/
class Requests
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $title;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setTitle($title)
{
$this->title = $title;
}
public function getTitle()
{
return $this->title;
}
}
Document Pictures:
<?php
namespace TestBundle\Document;
use Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB;
/**
* #MongoDB\Document(repositoryClass="TestBundle\Repository\PicturesRepository")
*/
class Pictures
{
/**
* #MongoDB\Id
*/
protected $id;
/**
* #MongoDB\String
*/
protected $filename;
public function setId($id)
{
$this->id = $id;
}
public function getId()
{
return $this->id;
}
public function setFilename($filename)
{
$this->filename = $filename;
}
public function getTitle()
{
return $this->filename;
}
}
My Basic Calls:
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm->getRepository('TestBundle:Requests')->find($requestId);
To my tests:
i added in the requests document the follow:
/**
* #MongoDB\ReferenceMany(targetDocument="Pictures",cascade={"persist"},simple="true")
*/
protected $pictures = array();
public function setPictures($pictures)
{
$this->pictures[] = $pictures;
}
public function getPictures()
{
return $this->pictures;
}
and added pictures like this:
$dm = $this->get('doctrine.odm.mongodb.document_manager');
$photo = $dm->getRepository('TestBundle:Pictures')->find($photoId);
$dm1 = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm1->getRepository('TestBundle:Requests')->find($requestId);
$request->setPictures($photo);
$dm1->flush();
this works - but i cannot get the pictures by loading the document.
my code to load:
$dm1 = $this->get('doctrine.odm.mongodb.document_manager');
$request = $dm1->getRepository('TestBundle:Requests')->find($requestId);
$pictures = $request->getPictures();
foreach($pictures as $picture)
{
print $picture->getId();
}
THIS WILL NOT WORK. i become the follow error:
Fatal error: Doctrine\ODM\MongoDB\Proxy\ProxyFactory::getProxy():
Failed opening required
'.../app/cache/dev/doctrine/odm/mongodb/Proxies/_CG_TestBundleDocumentPictures.php'
(include_path='.:.../library:/usr/local/zend/share/pear') in
..../test/vendor/doctrine-mongodb-odm/lib/Doctrine/ODM/MongoDB/Proxy/ProxyFactory.php
on line 100
thanks, jan
First off you only need to call doctrine one time in $dm your overloading your resources and thats bad practice. One function, one Doctrine call. Secondly, you need a $dm->persist($request) and then $dm->flush(). Create a OnetoOne between your Documents and then make $pictures an Doctrine Array Collection. Then set a picture like you tried, then make a smiple query and call $request->getPicture()->getId().
Ok i found the error:
In the deps file i have the following lines:
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.1.4
[doctrine-dbal]
git=http://github.com/doctrine/dbal.git
version=2.1.7
[doctrine]
git=http://github.com/doctrine/doctrine2.git
version=2.1.7
After updating them to:
[doctrine-common]
git=http://github.com/doctrine/common.git
version=2.2.1
[doctrine-dbal]
git=http://github.com/doctrine/dbal.git
version=2.2.1
[doctrine]
git=http://github.com/doctrine/doctrine2.git
version=2.2.1
And doing php bin/vendors update the references will work again
With currented build of Symfony 2.1 it should be possible to use MongoDB as Userprovider for the SecurityBundle without using FOSUserBundle (as introduced here: mongodb symfony user authentication?).
Can't figure out, where is actually the problem in the code, but I can't login with the predefined user test:test.
My security.yml looks like this:
security:
encoders:
test\TestBundle\Document\User: plaintext
providers:
document_members:
mongodb: { class: testTestBundle:User, property: username }
firewalls:
secured_area:
pattern: ^/
http_basic:
realm: "Login to TEST"
access_control:
- { path: ^/admin, roles: ROLE_ADMIN }
role_hierarchy:
ROLE_ADMIN: ROLE_USER
The test/TestBundle/Document/User.php-Document:
namespace test\TestBundle\Document;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\EquatableInterface;
use Doctrine\ODM\MongoDB\Mapping\Annotations as ODM;
/**
* #ODM\Document(collection="user", repositoryClass="test\TestBundle\Document\UserRepository")
*/
class User implements UserInterface, EquatableInterface
{
/**
* #ODM\Id
*/
protected $id;
/**
* #ODM\String
*/
protected $username;
/**
* #ODM\String
*/
protected $password;
/**
* #ODM\Collection
*/
protected $roles = array();
/**
* #ODM\String
*/
protected $salt;
/**
* #ODM\Boolean
*/
protected $isActive;
// Setter
/**
* #param String
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* #param String
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* #param String
*/
public function setRole($role)
{
$this->roles[] = $role;
}
/**
* #param array
*/
public function setRoles(array $roles)
{
$this->roles = (array) $roles;
}
/**
* #param String
*/
public function setSalt($salt)
{
$this->salt = $salt;
}
// Getter
/**
* #return String
*/
public function getUsername()
{
return $this->username;
}
/**
* #return String
*/
public function getPassword()
{
return $this->password;
}
/**
* #return array
*/
public function getRoles()
{
return $this->roles;
}
/**
* #return String
*/
public function getSalt()
{
return $this->salt;
}
// General
public function __construct()
{
$this->isActive = true;
$this->salt = '';
}
public function isEqualTo(UserInterface $user)
{
return $user->getUsername() === $this->username;
}
public function eraseCredentials()
{
}
}
the test/TestBundle/Document/UserRepository.php:
namespace test\TestBundle\Document;
use Doctrine\ODM\MongoDB\DocumentRepository;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Security\Core\Exception\UsernameNotFoundException;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
class UserRepository extends DocumentRepository implements UserProviderInterface
{
public function loadUserByUsername($username)
{
$q = $this->createQueryBuilder()
->field('username')->equals((string) $username)
->getQuery();
try
{
$user = $q->getSingleResult();
}
catch (NoResultException $e)
{
throw new UsernameNotFoundException(sprintf('Can\'t find Username "%s"', $username), null, 0, $e);
}
return $user;
}
public function refreshUser(UserInterface $user)
{
$class = get_class($user);
if (!$this->supportsClass($class)) {
throw new UnsupportedUserException(sprintf('Instances of "%s" are not supported.', $class));
}
return $this->loadUserByUsername($user->getUsername());
}
public function supportsClass($class)
{
return $class === 'test\TestBundle\Document\User';
}
}
The specific route:
Admin:
pattern: /admin
defaults: { _controller: testTestBundle:Test:index }
(will lead to an existing controller and view)
the predefined user-Document looks like this:
Array
(
[_id] => 4f59b5731c911ab41e001234
[username] => test
[password] => test
[roles] => Array
(
[0] => ROLE_ADMIN
)
[salt] =>
[isActive] => 1
)
But I can't login with the username test and password test at /admin.
problem is related to an issue with using symfony on apache + fastCGI (https://github.com/symfony/symfony/pull/3551).
Above code works as expected.