Pagination PagerFanta Symfony4 - php

I make an API with Symfony4 and
I use the PagerFanta bundle. I made an AbstractRepository abstract class for my pagination:
<?php
namespace App\Repository;
use Doctrine\ORM\EntityRepository;
use Doctrine\ORM\QueryBuilder;
use Pagerfanta\Adapter\DoctrineORMAdapter;
use Pagerfanta\Pagerfanta;
class AbstractRepository extends EntityRepository
{
protected function paginate(QueryBuilder $qb, $limit = 20, $offset = 0)
{
if (0 == $limit || 0 == $offset) {
throw new \LogicException('$limit & $offstet must be greater
than 0.');
}
$pager = new Pagerfanta(new DoctrineORMAdapter($qb));
$currentPage = ceil($offset + 1) / $limit;
$pager->setCurrentPage($currentPage);
$pager->setMaxPerPage((int)$limit);
return $pager;
}
}
My Entity Article:
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
use JMS\Serializer\Annotation\Expose;
use JMS\Serializer\Annotation\ExclusionPolicy;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Class Article
* #ORM\Entity(repositoryClass="App\Repository\ArticleRepository")
* #ORM\Table(name="article")
*
* #ExclusionPolicy("all")
*/
class Article
{
/**
* #ORM\Id()
* #ORM\Column(type="integer")
* #ORM\GeneratedValue()
*
* #Expose()
*/
private $id;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank(groups={"Create"})
* #Expose()
*/
private $title;
/**
* #ORM\Column(type="string")
* #Assert\NotBlank(groups={"Create"})
* #Expose()
*/
private $content;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id): void
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getTitle()
{
return $this->title;
}
/**
* #param mixed $title
*/
public function setTitle($title): void
{
$this->title = $title;
}
/**
* #return mixed
*/
public function getContent()
{
return $this->content;
}
/**
* #param mixed $content
*/
public function setContent($content): void
{
$this->content = $content;
}
}
I tested a var_dump of $ qb but I do not get the items already, My ArticleRepository:
<?php
namespace App\Repository;
class ArticleRepository extends AbstractRepository
{
public function search($term, $order = 'asc', $limit = 20, $offset = 0)
{
$qb = $this
->createQueryBuilder('a')
->select('a')
->orderBy('a.title', $order);
if ($term) {
$qb
->where('a.title LIKE ?1')
->setParameter(1, '%'.$term.'%');
}
return $this->paginate($qb, $limit, $offset);
}
}
My ArticleController:
<?php
namespace App\Controller;
use App\Entity\Article;
use FOS\RestBundle\Controller\Annotations as Rest;
use FOS\RestBundle\Controller\FOSRestController;
use FOS\RestBundle\Request\ParamFetcherInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use App\Representation\Articles;
use Symfony\Component\Validator\ConstraintViolationList;
class ArticleController extends FOSRestController
{
/**
* #Rest\Get(
* path = "/articles/{id}",
* name = "app_article_show",
* requirements = {"id"="\d+"}
* )
* #Rest\View()
*/
public function showAction(Article $article)
{
return $article;
}
/**
* #Rest\Post(
* path = "/articles",
* name= "app_article_show",
* )
* #Rest\View(StatusCode= 201)
* #ParamConverter(
* "article", converter="fos_rest.request_body",
* options={
"validator"={ "groups"="Create"}
* }
* )
*/
public function createAction(Article $article, ConstraintViolationList $violations)
{
if (count($violations)) {
return $this->view($violations, Response::HTTP_BAD_REQUEST);
}
$em = $this->getDoctrine()->getManager();
$em->persist($article);
$em->flush();
return $this->view(
$article,
Response::HTTP_CREATED,
[
'Location' => $this->generateUrl('app_article_show', ['id', $article->getId()], UrlGeneratorInterface::ABSOLUTE_URL)
]
);
}
/**
* #Rest\Get(
* path="/articles",
* name="app_article_list"
* )
* #Rest\QueryParam(
* name="keyword",
* requirements="[a-zA-Z0-9]",
* nullable=true,
* description="The keyword to search for."
* )
* #Rest\QueryParam(
* name="order",
* requirements="asc|desc",
* default="asc",
* description="Sort order (asc or desc)"
* )
* #Rest\QueryParam(
* name="limit",
* requirements="\d+",
* default="15",
* description="Max number of movies per page."
* )
* #Rest\QueryParam(
* name="offset",
* requirements="\d+",
* default="0",
* description="The pagination offset"
* )
* #Rest\View()
*/
public function listAction(ParamFetcherInterface $paramFetcher)
{
$pager = $this->getDoctrine()->getRepository('App:Article')->search(
$paramFetcher->get('keyword'),
$paramFetcher->get('order'),
$paramFetcher->get('limit'),
$paramFetcher->get('offset')
);
return new Articles($pager);
}
}
My Articles in Representation:
<?php
namespace App\Representation;
use Pagerfanta\Pagerfanta;
use JMS\Serializer\Annotation\Type;
class Articles
{
/**
* #Type("ArrayCollection<App\Entity\Article>")
*/
public $data;
public $meta;
public function __construct(Pagerfanta $data)
{
$this->data = $data->getCurrentPageResults();
$this->addMeta('limit', $data->getMaxPerPage());
$this->addMeta('current_items', count($data->getCurrentPageResults()));
$this->addMeta('total_items', $data->getNbResults());
$this->addMeta('offset', $data->getCurrentPageOffsetStart());
}
public function addMeta($name, $value)
{
if (isset($this->meta[$name])) {
throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
}
$this->setMeta($name, $value);
}
public function setMeta($name, $value)
{
$this->meta[$name] = $value;
}
}
And that's the mistake that returns to me postman:
When I var_dump in the repository I do not already recover the articles but I do not see why

