php and twig syntax - php

I have the following code to extract the username of an owner object. The Owner object is essentially the owner of the shop. Here's how it's defined in the Shop class.
/**
* Set owner
*
* #param User $owner
* #return Shop
*/
public function setOwner(User $owner = null)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* #return User
*/
public function getOwner()
{
return $this->owner;
}
/**
As you can see the owner returns a User object. However when I do .username to the User class I always get undefined. Why is this?
"<%= '/profile/'+item.get('shop').owner.username %>">
When I do the following:
"<%= '/profile/'+item.get('shop').name %>">
it prints out just fine.
Here's some more code on the Shop:
class Shop
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #Exclude()
* #ORM\Column(name="isVisible", type="boolean")
*/
private $isVisible = false;
/**
* #ORM\OneToOne(targetEntity="Shopious\MainBundle\Entity\ShopLogo", mappedBy="shop", cascade={"persist","remove"})
*/
protected $shoplogo;
/**
* #Assert\NotBlank(message="Shope name should not be blank")
* #ORM\Column(name="name", type="string", length=100, unique=true)
*/
protected $name;
/**
* Assert\NotBlank(message="Description should not be blank")
* #ORM\Column(name="description", type="string", length=350, nullable=true)
*/
protected $description = "";
/**
* #ORM\Column(name="tags", type="text",nullable=true)
*/
protected $tags = "";
/**
* #ORM\OneToMany(targetEntity="Shopious\MainBundle\Entity\Product", mappedBy="shop", cascade={"remove","persist"})
*/
protected $products;
/**
* #Exclude()
* #ORM\OneToOne(targetEntity="Shopious\UserBundle\Entity\User", inversedBy="shop")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE", nullable=true)
*/
protected $owner;
/**
* #Exclude()
* #ORM\OneToOne(targetEntity="Shopious\MainBundle\Entity\PaymentInfo", inversedBy="shop", cascade={"persist","remove"})
* #ORM\JoinColumn(name="paymentInfo_id", referencedColumnName="id" , onDelete="CASCADE")
*/
protected $paymentInfo;
/**
*
* #ORM\OneToMany(targetEntity="Shopious\MainBundle\Entity\ShopTestimonial", mappedBy="shop", cascade={"persist","remove"})
*/
protected $testimonials;
public function __toString()
{
return $this->shopname;
}
/**
* #ORM\PrePersist
*/
public function initialisation()
{
$this->shoplogo = new ShopLogo();
$this->shoplogo->setShop($this);
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set owner
*
* #param User $owner
* #return Shop
*/
public function setOwner(User $owner = null)
{
$this->owner = $owner;
return $this;
}
/**
* Get owner
*
* #return User
*/
public function getOwner()
{
return $this->owner;
}
/**
* Constructor
*/
public function __construct()
{
$this->products = new ArrayCollection();
}
/**
* Set shopname
*
* #param string $shopname
* #return Shop
*/
public function setName($shopname)
{
$this->name = $shopname;
//return $this;
}
/**
* Get shopname
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* Set description
*
* #param string $description
* #return Shop
*/
public function setDescription($description)
{
$this->description = $description;
return $this;
}
/**
* Get description
*
* #return string
*/
public function getDescription()
{
return $this->description;
}
/**
* Add products
*
* #param Product $products
* #return Shop
*/
public function addProduct(Product $products)
{
$this->products[] = $products;
return $this;
}
/**
* Remove products
*
* #param Product $products
*/
public function removeProduct(Product $products)
{
$this->products->removeElement($products);
}
/**
* Get products
*
* #return Collection
*/
public function getProducts()
{
return $this->products;
}
public function getPaymentInfo()
{
return $this->paymentInfo;
}
public function setPaymentInfo(\Shopious\MainBundle\Entity\PaymentInfo $paymentInfo)
{
$this->paymentInfo = $paymentInfo;
}
/**
* Set tags
*
* #param string $tags
* #return Shop
*/
public function setTags($tags)
{
$this->tags = $tags;
return $this;
}
/**
* Get tags
*
* #return string
*/
public function getTags()
{
return $this->tags;
}
/**
* Set shoplogo
*
* #param Shopious\MainBundle\Entity\ShopLogo $shoplogo
* #return Shop
*/
public function setShoplogo(\Shopious\MainBundle\Entity\ShopLogo $shoplogo = null)
{
$this->shoplogo = $shoplogo;
return $this;
}
/**
* Get shoplogo
*
* #return Shopious\MainBundle\Entity\ShopLogo
*/
public function getShoplogo()
{
return $this->shoplogo;
}
/**
* Add testimonials
*
* #param \Shopious\MainBundle\Entity\ShopTestimonial $testimonials
* #return Shop
*/
public function addTestimonial(\Shopious\MainBundle\Entity\ShopTestimonial $testimonials)
{
$this->testimonials[] = $testimonials;
return $this;
}
/**
* Remove testimonials
*
* #param \Shopious\MainBundle\Entity\ShopTestimonial $testimonials
*/
public function removeTestimonial(\Shopious\MainBundle\Entity\ShopTestimonial $testimonials)
{
$this->testimonials->removeElement($testimonials);
}
/**
* Get testimonials
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getTestimonials()
{
return $this->testimonials;
}
/**
* Set isVisible
*
* #param boolean $isVisible
* #return Product
*/
public function setIsVisible($isVisible)
{
$this->isVisible = $isVisible;
return $this;
}
/**
* Get isVisible
*
* #return boolean
*/
public function getIsVisible()
{
return $this->isVisible;
}
}
Some code of fetching the data values:
public function getItemsAction()
{
try{
$query = $this->getRequest()->query;
$em = $this->getDoctrine()->getEntityManager();
$items = $em->getRepository('ShopiousMainBundle:Product')->filterBy(
$query->get('category'),
$query->get('tag'),
$query->get('size'),
$query->get('price'),
$query->get('shop'),
$query->get('sort'),
$query->get('page')
);
return $this->Json($items);
}catch(\Exception $ex){
return $this->Json($ex->getMessage(),false);
}
}

