How to create custom repository in symfony2 - symfony

User Entity :
namespace Core\UserBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* User
* #ORM\Entity(repositoryClass="Core\UserBundle\Entity\UserRepository")
* #ORM\Table(name="user")
*/
class User
{
}
User Repository :
<?php
# src/Core/UserBundle/Entity/UserRepository.php
namespace Core\UserBundle\Entity;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function example()
{
return "hello word";
}
}
Controller :
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('CoreUserBundle:User');
$repo->example();
Note : get_class($repo) => Doctrine\ORM\EntityRepository
The error:
Error Message : Undefined method 'example'. The method name must start with either findBy or findOneBy!

Try with this
$repo = $em->getRepository('UserBundle:User');

Related

Symfony 3 - can't use custom Repository

I try to create default repository in my Symfony 3. First I created Repository class with method 'findByParentOrderedByName'. In next step I added in Entity line:
* #ORM\Entity(repositoryClass="AppBundle\Repository\ChildRepository")
Unfortunelly when I try to run findByParentOrderedByName() I get error
Undefined method 'findAllOrderedByName'. The method name must start with either findBy, findOneBy or countBy!
What I make incorrect?
Repository code:
<?php
namespace AppBundle\Entity;
/**
* Child
* #ORM\Entity(repositoryClass="AppBundle\Repository\ChildRepository")
*/
class Child
{
........
}
To use custom repository class properly, firstly repository class name must be defined in entity class.
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="AppBundle\Repository\ChildRepository")
*/
class Child
{
}
Then repository class created as like this:
namespace AppBundle\Repository;
use Doctrine\ORM\EntityRepository;
class ChildRepository extends EntityRepository
{
/**
* #return Child[]
*/
public function findAllOrderedByName()
{
return $this->getEntityManager()
->createQuery('SELECT * c FROM AppBundle:Child c ORDERED BY c.name ASC')
->getResult();
}
}

How can I decorate repository class in Symfony 3.4?

I have a task to cache doctrine result with custom keys using redis. Here is repository class:
<?php
namespace AppBundle\Repository;
class JobRepository extends EntityRepository implements JobRepositoryInterface
{
/**
* #return Job[]
*/
public function getActiveWithCategory()
{
$qb = $this->createQueryBuilder('j');
return $qb
->addSelect('c')
->leftJoin('j.category', 'c')
->addCriteria(JobCriteria::active())
->getQuery()
->getResult();
}
}
Interface:
<?php
namespace AppBundle\Repository;
interface JobRepositoryInterface
{
/**
* #return Job[]
*/
public function getActiveWithCategory();
}
Is it possible to create Decorator for this repository and say somehow to doctrine to return needed implementation?
Or I have to create service JobRepositoryService which implements interface. Here I call repository methods. And then create another JobCachedRepositoryService which is decorator for JobRepositoryService. And don't use $this->getDoctrine()->getRepository('Job') in whole project.
Is it right solution? How would you resolve this problem?
Thanks in advance
If you need to cache doctrine's result with redis custom key, you can to it like that:
<?php
namespace AppBundle\Repository;
class JobRepository extends EntityRepository implements JobRepositoryInterface
{
/**
* #return Job[]
*/
public function getActiveWithCategory()
{
$qb = $this->createQueryBuilder('j');
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$cacheDriver = new Doctrine\Common\Cache\RedisCache();
$cacheDriver->setRedis($redis);
$cacheDriver->setNamespace('some_namespace_');
$query->setResultCacheDriver($cacheDriver);
$query->useResultCache(true, 3600, 'result_key_in_redis');
$query = $qb->addSelect('c')
->leftJoin('j.category', 'c')
->addCriteria(JobCriteria::active())
->getQuery();
return $query->getResult();
}
}
You can install redis lib via pecl.

Symfony: The class * was not found in the chain configured namespaces UsersBundle\Entity, FOS\UserBundle\Model