I see my problem in AbstractRepository replace
$currentPage = ceil($offset + 1) / $limit;
per:
$currentPage = ceil(($offset + 1) / $limit);
And my ArticleController replace
* #Rest\QueryParam(
* name="offset",
* requirements="\d+",
* default="0",
* description="The pagination offset"
* )
* #Rest\View()
*/
per
* #Rest\QueryParam(
* name="offset",
* requirements="\d+",
* default="1",
* description="The pagination offset"
* )
* #Rest\View()
*/
Thanks

Related

JMS Groups Serialization and PagerFantaBundle

I'm working on a RESTFull API with Symfony and FOSRESTBundle. I use the JMS Serializer with groups to show differents fields depending on the context.
For listing my resources, I want implement PagerFantaBundle. All work fine except that PagerFanta does not consider the serialization groups.
Below my code :
Pagination function :
protected function paginate(QueryBuilder $qb, $limit = 20, $offset = 0) {
if($limit == 0 || $offset < 0) {
throw new \LogicException("$limit & $offset must be greater than 0");
}
$pager = new Pagerfanta(new DoctrineORMAdapter($qb));
$currentPage = ceil($offset + 1 / $limit);
$pager->setCurrentPage($currentPage);
$pager->setMaxPerPage((int) $limit);
return $pager;
}
List apartment function :
public function listApartments(Location $location, $order = 'asc', $limit = 20, $offset = 0) {
$qb = $this->createQueryBuilder('a')
->select('a')
->orderBy('a.title', $order);
return $this->paginate($qb, $limit, $offset);
}
Controller :
/**
* #Rest\Get(
* path = "/apartments",
* name = "apartments_get_all"
* )
* #Rest\QueryParam(
* name="order",
* requirements="asc|desc",
* nullable=true,
* description="Sort order (asc or desc)"
* )
* #Rest\QueryParam(
* name="limit",
* requirements="\d+",
* default="20",
* description="Max number of apartments per page"
* )
* #Rest\QueryParam(
* name="offset",
* requirements="\d+",
* default="0",
* description="Pagination offset"
* )
* #Rest\View(statusCode=200, serializerGroups={"listApartment"})
*/
public function getApartmentsAction(ParamFetcherInterface $paramFetcher)
{
$pager = $this->getDoctrine()->getRepository("HGBCoreBundle:Apartment")->listApartments(
new Location(),
$paramFetcher->get('order'),
$paramFetcher->get('limit'),
$paramFetcher->get('offset')
);
return new Apartments($pager);
}
Apartments representation :
class Apartments
{
/**
* #Type("array<HGB\CoreBundle\Entity\Apartment>")
*/
public $data;
public $meta;
public function __construct(Pagerfanta $data)
{
$this->data = $data->getCurrentPageResults();
$this->addMeta('limit', $data->getMaxPerPage());
$this->addMeta('current_items', count($data->getCurrentPageResults()));
$this->addMeta('total_items', $data->getNbResults());
$this->addMeta('offset', $data->getCurrentPageOffsetStart());
}
public function addMeta($name, $value)
{
if (isset($this->meta[$name])) {
throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
}
$this->setMeta($name, $value);
}
public function setMeta($name, $value)
{
$this->meta[$name] = $value;
}
}
Apartment Entity :
/**
* Apartment
*
* #ORM\Table(name="apartment")
* #ORM\Entity(repositoryClass="HGB\CoreBundle\Repository\ApartmentRepository")
* #JMS\ExclusionPolicy("all")
*/
class Apartment
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #JMS\Groups({"listApartment"})
* #JMS\Expose()
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=200)
* #JMS\Groups({"listApartment"})
* #JMS\Expose()
* #Assert\NotBlank()
*/
private $title;
...
So, how can I use group serialization with PagerFanta, or what pagination system could I use with groups serialization ?
Thanks
I've found the solution. Just need to configure the serialization groups for the Apartments representation like this :
<?php
namespace HGB\CoreBundle\Representation;
use JMS\Serializer\Annotation as Serializer;
use Pagerfanta\Pagerfanta;
/**
* Class Apartments
* #package HGB\CoreBundle\Representation
* #Serializer\ExclusionPolicy("all")
*/
class Apartments
{
/**
* #Serializer\Type("array<HGB\CoreBundle\Entity\Apartment>")
* #Serializer\Groups("listApartment")
* #Serializer\Expose()
*/
public $data;
/**
* #Serializer\Groups("listApartment")
* #Serializer\Expose()
*/
public $meta;
public function __construct(Pagerfanta $data)
{
$this->data = $data;
$this->addMeta('limit', $data->getMaxPerPage());
$this->addMeta('current_items', count($data->getCurrentPageResults()));
$this->addMeta('total_items', $data->getNbResults());
$this->addMeta('offset', $data->getCurrentPageOffsetStart());
}
public function addMeta($name, $value)
{
if (isset($this->meta[$name])) {
throw new \LogicException(sprintf('This meta already exists. You are trying to override this meta, use the setMeta method instead for the %s meta.', $name));
}
$this->setMeta($name, $value);
}
public function setMeta($name, $value)
{
$this->meta[$name] = $value;
}
}