I am guessing it is because their is not data for the relationship. It looks like you probably have an item that you are calling a method on to get another object and then calling another method on that object to get yet another object. Since the first call is a proxy object it probably doesn't load the second proxy object data with it. If you look at the data in the data outside the template like in the controller I am guessing it isn't defined there. you might want to make sure that the data is loaded prior to getting to the view. I think that the root of the problem is the initial relationship.
To help you might post some of your controller code where you are getting fetching the data or setting the values.

sounds like class Owner's name is stored into variable "name", not "username"

i think protected $username; doesnot exist only protected $name;
if you want
"<%= '/profile/'+item.get('shop').owner.username %>">
then change
add this to you class first
protected $username[];
public function addUsers(User $user = null)
{
array_push($this->username, $user);
return $this->username;
}
public function getUsers()
{
return $this->username;
}
or a single user
protected $username;
public function addUsers(User $user = null)
{
$this->username= $user;
return $this->username;
}
public function getUsers()
{
return $this->username;
}

Related

Symfony ArrayCollection vs PersistentCollection

As I understood when you query database by repository you get PersistentCollection and when your working with your entities you get ArrayCollection.
so consider I have one to many self referencing relation for my user entity.
and in my user entity I have a setChildren method which get ArrayCollection of users as argument .
<?php
namespace UserBundle\Entity;
use Abstracts\Entity\BaseModel;
use CertificateBundle\Entity\Certificate;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use EducationBundle\Entity\Education;
use LanguageBundle\Entity\Language;
use PostBundle\Entity\Post;
use ProfileBundle\Entity\Company;
use RoleBundle\Entity\Role;
use SkillBundle\Entity\Skill;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
/**
* User
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="UserBundle\Repository\Entity\UserRepository")
* #UniqueEntity("email")
* #UniqueEntity("username")
*/
class User implements UserInterface
{
use BaseModel;
/**
* #var int
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="type", type="string", columnDefinition="ENUM('merchant', 'company', 'customer') ")
*/
private $type;
/**
* #ORM\Column(type="string", unique=true)
* #Assert\NotBlank()
*/
private $username;
/**
* #var string
*
* #ORM\Column(type="string", length=255)
* #Assert\NotBlank()
*/
private $email;
/**
* #var string
* #ORM\Column(type="string", nullable=true)
*/
private $avatar = null;
/**
* #var string
* #ORM\Column(type="string", nullable=true)
*/
private $cover = null;
/**
* #ORM\OneToMany(targetEntity="PostBundle\Entity\Post", mappedBy="user", orphanRemoval=true, cascade={"persist", "remove"})
*/
private $posts;
/**
* #ORM\OneToMany(targetEntity="EducationBundle\Entity\Education" , mappedBy="user" , orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $educations;
/**
* #ORM\OneToMany(targetEntity="SkillBundle\Entity\SkillUser" , mappedBy="user" , orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $skills;
/**
* #ORM\OneToMany(targetEntity="LanguageBundle\Entity\LanguageUser" , mappedBy="user" , orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $languages;
/**
* #ORM\OneToMany(targetEntity="ResumeBundle\Entity\Resume" , mappedBy="user" , cascade={"all"})
*/
protected $resumes;
/**
* #ORM\OneToMany(targetEntity="CertificateBundle\Entity\CertificateUser" , mappedBy="user" , orphanRemoval=true, cascade={"persist", "remove"})
*/
protected $certificates;
/**
* #ORM\OneToOne(targetEntity="ProfileBundle\Entity\Company", mappedBy="user")
*/
protected $company;
/**
* #ORM\OneToOne(targetEntity="ProfileBundle\Entity\Customer", mappedBy="user")
*/
protected $customer;
/**
* #ORM\OneToOne(targetEntity="ProfileBundle\Entity\Merchant", mappedBy="user")
*/
protected $merchant;
/**
* #var string
* #Assert\NotBlank()
* #Assert\Length(min=4)
* #ORM\Column(name="password", type="string", length=255)
*
*/
private $password;
/**
* #ORM\ManyToMany(targetEntity="RoleBundle\Entity\Role", inversedBy="users", cascade={"persist"})
* #ORM\JoinTable(name="user_role", joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")}, inverseJoinColumns={#ORM\JoinColumn(name="role_id", referencedColumnName="id")})
*/
private $roles;
/**
* #ORM\ManyToOne(targetEntity="UserBundle\Entity\User", inversedBy="children")
* #ORM\JoinColumn(name="parent_id", referencedColumnName="id", onDelete="SET NULL")
*/
protected $parent;
/**
* #ORM\OneToMany(targetEntity="UserBundle\Entity\User", mappedBy="parent", orphanRemoval=true, cascade={"persist", "remove"})
*
*/
protected $children;
/**
* #var array
*/
public static $fields = [ 'email', 'username', 'id', 'avatar', 'cover', 'type'];
/**
* User Entity constructor.
*/
public function __construct(/*EncoderFactoryInterface $encoderFactory*/)
{
//$this->encoderFactory = $encoderFactory;
$this->posts = new ArrayCollection();
$this->skills = new ArrayCollection();
$this->languages = new ArrayCollection();
$this->certificates = new ArrayCollection();
$this->educations = new ArrayCollection();
$this->children = new ArrayCollection();
dump($this->children);
die();
}
/**
* #param User $user
* #return $this
*/
public function setParent(User $user)
{
$this->parent = $user;
return $this;
}
/**
* #return $this
*/
public function removeParent()
{
$this->parent = null;
return $this;
}
/**
* #param User $user
* #return $this
*/
public function addChild(User $user)
{
if(!$this->children->contains($user)){
$this->children->add($user);
}
return $this;
}
/**
* #param User $user
* #return bool
*/
public function hasChild(User $user)
{
return $this->children->contains($user);
}
/**
* #param User $user
* #return bool
*/
public function isChildOf(User $user)
{
return $user->getChildren()->contains($this);
}
/**
* #return ArrayCollection
*/
public function getChildren()
{
return $this->children;
}
/**
* #param User $user
* #return $this
*/
public function removeChild(User $user)
{
if($this->children->contains($user)){
$this->children->removeElement($user);
}
return $this;
}
/**
* #param ArrayCollection $users
* #return $this
*/
public function setChildren(ArrayCollection $users)
{
$this->children = $users;
return $this;
}
/**
* #return $this
*/
public function removeChildren()
{
$this->children->clear();
return $this;
}
/**
* #param ArrayCollection $certificates
* #return $this
*/
public function setCertificates(ArrayCollection $certificates)
{
$this->certificates = $certificates;
return $this;
}
/**
* #param Certificate $certificate
* #return $this
*/
public function addCertificate(Certificate $certificate)
{
if(!$this->certificates->contains($certificate))
$this->certificates->add($certificate);
return $this;
}
/**
* #param Certificate $certificate
* #return $this
*/
public function removeCertificate(Certificate $certificate)
{
if($this->certificates->contains($certificate))
$this->certificates->removeElement($certificate);
return $this;
}
/**
* #return $this
*/
public function removeCertificates()
{
$this->certificates->clear();
return $this;
}
/**
* #param ArrayCollection $skills
* #return $this
*/
public function setSkills(ArrayCollection $skills)
{
$this->skills = $skills;
return $this;
}
/**
* #param Skill $skill
* #return $this
*/
public function addSkill(Skill $skill)
{
if(!$this->skills->contains($skill))
$this->skills->add($skill);
return $this;
}
/**
* #param Skill $skill
* #return $this
*/
public function removeSkill(Skill $skill)
{
if($this->skills->contains($skill))
$this->skills->removeElement($skill);
return $this;
}
/**
* #return $this
*/
public function removeSkills()
{
$this->skills->clear();
return $this;
}
/**
* #param ArrayCollection $languages
* #return $this
*/
public function setLanguages(ArrayCollection $languages)
{
$this->languages = $languages;
return $this;
}
/**
* #param Language $language
* #return $this
*/
public function addLanguage(Language $language)
{
if(!$this->languages->contains($language))
$this->languages->add($language);
return $this;
}
/**
* #param Language $language
* #return $this
*/
public function removeLanguage(Language $language)
{
if($this->languages->contains($language))
$this->languages->removeElement($language);
return $this;
}
/**
* #return $this
*/
public function removeLanguages()
{
$this->languages->clear();
return $this;
}
/**
* #param ArrayCollection $posts
* #return $this
*/
public function setPosts(ArrayCollection $posts)
{
$this->posts = $posts;
return $this;
}
/**
* #param Post $post
* #return $this
*/
public function addPost(Post $post)
{
$this->posts->add($post);
return $this;
}
/**
* #param Post $post
* #return $this
*/
public function removePost(Post $post)
{
$this->posts->removeElement($post);
return $this;
}
/**
* #return $this
*/
public function removePosts()
{
$this->posts->clear();
return $this;
}
/**
* #param ArrayCollection $educations
* #return $this
*/
public function setEducations(ArrayCollection $educations)
{
$this->educations = $educations;
return $this;
}
/**
* #param Education $education
* #return $this
*/
public function addEducation(Education $education)
{
$this->educations->add($education);
return $this;
}
/**
* #param Education $education
* #return $this
*/
public function removeEducation(Education $education)
{
$this->educations->removeElement($education);
return $this;
}
/**
* #return $this
*/
public function removeEducations()
{
$this->educations->clear();
return $this;
}
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* #param integer $id
* #return $this
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* #return mixed
*/
public function getType()
{
return $this->type;
}
/**
* #param mixed $type
* #return $this
*/
public function setType($type)
{
$this->type = $type;
return $this;
}
/**
* Set email
*
* #param string $email
* #return User
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* #param $username
* #return $this
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* #return mixed
*/
public function getUsername()
{
return $this->username;
}
/**
* #return array
*/
public function getRoles()
{
return ['ROLE_USER', 'IS_AUTHENTICATED_ANONYMOUSLY'];
}
/**
* #param $password
* #return $this
*/
public function setPassword($password)
{
//$password =$this->encoderFactory->getEncoder($this)->encodePassword($password, $this->getSalt());
$this->password = $password;
return $this;
}
/**
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
*
*/
public function getSalt()
{
return md5(sha1('somesalt'));
}
/**
*
*/
public function eraseCredentials()
{
}
/**
* #param $cover
* #return $this
*/
public function setCover($cover)
{
$this->cover = $cover;
return $this;
}
/**
* #return string
*/
public function getCover()
{
return $this->cover;
}
/**
* #param $avatar
* #return $this
*/
public function setAvatar($avatar)
{
$this->avatar = $avatar;
return $this;
}
/**
* #return string
*/
public function getAvatar()
{
return $this->avatar;
}
/**
* #param Role $roles
*/
public function addRoles(Role $roles)
{
$this->roles[] = $roles;
}
/**
* #return mixed
*/
public function getRoles2()
{
return $this->roles;
}
/**
* #return array
*/
public function getRolesAsArray()
{
$rolesArray = [];
foreach ($this->getRoles2() as $role) {
$rolesArray[] = $role->getName();
}
return $rolesArray;
}
/**
* #return Company
*/
public function getCompany()
{
return $this->company;
}
/**
* #param Company $company
* #return $this
*/
public function setCompany(Company $company)
{
$this->company = $company;
return $this;
}
}
and this is what I want to do
$new_owner = $this->userRepository->findOneById($user_id, false);
$children = $old_owner->getChildren();
$old_owner->removeChildren();
$new_owner->setChildren($children);
and I get error which says :
Argument 1 passed to
Proxies__CG__\UserBundle\Entity\User::setChildren() must be an
instance of Doctrine\Common\Collections\ArrayCollection, instance of
Doctrine\ORM\PersistentCollection given
should I change my type hint in setChildren method to PersistentCollection ??
or I need to totally change my approach?
Short answer:
/**
* #param Doctrine\Common\Collections\Collection $users
* #return $this
*/
public function setChildren(Doctrine\Common\Collections\Collection $users)
{
$this->children = $users;
return $this;
}
Explanation:
If you look deep into Doctrine Classes you will see the following structure:
Array collection is class that implements interface Collection:
class ArrayCollection implements Collection, Selectable
PersistentCollection is class that extentds AbstractLazyCollection:
final class PersistentCollection extends AbstractLazyCollection implements Selectable
but AbstractLazyCollection implements Collection:
abstract class AbstractLazyCollection implements Collection
So:
Collection is interface, that you should use in method setChildren().
This is because of doctrine use lazy loading - mechanism that allow to load not all properties, but only these, that are needed.
Similar question:
Doctrine manyToMany return PersistentCollection instead of ArrayCollection
In your typing add Collection $children
use Doctrine\Common\Collections\Collection;
...
private ?Collection $children;
symfony: 5.3

