Where condition in Doctrine and Zend Framework 2 Pagination - php

I'm unable to make a where condition to work with Doctrine and Zend framework 2 pagination.
My code is given below.
public function indexAction(){
$em = $this->getEntityManager();
$repository = $em->getRepository('Catalog\Entity\Category');
$queryBuilder = $repository->createQueryBuilder('Category');
$adapter = new DoctrinePaginator(new ORMPaginator($queryBuilder));
$paginator = new Paginator($adapter);
$paginator->setDefaultItemCountPerPage(9);
$page = (int)$this->params()->fromQuery('page');
if($page) $paginator->setCurrentPageNumber($page);
$view = new ViewModel(
array('paginator' => $paginator)
);
return $view;
}
I want to get Categories for which 'enabled' column value is 1.
The alternate way I got is create DQL query but I don't get the benifit of zend framework 2 pagination.
$repository->createQueryBuilder('Category')->where(array('enabled' => 1));
I want to use my top code way because it helps me to take full benefit of zend framework 2 pagination but how can I specify a where condition in it?

I solved it by using QueryBuilder of Doctrine. Find the code below to add condition along with Zend Framework 2 pagination.
public function indexAction(){
$em = $this->getEntityManager();
$repository = $em->getRepository('Catalog\Entity\Category');
$queryBuilder = $repository->createQueryBuilder('category')
->where('category.enabled = 1')
->orderBy('category.sortOrder', 'ASC');
$adapter = new DoctrinePaginator(new ORMPaginator($queryBuilder));
$paginator = new Paginator($adapter);
$paginator->setDefaultItemCountPerPage(9);
$page = (int)$this->params()->fromQuery('page');
if($page) $paginator->setCurrentPageNumber($page);
$view = new ViewModel(
array('paginator' => $paginator)
);
return $view;
}

Related

Paginate Results of Model Laravel

I have a problem with pagination in laravel 5.3
The code:
public function deals()
{
return $this->belongsToMany('App\Models\ListsDeals', 'list_has_deals' , 'list_id', 'deal_id')->withPivot('list_id');
}
public function form_edit_list( $id ){
$list = Lists::find( $id );
PAGINATE THIS -----> $deals = $list->deals;
$user = User::find( $list->id_user );
$categoriesArray = ListsCategories::all();
$featuresArray = ListsFeatures::all();
$images = ListsGalleries::all();
return view( "admin.forms.form_edit_list" )
->with( "list", $list )
->withCategoriesArray( $categoriesArray )
->withFeaturesArray( $featuresArray )
->withImages( $images )
->with( "user", $user );
}
I have tried this,
$deals = $list->deals->paginate(5);
How can I paginate the results of deals ?
Because paginate is not a method of that.
I believe you can add the paginate() call to the deals() relationship definition (which will paginate all uses of it).
That may not be ideal, so you can also do $deals = $list->deals()->paginate();
$list->deals is a collection of items, while $list->deals() is an Eloquent query builder instance you can make further adjustments to before fetching the reuslts.

Multiple stage routing in customer Symfony2 framework