I try to follow this tutorial for the pagination: https://knpuniversity.com/screencast/symfony-rest3/pagerfanta-pagination
For the moment I have installed the white-october/pagerfanta-bundle, and when I made my user repository as following :
<?php
// src/UsersBundle/Repository/UserRepository.php
namespace UsersBundle\Repository;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository {
public function findAllQueryBuilder() {
return $this->createQueryBuilder('user');
}
}
and in my controller action I did this:
<?php
// src/UsersBundle/Controller/UsersController.php
namespace UsersBundle\Controller;
// use statements ...
/**
* Class UsersController
*
* #package UsersBundle\Controller
*
* #Rest\RouteResource("user", pluralize=false)
* #Rest\NamePrefix( "api_v1_" )
*/
class UsersController extends FOSRestController implements ClassResourceInterface {
// ...
/**
* Responsible to list all the registered users.
*
* #Rest\QueryParam(name="page", default="1", requirements="\d+",nullable=true)
*
* #return array|\Traversable
*/
public function getListAction( ParamFetcher $param_fetcher ) {
if ( ! $this->isGranted( 'ROLE_ADMIN' ) ) {
throw new UnauthorizedHttpException( 'You do not have sufficient permission to access this resource' );
}
$qb = $this->getDoctrine()
->getRepository('UsersBundle\Repository\UserRepository')
->findAllQueryBuilder();
$adapter = new DoctrineORMAdapter( $qb );
$users = $this->user_manager->findUsers();
return $users;
}
// ...
}
I got this output:
{"code":500,"message":"The class 'UsersBundle\\Repository\\UserRepository' was not found in the chain configured namespaces UsersBundle\\Entity, FOS\\UserBundle\\Model"}
Anyone knows what that output means? Unfortunately I am totally new to Symfony, and I cannot understand what is the issue for this output.
$qb = $this->getDoctrine()
->getRepository('UsersBundle\Repository\UserRepository')
->findAllQueryBuilder();
You should find you Repository throug your entity, so something like this
$qb = $this->getDoctrine()
->getRepository('User:class')
->findAllQueryBuilder();
Doc: https://symfony.com/doc/current/doctrine.html#fetching-objects-from-the-database
And in your User entity you should have something like this
/**
* #ORM\Table(name="User")
* #ORM\Entity(repositoryClass=UserRepository::class)
*/
class User {
...

Symfony 2 : how to override repository of another bundle

I have 2 bundles and i want to override the repository of one of them in the other :
I have a source bundle : SourceBundle.
I have my override bundle : OverrideBundle
First, in OurVendorOverrideBundle.php, I added :
public function getParent()
{
return 'SomeVendorSourceBundle';
}
Then
I wanted to add a custom method for the repository of an entity of SourceBundle.
The source entity is Response.php, and its repository is ResponseRepository.php
So i did :
<?php
namespace OurVendor\OverrideBundle\Repository;
use Doctrine\ORM\EntityRepository;
use SomeVendor\SourceBundle\Repository\ResponseRepository as BaseRepository;
class ResponseRepository extends BaseRepository
{
/**
*
* #return array
*/
public function getQueryExerciseAllResponsesForAllUsers($exoId)
{
$qb = $this->createQueryBuilder('r');
$qb->join('r.paper', 'p')
->join('p.exercise', 'e')
->where('e.id = ?1')
->andWhere('p.interupt = ?2')
->setParameters(array(1 => $exoId, 2 => 0));
return $qb->getQuery();
}
}
If i dont set the Entity in the OverrideBundle i have this error :
The autoloader expected class "CPASimUSante\ExoverrideBundle\Entity\Response" to be defined in file "/home/www/myproject/vendor/ourvendor/override-bundle/OurVendor/OverrideBundle/Entity/Response.php". The file was found but the class was not in it, the class name or namespace probably has a typo.
The SourceBundle entity is :
<?php
namespace SomeVendor\SourceBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* SomeVendor\SourceBundle\Entity\Response
*
* #ORM\Entity(repositoryClass="SomeVendor\SourceBundle\Repository\ResponseRepository")
* #ORM\Table(name="source_response")
*/
class Response
{
...
}
So i add the Entity in the OverrideBudle :
<?php
namespace OurVendor\OverrideBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use SomeVendor\SourceBundle\Entity\Response as BaseEntity;
/**
* SomeVendor\SourceBundle\Entity\Response
*
* #ORM\Entity(repositoryClass="OurVendor\OverrideBundle\Repository\ResponseRepository")
* #ORM\Table(name="override_response")
*/
class Response extends BaseEntity
{
public function __construct()
{
parent::__construct();
}
}
But then i have this error :
An exception occurred while executing 'SELECT u0_.id AS id0, u0_.ip AS ip1, u0_.mark AS mark2, u0_.nb_tries AS nb_tries3, u0_.response AS response4, u0_.paper_id AS paper_id5, u0_.interaction_id AS interaction_id6 FROM ujm_exoverride_response u1_ INNER JOIN ujm_paper u2_ ON u0_.paper_id = u2_.id INNER JOIN ujm_exercise u3_ ON u2_.exercise_id = u3_.id WHERE u3_.id = ? AND u2_.interupt = ?' with params ["1", 0]:
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'u0_.id' in 'field list'
This seems that fields in the table are not found. So i changed to
<?php
namespace OurVendor\OverrideBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use SomeVendor\SourceBundle\Entity\Response as BaseEntity;
/**
* SomeVendor\SourceBundle\Entity\Response
*
* #ORM\Entity(repositoryClass="OurVendor\OverrideBundle\Repository\ResponseRepository")
* #ORM\Table(name="source_response")
*/
class Response extends BaseEntity
{
public function __construct()
{
parent::__construct();
}
}
And it worked.
...But when i reinstalled the bundle, to test if everything was ok i had this fatal error stating that source_response is already defined (which is, indeed).
So what can i do then ?
I have also read that i can't override an entity unless the source extends MappedSuperclass, in my case, it doesn't.
But i am doomed if i only want to override its repository ? Is it possible ? If then, what is the right way ?
If i remove altogether the annotation for the override entity, i have :
Class "OurVendor\OverrideBundle\Entity\Response" sub class of "SomeVendor\SourceBundle\Entity\Response" is not a valid entity or mapped super class.
500 Internal Server Error - MappingException
Doctrine mapping in another bundles can be overriden on entity class metadata loading.
EventListener
<?php
namespace Lol\RandomBundle\EventListener;
use Doctrine\ORM\Event\LoadClassMetadataEventArgs;
class ClassMetadataListener
{
/**
* Run when Doctrine ORM metadata is loaded.
*
* #param LoadClassMetadataEventArgs $eventArgs
*/
public function loadClassMetadata(LoadClassMetadataEventArgs $eventArgs)
{
$classMetadata = $eventArgs->getClassMetadata();
if ('AnotherLol\AnotherRandomBundle\Entity\Response' === $classMetadata->name) {
// Do whatever you want...
$classMetadata->customRepositoryClassName = 'ThirdLol\SomeBundle\Repository\NewResponseRepository';
}
}
}
Service configuration
services:
lol.random.listener.class_metadata:
class: Lol\RandomBundle\EventListener\ClassMetadataListener
tags:
- { name: doctrine.event_listener, event: loadClassMetadata }

Class repository doesn't work in symfony 2

It's my code:
file Entity/Article.php
namespace Kaker\FormularzBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Table(name="article")
* #ORM\Entity(repositoryClass="Kaker\FormularzBundle\Entity\ArticleRepository")
*/
class Article {...}
file Entity/ArticleRepository:
namespace Kaker\FormularzBundle\Entity;
use Doctrine\ORM\EntityRepository;
class ArticleRepository extends EntityRepository
{
public function getNickInfo($nick)
{
return $this->getEntityManager()
->createQuery(
'SELECT a FROM KakerFormularzBundle:Article a WHERE a.nick = :nick '
)
->setParameter('nick', $nick)
->getResult();
}
}
file UserController
$em = $this->getDoctrine()->getManager();
$article = $em->getRepository("KakerFormularzBundle:Article")
->getNickInfo($nick);
And I have this error:
Warning: Missing argument 1 for Doctrine\ORM\EntityRepository::__construct(), called in /var/www/apps/sf2-podstwy/app/cache/dev/appDevDebugProjectContainer.php on line 1496 and defined

Resources