New to Symfony & Doctrine
I trying to fetch a selection of objects from a MySQL database via Doctrine in a Symfony project. I am doing this with createQueryBuilder;
$repository = $this->getDoctrine()
->getRepository('mcsyncBundle:DB');
$query = $repository->createQueryBuilder('p')
->select('p')
->where('(p.created=:)' . $till)
->setParameter('created', $till)
->orderBy('p.created', 'ASC')
->getQuery();
$PackDB = $query->getResult();
But I keep getting the error:
*Method 'QueryBuilder' not found in class \Doctrine\Common\Persistence\ObjectRepository*.
Anyone that can explain (fix) this problem?
EDIT: This error is coming from inside PHPStorm by the way and NOT from Symfony itself
I suppose you wrote that code in a Controler file. QueryBuilders are meant to be in Repository files. For /Entity/Plop.php, you should have /Entity/PlopRepository.php as well.
PlopRepository.php
namespace Foo\BarBundle\Entity;
use Doctrine\ORM\EntityRepository;
class PlopRepository extends EntityRepository
{
public function getCreatedP()
{
$qb = $this->createQueryBuilder('p')
->select('p')
->where('p.created = :created')
->setParameter('created', $till)
->orderBy('p.created', 'ASC');
return $qb->getQuery()
->getResults();
}
// ...
}
EDIT 1 : and there was a mistake in your ->where('...') statement I fixed ;)
EDIT 2 : to be complete, controller part :
TotoController.php
public function getPlopAction()
{
$entityManager = $this->getDoctrine()->getManager();
$plopRepository = $entityManager->getRepository('FooBarBundle:Plop');
$plops = $plopRepository->getCreatedP();
// ...
}
Related
I have this problem, I would like to create "smart" criteria. Suppose there's a model of 1 Author : n Books.
So, instead of:
$qb = $em->getRepository('Books')->createQueryBuilder('b')
->join('b.author', 'a')
->where('a.dod is null')
->where('a.name = :name')
->setParameter('name', 'Mozart');
;
...i'd like to do something like:
$qb = $em->getRepository('Books')->createQueryBuilder('b')
->whereAuthorIsAlive()
->whereAuthorName('Mozart');
I am aware of the possibility to creating custom EntityManager but this is not quite it. Custom QueryBuider would be more suitable.
You could extend the QueryBuilder with your custom methods, but have a little overhead by overwriting the createQueryBuilder method of your repository:
Extend the default QueryBuilder class:
class BookQueryBuilder extends \Doctrine\ORM\QueryBuilder
{
public function whereAuthorIsAlive(): self
{
return $this->join($this->getRootAlias() . '.author', '_a')
->andWhere('_a.alive = true');
}
}
In your Repository, overwrite the createQueryBuilder method:
class BookRepository extends EntityRepository
{
public function createQueryBuilder($alias, $indexBy = null)
{
return (new BookQueryBuilder($this->_em))
->select($alias)
->from($this->_entityName, $alias, $indexBy);
}
}
Use the new method
$qb = $em->getRepository('Books')->createQueryBuilder('b')
->whereAuthorIsAlive();
I used such kind of the same in a repository.
I created methods in the repository class that added QueryBuilder parts to a query.
In example, based on yours :
namespace App\Repository;
class BooksRepository extends EntityRepository
{
private function whereAuthorIsAlive($qb)
{
$qb->where('a.dod is null');
return $qb;
}
private function whereAuthorName($qb, $name)
{
$qb->where('a.name = :name')
->setParameter('name', $name);
return $qb;
}
public function getBooksByAliveAuthorName($name)
{
$qb = $this->createQueryBuilder('b')
->join('b.author', 'a')
$qb = $this->whereAuthorIsAlive($qb);
$qb = $this->whereAuthorName($qb, $name);
return $qb->getQuery()->getResult();
}
}
To register this repository with your entity :
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity(repositoryClass="App\Repository\BooksRepository")
*/
class Books
{
// your entity
}
And then, in a controller :
$books = $this->getDoctrine()
->getRepository('App:Books')
->getBooksByAliveAuthorName('Mozart');
i want create a request from my EntityRepository so this is my code:
<?php
namespace zhr\myprojectBundle\Entity;
use Doctrine\ORM\EntityRepository;
/**
* myprojectdbEntityRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class myprojectdbEntityRepository extends EntityRepository
{
public function getAll()
{
$qb = $this->createQueryBuilder('s');
$query = $qb;
$result = $qb->getQuery()->execute();
}
}
i want use it in my controller file so this is my code:
public function searchusersAction(Request $request)
{
$em = $this->getDoctrine()->getManager();
$repository = $em->getRepository('myprojectBundle:User');
$utilisateur = $repository->getAll();
var_dump($utilisateur); die();
//return $this->render('mypageBundle:Admin:adminindex.html.twig', array('sheet'=>$utilisateur));
}
i get a error:
Undefined method 'getAll'. The method name must start with either findBy or findOneBy!
??? normaly all methode in repository file must be defined in my controller file no ?
thanks first guys
You have to use getResult() to return a result as follow:
public function getAll()
{
return $this->createQueryBuilder('s')->getQuery()->getResult();
}
But you really don't need this kind of function since EntityRepository class already has findAll() function to get all rows from an entity:
$em = $this->getDoctrine()->getManager();
$rows = $em->getRepository('myprojectBundle:User')->findAll();
I suggest you to check documentation for QueryBuilder and EntityRepository api.
I don't know if it's good practice. But I think that I can put this part of code:
$categories = DB::table('categories')
//[something]
->get();
somewhere to not ctrl+c ctrl+v in many places. Can you tell me what can I do with it in Laravel?
full example:
class FirstController extends Controller
{
public function index()
{
$articles = DB::table('articles')
//[something]
->get();
$categories = DB::table('categories')
//[something]
->get();
return view('pages.home', compact('articles', 'categories'));
}
public function show($id)
{
$categories = DB::table('categories')
//[something]
->get();
$article = Article::findOrFail($id);
return view('pages.show', compact('article', 'categories'));
}
}
class SecondController extends Controller
{
public function index()
{
$categories = DB::table('categories')
//[something]
->get();
return view('pages.contact')->with('categories', $categories);
}
}
What you might consider is writing a separate Repository (and Service) for every group of database interactions with method names that accurately describe what is going on and then using Laravels Dependency Injection framework to wire it to your controllers. This is a good resource on how to do that. This also looks really promising. This is the recommended approach if you anticipate that this project will become larger and should remain maintainable (and if your time and resources allow it).
You should make the consideration if what you're currently doing is "good enough" or if it would become unmaintainable in the future and change the implementation to using repositories (and possible services).
After studying your code a bit, a CategoryRepository would look something like this:
use Illuminate\Database\ConnectionInterface;
class CategoryRepository {
protected $connectionInterface;
public function __construct(ConnectionInterface $_connectionInterface) {
$this->connectionInterface = $_connectionInterface;
}
public function all() {
return db::table('categories')
//[something]
->get();
}
}
which you can then reference and use in your controllers like so:
class FirstController extends Controller {
protected $categoryRepository;
public function __construct(CategoryRepository $_categoryRepository) {
$this->categoryRepository = $_categoryRepository;
}
...
public function show($id) {
$categories = $this->categoryRepository->all();
$article = Article::findOrFail($id);
return view('pages.show', compact('article', 'categories'));
}
...
}
You could then try to write an get method, a save method etc. After that, you could write an ArticleRepository and incrementally clean up your controller.
I haven't verified this code so copy-and-paste with caution.
What you need is called View Composer in Laravel.
View composers are callbacks or class methods that are called when a view is rendered. If you have data that you want to be bound to a view each time that view is rendered, a view composer can help you organize that logic into a single location.
More about View Composers: https://laravel.com/docs/5.2/views#view-composers
I'm doing my first WebSocket Application in Symfony user Varspool/WebsocketBundle.
I need to insert data for a vote server side.
To do so, I've made an Controller that insert data in the DB when the user chose an answer for the vote.
Following this documentation : http://symfony.com/doc/2.0/cookbook/controller/service.html I've got a "Call to undefined method forward()" error. It should be because I'm in an Application and not in a Controller
I see a lot of things like rebooting the Kernel inside the Controller and a lot of lot of other strange things like this :
$kernel = new \AppKernel('dev', true);
$kernel->loadClassCache();
$kernel->boot();
$controller->setContainer($kernel->getContainer());
[EDIT]
I show you my last try that display a " Call to a member function has() on a non-object" (which I don't really understand oO)
My Controller as service
Edit1 - Update __construct
use Doctrine\ORM\EntityManager;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Krum\AGBundle\Application\ExempleApplication;
use Krum\AGBundle\Form\AGVoteSetType;
use Krum\AGBundle\Form\AGVoteAffichType;
use Krum\AGBundle\Form\AGVoteType;
use Krum\AGBundle\Entity\AGDummy;
use Krum\AGBundle\Entity\AGVote;
use Krum\AGBundle\Entity\AGReponse;
use Krum\AGBundle\Entity\AGScrutin;
use Krum\KBundle\Entity\Users;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\DependencyInjection\ContainerInterface;
class AGServicesController extends Controller {
protected $em;
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function get($service){
return $this->container->get($service);
}
public function voteeffective($vote, $reponse, $users) {
$em = $this->em;
$userbyFOS = $em->createQueryBuilder('u')
->select('u')
->from('KrumKBundle:Users', 'u')
->leftJoin('u.utilisateur', 'ut')
->where('ut.id = ?1')
->setParameter(1, $users)
->getQuery();
$user = $userbyFOS->getOneOrNullResult();
$userstatus = $em->createQueryBuilder('scru')
->select('scru')
->from('KrumAGBundle:AGScrutin', 'scru')
->where('scru.users = ?1')
->andWhere('scru.AGVote = ?2')
->andWhere('scru.AGReponse = ?3')
->setParameters(array(
1 => $user,
2 => $vote,
3 => $reponse
))
->getQuery();
$stat = $userstatus->getResult();
if ($stat == NULL) {
$votety = $em->getRepository('KrumAGBundle:AGVote')->findOneById($vote);
$reponsety = $em->getRepository('KrumAGBundle:AGReponse')->findOneById($reponse);
$scrutinty = new AGScrutin();
$scrutinty->setAGReponse($reponsety);
$scrutinty->setAGVote($votety);
$scrutinty->setUsers($user);
$scrutinty->setType("AGScrutin");
$em->persist($scrutinty);
$em->flush();
return "vote-ok:".$scrutinty->getId();
} else {
return "vote-false";
}
}
}
My Application (WebSocket Server)
namespace Krum\AGBundle\Application;
use Varspool\WebsocketBundle\Application\Application;
use Varspool\WebsocketBundle\Application\NamedApplication;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Krum\AGBundle\Controller\AGServicesController;
class ExempleApplication extends Application {
protected $clients = array();
public function onData($data, $client) {
foreach ($this->clients as $sendto) {
$scrutin = (json_decode($data) != NULL) ? true : false;
if ($scrutin == true ){
$vote = $scrutin["AGVote"];
$reponse = $scrutin["AFreponse"] ;
$users = $scrutin["users"];
$scrutinservice = new AGServicesController();
$scrutinsend = $controller->voteeffective($vote, $reponse, $users);
$sendto->send($scrutinsend);
}
}
else
$sendto->send($data);
}
}
}
My config.yml
parameters:
agservices.class: Krum\AGBundle\Controller\AGServicesController
services :
agservices:
class : %agservices.class%
arguments :
container : "#service_container"
services.yml
Edit 1 : sercices.yml configuration
krum.agservices:
class: Krum\AGBundle\Controller\AGServicesController
arguments: ["#doctrine.orm.default_entity_manager"]
All answer is or idea is appreciable !
Thank you for watching ;)
**Edit 1 : Now, I have another ExceptionError
Warning: Missing argument 1 for Krum\AGBundle\Controller\AGServicesController::__construct(), called in /opt/lampp/htdocs/Krum/src/Krum/AGBundle/Application/ExempleApplication.php on
line 62 and defined in /opt/lampp/htdocs/Krum/src/Krum/AGBundle/Controller/AGServicesController.php line 34
*
I thought that the services.yml should add in parameter automatically the correct doctrine entity manager or it just specify the type of the parameters and I have to add it manually while calling the controller ?
In a bundle I'm developing and was working correctly I added a new functionality which involves adding a repository to the entity. Now, when I execute the newly added method I get the following error:
Warning: class_parents() [function.class-parents]: Class CmsPages does not exist and could not be loaded in /Applications/MAMP/htdocs/symfony-standard-2.1/vendor/doctrine/common/lib/Doctrine/Common/Persistence/Mapping/RuntimeReflectionService.php line 40
The newly added code is:
Controller:
/**
* Returns an json formated tree
*
* #Route("/getTree", name="admin_cmsPages_getTree", options={"expose"=true})
*/
public function getTreeAction()
{
$em = $this->getDoctrine()->getManager();
$tree = $em->getRepository('CmsPages')->loadTree();
$response = new Response(json_encode( $tree ));
$response->headers->set('Content-Type', 'application/json');
return $response;
}
Repository:
namespace Yanic\CmsBundle\Entity;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\NoResultException;
class CmsPagesRepository extends EntityRepository
{
public function loadTree()
{
$q = $this
->createQueryBuilder('p')
->select('p')
->orderBy( 'p.lft' )
->getQuery()
;
return $q->getArrayResult();
}
}
That's all that has changed... if any more code is needed for clarification I will post it.
So could anybody tell me what I'm doing wrong? I couldn't find anything neither on SO nor on Google.
Thanks in advance
I just found the error myself... the line
$tree = $em->getRepository('CmsPages')->loadTree();
has to be
$tree = $em->getRepository('CmsBundle:CmsPages')->loadTree();