Doctrine & Symfony2 join multiple tables

I've been struggling with doing a multiple join in DQL.
Here is my code:
$query = $em->createQuery(
'SELECT k
FROM AppBundle:Keyword k
JOIN k.company c
JOIN k.entry e
WHERE c.user = :id
ORDER BY k.name ASC'
)->setParameter('id',$user_id);
But it gives me "Notice: Undefined index: entry", when executing it.
Here is my keyword entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Keyword
*/
class Keyword
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $name;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set name
*
* #param string $name
* #return Keyword
*/
public function setName($name)
{
$this->name = $name;
return $this;
}
/**
* Get name
*
* #return string
*/
public function getName()
{
return $this->name;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $user;
/**
* Constructor
*/
public function __construct()
{
$this->user = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add user
*
* #param \AppBundle\Entity\User $user
* #return Keyword
*/
public function addUser(\AppBundle\Entity\User $user)
{
$this->user[] = $user;
return $this;
}
/**
* Remove user
*
* #param \AppBundle\Entity\User $user
*/
public function removeUser(\AppBundle\Entity\User $user)
{
$this->user->removeElement($user);
}
/**
* Get user
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getUser()
{
return $this->user;
}
/**
* Set user
*
* #param \AppBundle\Entity\User $user
* #return Keyword
*/
public function setUser(\AppBundle\Entity\User $user = null)
{
$this->user = $user;
return $this;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $company;
/**
* Add company
*
* #param \AppBundle\Entity\Company $company
* #return Keyword
*/
public function addCompany(\AppBundle\Entity\Company $company)
{
$this->company[] = $company;
return $this;
}
/**
* Remove company
*
* #param \AppBundle\Entity\Company $company
*/
public function removeCompany(\AppBundle\Entity\Company $company)
{
$this->company->removeElement($company);
}
/**
* Get company
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getCompany()
{
return $this->company;
}
/**
* Set company
*
* #param \AppBundle\Entity\Company $company
* #return Keyword
*/
public function setCompany(\AppBundle\Entity\Company $company = null)
{
$this->company = $company;
return $this;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $entry;
/**
* Add entry
*
* #param \AppBundle\Entity\Entry $entry
* #return Keyword
*/
public function addEntry(\AppBundle\Entity\Entry $entry)
{
$this->entry[] = $entry;
return $this;
}
/**
* Remove entry
*
* #param \AppBundle\Entity\Entry $entry
*/
public function removeEntry(\AppBundle\Entity\Entry $entry)
{
$this->entry->removeElement($entry);
}
/**
* Get entry
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getEntry()
{
return $this->entry;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $ranking;
/**
* Add ranking
*
* #param \AppBundle\Entity\Ranking $ranking
* #return Keyword
*/
public function addRanking(\AppBundle\Entity\Ranking $ranking)
{
$this->ranking[] = $ranking;
return $this;
}
/**
* Remove ranking
*
* #param \AppBundle\Entity\Ranking $ranking
*/
public function removeRanking(\AppBundle\Entity\Ranking $ranking)
{
$this->ranking->removeElement($ranking);
}
/**
* Get ranking
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getRanking()
{
return $this->ranking;
}
}
And my entry entity:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Entry
*/
class Entry
{
/**
* #var integer
*/
private $id;
/**
* #var string
*/
private $path;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set path
*
* #param string $path
* #return Entry
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get path
*
* #return string
*/
public function getPath()
{
return $this->path;
}
/**
* #var \AppBundle\Entity\Keyword
*/
private $keyword;
/**
* Set keyword
*
* #param \AppBundle\Entity\Keyword $keyword
* #return Entry
*/
public function setKeyword(\AppBundle\Entity\Keyword $keyword = null)
{
$this->keyword = $keyword;
return $this;
}
/**
* Get keyword
*
* #return \AppBundle\Entity\Keyword
*/
public function getKeyword()
{
return $this->keyword;
}
/**
* #var \Doctrine\Common\Collections\Collection
*/
private $ranking;
/**
* Constructor
*/
public function __construct()
{
$this->ranking = new \Doctrine\Common\Collections\ArrayCollection();
}
/**
* Add ranking
*
* #param \AppBundle\Entity\Ranking $ranking
* #return Entry
*/
public function addRanking(\AppBundle\Entity\Ranking $ranking)
{
$this->ranking[] = $ranking;
return $this;
}
/**
* Remove ranking
*
* #param \AppBundle\Entity\Ranking $ranking
*/
public function removeRanking(\AppBundle\Entity\Ranking $ranking)
{
$this->ranking->removeElement($ranking);
}
/**
* Get ranking
*
* #return \Doctrine\Common\Collections\Collection
*/
public function getRanking()
{
return $this->ranking;
}
}
Btw I'm pretty new with symfony and doctrine.
I appreciate all kinds of help!
You need to provide mapping information for each attribute in your model class as well as provide the Entity mapping for the class. Take a look at http://doctrine-common.readthedocs.org/en/latest/reference/annotations.html
Each of your model classes need the #ORM\Entity annotation to tell doctrine it is a mapped entity. So for your case you would have:
/**
* Entry
* #ORM\Entity
*/
class Entry
{
...
Then each attribute you want to be mapped to the database needs an #ORM\Column annotation. For example:
/**
* #var integer
* #ORM\Id #ORM\Column #ORM\GeneratedValue
*/
private $id;
/**
* #var string
* #ORM\Column(type="string")
*/
private $path;
Then you need to create relationship mapping annotations for any relationships between your models (Keyword -> Company, Keyword -> Entry etc), using one of the mappings on here http://doctrine-orm.readthedocs.org/en/latest/reference/association-mapping.html
Once you have all the correct mappings use the command line tool app/console doctrine:schema:update to make sure your model is in sync with your database.
Your DQL seems fine so once you have the correct mappings in place you might have better luck.

unexpected behaviour following changing entity relationships

my nightmare of a day continues.....
after implimenting a successful solution in an earlier thread where I need to alter my inter-entity relationships I am now getting this error when I try to log a user into the app:
CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\UndefinedMethodException: "Attempted to call method "getRole" on class "Closure"." at C:\Dropbox\xampp\htdocs\etrack3\src\Ampisoft\Bundle\etrackBundle\Entity\Users.php line 234
I changed from a manyToMany relationship, to a manyToOne/OneToMany between a Users/Roles entity.
Ive read that serialize could cause the issue but Ive taken it out and it didnt make any difference. The remnants of the serialize required methods are still in there so please ignore (unless they are the issue).
Please could someone tell me what Ive done wrong? Im wondering if its best to scrap all the database tables and start again!!!!
here is the entity class.
/**
* user
*
* #ORM\Table(name="users")
* #ORM\Entity(repositoryClass="Ampisoft\Bundle\etrackBundle\Entity\UsersRepository")
*/
class Users implements UserInterface
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="username", type="string", length=25, unique=true)
*/
private $username;
/**
* #var string
*
* #ORM\Column(name="password", type="string", length=64)
*/
private $password;
/**
* #ORM\Column(name="firstname", type="string", length=25)
*/
private $firstname;
/**
* #ORM\Column(name="surname", type="string", length=25)
*/
private $lastname;
/**
* #var boolean
*
* #ORM\Column(name="isActive", type="boolean")
*/
private $isActive = 1;
/**
* #var string
*
* #ORM\Column(name="email", type="string", length=255, unique=true)
*/
private $email;
/**
* #var \DateTime
*
* #ORM\Column(name="lastLogged", type="string")
*/
private $lastLogged = '-0001-11-30 00:00:00';
/**
* #var string;
*
* #ORM\Column(name="salt", type="string", length=255)
*/
private $salt;
/**
* #ORM\ManyToOne(targetEntity="Roles", inversedBy="users")
*
*/
private $roles;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set Id
*
* #return integer
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Set username
*
* #param string $username
* #return user
*/
public function setUsername($username)
{
$this->username = $username;
return $this;
}
/**
* Get username
*
* #return string
*/
public function getUsername()
{
return $this->username;
}
/**
* Set password
*
* #param string $password
* #return user
*/
public function setPassword($password)
{
$this->password = $password;
return $this;
}
/**
* Get password
*
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set isActive
*
* #param boolean $isActive
* #return user
*/
public function setIsActive($isActive)
{
$this->isActive = $isActive;
return $this;
}
/**
* Get isActive
*
* #return boolean
*/
public function getIsActive()
{
return $this->isActive;
}
/**
* Set email
*
* #param string $email
* #return user
*/
public function setEmail($email)
{
$this->email = $email;
return $this;
}
/**
* Get email
*
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set lastLogged
*
* #param \DateTime $lastLogged
* #return user
*/
public function setLastLogged($lastLogged)
{
$this->lastLogged = $lastLogged;
return $this;
}
/**
* Get lastLogged
*
* #return \DateTime
*/
public function getLastLogged()
{
return $this->lastLogged;
}
public function __construct()
{
$this->roles = new ArrayCollection();
$this->isActive = true;
}
/**
* #inheritDoc
*/
public function getRoles()
{
$roles = array();
foreach ($this->roles as $role) {
$roles[] = $role->getRole();
}
return $roles;
}
/**
* #param $roles
* #return $this
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
/**
* #inheritDoc
*/
public function eraseCredentials()
{
}
/**
* #inheritDoc
*/
public function getSalt()
{
return $this->salt;
}
public function setSalt($salt)
{
$this->salt = $salt;
return $this;
}
public function isAccountNonExpired()
{
return true;
}
public function isAccountNonLocked()
{
return true;
}
public function isCredentialsNonExpired()
{
return true;
}
public function isEnabled()
{
return $this->isActive;
}
/**
* Add roles
*
* #param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
* #return users
*/
public function addRoles(Roles $roles)
{
$this->roles[] = $roles;
return $this;
}
/**
* Remove roles
*
* #param \Ampisoft\Bundle\etrackBundle\Entity\Roles $roles
*/
public function removeRoles(Roles $roles)
{
$this->roles->removeElement($roles);
}
/**
* Set firstname
*
* #param string $firstname
* #return users
*/
public function setFirstname($firstname)
{
$this->firstname = $firstname;
return $this;
}
/**
* Get firstname
*
* #return string
*/
public function getFirstname()
{
return $this->firstname;
}
/**
* Set lastname
*
* #param string $lastname
* #return users
*/
public function setLastname($lastname)
{
$this->lastname = $lastname;
return $this;
}
/**
* Get lastname
*
* #return string
*/
public function getLastname()
{
return $this->lastname;
}
/**
* #see \Serializable::serialize()
*/
/**
* Serializes the content of the current User object
* #return string
*/
public function serialize()
{
return \json_encode(
array($this->username, $this->password, $this->salt,
$this->roles, $this->id));
}
/**
* Unserializes the given string in the current User object
* #param serialized
*/
public function unserialize($serialized)
{
list($this->username, $this->password, $this->salt,
$this->roles, $this->id) = \json_decode(
$serialized);
}
}
update 1
this has worked but produced a new error Im going to move it to a new question when the post timer lets me.
Catchable Fatal Error: Argument 4 passed to Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::__construct() must be of the type array, object given, called in C:\Dropbox\xampp\htdocs\etrack3\vendor\symfony\symfony\src\Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider.php on line 96 and defined
HI I think what you want is not this
public function getRoles()
{
$roles = array();
foreach ($this->roles as $role) {
$roles[] = $role->getRole();
}
return $roles;
}
but this
public function getRoles()
{
return $this->roles;
}
Roles should be an ArrayCollection already, so calling getRole on the ( I assume ) Role class seems to be possible the issue.
If you are using an IDE such as Eclipse then the class is Doctrine\Common\Collections\ArrayCollection; this should be your collection of Roles, I would suggest also is you are using an IDE to do something like this ( for type hinting )
//... at the top of the class file before the class deceleration
use Doctrine\Common\Collections\ArrayCollection;
/**
* #param ArrayCollection $roles
*/
public function setRoles(ArrayCollection $roles)
{
//.. type cast the input to allow only use of ArrayCollection class
$this->roles = $roles;
}
/**
* #return ArrayCollection
*/
public function getRoles()
{
return $this->roles;
}
Also there is a good chance you are setting $this->roles to be a standard array at some point. You should always type cast your input to a specific class if it can only accept that type of class to rule out errors such as using a plain array.
Last thing, is generally protected for the properties are preferred because latter you can extend the class, it's not accessible outside the class much like private, but unlike private it is accessible in inheriting classes.

PHP: Call to a member function .... on a non-object

hello I'm having trouble with:
public function isAdmin()
{
$role = $this->getFirstRole();
if ($role->getRoleId() == "admin")
return true;
return false;
}
it causes: Call to a member function getRoleId() on a non-object
please guys, help. thanks
classes:
class Role implements HierarchicalRoleInterface
{
/**
* Store id.
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* Store role kind.
* Possible user kinds: 'guest' (not signed in),
'user' (default for signed in user), 'admin'.
* #var string
* #ORM\Column(type="string", length=255,
unique=true, nullable=true)
*/
protected $roleId;
/**
* Store role parent for inheritance measure.
* #var Role
* #ORM\ManyToOne(targetEntity="User\Entity\Role")
*/
protected $parent;
/**
* Get id.
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
* #param int $id
* #return void
*/
public function setId($id)
{
$this->id = (int)$id;
}
/**
* Get role kind.
* #return string
*/
public function getRoleId()
{
return $this->roleId;
}
/**
* Set role kind.
* #param string $roleId
* #return void
*/
public function setRoleId($roleId)
{
$this->roleId = (string) $roleId;
}
/**
* Get parent role
* #return Role
*/
public function getParent()
{
return $this->parent;
}
/**
* Set parent role.
* #param Role $parent
* #return void
*/
public function setParent(Role $parent)
{
$this->parent = $parent;
}
}
class User implements UserInterface, ProviderInterface
{
/**
* Store id.
* #var int
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* Store username.
* #var string
* #ORM\Column(type="string", length=255, unique=true)
*/
protected $username;
/**
* Store email.
* #var string
* #ORM\Column(type="string", unique=true, length=255)
*/
protected $email;
/**
* Store displayName.
* #var string
* #ORM\Column(type="string", length=50, nullable=true)
*/
protected $displayName;
/**
* Store password.
* #var string
* #ORM\Column(type="string", length=128)
*/
protected $password;
/**
* Store state.
* #var int
*/
protected $state;
/**
* Store mark.
* #var float
*/
protected $mark;
/**
* Store roles collection.
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="User\Entity\Role")
* #ORM\JoinTable(name="users_roles",
* joinColumns={
#ORM\JoinColumn(
name="user_id",
referencedColumnName="id"
)
},
* inverseJoinColumns={
#ORM\JoinColumn(
name="role_id",
referencedColumnName="id"
)
}
* )
*/
protected $roles;
/**
* Store albums collection
* #var \Doctrine\Common\Collections\Collection
* #ORM\OneToMany(targetEntity="Album\Entity\Album", mappedBy="user",
cascade={"all"})
*/
protected $albums;
/**
* Store comments collection.
* #var \Doctrine\Common\Collections\Collection
* #ORM\OneToMany(targetEntity="Comment\Entity\Comment", mappedBy="user",
cascade={"all"})
*/
protected $comments;
/**
* Store marks collection.
* #var \Doctrine\Common\Collections\Collection
* #ORM\OneToMany(targetEntity="Mark\Entity\Mark", mappedBy="user",
cascade={"all"})
*/
protected $marks;
/**
* Initialies collections.
*/
public function __construct()
{
$this->roles = new ArrayCollection();
$this->albums = new ArrayCollection();
$this->comments = new ArrayCollection();
$this->marks = new ArrayCollection();
}
/**
* Get id.
* #return int
*/
public function getId()
{
return $this->id;
}
/**
* Set id.
* #param int $id
* #return void
*/
public function setId($id)
{
$this->id = (int) $id;
}
/**
* Get username.
* #return string
*/
public function getUsername()
{
return htmlspecialchars($this->username);
}
/**
* Set username.
* #param string $username
* #return void
*/
public function setUsername($username)
{
$this->username = $username;
}
/**
* Get email.
* #return string
*/
public function getEmail()
{
return $this->email;
}
/**
* Set email.
* #param string $email
* #return void
*/
public function setEmail($email)
{
$this->email = $email;
}
/**
* Get displayName.
* #return string
*/
public function getDisplayName()
{
return $this->displayName;
}
/**
* Set displayName.
* #param string $displayName
* #return void
*/
public function setDisplayName($displayName)
{
$this->displayName = $displayName;
}
/**
* Get password.
* #return string
*/
public function getPassword()
{
return $this->password;
}
/**
* Set password.
* #param string $password
* #return void
*/
public function setPassword($password)
{
$this->password = $password;
}
/**
* Get state.
* #return int
*/
public function getState()
{
return $this->state;
}
/**
* Set state.
* #param int $state
* #return void
*/
public function setState($state)
{
$this->state = $state;
}
/**
* Get roles collection.
* #return \Doctrine\Common\Collections\Collection
*/
public function getRoles()
{
return $this->roles;
}
public function getFirstRole() {
$roles = $this->getRoles();
$firstRole = $roles[0];
return $firstRole;
}
/**
* Get comments collection.
* #return \Doctrine\Common\Collections\Collection
*/
public function getComments()
{
return $this->comments;
}
/**
* Get marks collection.
* #return \Doctrine\Common\Collections\Collection
*/
public function getMarks()
{
return $this->marks;
}
/**
* Add a role to user.
* #param Role $role
* #return void
*/
public function addRole($role)
{
$this->roles[] = $role;
}
/**
* Get albums.
* #return \Doctrine\Common\Collections\Collection
*/
public function getAlbums()
{
return $this->albums;
}
public function isAdmin(){
$role = $this->getFirstRole();
if ($role->getRoleId() == "admin")
return true;
return false;
}
/**
* Calculate user mark.
* #return float
*/
public function mark()
{
if (!$this->mark) {
$albums = $this->getAlbums();
$result = 0;
foreach ($albums as &$album) {
$result += $album->mark();
}
$this->mark = $result;
}
return $this->mark;
}
}
anyone?
(writing this becaue it says my post is mostly code)
(writing this becaue it says my post is mostly code)
/**
* Get roles collection.
* #return \Doctrine\Common\Collections\Collection
*/
public function getRoles()
{
return $this->roles;
}
Collections are not accessed by [0], they are Collection objects, use like this:
public function getFirstRole() {
return $this->roles->first();
}
#h2ooooooo gave this helpful link to the docs, containing all methods of the collection: http://www.doctrine-project.org/api/common/2.3/class-Doctrine.Common.Collections.ArrayCollection.html
You can compare ID with an ID (integer), or string by string,
but the best is to compare Entities to keep the whole system integral:
public function isAdmin() {
$role = $this->getFirstRole();
$admin = $entityManager
->getRepository('User\Entity\Role')
->findOneByName('admin');
if ($role === $admin) {
return true;
} else {
return false;
}
}
it seems that $this->getFirstRole() returned user role as string. you just need to compare it as string.
try this:
public function isAdmin()
{
$role = $this->getFirstRole();
return $role == "admin" ? true : false;
}

FatalErrorException: Error: Call to a member function getId() on a non-object in ...PostListener.php line 20

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.

Categories