Fields from child entity don't show in symfony

I apologize in advance for a noob question. I just started learning symfony and I ran into a roadblock.
I created the RequestForEstimate entity and it may have multiple records associated under the RequestForEstimateDetail entity. Now, Im trying to create a form that not only displays fields from the first entity but also from the second one as well. Symfony doesn't return any errors however it doesn't render the "quantity" field from the RequestForEstimateDetail entity. I used the following tutorial to create this code: How to Embed a Collection of Forms
This is an example of my RequestForEstimate entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimate
*
* #ORM\Table(name="request_for_estimate")
* #ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateRepository")
*/
class RequestForEstimate
{
/**
* #var int
*
* #ORM\Column(name="requestId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var int
*
* #ORM\Column(name="status", type="integer")
*/
private $status;
/**
* #var \DateTime
*
* #ORM\Column(name="createTime", type="datetime")
*/
private $createTime;
/**
* #var \DateTime
*
* #ORM\Column(name="updateTime", type="datetime")
*/
private $updateTime;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="RequestForEstimateDetail", mappedBy="detail", cascade={"persist", "remove"}, orphanRemoval=true)
*/
private $details;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set status
*
* #param integer $status
*
* #return RequestForEstimate
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* Get status
*
* #return int
*/
public function getStatus()
{
return $this->status;
}
/**
* Set createTime
*
* #param \DateTime $createTime
*
* #return RequestForEstimate
*/
public function setCreateTime($createTime)
{
$this->createTime = $createTime;
return $this;
}
/**
* Get createTime
*
* #return \DateTime
*/
public function getCreateTime()
{
return $this->createTime;
}
/**
* Set updateTime
*
* #param \DateTime $updateTime
*
* #return RequestForEstimate
*/
public function setUpdateTime($updateTime)
{
$this->updateTime = $updateTime;
return $this;
}
/**
* Get updateTime
*
* #return \DateTime
*/
public function getUpdateTime()
{
return $this->updateTime;
}
/**
* Set name
*
* #param string $name
*
* #return RequestForEstimate
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Constructor
*/
public function __construct()
{
$this->details = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add detail
*
* #param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*
* #return RequestForEstimate
*/
public function addDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details[] = $detail;
return $this;
}
/**
* Remove detail
*
* #param \SourcingBundle\Entity\RequestForEstimateDetail $detail
*/
public function removeDetail(\SourcingBundle\Entity\RequestForEstimateDetail $detail)
{
$this->details->removeElement($detail);
}
/**
* Get details
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getDetails()
{
return $this->details;
}
}
This is my RequestForEstimateDetail entity:
<?php
namespace SourcingBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* RequestForEstimateDetail
*
* #ORM\Table(name="request_for_estimate_detail")
* #ORM\Entity(repositoryClass="SourcingBundle\Repository\RequestForEstimateDetailRepository")
*/
class RequestForEstimateDetail
{
/**
* #var int
*
* #ORM\Column(name="requestDetailId", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="RequestForEstimate", inversedBy="details")
* #ORM\JoinColumn(name="requestId", referencedColumnName="requestId")
*/
private $detail;
/**
* #var int
*
* #ORM\Column(name="productId", type="integer")
*/
private $productId;
/**
* #var int
*
* #ORM\Column(name="quantity", type="integer")
*/
private $quantity;
/**
* #var string
*
* #ORM\Column(name="pricePerUnit", type="decimal", precision=2, scale=0)
*/
private $pricePerUnit;
/**
* #var string
*
* #ORM\Column(name="shippingCost", type="decimal", precision=2, scale=0)
*/
private $shippingCost;
/**
* #var string
*
* #ORM\Column(name="otherFees", type="decimal", precision=2, scale=0)
*/
private $otherFees;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set product
*
* #param integer $product
*
* #return RequestForEstimateDetail
*/
public function setProduct($product)
{
$this->product = $product;
return $this;
}
/**
* Get product
*
* #return int
*/
public function getProduct()
{
return $this->product;
}
/**
* Set quantity
*
* #param integer $quantity
*
* #return RequestForEstimateDetail
*/
public function setQuantity($quantity)
{
$this->quantity = $quantity;
return $this;
}
/**
* Get quantity
*
* #return int
*/
public function getQuantity()
{
return $this->quantity;
}
/**
* Set pricePerUnit
*
* #param string $pricePerUnit
*
* #return RequestForEstimateDetail
*/
public function setPricePerUnit($pricePerUnit)
{
$this->pricePerUnit = $pricePerUnit;
return $this;
}
/**
* Get pricePerUnit
*
* #return string
*/
public function getPricePerUnit()
{
return $this->pricePerUnit;
}
/**
* Set shippingCost
*
* #param string $shippingCost
*
* #return RequestForEstimateDetail
*/
public function setShippingCost($shippingCost)
{
$this->shippingCost = $shippingCost;
return $this;
}
/**
* Get shippingCost
*
* #return string
*/
public function getShippingCost()
{
return $this->shippingCost;
}
/**
* Set otherFees
*
* #param string $otherFees
*
* #return RequestForEstimateDetail
*/
public function setOtherFees($otherFees)
{
$this->otherFees = $otherFees;
return $this;
}
/**
* Get otherFees
*
* #return string
*/
public function getOtherFees()
{
return $this->otherFees;
}
/**
* Set requestId
*
* #param \SourcingBundle\Entity\RequestForEstimate $requestId
*
* #return RequestForEstimateDetail
*/
public function setRequestId(\SourcingBundle\Entity\RequestForEstimate $requestId = null)
{
$this->requestId = $requestId;
return $this;
}
/**
* Get requestId
*
* #return \SourcingBundle\Entity\RequestForEstimate
*/
public function getRequestId()
{
return $this->requestId;
}
/**
* Set productId
*
* #param \SourcingBundle\Entity\Product $productId
*
* #return RequestForEstimateDetail
*/
public function setProductId(\SourcingBundle\Entity\Product $productId = null)
{
$this->productId = $productId;
return $this;
}
/**
* Get productId
*
* #return \SourcingBundle\Entity\Product
*/
public function getProductId()
{
return $this->productId;
}
/**
* Set detail
*
* #param \SourcingBundle\Entity\RequestForEstimate $detail
*
* #return RequestForEstimateDetail
*/
public function setDetail(\SourcingBundle\Entity\RequestForEstimate $detail = null)
{
$this->detail = $detail;
return $this;
}
/**
* Get detail
*
* #return \SourcingBundle\Entity\RequestForEstimate
*/
public function getDetail()
{
return $this->detail;
}
}
This is my RequestForEstimateController:
<?php
namespace SourcingBundle\Controller;
use SourcingBundle\Entity\RequestForEstimate;
use SourcingBundle\Form\Type\RequestForEstimateType;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
class RequestForEstimateController extends Controller
{
/**
* #Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
These are my form classes:
RequestForEstimateType.php
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
class RequestForEstimateType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name');
$builder->add('details', CollectionType::class, array(
'entry_type' => RequestForEstimateDetailType::class
));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimate',
));
}
}
RequestForEstimateDetailType.php:
<?php
namespace SourcingBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class RequestForEstimateDetailType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('quantity',TextType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'SourcingBundle\Entity\RequestForEstimateDetail',
));
}
}
Now my view:
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Create Request For Estimate</h5>
</div>
<div class="ibox-content">
{{ form_start(form) }}
{{ form_errors(form) }}
<div>
{{ form_widget(form) }}
</div>
{{ dump(form.details)}}
{% for detail in form.details %}
<li>{{ form_row(detail.quantity) }}</li>
{% endfor %}
{{ form_end(form) }}
</div>
</div>
</div>
</div>
You need to create some RequestForEstimateDetail entities in your controller class and add it to RequestForEstimate entity. Like this:
class RequestForEstimateController extends Controller
{
/**
* #Route("sourcing/request-for-estimate", name="request_for_estimate")
*/
public function addRequest(Request $request)
{
$RequestForEstimate = new RequestForEstimate();
$detail1 = new RequestForEstimateDetail();
$detail2 = new RequestForEstimateDetail();
$RequestForEstimate->addDetail($detail1);
$RequestForEstimate->addDetail($detail2);
$form = $this->createForm(RequestForEstimateType::class, $RequestForEstimate);
return $this->render('sourcing/requestforestimate/create.html.twig', array(
'form' => $form->createView(),
));
}
}
PS. U can read this doc http://symfony.com/doc/current/form/form_collections.html it's pretty clear =)

