doctrine 2, how do get data from the inverse side (many to one) - doctrine

I have two entities, entry and comments.
comments:
/**
* #Entity(repositoryClass="\Entities\Blog\CommentRepository")
* #Table(name="blog_comment")
* #HasLifecycleCallbacks
*/
class Comment extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ManyToOne(targetEntity="Entry", inversedBy="comments")
* #JoinColumn(name="entry_id", referencedColumnName="id")
*/
protected $entry;
/** #Column(name="approved", type="string", length=255) */
protected $approved;
/** #Column(name="title", type="string", length=255) */
protected $title;
/** #Column(name="content", type="text") */
protected $content;
/** #Column(name="pub_date", type="datetime") */
protected $pub_date;
/** #Column(type="datetime") */
private $created_at;
/** #Column(type="datetime") */
private $updated_at;
/** #PreUpdate */
public function updated()
{
$this->updated_at = new \DateTime("now");
}
public function __construct()
{
$this->created_at = $this->updated_at = new \DateTime("now");
}
}
class CommentRepository extends \Entities\PaginatedRepository
{
protected $_entityClassName = 'Entities\Blog\Comment';
}
and entry:
<?php
namespace Entities\Blog;
/**
* #Entity(repositoryClass="\Entities\Blog\EntryRepository")
* #Table(name="blog_entry")
* #HasLifecycleCallbacks
*/
class Entry extends \Entities\AbstractEntity
{
/**
* #Id #Column(name="id", type="integer")
* #GeneratedValue(strategy="AUTO")
*/
protected $id;
/** #Column(name="permalink", type="string", length=255) */
protected $permalink;
/** #Column(name="title", type="string", length=255) */
protected $title;
/** #Column(name="pub_date", type="datetime") */
protected $pub_date;
/** #Column(name="content", type="text") */
protected $content;
/** #OneToMany(targetEntity="Comment", mappedBy="entry") */
protected $comments;
/** #Column(type="datetime") */
private $created_at;
/** #Column(type="datetime") */
private $updated_at;
/** #PreUpdate */
public function updated()
{
$this->updated_at = new \DateTime("now");
}
public function __construct()
{
$this->comments = new \Doctrine\Common\Collections\ArrayCollection();
}
I can get the collection of all comments belonging to each entry via:
foreach ($comments as $comment){
$comment-$commentId;
}
but how can I get the entry information from the comments side. for example, I would like to get the entry id from a specific comment

Each time you create a #OneToMany relation, you create a Collection of proxy objects in class on "One"-side of relation, and single proxy object in class on "Many"-side of relation. Proxy classes are automatically generated by Doctrine2 from your mapping information.
To allow Doctrine2 filling proxy object with real data from DB it's important to declare it protected or private. I'm not sure about that, but seems like Doctrine tracks down any requests to proxy objects inside your entity class and ensures that proxies are populated before first usage.
To access the associated object you have to define accessor function in your Comment class:
class Comment extends \Entities\AbstractEntity{
/** other definitions */
function getEntity(){
return $this->entity;
}
}
And use it like
$comment = $em->find("Entities\Comment",1);
$entity = $comment->getEntity();
Doctrine2 will automatically populate $comment->entity proxy with actual Entity object.
See "Workin with Objects" chapter of Doctrine documentation and "Can you explain me what is a Proxy in Doctrine 2?" on details of proxies.

Related

Prestashop 1.7.x differences cookies

I am using cookies successfully in Prestashop but I am not clear what is the difference between this way
$context = Context::getContext();
$context->cookie->__set("mycookie","myvalue");
and this
$cookie = new Cookie('mycookie');
$cookie->setExpire(time() + 30 * 60);
$cookie->variable_name = ......
Thank you.
Context in prestashop is you can say global object; which keeps detailed information of main objects that is used mainly regularly; for ex. cart, customer, link etc. Context keeps details of below objects;
/** #var Cart */
public $cart;
/** #var Customer */
public $customer;
/** #var Cookie */
public $cookie;
/** #var Link */
public $link;
/** #var Country */
public $country;
/** #var Employee */
public $employee;
/** #var AdminController|FrontController */
public $controller;
/** #var string */
public $override_controller_name_for_translations;
/** #var Language */
public $language;
/** #var Currency */
public $currency;
/** #var AdminTab */
public $tab;
/** #var Shop */
public $shop;
/** #var Theme */
public $theme;
/** #var Smarty */
public $smarty;
So in context as you can see Cookie object is also included.
When you use new Cookie('mycookie'); it will use separate Cookie class to create object.

Doctrine in laravel, getting all user's roles

I have a simple project in laravel 5.4 with Doctrine 2.0. I have three tables: users, roles, user_roles. Screenshot from tables schemas from HEIDISQL I show below:
users:
roles:
user_roles:
I have three Entities classes for each table of course:
<?php
namespace TodoList\Http\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="users")
*/
class User
{
/**
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
*
*/
private $id;
/**
*
* #ORM\Column(type="string")
*
*/
private $name;
/**
*
* #ORM\Column(type="string")
*
*/
private $email;
/**
* #ORM\OneToMany(targetEntity="Task", mappedBy="user", cascade={"persist"})
* #var ArrayCollection|Task[]
*/
private $tasks;
/**
* #ORM\OneToMany(targetEntity="UserRole", mappedBy="user")
*/
protected $user_roles;
/**
* User constructor
* #param #name
* #param #email
* #param $password
*/
public function __construct($name, $email) {
$this->name = $name;
$this->email = $email;
$this->tasks = new ArrayCollection();
$this->user_roles = new ArrayCollection();
}
/**
*
* #return mixed
*
*
*/
public function getName()
{
return $this->name;
}
/**
* #return mixed
*/
public function getEmail()
{
return $this->email;
}
/**
* #return mixed
*/
public function getTasks()
{
return $this->tasks;
}
public function addTask(Task $task)
{
if(!$this->tasks->contains($task)) {
$task->setUser($this);
$this->tasks->add($task);
}
}
public function getId(){
return $this->id;
}
public function getUserRoles(){
return $this->user_roles;
}
}
<?php
namespace TodoList\Http\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="roles")
*
*/
class Role{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #var string
*
* #ORM\Column(name="name", type="string")
*/
private $name;
/**
* #var string
*
* #ORM\Column(name="description", type="text")
*/
private $description;
/**
* #ORM\OneToMany(targetEntity="UserRole", mappedBy="role",cascade={"persist"})
*/
protected $user_roles;
public function getId(){
return $this->id;
}
public function getName(){
return $this->name;
}
public function getDescription(){
return $this->description;
}
}
<?php
namespace TodoList\Http\Entities;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="user_roles")
*/
class UserRole
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="User", inversedBy="user_roles")
* #ORM\JoinColumn(name="user_id", referencedColumnName="id")
*
*/
private $user;
/**
*
* #ORM\ManyToOne(targetEntity="Role", inversedBy="user_roles")
* #ORM\JoinColumn(name="role_id", referencedColumnName="id")
*/
private $role;
public function setUser(User $user)
{
$this->user = $user;
return $this;
}
/**
* Get user
*
* #return \NVC\UserBundle\Entity\User
*/
public function getUser()
{
return $this->user;
}
/**
* Set recipe
*
* #param \NVC\RecipeBundle\Entity\Recipe $recipe
* #return UserRecipeAssociation
*/
public function setRole(Role $role)
{
$this->role = $role;
return $this;
}
/**
* Get recipe
*
* #return \NVC\RecipeBundle\Entity\Recipe
*/
public function getRole()
{
return $this->role;
}
}
I have a problem when I'm trying retrieve roles of particular user by doctrine Entity Managar. I'm trying to do that in that way:
public function showUserRoles(EntityManagerInterface $em){
$userRoles = $em->getRepository('\TodoList\Http\Entities\UserRole');
$userRoles->findBy(['user' => 2]);
//count($userRole);
}
There is an error from method findBy
Error message is:
(1/1) FatalErrorException
Doctrine\Common\Proxy\AbstractProxyFactory::getProxyDefinition():
Failed opening required
'C:\xampp\htdocs\Project\storage\proxies__CG__TodoListHttpEntitiesRole.php'
(include_path='C:\xampp\php\PEAR')
Is anything wrong with my Entities? I don't know how could I solve that problem. Could someone help me with that?
I would be very greateful
Best regards ;)
You need to set folder C:\xampp\htdocs\Project\storage\proxies\ as writable and then you need to generate proxies by console command:
doctrine:generate:proxies

