inform symfony of where repository classes are located - symfony

I see in the creating your own entity provider section that you put the UserRepository class in the Entity directory. Can you stray from this code organization? For example if i wanted a structure like this:
MyCompany
MyProject
MyBundle
Controller
DependencyInjection
Entity
Repositories
doctrine
UserRespository.php
Resources
doc
public
translations
views
Can you inform symfony about where to locate the UserRepository?

This would do:
/**
* #ORM\Entity(repositoryClass="MyCompany\MyBundle\Repositories\doctrine\UserRepository")
*/
class User
{
}

In reading your doc :
/**
* Acme\UserBundle\Entity\User
*
* #ORM\Table(name="acme_users")
* #ORM\Entity(repositoryClass="Acme\Entity\UserRepository")
*/
class User implements UserInterface, \Serializable
{
So just replace the path by the path you want :
* #ORM\Entity(repositoryClass="MyCompany\MyBundle\Repositories\doctrine\UserRepository")

Related

how and where to execute custom queries in symfony 4

I am using an entity class which extends ServiceEntityRepository like this:
class Sms extends ServiceEntityRepository
{
public function __construct(ManagerRegistry $registry)
{
parent::__construct($registry, Sms::class);
}
...
}
so when I need to persist an instance of the entity class in my controller file I need to pass the ManagerRegistry as the argument for my Entity class but I couldn't find a way to access the ManagerRegistry in my controller.
can anyone help?
The problem was that ServiceEntityRepository should be extended in a repository class, not an entity class.
as it is mentioned here, there is no good description for auto-generating repositories from an existing database.
This is my entity class with its annotations:
/**
* Sms
*
* #ORM\Table(name="sms")
* #ORM\Entity(repositoryClass="App\Repository\SMSRepository")
*/
class Sms
{ ... }
this line is very important:
#ORM\Entity(repositoryClass="App\Repository\SMSRepository")
another important thing is to removing Entity from excluding in the services.YAML file.
if you set a name for the repository of your entity class by annotation, by running this command you will have your repository generated:
php bin\console make:entity --regenerate
and you can simply write you complex queries in the repository file which is generated by the aforementioned command.
for calling methods of your repository class you can use this in your controller files:
$this->getDoctrine()->getRepository(EntityFile::class)->youFunctionNameInRepositoryFile()
be careful about the argument of the getRepository which is the Entity file, not the repository file.

FOS UserBundle how to create own User Repository

i stack to create my own FOS UserBundle UserRepository.
I guess its not correct extended?
app/Resources/FOSUserBundle/Repository/UserRepository.php:
<?php
namespace FOS\UserBundle\Repository;
/**
* UserRepository
*/
class UserRepository extends \Doctrine\ORM\EntityRepository
{
// some function
}
Thanks for help.
Mike
A repository class is optional so FOS does not define a repository. They only have the UserManager that calls the repository for the entity from Doctrine.
You have to change the repository on your entity:
#ORM\Entity(repositoryClass="AppBundle\UserBundle\Entity\UserRepository")
This should do the trick.

How to get the instance of the Entity Manager in FOSUserBundle Controller

I am using FOSUserBundle in Symfony 2.3, I created an additional table for store the user profile, at some point, I need to access to the entity manager to persist and flush the data coming from the profile form to the profile table, but I am having problems trying to get an instance of the entity manager.
Any idea?
Thanks!
To edit profiles of users using the FOSUserBundle, you have to create a new ProfileController which extends the ProfileController of FOSUserBundle.
Here you can now override methods of the FOSUserBundle.
An exemple of start :
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Acme\UserBundle\Controller;
use FOS\UserBundle\Model\UserInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use FOS\UserBundle\Controller\ProfileController as BaseController;
/**
* Controller managing the user profile
*
* #author Christophe Coevoet <stof#notk.org>
*/
class ProfileController extends BaseController
{
public function editAction()
{
$em = $this->container->get('doctrine')->getManager();
// your code here
}
}
You can access to the Doctrine service this way :
$em = $this->container->get('doctrine')->getManager();
The controllers of the FOSUserBundle extend from Symfony\Component\DependencyInjection\ContainerAware. So you have access to the Symfony\Component\DependencyInjection\ContainerInterface through $this->container. With this container you can access doctrine and subequently the EntityManager:
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();

FOSRestBundle's serializer throws recursion error using inherited entities

I’m developing an application that inherits abstract classes. These abstract classes have their own mapping for the serializer as shown in the example bellow
Hezten\CoreBundle\Model\Enroled:
exclusion_policy: ALL
And the abstract class:
<?php
namespace Hezten\CoreBundle\Model;
abstract class Enroled implements EnroledInterface
{
protected $student;
protected $subject;
//Some functions...
}
The class that inherits the previous class looks as follows
<?php
namespace XXX\XXXBundle\Entity;
use JMS\Serializer\Annotation\SerializedName;
use JMS\Serializer\Annotation\ExclusionPolicy;
use JMS\Serializer\Annotation\Exclude;
use Doctrine\ORM\Mapping as ORM;
use Hezten\CoreBundle\Model\Enroled as BaseEnroled;
/**
* #ORM\Entity
* #ExclusionPolicy("NONE")
*/
class Enroled extends BaseEnroled
{
/** #ORM\Id
* #ORM\ManyToOne(targetEntity="XXX\XXXBundle\Entity\Student", inversedBy="enroled")
* #Exclude
*/
protected $student;
/** #ORM\Id
* #ORM\ManyToOne(targetEntity="XXX\XXXBundle\Entity\Subject", inversedBy="enroled")
* #Exclude
*/
protected $subject;
/** #ORM\Column(type="boolean") */
private $field0;
/** #ORM\Column(type="boolean")
*/
private $field1;
/** #ORM\Column(type="boolean") */
private $field2;
}
The error thrown says this:
Warning: json_encode() [<a href='function.json-encode'>function.json-encode</a>]: recursion detected in C:\xampp\htdocs\Project\vendor\jms\serializer\src\JMS\Serializer\JsonSerializationVisitor.php line 29
For sure, I'm doing something wrong as no entities are exposed, just three fields of "Enroled" entity according to the mappings but I have no clue. I spent a couple of days trying to figure out what's the mistake without success.
What is the proper way to do the mapping of inhertied properties?
Update
Code used to serialize JSON using FOSRestBundle:
$students = $this->get('hezten_core.manager.enroled')->findEnroledBySubject($subject);
$view = View::create()
->setStatusCode(200)
->setFormat('json')
->setData($students);
return $this->get('fos_rest.view_handler')->handle($view);
Finally the API is working... I had to override the metadata of the classes I was inheriting adding the following lines to the config.yml
jms_serializer:
metadata:
directories:
HeztenCoreBundle:
namespace_prefix: "Hezten\\CoreBundle"
path: "%kernel.root_dir%/serializer/HeztenCoreBundle"
In the path that is selected above I added one yml file for each Model setting exclusion policy to ALL:
Hezten\CoreBundle\Model\Enroled:
exclusion_policy: ALL
And I used annotations on the entities that were inheriting those models to expose required info.
I don't know if this is the best approach but works well for me

Symfony2 - FOSUserBundle - FindUserBy<field_in_custom_UserBundle>

I´ve created my own user Bundle, extending FOSUserBundle.
In my UserBundle, I have a memberID field, with its setters and getters.
I can already find users by memberID using EntityManager, and then I could find the user through UserManager matching the username/email/... obtained with that EntityManager query, but...
Is there a way to findUserByMemberID using UserManager?
Thank you.
Thank you for your replies. It seems it´s easier than all this stuff.
OwnUserBundle:
/**
* #ORM\Column(type="string")
*
*/
protected $memberID;
public function getMemberID()
{
return $this->memberID;
}
public function setMemberID($memberID)
{
$this->memberID = $memberID;
}
You can query FOSUserBundle:
$userManager = $this->get('fos_user.user_manager');
$user = $userManager->findUserBy(array('memberID' => '123'));
Then, using method findUserBy(array(*OwnUserBundle_field* => *search_parameter_value*)) you´ll get the user/s instance.
Every query that is "not standard" one has to be written into a repository class
You have also to relate this class with one that represent you data model.
Suppose that your entity is called User, you have to do something like this
/**
* VendorName\UserBundle\Entity\User
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="VendorName\UserBundle\Repository\UserRepository")
*/
class User implements AdvancedUserInterface
{
[...]
This says that every "custom" query for that entity will be fit into that repository class.
Now you have to create the repository
class UserRepository extends EntityRepository implements UserProviderInterface
{
public function findUserByMemberID($id)
{
/* your logic here */
}
[...]
and you can use that in the following way
$userRepo = $this->em->getRepository('VendorUserBundle:User');
$userRepo->findUserByMemberID();
You could extend the UserManager from the FOSUserBundle in your bundle and write your own method. And you could follow these instructions http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes

Resources