Symfony Error when trying to get data in a relationship

Symfony is tormenting my head right now. I'm trying to get data from a table where the column associates a relationship with an id from another table. Thats my controller function:
/**
* #Route("/proposta/{id}", defaults={"id"=null})
*/
public function mostraAction($id) {
$model = $this->getDoctrine()->getManager();
$lista = $model->getRepository('AppBundle:Propostes')->find($id);
$em = $this->getDoctrine()->getManager();
$listaVotacions = $em->getRepository('AppBundle:Votacions')->findByIdProposta($id);
return $this->render(':Proposta:index.html.php',
array('lista'=>$lista,'listaVotacions'=>$listaVotacions));
}
That's not working, when I execute this function, my server falls and I get this error:
[ERROR] Built-in server terminated unexpectedly.
That's my class of Votacions:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Votacions
*
* #ORM\Table(name="votacions")
* #ORM\Entity(repositoryClass="AppBundle\Repository\VotacionsRepository")
*/
class Votacions
{
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Propostes")
*/
private $idProposta;
/**
* #ORM\ManyToOne(targetEntity="Usuaris")
*/
private $idUsuari;
/**
* #var bool
*
* #ORM\Column(name="vot", type="boolean", nullable=true)
*/
private $vot;
/**
* Get id
*
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set idProposta
*
* #param integer $idProposta
*
* #return Votacions
*/
public function setIdProposta($idProposta)
{
$this->idProposta = $idProposta;
return $this;
}
/**
* Get idProposta
*
* #return int
*/
public function getIdProposta()
{
return $this->idProposta;
}
/**
* Set idUsuari
*
* #param integer $idUsuari
*
* #return Votacions
*/
public function setIdUsuari($idUsuari)
{
$this->idUsuari = $idUsuari;
return $this;
}
/**
* Get idUsuari
*
* #return int
*/
public function getIdUsuari()
{
return $this->idUsuari;
}
/**
* Set vot
*
* #param boolean $vot
*
* #return Votacions
*/
public function setVot($vot)
{
$this->vot = $vot;
return $this;
}
/**
* Get vot
*
* #return bool
*/
public function getVot()
{
return $this->vot;
}
}
And this my repository Votacions:
namespace AppBundle\Entity;
use Doctrine\ORM\EntityRepository;
class VotacionsRepository extends EntityRepository
{
public function findByIdProposta($id)
{
return $this->getEntityManager()
->createQuery(
'SELECT * FROM AppBundle:Votacions WHERE idProposta ='.$id
)->getResult();
}
}
Someone could help me :(?
Thank you so much.
Carles
Call only one time the "GetDoctrine"
-> find your lista object
-> Access idProposta from $lista object
-> the id from Proposta Entity
public function mostraAction($id) {
$model = $this->getDoctrine()->getManager();
$lista = $model->getRepository('AppBundle:Votacions')->find($id);
$lista->getIdProposta()->getId();
//..
return $this->render(':Proposta:index.html.php',
array('lista'=>$lista,'listaVotacions'=>$listaVotacions));
}

Symfony 2, Undefined variable, protected member initialized in constructor as ArrayCollection throughs error, that it is undefined

I use Symfony 2. I have Entity with protected variable, which is initialized in constructor as ArrayCollection. But than i use command
>php app/console doctrine:fixtures:load -vvv
i am getting error:
[Symfony\Component\Debug\Exception\ContextErrorException]
Notice: Undefined variable: comments
Exception trace:
() at C:\Bitnami\wampstack-5.5.30-0\sym_prog\dctr\src\BlogBundle\Entity\Post.ph
p:183
Symfony\Component\Debug\ErrorHandler->handleError() at C:\Bitnami\wampstack-5.5
.30-0\sym_prog\dctr\src\BlogBundle\Entity\Post.php:183
BlogBundle\Entity\Post->addComment() at C:\Bitnami\wampstack-5.5.30-0\sym_prog\
dctr\src\BlogBundle\DataFixtures\ORM\LoadAuthorData.php:54
<...>
//C:\Bitnami\wampstack-5.5.30-0\sym_prog\dctr\src\BlogBundle\Entity\Post.php
/**
* Add comment
*
* #param \BlogBundle\Entity\Comment $comment
*
* #return Post
*/
public function addComment(\BlogBundle\Entity\Comment $comment)
{
182 $this->comments[] = $comment;
183 $comments->setPost($this);
184 return $this;
}
//Full file: \dctr\src\BlogBundle\Entity\Post.php
<?php
namespace BlogBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Id;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\OneToMany;
use Doctrine\ORM\Mapping\ManyToMany;
use Doctrine\ORM\Mapping\JoinTable;
use Doctrine\ORM\Mapping\JoinColumn;
//use Symfony\Component\Validator\Constraints as Assert;
/**
* Post
*
* #ORM\Table(indexes={#ORM\Index(name="publication_date_idx",columns="publicationDate")})
* #ORM\Entity(repositoryClass="BlogBundle\Entity\PostRepository")
*/
class Post
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="body", type="text")
*/
private $body;
/**
* #var \DateTime
*
* #ORM\Column(name="publicationDate", type="datetime")
*/
private $publicationDate;
/**
* #var Comment[]
*
* #ORM\OneToMany(targetEntity="Comment", mappedBy="post")
*/
protected $comments;
/**
* #var Tag[]
*
* #ORM\ManyToMany(targetEntity="Tag", inversedBy="posts", fetch="EAGER", cascade={"persist"}, orphanRemoval=true)
* #ORM\JoinTable(
* inverseJoinColumns={#ORM\JoinColumn(name="tag_name", referencedColumnName="name")}
* )
*/
protected $tags;
/**
* #var PostAuthor
*
* #ORM\ManyToOne(targetEntity="PostAuthor", inversedBy="posts")
*/
protected $author;
/**
* Initializes collections
*/
public function __construct()
{
$this->comments = new ArrayCollection();
$this->tags = new ArrayCollection();
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set title
*
* #param string $title
*
* #return Post
*/
public function setTitle($title)
{
$this->title = $title;
return $this;
}
/**
* Get title
*
* #return string
*/
public function getTitle()
{
return $this->title;
}
/**
* Set body
*
* #param string $body
*
* #return Post
*/
public function setBody($body)
{
$this->body = $body;
return $this;
}
/**
* Get body
*
* #return string
*/
public function getBody()
{
return $this->body;
}
/**
* Set publicationDate
*
* #param \DateTime $publicationDate
*
* #return Post
*/
public function setPublicationDate($publicationDate)
{
$this->publicationDate = $publicationDate;
return $this;
}
/**
* Get publicationDate
*
* #return \DateTime
*/
public function getPublicationDate()
{
return $this->publicationDate;
}
/**
* Add comment
*
* #param \BlogBundle\Entity\Comment $comment
*
* #return Post
*/
public function addComment(\BlogBundle\Entity\Comment $comment)
{
$this->comments[] = $comment;
$comments->setPost($this);
return $this;
}
/* Another important thing, as already explained,
* is that Doctrine only manages the owning side of an association.
* This is why we call the setPost() method of the Comment entity
* in the addComment() method. This allows persisting
* with an association from the inverse side. */
/**
* Remove comment
*
* #param \BlogBundle\Entity\Comment $comment
*/
public function removeComment(\BlogBundle\Entity\Comment $comment)
{
$this->comments->removeElement($comment);
}
/**
* Get comments
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getComments()
{
return $this->comments;
}
/**
* Add tag
*
* #param \BlogBundle\Entity\Tag $tag
*
* #return Post
*/
public function addTag(\BlogBundle\Entity\Tag $tag)
{
$this->tags[] = $tag;
return $this;
}
/**
* Remove tag
*
* #param \BlogBundle\Entity\Tag $tag
*/
public function removeTag(\BlogBundle\Entity\Tag $tag)
{
$this->tags->removeElement($tag);
}
/**
* Get tags
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTags()
{
return $this->tags;
}
/**
* Set author
*
* #param \BlogBundle\Entity\PostAuthor $author
*
* #return Post
*/
public function setAuthor(\BlogBundle\Entity\PostAuthor $author = null)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return \BlogBundle\Entity\PostAuthor
*/
public function getAuthor()
{
return $this->author;
}
}
//sym_prog\dctr\src\BlogBundle\DataFixtures\ORM\LoadAuthorData.php
line 54 $post->addComment($comment);
//sym_prog\dctr\src\BlogBundle\DataFixtures\ORM\LoadAuthorData.php
<?php
namespace BlogBundle\DataFixtures;
/* This fixture creates instances
of Post, PostAuthor, Comment, and CommentAuthor
and then persists them to the database.
*/
use BlogBundle\Entity\Comment;
use BlogBundle\Entity\CommentAuthor;
use BlogBundle\Entity\Post;
use BlogBundle\Entity\PostAuthor;
use Doctrine\Common\DataFixtures\Doctrine;
use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
/**
* Author fixtures
*/
class LoadAuthorData implements FixtureInterface
{
/**
* {#inheritDoc}
*/
public function load(ObjectManager $manager)
{
$postAuthor = new PostAuthor();
$postAuthor->setName('George Abitbol');
$postAuthor->setEmail('gabitbol#example.com');
$postAuthor->setBio('L\'homme le plus classe du monde');
$manager->persist($postAuthor);
$post = new Post();
$post->setTitle('My post');
$post->setBody('Lorem ipsum');
$post->setPublicationDate(new \DateTime());
$post->setauthor($postAuthor);
$manager->persist($post);
$commentAuthor = new CommentAuthor();
$commentAuthor->setName('Kévin Dunglas');
$commentAuthor->setEmail('dunglas#gmail.com');
$manager->persist($commentAuthor);
$comment = new Comment();
$comment->setBody('My comment');
$comment->setAuthor($commentAuthor);
$comment->setPublicationDate(new \DateTime());
$post->addComment($comment);
$manager->persist($comment);
$manager->flush();
}
}
Line 183 you use $comments with S but your function receive $comment without S.
/**
* Add comment
*
* #param \BlogBundle\Entity\Comment $comment
*
* #return Post
*/
public function addComment(\BlogBundle\Entity\Comment $comment)
{
182 $this->comments[] = $comment;
183 $comments->setPost($this); // Should be $comment->setPost($this);
184 return $this;
}
The solution is :
C:\Bitnami\wampstack-5.5.30-0\sym_prog\dctr\src\BlogBundle\Entity\Post.php
<...>
public function addComment(\BlogBundle\Entity\Comment $comment)
{
181 $this->comments[] = $comment;
182 $comment->setPost($this);
//instead of $comments->setPost($this);
183 return $this;
}
On the line 182 i have to setPost to the $comment object, not to the $comments variable.
Comments variable does not exists in this method, it exists only as $this->comments.
$this->comments is a variable thus it can not have a method setPost($this).