How to get all property for a custom entity in FOSUserBundle?

I am using FOSUserBundle
I created a User entity that extents baseuser, and I added a protected property I called $apiKey. The registration form works fine.
then, I created a userController that extends controller, and in a methoid to edit my user I have:
$em = $this->getDoctrine()->getManager();
$user = $em->getRepository('AppBundle:User')->find($id);
my $user has the apiKey property but this is empty (of course the field in the DB is not).
any idea?
thanks
UPDATE: user entity
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* #ORM\Entity
* #ORM\Table(name="fos_user")
*/
class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #ORM\ManyToMany(targetEntity="AppBundle\Entity\Group")
* #ORM\JoinTable(name="fos_user_user_group",
* joinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="id")},
* inverseJoinColumns={#ORM\JoinColumn(name="group_id", referencedColumnName="id")}
* )
*/
protected $groups;
/**
* #ORM\Column(type="string", unique=true, nullable=true)
*/
protected $apiKey;
/* public function __construct()
{
parent::__construct();
// your own logic
//$this->roles = array('ROLE_USER'); //default role for new users
}*/
public function __construct()
{
parent::__construct();
// your own logic
$this->groups = new ArrayCollection();
}
/**
* #return mixed
*/
public function getApiKey()
{
return $this->apiKey;
}
/**
* #param mixed $apiKey
*/
public function setApiKey($apiKey)
{
$this->apiKey = $apiKey;
}
/**
* #return mixed
*/
public function getGroups()
{
return $this->groups;
}
/**
* #param mixed $groups
*/
public function setGroups($groups)
{
$this->groups = $groups;
}
}

