For a project, I need to manage "cards".
There are 2 card types : "Client card" and "Member card".
Cards can be ordered by a user of this application.
To achieve that, I created an abstract Card entity using a Type discriminator.
/* #ORM\Entity
* #ORM\Table(name="cards")
* #ORM\InheritanceType("SINGLE_TABLE")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"member"="MemberCard", "client"="ClientCard"})
*/
abstract class Card
{
const MEMBER = 'member';
const CLIENT = 'client';
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\Column(type="integer")
*/
protected $id;
/**
* #ORM\ManyToOne(targetEntity="CardsOrder", inversedBy="cards")
* #ORM\JoinColumn(name="order_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $order;
/**
* Return the card type
*
* #return string
*/
abstract public function getType();
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param CardsOrder $order
*
* #return $this
*/
public function setOrder(CardsOrder $order)
{
$this->order = $order;
return $this;
}
/**
* #return CardsOrder
*/
public function getOrder()
{
return $this->order;
}
}
The MemberCard entity
/**
* #ORM\Entity
*/
class MemberCard extends Card
{
/**
* #ORM\ManyToOne(targetEntity="Member", inversedBy="cards")
* #ORM\JoinColumn(name="member_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $member;
/**
* #param Member $member
*
* #return $this
*/
public function setMember(Member $member)
{
$this->member = $member;
return $this;
}
/**
* #return Member
*/
public function getMember()
{
return $this->member;
}
/**
* #return string
*/
public function getType()
{
return self::MEMBER;
}
}
The ClientCard entity
/**
* #ORM\Entity
*/
class ClientCard extends Card
{
/**
* ClientCard - client n-1 relation
*
* #ORM\ManyToOne(targetEntity="Client", inversedBy="cards")
* #ORM\JoinColumn(name="client_id", referencedColumnName="id", onDelete="CASCADE")
*/
protected $client;
/**
* #param \Admin\Crm\Entity\Client\Client $client
*
* #return $this
*/
public function setClient(Client $client)
{
$this->client = $client;
return $this;
}
/**
* #return Client
*/
public function getClient()
{
return $this->client;
}
/**
* #return string
*/
public function getType()
{
return self::CLIENT;
}
}
Now, I want to know if a member or a client has a pending ordered card (status is a binary status flag) :
public function findPendingCard($clientOrMember)
{
// $this->getRepository is the Card repository, injected in a factory
$query = $this->getRepository()->createQueryBuilder('c')
->join('c.order', 'o', 'WITH', 'BIT_AND(o.status, :oStatus) > 0')
->where('c INSTANCE OF :memberCardEntity AND c.member = :clientOrMember')
->orWhere('c INSTANCE OF :clientCardEntity AND c.client = :clientOrMember')
->setParameters([
'oStatus' => CardsOrder::OPEN,
'clientOrMember' => $clientOrMember,
'memberCardEntity' => MemberCard::class,
'clientCardEntity' => ClientCard::class,
])
->getQuery();
return $query->getOneOrNullResult();
}
But I got this error :
[Semantical Error] line 0, col 148 near 'member = :clientOrMember)': Error: Class Card has no field or association named member
Any idea what I'm doing wrong?
It's not so much that you're doing something wrong, but there is a method to work around the issue. You can make it possible to return the card type with the following.
In class Card add:
public function getCardType()
{
return $this->discr;
}
in class MemberCard add:
protected $discr = 'member';
in class ClientCard add:
protected $discr = 'client';
Related
I am new with Symfony. I am working with version 3. I simplified my example. I have 3 Tables, for this tables I created a class for each one.
Table "Person": id | name
Table "Group": id | groupname
Table "PersonGroup": id | person | group
Every Person could be in several groups and every groups can have several persons. In the table PersonGroup I connect the persons with the groups. In my Controller I want to request in which group the selected person is. But in the Dump I only have the data from the PersonGroup table and not the details from the Group (in this example the name):
PersonGroup {#485 ▼
-id: 5
-person: Person {#456 ▼
-id: 4
-name: "Adam"
-personGroups: PersistentCollection {#445 ▶}
}
-group: Group {#486 ▼
+__isInitialized__: false
-id: 5
-name: null
-personGroups: null
…2
}
}
My Controller:
/**
* #Route("/person/{personId}", name="personController")
*/
public function showAction($personId)
{
$em = $this->getDoctrine()->getManager();
$item = $em->getRepository('AppBundle:Person')
->findOneBy(['id' => $personId]);
foreach ($person->getPersonGroup() as $personGroup) {
dump($personGroup);
}
return $this->render('person/detail.html.twig', [
'person' => $person
]);
}
Person class / entity:
class Person
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PersonGroup", mappedBy="person")
*/
private $personGroups;
/**
* Item constructor.
*/
public function __construct()
{
$this->personGroups= new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return ArrayCollection*
*/
public function getPersonGroups()
{
return $this->personGroups;
}
}
Group class/Entity:
class Group
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\Column(type="string")
*/
private $name;
/**
* #ORM\OneToMany(targetEntity="AppBundle\Entity\PersonGroup", mappedBy="group")
*/
private $personGroups;
/**
* Item constructor.
*/
public function __construct()
{
$this->personGroups= new ArrayCollection();
}
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return mixed
*/
public function getName()
{
return $this->name;
}
/**
* #param mixed $name
*/
public function setName($name)
{
$this->name = $name;
}
/**
* #return ArrayCollection*
*/
public function getPersonGroups()
{
return $this->personGroups;
}
}
PersonGroup class / entity:
class PersonGroup
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Person", inversedBy="group")
* #ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Group", inversedBy="person")
* #ORM\JoinColumn(nullable=false)
*/
private $group;
/**
* #return mixed
*/
public function getId()
{
return $this->id;
}
/**
* #param mixed $id
*/
public function setId($id)
{
$this->id = $id;
}
/**
* #return Person
*/
public function getPerson()
{
return $this->person;
}
/**
* #param Person $person
*/
public function setPerson(Person $person)
{
$this->person = $person;
}
/**
* #return Group
*/
public function getGroup()
{
return $this->group;
}
/**
* #param Group $group
*/
public function setGroup(Group $group)
{
$this->group = $group;
}
}
You can access to your Group entity from PersonGroup
/**
* #Route("/person/{personId}", name="personController")
*/
public function showAction($personId)
{
$em = $this->getDoctrine()->getManager();
$item = $em->getRepository('AppBundle:Person')
->findOneBy(['id' => $personId]);
foreach ($person->getPersonGroup() as $personGroup) {
dump($personGroup->getGroup());
}
return $this->render('person/detail.html.twig', [
'person' => $person
]);
}
But you should create a custom function in Group repository and Person repository to retrieve the correct entity.
EDIT
If you want te retrieve all the Group entity you should add a parameter fetch="EAGER" to your relations, it will automatically do aan innerJoin on your relation.
class PersonGroup
{
/**
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Person", inversedBy="group", fetch="EAGER")
* #ORM\JoinColumn(nullable=false)
*/
private $person;
/**
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\Group", inversedBy="person", fetch="EAGER")
* #ORM\JoinColumn(nullable=false)
*/
private $group;
For example if you want to get All Groups from a Person you can do a custom repository function.
Ex:
<?php
namespace AppBundle\Repository;
use AppBundle\Entity\Person;
/**
* GroupRepository
*
* This class was generated by the Doctrine ORM. Add your own custom
* repository methods below.
*/
class GroupRepository extends \Doctrine\ORM\EntityRepository
{
public function findByPerson(Person $person){
return $this->createQueryBuilder('g')
->leftJoin('g.personGroups', 'pg')
->leftJoin('pg.person', 'p')
->where('p.id = :personId')
->setParameter('personId', $person->getId())
->getQuery()->getResult();
}
}
I have a question.
I have 2 entity
/**
* #ORM\Entity
* #ORM\Table(name="call_center")
*/
class Call {
/**
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id
* #ORM\Column(type="integer")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="Number", mappedBy="number")
* #ORM\Column(type="string")
*/
private $number;
/**
* #ORM\Column(type="string")
*/
private $value;
......
getters setters
/**
* #ORM\Entity
* #ORM\Table(name="number")
*/
class Number {
/**
* #ORM\GeneratedValue(strategy="AUTO")
* #ORM\Id
* #ORM\Column(type="integer")
*
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="Call", inversedBy="number")
* #ORM\JoinColumn(nullable=false)
*/
private $number;
/**
* #ORM\Column(type="string")
*/
private $link;
And I would like to show my data in controller.
This is my controller
class DefaultController extends Controller
{
/**
* #Route("/pl/", name="homepage")
*/
public function indexAction(Request $request)
{
$em = $this->getDoctrine()->getRepository('AppBundle:Call')->findAll();
foreach ($em as $name) {
switch(1) {
case $name->getNumber():
echo $name->getValue();
echo $name->getLink(); <----PROBLEME
break;
default:
break;
}
}
return $this->render('default/index.html.twig', array(
'em' => $name
));
}
}
Data with entity call displayed but I don't know how dipsplay data from Number (getLink()). The problem is that I have a loop in which I have to display for a particular value relationship. Probably I have to create repository for entity?
Entity Call
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set number
*
* #param string $number
*
* #return Call
*/
public function setNumber($number)
{
$this->number = $number;
return $this;
}
/**
* Get number
*
* #return string
*/
public function getNumber()
{
return $this->number;
}
/**
* Set value
*
* #param string $value
*
* #return Call
*/
public function setValue($value)
{
$this->value = $value;
return $this;
}
/**
* Get value
*
* #return string
*/
public function getValue()
{
return $this->value;
}
entity Number
/**
* Set number
*
* #param \AppBundle\Entity\Call $number
*
* #return Number
*/
public function setNumber(\AppBundle\Entity\Call $number)
{
$this->number = $number;
return $this;
}
/**
* Get number
*
* #return \AppBundle\Entity\Call
*/
public function getNumber()
{
return $this->number;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set link
*
* #param string $link
*
* #return Number
*/
public function setLink($link)
{
$this->link = $link;
return $this;
}
/**
* Get link
*
* #return string
*/
public function getLink()
{
return $this->link;
}
Maybe you have a string because you tell doctrine to put a string ?
remove the following annotation from your relation :
#ORM\Column(type="string")
Have you tried to access it via $name->getNumber()->getLink() ?
as pointed out below, by tny, you should fix your annotations, or the above will not work, as getNumber() is currently returning a string instead of a Number instance
I need to merge table 'fos_user' and 'institution'.And I need to display registration form from both entities.
I have a problem with FOSUserBundle.
I created new properties in User class
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
protected $workPhone;
protected $adminPhone;
protected $name;
protected $adress;
public function __construct()
{
parent::__construct();
}
public function setAdress($adress)
{
$this->adress = $adress;
}
public function setName($name)
{
$this->name = $name;
}
public function setWorkPhone($workPhone)
{
$this->workPhone = $workPhone;
}
public function setAdminPhone($adminPhone)
{
$this->adminPhone = $adminPhone;
}
public function getName()
{
return $this->name;
}
public function getAdress()
{
return $this->adress;
}
public function getWorkPhone()
{
return $this->workPhone;
}
public function getAdminPhone()
{
return $this->adminPhone;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
And I have entity Institution, which I want merge.
/**
* #var integer
*
* #ORM\Column(name="id_institution", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $idInstitution;
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=45, nullable=false)
*/
private $name;
/**
* #var integer
*
* #ORM\Column(name="work_phone", type="integer", nullable=false)
*/
private $workPhone;
/**
* #var integer
*
* #ORM\Column(name="admin_phone", type="integer", nullable=true)
*/
private $adminPhone;
/**
* #var string
*
* #ORM\Column(name="adress", type="string", length=255, nullable=false)
*/
private $adress;
/**
* #var \AppBundle\Entity\FosUser
*
* #ORM\ManyToOne(targetEntity="AppBundle\Entity\FosUser")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="id_fos_user", referencedColumnName="id")
* })
*/
private $idFosUser;
/**
* Get idInstitution
*
* #return integer
*/
public function getIdInstitution()
{
return $this->idInstitution;
}
/**
* Set name
*
* #param string $name
* #return Institution
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set workPhone
*
* #param integer $workPhone
* #return Institution
*/
public function setWorkPhone($workPhone)
{
$this->workPhone = $workPhone;
return $this;
}
/**
* Get workPhone
*
* #return integer
*/
public function getWorkPhone()
{
return $this->workPhone;
}
/**
* Set adminPhone
*
* #param integer $adminPhone
* #return Institution
*/
public function setAdminPhone($adminPhone)
{
$this->adminPhone = $adminPhone;
return $this;
}
/**
* Get adminPhone
*
* #return integer
*/
public function getAdminPhone()
{
return $this->adminPhone;
}
/**
* Set adress
*
* #param string $adress
* #return Institution
*/
public function setAdress($adress)
{
$this->adress = $adress;
return $this;
}
/**
* Get adress
*
* #return string
*/
public function getAdress()
{
return $this->adress;
}
/**
* Set idFosUser
*
* #param \AppBundle\Entity\FosUser $idFosUser
* #return Institution
*/
public function setIdFosUser($idFosUser = null)
{
$this->idFosUser = $idFosUser;
return $this;
}
/**
* Get idFosUser
*
* #return \AppBundle\Entity\FosUser
*/
public function getIdFosUser()
{
return $this->idFosUser;
}
This is pert of InstitutionManager where I want save Entity, and this is like service now:
public function createNewEntity($user)
{
$entity = new Institution();
$entity->setName($user->getName());
$entity->setAdminPhone($user->getAdminPhone());
$entity->setWorkPhone($user->getWorkPhone());
$entity->setAdress($user->getAdress());
$entity->setidFosUser($user->getId());
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
}
And hear override RegistrationController:
public function registerAction()
{
$form = $this->container->get('fos_user.registration.form');
$formHandler = $this->container->get('fos_user.registration.form.handler');
$confirmationEnabled = $this->container->getParameter('fos_user.registration.confirmation.enabled');
$process = $formHandler->process($confirmationEnabled);
if ($process) {
$user = $form->getData();
$authUser = false;
if ($confirmationEnabled) {
$this->container->get('session')->set('fos_user_send_confirmation_email/email', $user->getEmail());
$route = 'fos_user_registration_check_email';
} else {
$authUser = true;
$route = 'fos_user_registration_confirmed';
}
$this->setFlash('fos_user_success', 'registration.flash.user_created');
$institutionManager = $this->container->get('institution_manager');
$institution = $institutionManager->createNewEntity($user);
$url = $this->container->get('router')->generate($route);
$response = new RedirectResponse($url);
if ($authUser) {
$this->authenticateUser($user, $response);
}
return $response;
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
'form' => $form->createView(),
));
}
services.yml:
services:
institution_manager:
class: AppBundle\Lib\Manager\InstitutionManager
arguments: [ #doctrine.orm.default_entity_manager ]
Your InstitutationController is not being properly initialized. There is a setContainer method which the router calls to, well, set the container. getDoctrine in turn needs the container, hence the null object error.
A simple hack would be to call the setContainer method yourself:
$entity = new InstitutionController();
$entity->setContainer($this->container);
$entity->createNewEntity($user);
But it's a hack you should do some redesigning. What you are calling a controller is not a controller at all. It's a service, maybe a sort of a factory or manager. Sort of like the FOS UserManager.
So read up on how to define a service: http://symfony.com/doc/current/book/service_container.html
It takes a bit of research but once you understand the process then services will become second nature. You will inject the doctrine entity manager directly into your service.
class InstitutionManager
{
protected $entityManager;
public function __construct($entityManager)
{
$this->entityManager = $entityManager;
}
public function createNewEntity($user)
{
$entity = new Institution();
$entity->setName($user->getName());
$entity->setAdminPhone($user->getAdminPhone());
$entity->setWorkPhone($user->getWorkPhone());
$entity->setAdress($user->getAdress());
$entity->setidFosUser($user->getId());
$this->entityManager->persist($entity);
$this->entityManager->flush();
return $entity;
}
I will leave services.yml up to you. The entity manager service id is doctrine.orm.default_entity_manager
Your controller would then look like:
$institutionManager = $this->get('institution_manager');
$institution = $institutionManager->create($user);
You will also want to rethink how you are relating the user object. The userId stuff is a no no. You will want to make a one-to-one relation between $institution and $user. But that is really a different topic.
Enjoy.
I have an User entity and a mission entity, that are associated
In the profiler of symfony i get two errors.
For the class Acme\ManagementBundle\Entity\User I get:
The mappings Acme\ManagementBundle\Entity\User#missions and Acme\ManagementBundle\Entity\Mission#users are incosistent with each other.
For the class Acme\ManagementBundle\Entity\Mission I get:
The association Acme\ManagementBundle\Entity\Mission#users refers to the inverse side field Acme\ManagementBundle\Entity\User#users which does not exist.
I tried to solve by myself reading here but I could't.
My mission entity is:
class Mission {
/**
* #ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\User", inversedBy="users")
*/
protected $users;
public function __construct(){
$this -> users = new ArrayCollection();
}
/**
* Add users
*
* #param \Acme\ManagementBundle\Entity\User $users
* #return Mission
*/
public function addUser(\Acme\ManagementBundle\Entity\User $users)
{
$this->users[] = $users;
return $this;
}
/**
* Remove users
*
* #param \Acme\ManagementBundle\Entity\User $users
*/
public function removeUser(\Acme\ManagementBundle\Entity\User $users)
{
$this->users->removeElement($users);
}
/**
* Get users
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUsers()
{
return $this->users;
}
//...
}
And my user entity:
abstract class User extends BaseUser
{
/**
* #ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\Mission", mappedBy="users")
*/
protected $missions;
public function __construct(){
parent::__construct();
$this -> missions = new ArrayCollection();
}
/**
* Add missions
*
* #param \Acme\ManagementBundle\Entity\Mission $missions
* #return User
*/
public function addMission(\Acme\ManagementBundle\Entity\Mission $missions)
{
$this->missions[] = $missions;
return $this;
}
/**
* Remove missions
*
* #param \Acme\ManagementBundle\Entity\Mission $missions
*/
public function removeMission(\Acme\ManagementBundle\Entity\Mission $missions)
{
$this->missions->removeElement($missions);
}
/**
* Get missions
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getMission()
{
return $this->missions;
}
}
You have wrong annotation in the users property in Mission class. It should be:
/**
* #ORM\ManyToMany(targetEntity="Acme\ManagementBundle\Entity\User", inversedBy="missions")
*/
protected $users;
I'm new in Symfony2. I've a task to create blog. One of the necessary is displaying most popular posts. So I think that the best varient is create listener. It will be call, when visiter will read post. And listener will increment onе of the fild in database(MySQL). I create method in repository, which makes selection by this field. And also create Action, which renders posts by this selection. But when I try to read post, a have error:
FatalErrorException: Error: Call to a member function getId() on a non-object in /var/www/blo/src/Blog/Bundle/BlogBundle/EventListener/PostVisitedListener.php line 20.
Please, help me.
This my Entity (Post):
namespace Blog\Bundle\BlogBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Gedmo\Mapping\Annotation as Gedmo;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Post
*
* #ORM\Table(name="post")
* #ORM\Entity(repositoryClass="Blog\Bundle\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)
* #Assert\NotBlank
* #Assert\Length(min="13", max="255")
*/
private $title;
/**
* #var string
*
* #ORM\Column(name="author", type="string", length=100)
* #Assert\NotBlank
* #Assert\Length(min="13", max="100")
*/
private $author;
/**
* #var string
*
* #ORM\Column(name="post", type="text")
* #Assert\NotBlank
* #Assert\Length(min="100")
*/
private $post;
/**
* #var string
*
* #ORM\Column(name="image", type="string", length=100)
*/
private $image;
/**
* #Gedmo\Timestampable(on="create")
* #ORM\Column(name="createdAt", type="datetime")
*
*/
private $createdAt;
/**
*
* #ORM\Column(name="tags", type="text")
*/
private $tags;
/**
* #ORM\ManyToOne(targetEntity="Category", inversedBy="posts")
*/
private $category;
/**
* #ORM\OneToMany(targetEntity="Comment", mappedBy="post")
*/
private $comments;
/**
* #var integer
*
* #ORM\Column(name="visitedIncrement", type="integer")
*/
private $visitedIncrement;
public function __construct()
{
$this->comments = 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 author
*
* #param string $author
* #return Post
*/
public function setAuthor($author)
{
$this->author = $author;
return $this;
}
/**
* Get author
*
* #return string
*/
public function getAuthor()
{
return $this->author;
}
/**
* Set post
*
* #param string $post
* #return Post
*/
public function setPost($post)
{
$this->post = $post;
return $this;
}
/**
* Get post
*
* #return string
*/
public function getPost()
{
return $this->post;
}
/**
* Set image
*
* #param string $image
* #return Post
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* #return string
*/
public function getImage()
{
return $this->image;
}
/**
* Set tags
*
* #param string $tags
* #return Post
*/
public function setTags($tags)
{
$this->tags = $tags;
return $this;
}
/**
* Get tags
*
* #return string
*/
public function getTags()
{
return $this->tags;
}
/**
* Set category
*
* #param $category
* #return $this
*/
public function setCategory($category)
{
$this->category = $category;
return $this;
}
/**
* Get category
*
* #return integer
*/
public function getCategory()
{
return $this->category;
}
/**
* Set comments
*
* #param string $comments
* #return Post
*/
public function setComments($comments)
{
$this->comments = $comments;
return $this;
}
/**
* Get comments
*
* #return string
*/
public function getComments()
{
return $this->comments;
}
/**
* #param \DateTime $createdAt
*/
public function setCreatedAt($createdAt)
{
$this->createdAt = $createdAt;
return $this;
}
/**
* #return \DateTime
*/
public function getCreatedAt()
{
return $this->createdAt;
}
/**
* #param int $visitedIncrement
*/
public function setVisitedIncrement($visitedIncrement)
{
$this->visitedIncrement = $visitedIncrement;
return $this;
}
/**
* #return int
*/
public function getVisitedIncrement()
{
return $this->visitedIncrement;
}
public function __toString()
{
return $this->getTitle();
}
}
This is my PostRepository
public function visitedIncrement($id)
{
$query = $this->getEntityManager()
->createQuery(
'UPDATE BlogBlogBundle:Post p
SET p.visitedIncrement = p.visitedIncrement + 1
WHERE p.id = :post_id')
->setParameter(':post_id', $id);
$query->execute();
This is my PostVisitedEvent
namespace Blog\Bundle\BlogBundle\Event;
use Blog\Bundle\BlogBundle\Entity\Post;
use Symfony\Component\EventDispatcher\Event;
class PostVisitedEvent extends Event
{
protected $post;
/**
* #param Post $post
*/
public function setPost(Post $post)
{
return $this->post;
}
/**
* #return Post
*/
public function getPost()
{
return $this->post;
}
}
This is my PostVisitedListener
namespace Blog\Bundle\BlogBundle\EventListener;
use Blog\Bundle\BlogBundle\Entity\PostRepository;
use Doctrine\ORM\EntityManager;
use Blog\Bundle\BlogBundle\Event\PostVisitedEvent;
class PostVisitedListener
{
protected $repository;
public function __construct(PostRepository $repository)
{
$this->repository = $repository;
}
public function onPostVisited(PostVisitedEvent $event)
{
$this->repository->visitedIncrement($event->getPost()->getId());
}
This is my Action (it opens post and gives a opportunity to create comment):
public function showPostAction($id)
{
$postRepository = $this->container->get('blog_blog_bundle.post.repository');
$post = $postRepository->find($id);
if (!$post) {
throw $this->createNotFoundException('The post is not found!');
}
$commentRepository = $this->container->get('blog_blog_bundle.comment.repository');
$comments = $commentRepository->findCommentForPost($post->getId());
$event = new PostVisitedEvent();
$event->setPost($post);
$eventDispatcher = $this->get('event_dispatcher');
$eventDispatcher->dispatch('blog_blog_bundle.post_visited', $event);
return $this->render('BlogBlogBundle:Default:showPost.html.twig', array(
'post' => $post,
'comments' => $comments,
));
}
Yuo can see, that I also create services for repositories and listener. There are:
service id="blog_blog_bundle.post.repository" class="Blog\Bundle\BlogBundle\Entity\PostRepository" factory-service="doctrine.orm.entity_manager" factory-method="getRepository"
argument>BlogBlogBundle:Post argument
service
service id="blog_blog_bundle.comment.repository" class="Blog\Bundle\BlogBundle\Entity\CommentRepository" factory-service="doctrine.orm.entity_manager" factory-method="getRepository"
argument BlogBlogBundle:Comment argument
service
service id="blog_blog_bundle.post_visited_listener" class="Blog\Bundle\BlogBundle\EventListener\PostVisitedListener"
argument type="service" id="blog_blog_bundle.post.repository"
tag name="kernel.event_listener" event="blog_blog_bundle.post_visited" method="onPostVisited"
service
Please, help me.
public function onPostVisited(PostVisitedEvent $event)
{
if (!($event->getPost() instanceof PostInterface)) return;
$this->repository->visitedIncrement($event->getPost()->getId());
}
PostInterface is not a symfony interface. You have to code it. Asking for interface is better than asking for a concrete instance because symfony sometimes uses proxy classes instead of concrete classes.