No mapping file found for Entity class

I am quite new to Symfony2I created an Entity class in my project but I get an error. I googled the solution a lot but coudn't find it. Here is my controller
<?php
namespace IDP\Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use IDP\Bundle\Entity\Portfolio;
class PortfolioController extends Controller {
public function indexAction() {
$product = $this->getDoctrine()
->getRepository('IDPBundle:Portfolio')
->find(1);
return $this->render('IDPBundle:Portfolio:index.html.twig');
}
}
My Portfolio.php in Entity folder is like
<?php
namespace IDP\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* IDP\Bundle\Entity\Portfolio
* #ORM\Table(name="pm_portfolios")
*/
class Portfolio
{
/**
* #var integer $id
*/
private $id;
/**
* #var integer $user_id
*/
private $user_id;
/**
* #var string $portfolio_name
*/
private $portfolio_name;
/**
* #var text $description
*/
private $description;
/**
* #var string $permalink
*/
private $permalink;
/**
* #var string $sharing_code
*/
private $sharing_code;
/**
* #var boolean $shared
*/
private $shared;
/**
* #var integer $shared_portfolio_calls
*/
private $shared_portfolio_calls;
/**
* #var integer $patentgroup_id
*/
private $patentgroup_id;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set user_id
*
* #param integer $userId
*/
public function setUserId($userId)
{
$this->user_id = $userId;
}
/**
* Get user_id
*
* #return integer
*/
public function getUserId()
{
return $this->user_id;
}
/**
* Set portfolio_name
*
* #param string $portfolioName
*/
public function setPortfolioName($portfolioName)
{
$this->portfolio_name = $portfolioName;
}
/**
* Get portfolio_name
*
* #return string
*/
public function getPortfolioName()
{
return $this->portfolio_name;
}
/**
* Set description
*
* #param text $description
*/
public function setDescription($description)
{
$this->description = $description;
}
/**
* Get description
*
* #return text
*/
public function getDescription()
{
return $this->description;
}
/**
* Set permalink
*
* #param string $permalink
*/
public function setPermalink($permalink)
{
$this->permalink = $permalink;
}
/**
* Get permalink
*
* #return string
*/
public function getPermalink()
{
return $this->permalink;
}
/**
* Set sharing_code
*
* #param string $sharingCode
*/
public function setSharingCode($sharingCode)
{
$this->sharing_code = $sharingCode;
}
/**
* Get sharing_code
*
* #return string
*/
public function getSharingCode()
{
return $this->sharing_code;
}
/**
* Set shared
*
* #param boolean $shared
*/
public function setShared($shared)
{
$this->shared = $shared;
}
/**
* Get shared
*
* #return boolean
*/
public function getShared()
{
return $this->shared;
}
/**
* Set shared_portfolio_calls
*
* #param integer $sharedPortfolioCalls
*/
public function setSharedPortfolioCalls($sharedPortfolioCalls)
{
$this->shared_portfolio_calls = $sharedPortfolioCalls;
}
/**
* Get shared_portfolio_calls
*
* #return integer
*/
public function getSharedPortfolioCalls()
{
return $this->shared_portfolio_calls;
}
/**
* Set patentgroup_id
*
* #param integer $patentgroupId
*/
public function setPatentgroupId($patentgroupId)
{
$this->patentgroup_id = $patentgroupId;
}
/**
* Get patentgroup_id
*
* #return integer
*/
public function getPatentgroupId()
{
return $this->patentgroup_id;
}
}
The error I am getting is
No mapping file found named 'IDP.Bundle.Entity.Portfolio.php' for class 'IDP\Bundle\Entity\Portfolio'.
Am I missing anything ?
Thanks?
You need to add #ORM\Entity to your Entity class. Try:
<?php
namespace IDP\Bundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* IDP\Bundle\Entity\Portfolio
*
* #ORM\Entity
* #ORM\Table(name="pm_portfolios")
*/
class Portfolio
{
You'll also need to add ORM mappings to each property of your Portfolio entity (see http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/annotations-reference.html#annref-column).
I got the same error and found the reason to having used annotations and yml at the same time..use only one at a time...

Categories