What I would like to do is separate the /{id} into it's own routing table, so if it's omitted, I can set a default id and use the same routing table.
index.php:
use Symfony\Component\Routing\RouteCollection;
use Symfony\Component\Routing\Route;
use Symfony\Component\HttpFoundation\Request;
$routes = new RouteCollection();
$routes->add('month_view', new Route('/{id}/month/{year}/{month}',
array('_controller' => function(Request $request) {
$id = $request->get('id'
$year = $request->get('year');
$month = $request->get('month');
return MonthController::showAction($id, $year, $month);
})));
$routes->add('day_view', new Route('/{id}/day/{year}/{month}/{day}',
array('_controller' => function(Request $request) {
$id = $request->get('id');
$year = $request->get('year');
$month = $request->get('month');
$day = $request->get('day');
return DayController::showAction($id, $year, $month, $day);
})));
$framework = new Framework($routes);
$framework->handle(Request::createFromGlobals())->send();
Framework.php:
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\HttpKernel;
use Symfony\Component\EventDispatcher\EventDispatcher;
class Framework extends HttpKernel\HttpKernel
{
public function __construct($routes)
{
$context = new RequestContext();
$matcher = new UrlMatcher($routes, $context);
$resolver = new HttpKernel\Controller\ControllerResolver();
$dispatcher = new EventDispatcher();
$dispatcher->addSubscriber(new HttpKernel\EventListener\RouterListener($matcher));
$dispatcher->addSubscriber(new HttpKernel\EventListener\ResponseListener('UTF-8'));
parent::__construct($dispatcher, $resolver);
}
}
This is for a project that uses Symfony2 components but not the entire Symfony2 framework.
You might want to consider 3 options:
1.
Simpliest solution would be to use a keyword as an id, so an url could look like
/default/month/2015/12
then you would recognize the fact that $id == 'default' in your showAction and use some default id to show data
2.
Same as 1. but instead of checking if $id == 'default' in your showAction, you would create showDefaultAction for an url
/month/{year}/{month} (no id parameter)
3.
again based on 1. but you would add 2 routes: /{id}/month/{year}/{month} one would require $id to be an integer, the other one would expect a string(the 'default' option), you could then lead them to two different actions (show/showDefault)

Symfony2: Where to put request to db build with QueryBuilder

I am new by using Symfony and I am a bit confused concerning the structure. I made a custom query with the queryBuilder but I don't really know where to put this piece of code. It work inside the controller but I don't like to have interaction with db there. So I though to put it inside an entity repository but it's really limited and I am not able to use it for my case. This query make a request with join and filter by multiple column.
So where could I put this code?
Edit1:
$repository = $this->getDoctrine()->getRepository('EgCBGEBundle:portfoliohistory_pfh');
$queryBuilder = $repository->createQueryBuilder('pfh');
$queryBuilder->innerJoin('pfh.portfolio', 'pfo', \Doctrine\ORM\Query\Expr\Join::WITH, 'pfh.id_pfo = pfo.id_pfo');
$queryBuilder->where('pfh.scenario = :scenario')
->andWhere('pfh.measure_catalogue = :measureCatalogue')
->andWhere('pfh.portfolio IN ('.$subs.')')
->andWhere('pfh.date = :date')
->setParameter('scenario', $scenario)
->setParameter('measureCatalogue', $type)
->setParameter('date', $date)
->groupBy('pfh.portfolio, pfh.id') // , pfo.id
//->orderBy('pfo.id', 'ASC')
->setMaxResults(5);
return $queryBuilder->getQuery()->getResult();
Add it to your custom repository: http://docs.doctrine-project.org/en/2.0.x/reference/working-with-objects.html#custom-repositories
Class YourEntityRepository extends EntityRepository
{
public function findMyQuery($scenario, $type, $date){
$queryBuilder = $this->createQueryBuilder('pfh');
$queryBuilder->innerJoin('pfh.portfolio', 'pfo', \Doctrine\ORM\Query\Expr\Join::WITH, 'pfh.id_pfo = pfo.id_pfo');
$queryBuilder->where('pfh.scenario = :scenario')
->andWhere('pfh.measure_catalogue = :measureCatalogue')
->andWhere('pfh.portfolio IN ('.$subs.')')
->andWhere('pfh.date = :date')
->setParameter('scenario', $scenario)
->setParameter('measureCatalogue', $type)
->setParameter('date', $date)
->groupBy('pfh.portfolio, pfh.id') // , pfo.id
//->orderBy('pfo.id', 'ASC')
->setMaxResults(5);
return $queryBuilder->getQuery()->getResult();
}
And don't forget to include it in your entity:
/**
* #ORM\entity(repositoryClass="My\Bundle\Entity\YourEntityRepository ")
*/
In your controller
$results= $em->getRepository('My\Bundle\Entity\YourEntity')->findMyQuery($scenario, $type, $date);
You should put it in your repository
class YourEntityRepository extends EntityRepository
{
public function findItWithACustomQuery($some_params){
$queryBuilder = $this->createQueryBuilder('pfh');
$queryBuilder->innerJoin('pfh.portfolio', 'pfo', \Doctrine\ORM\Query\Expr\Join::WITH, 'pfh.id_pfo = pfo.id_pfo');
$queryBuilder->where('pfh.scenario = :scenario')
->andWhere('pfh.measure_catalogue = :measureCatalogue')
->andWhere('pfh.portfolio IN ('.$subs.')')
->andWhere('pfh.date = :date')
->setParameter('scenario', $scenario)
->setParameter('measureCatalogue', $type)
->setParameter('date', $date)
->groupBy('pfh.portfolio, pfh.id') // , pfo.id
//->orderBy('pfo.id', 'ASC')
->setMaxResults(5);
return $queryBuilder->getQuery()->getResult();
}
Then you just call it in your controller or service by
$em->getRepository('YourEntityBundle:YourEntity')->findItWithACustomQuery($params);
QueryBuilder is part of Doctrine. You can use it in your controller or in a custom class.
Here is a part of the official doc http://doctrine-orm.readthedocs.org/en/latest/reference/query-builder.html
http://www.doctrine-project.org/api/orm/2.4/class-Doctrine.ORM.QueryBuilder.html
And an example : http://drafts.easybib.com/post/44139111915/taiming-repository-classes-in-doctrine-with-the

Loading dozens of data fixtures in a neat manner

I have a Media entity in an app I'm working on that has associations with several other entities: Speaker, Tag, Category, etc.
In the code below I've shown a fixture I've written to create some test-data. It's obviously very long in order to setup and assign the numerous relations between the data.
public function load(ObjectManager $manager)
{
$videoType = new Mediatype();
$videoType->setName('video');
$videoType->setType('video');
$manager->persist($videoType);
$speaker1 = new Speaker();
$speaker1->setName('Joe Bloggs');
$speaker1->setBiography('Joe Bloggs bio.');
$manager->persist($speaker1);
$category1 = new Category();
$category1->setName('PHP');
$category1->setSlug('php');
$manager->persist($category1);
$tag1 = new Tag();
$tag1->setName('PHPNW');
$tag1->setSlug('phpnw');
$manager->persist($tag1);
$video1 = new Media();
$video1->setMediatype($videoType);
$video1->setSpeakers(
new ArrayCollection(
array(
$speaker1
)
)
);
$video1->setCategories(
new ArrayCollection(
array(
$category1
)
)
);
$video1->setTags(
new ArrayCollection(
array(
$tag1
)
)
);
$video1->setDate(new \Datetime());
$video1->setCreationDate(new \DateTime());
$video1->setTitle('My video about PHP');
$video1->setDescription('A video about PHP!');
$video1->setContent('http://some.video-url.com');
$video1->setLength('20:00:00');
$video1->setRating(2.5);
$video1->setVisits(100);
$video1->setLanguage('EN');
$video1->setHostName('PHP');
$video1->setHostUrl('php');
$video1->setStatus('pub');
$manager->persist($video1);
$manager->flush();
}
Now I want to replace this fixture with real data and load a dozen or so Media entities in one fixture. I could copy and paste it a dozen times and make change the data but that's messy and harder to maintain. Is there an nice way to load numerous entities of the same type like this?
I realised that the doctrine/data-fixtures bundle already does exactly what I wanted.
To do this I load each entity in their own fixture and do $this->addReference('admin-user', $user); to access it from another fixture using $this->getReference('admin-user');
Loading fixtures that are dependencies is easy too:
public function getDependencies()
{
// fixture classes that this fixture is dependent on
return array('MyDataFixtures\MyOtherFixture');
}
So now my fixture looks like this:
public function load(ObjectManager $manager)
{
$video1 = new Media();
$video1->setMediatype($this->getReference('video'));
$video1->setSpeakers(
new ArrayCollection(
array(
$this->getReference('joe-bloggs')
)
)
);
$video1->setCategories(
new ArrayCollection(
array(
$this->getReference('php')
)
)
);
$video1->setTags(
new ArrayCollection(
array(
$this->getReference('phpnw')
)
)
);
$video1->setDate(new \Datetime());
$video1->setCreationDate(new \DateTime());
$video1->setTitle('My video about PHP');
$video1->setDescription('A video about PHP!');
$video1->setContent('http://some.video-url.com');
$video1->setLength('20:00:00');
$video1->setRating(2.5);
$video1->setVisits(100);
$video1->setLanguage('EN');
$video1->setHostName('PHP');
$video1->setHostUrl('php');
$video1->setStatus('pub');
$manager->persist($video1);
$manager->flush();
}
/**
* Load this fixtures dependencies
* #see https://github.com/doctrine/data-fixtures
*
* #return array
*/
public function getDependencies()
{
return array(
'...\LoadMediatypeData',
'...\LoadSpeakerData',
'...\LoadCategoryData',
'...\LoadTagData'
);
}

Pagination using Doctrine and ZF2

i am trying to implement Pagination Using ZF2 and Doctrine.
What i am trying to do here is to fetch data from An associated table lets say 'xyz'.
Where as my categories table is doing one to many self referencing on its own PK.
MY catgories tables has following feilds
ID (PK)
Created_at
Category_id (self referencing PK)
My XYZ table lets say it is called Name table has
ID (PK)
Category_id(FK)
name
Detail
This is what i am trying to do to fetch data
public function allSubcategories($id, $column, $order) {
$repository = $this->entityManager->getRepository('Category\Entity\Category');
$queryBuilder = $repository->createQueryBuilder('category');
$queryBuilder->distinct();
$queryBuilder->select('category');
$queryBuilder->join('Category\Entity\CategoryName', 'category_name', 'WITH', 'category.id = category_name.category');
$queryBuilder->orderBy("category.status");
$q = $queryBuilder->getDql();
return $query = $this->entityManager->createQuery($q);
}
And in my controller this is what i am doing
public function subcategoryAction() {
///////////////////////////InPut Params Given for the pagination
$category_id = (int) $this->params()->fromRoute('id', 0);
$page = (int) $this->params()->fromRoute('page', 0);
$column = $this->params()->fromQuery('column');
$order = $this->params()->fromQuery('order');
$categoryModel = $this->getServiceLocator()->get('Category');
$categoryModel->category = $category_id;
$perPage = 10;
$request = $this->getRequest();
if ($request->isGet()) {
$view = new ViewModel();
$query = $categoryModel->allSubcategories($category_id, $column, $order);
$paginator = new ORMPaginator($query);
$paginator = new \Zend\Paginator\Paginator(new
\Zend\Paginator\Adapter\ArrayAdapter(array($paginator)));
$paginator->setCurrentPageNumber($page);
$paginator->setItemCountPerPage(2);
}
return array('id' => $category_id, 'view' => $paginator);
}
Now i am not getting results with pagination implemented can some 1 guide me about what i am missing?
You are using the wrong paginator there. Instead, you can use the one by DoctrineORMModule ( see DoctrineORMModule\Paginator\Adapter\DoctrinePaginator).
It may not be very obvious, but the logic is similar to what you already wrote:
use DoctrineORMModule\Paginator\Adapter\DoctrinePaginator as PaginatorAdapter;
use Doctrine\ORM\Tools\Pagination\Paginator as ORMPaginator;
use Zend\Paginator\Paginator as ZendPaginator;
$query = $categoryModel->allSubcategories($category_id, $column, $order);
$paginator = new ZendPaginator(new PaginatorAdapter(new ORMPaginator($query)));

Categories