Sonata admin configureFormField

i use sonata admin and i have a 'Fonctionnare' entity. i changed the 'codeFonctionnaire' type of this entity to string but when i create the Fonctionnaire admin class and try to add new fonctionaire i got this error message:
Neither the property "codeFonctionnaire" nor one of the methods "setCodeFonctionnaire()", "_set()" or "_call()" exist and have public access in class "Examens\ExamensBundle\Entity\Fonctionnaire".
Fonctionnaire.php:
<?php
namespace Examens\ExamensBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Fonctionnaire
*/
class Fonctionnaire
{
/**
* #var string
*/
private $codeFonctionnaire;
//////
/**
* Get codeFonctionnaire
*
* #return string
*/
public function getCodeFonctionnaire()
{
return $this->codeFonctionnaire;
}
////////
FonctionnaireAdmin.php:
<?php
namespace Examens\ExamensBundle\Admin;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;
use Examens\ExamensBundle\Entity\Fonctionnaire;
class FonctionnaireAdmin extends Admin
{
protected $datagridValues = array(
'_sort_order' => 'ASC',
'_sort_by' => 'codeFonctionnaire'
);
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('codeFonctionnaire','text',array('label'=>'Code fonctionnaire'))
//////
}
what's wrong with the entity?
You need to regenerate the getters and setters of your Fonctionnaire class. Your IDE can do it for you.
Or at least, just add a
public function setCodeFonctionnaire($codeFonctionnaire) {
$this->codeFonctionnaire = $codeFonctionnaire;
}
EDIT
Here is what might be your complete Fonctionnaire class :
namespace TechVehi\BlogBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
class Fonctionnaire {
/**
* #var string
*
* #ORM\Column(name="codeFonctionnaire", type="string", length=255, nullable=true)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $codeFonctionnaire;
/**
* #param string $codeFonctionnaire
*/
public function setCodeFonctionnaire($codeFonctionnaire) {
$this->codeFonctionnaire = $codeFonctionnaire;
}
/**
* #return string
*/
public function getCodeFonctionnaire() {
return $this->codeFonctionnaire;
}
}
You might have forgotten other informations, like the ORM annotation to link your object to your database.
i deleted this code from fonctionnaire.orm.yml:
generator:
strategy: IDENTITY
and it works.

Symfony2/Doctrine2 One-To-Many same object twice

My current Client-Entity has an unloading and a loading Area, which are both ClientArea-Entities.
namespace ACME\DemoBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Sorien\DataGridBundle\Grid\Mapping as GRID;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
/**
* ACME\DemoBundle\Entity\Client
*
* #ORM\Table()
* #ORM\Entity(repositoryClass="ACME\DemoBundle\Entity\ClientRepository")
*/
class Client
{
/**
* #ORM\OneToMany(targetEntity="ClientArea",mappedBy="client", cascade={"persist", "remove"})
*/
public $unloading_areas;
/**
* #ORM\OneToMany(targetEntity="ClientArea",mappedBy="client", cascade={"persist", "remove"})
*/
public $loading_areas;
}
class ClientArea
{
/**
* #ORM\ManyToOne(targetEntity="Client")
*/
public $client;
}
This does not work because client can only map 1 association.
How can i map the relation properly?
To create entity relations you need to have keys to use when joining tables. Your Client class should have an id key defined and you need to initialize collections, like this:
class Client
{
//....
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity="ClientArea", mappedBy="client", cascade={"persist", "remove"})
*/
public $unloading_areas;
/**
* #ORM\OneToMany(targetEntity="ClientArea", mappedBy="client", cascade={"persist", "remove"})
*/
public $loading_areas;
public function __construct() {
// Initialize collections
$this->unloading_areas = new \Doctrine\Common\Collections\ArrayCollection();
$this->loading_areas = new \Doctrine\Common\Collections\ArrayCollection();
}
// ....
}
Your ClientArea class should then look something like this:
class ClientArea
{
// ....
/**
* #ORM\Column(name="client_id", type="int", nullable=false)
*/
private $clientId;
/**
* #ORM\ManyToOne(targetEntity="Client")
* #JoinColumn(name="client_id", referencedColumnName="id")
*/
public $client;
// ....
}
Now, those two entities should be mapped correctly.
To learn more about association mappings in Doctrine, read article here: http://docs.doctrine-project.org/projects/doctrine-orm/en/2.0.x/reference/association-mapping.html
Hope this helps.

Resources