The first entity called BUNDLE
/**
* #var \Doctrine\Common\Collections\Collection of \Akademie\Course\Course
* #ManyToMany(targetEntity="Akademie\Course\Course", mappedBy="bundles")
*/
private $courses;
The second entity is called COURSE
/**
* #var \Doctrine\Common\Collections\Collection of \Akademie\Bundle\Bundle
* #ManyToMany(targetEntity="Akademie\Bundle\Bundle", inversedBy="courses")
*/
private $bundles;
/**
* #var \Doctrine\Common\Collections\Collection of \Akademie\Course\CourseDate
* #OneToMany(targetEntity="Akademie\Course\CourseDate", mappedBy="course")
*/
private $courseDates;
/**
* #var int
* #Column(type="boolean")
*/
private $hidden;
and the third is called COURSEDATE
/**
* #var \Akademie\Course\Course
* #ManyToOne(targetEntity="Akademie\Course\Course", inversedBy="courseDates")
* #JoinColumn(nullable=false)
*/
private $course;
/**
* #var \DateTime
* #Column(type="datetimetz", nullable=true)
*/
private $beginDate;
I have parameter course and I need to get all bundles, which contains this course. What's more, all other courses in that bundle has to have courseDate newer than current date and can't be hidden. Otherwise I don't want to get this bundle. I hope it is clear now...
In a repository (bundle of entity BUNDLE for example), you have to create a custom method :
public function myMethod($course){
$qb = $this->createQueryBuilder("b")
->join("b.course", "c")
->join("c.courseDates", "cd")
->Where("c = :course")
->andWhere(" cd.beginDate > :now ")
->andWhere("c.hidden = 1")// if 1 means not hidden
->setParameter(":course", $course)
->setParameter(":now", new \DateTime('now'));
And then, in your controller, you have to do something like that :
$bundles = $this->getDoctrine()->getManager()->getRepository('namespace of your BUNDLE entity')->myMethod($course);
Related
I want to override an Extbase Controller, e.g. news in TYPO3 v10.4. Therefore I register an XClass in my ext_locaconf.php
$GLOBALS['TYPO3_CONF_VARS']['SYS']['Objects'][\GeorgRinger\News\Controller\NewsController::class] = [
'className' => \Clickstorm\CsEvents\Controller\EventController::class
];
Afterwards I want to inject my new Repository
/**
* eventDateRepository
*
* #var EventDateRepository
*/
protected $eventDateRepository = null;
/**
* Inject a eventDateRepository
*
* #param EventDateRepository $eventDateRepository
*/
public function injectEventDateRepository(EventDateRepository $eventDateRepository)
{
$this->eventDateRepository = $eventDateRepository;
}
But my eventDateRepository is null. Also when I use a constructor instead.
Even though I don't know the reason for such a behaviour, a sustainable workaround is to manually instantiate your dependencies in the initializeAction method.
In my case, this is what I wrote:
/**
* #var \TYPO3\CMS\Extbase\Service\ImageService
*/
protected $imageService;
public function initializeAction()
{
parent::initializeAction();
$objectManager = GeneralUtility::makeInstance(ObjectManager::class);
$this->imageService = $objectManager->get(\TYPO3\CMS\Extbase\Service\ImageService::class);
}
I am using the wonderful project api platform. I create my entities and endpoints are working like a charm.
Right now, I want to configure the documentation because endpoints are showed duplicated. For example, I have a relation 1 to N between two entities and on documentation which is automatically generated via swagger the endpoints are duplicated.
For example, in this relation between competition and event, I have the same endpoint [/competitions/{id}/events] for each entity.
Do you know if is there any way to show endpoints once? It is not a big deal, but I want to keep the documentation as clean as possible.
Edited
Competition:
/**
* Competitions able to request.
*
* #ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}}
* },
* collectionOperations={"get", "post"},
* itemOperations={"get"}
* )
* #ORM\Entity
*/
class Competition
{
/**
* #var int The competition Id
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"read","write"})
*/
private $id;
/**
* #var string Name of the competition
*
* #ORM\Column
* #Assert\NotBlank
* #Groups({"read","write"})
*
*/
public $name = '';
/**
* #ORM\OneToMany(targetEntity="Event", mappedBy="competitions", cascade={"persist"})
* #ApiSubresource(maxDepth=1)
* #Groups("write")
*/
public $events;
Event:
/**
* Available event
*
* #ApiResource(
* attributes={
* "normalization_context"={"groups"={"read"}},
* "denormalization_context"={"groups"={"write"}}
* },
* collectionOperations={"get", "post"},
* itemOperations={
* "get"}
* )
* #ORM\Entity
*/
class Event
{
/**
* #var int The entity Id
*
* #ORM\Id
* #ORM\GeneratedValue
* #ORM\Column(type="integer")
* #Groups({"read", "write"})
*/
private $id;
/**
* #var string The name of the event available.
*
* #ORM\Column(type="text")
* #Assert\NotBlank
* #Groups({"read","write"})
*/
public $name = '';
/**
* #var string Start date
*
* #ORM\Column(type="datetime")
* #Assert\NotBlank
* #Groups({"read","write"})
*/
public $start;
/**
* #ORM\ManyToOne(targetEntity="Competition", inversedBy="events")
* #Groups({"write"})
*/
public $competitions;
You could be able to disable some "operations":
https://api-platform.com/docs/core/operations
<?php
// api/src/Entity/Book.php
use ApiPlatform\Core\Annotation\ApiResource;
/**
* ...
* #ApiResource(
* collectionOperations={"get"},
* itemOperations={"get"}
* )
*/
class Book
{
// ...
}
To hide/show what you want.
I have a relation one-to-many between project and images and many-to-one between project and propriety. I would to select the procts ho have image.cover=1 and propriety.activated=1 but the code always give me all images for projects
class ProjectImage
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="BI\AdminBundle\Entity\Project", inversedBy="images")
* #ORM\JoinColumn(nullable=false, name="id_project", referencedColumnName="id")
*/
private $idProject;
******************
class Project
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #ORM\ManyToOne(targetEntity="BI\AdminBundle\Entity\Promoteur", inversedBy="projects")
* #ORM\JoinColumn(nullable=false, name="id_promoteur", referencedColumnName="id")
*/
private $idPromoteur;
/**
*
* #ORM\ManyToOne(targetEntity="BI\AdminBundle\Entity\Governorate")
* #ORM\JoinColumn(nullable=false, name="id_governorate")
*/
private $idGovernorate;
/**
*
* #ORM\ManyToOne(targetEntity="BI\AdminBundle\Entity\Delegation")
* #ORM\JoinColumn(nullable=true, name="id_delegation")
*/
private $idDelegation;
/**
* #ORM\ManyToOne(targetEntity="BI\AdminBundle\Entity\Locality")
* #ORM\JoinColumn(nullable=true, name="id_locality")
*/
private $idLocality;
/**
* #ORM\OneToMany(targetEntity="BI\AdminBundle\Entity\ProjectImage", mappedBy="idProject",cascade={"persist", "remove", "merge"})
*/
private $images;
**********************************
class Promoteur
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\OneToMany(targetEntity = "BI\AdminBundle\Entity\Project", mappedBy = "idPromoteur")
*/
private $projects;
On your OneToMany associations, you should use an ArrayCollection since you store can several instances of your target entity on this end. You should also import the ArrayCollection class and instanciate this collection in your constructor.
So in your Project class you may want to add something like this:
use Doctrine\Common\Collections\ArrayCollection;
/**
* #var ArrayCollection
* #ORM\OneToMany(targetEntity="BI\AdminBundle\Entity\ProjectImage",
mappedBy="idProject",cascade={"persist", "remove", "merge"})
*/
private $images;
public function __construct() {
$this->images = new ArrayCollection();
}
Then you can generate the getters and setters with app/console doctrine:generate:entities. This command will also create two additional methods addImage and removeImage to manage your collection.
Hope this will helps
I have the User entity:
class User extends Entity implements UserInterface, ProviderInterface
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="user_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\Child", mappedBy="parents")
*/
protected $children;
...
}
And the Child entity:
class Child extends Entity
{
/**
* #var int
* #ORM\Id
* #ORM\Column(name="child_id", type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* #var \Application\Entity\Classroom
*
* #ORM\ManyToOne(targetEntity="Application\Entity\Classroom")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="classroom_id", referencedColumnName="classroom_id")
* })
*/
protected $classroom;
/**
* #var \Doctrine\Common\Collections\Collection
* #ORM\ManyToMany(targetEntity="Application\Entity\User", inversedBy="children")
* #ORM\JoinTable(name="child_parent",
* joinColumns={#ORM\JoinColumn(name="child_id", referencedColumnName="child_id")},
* inverseJoinColumns={#ORM\JoinColumn(name="user_id", referencedColumnName="user_id")}
* )
*/
protected $parents;
...
}
What I need to do is to add in the UserRepository a condition for obtaining the users whose children are in the classroom X. I haven't seen any example on making join clauses for ManyToMany relationships. Have you got any idea or good example?
Thanks in advance.
The most straightforward way would be using a DQL query, I think this one should be close to what you want:
SELECT u
FROM Application\Entity\User u
JOIN u.children ch
JOIN c.classroom cr
WHERE cr.id = :classroom
GROUP BY u
Hope this helps!
This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 10 years ago.
Symfony 2, Doctrine 2.1.
I've got 3 entities, one of them intermediate (join table). Let's say it's SomeObject, SomeProperty and ObjectProperties.
Problem: I can't get the value of SomeProperty 'name' property. Here's the code:
[...]
class SomeObject
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
*
* #var ObjectProperties $objectProperties
*
* #ORM\OneToMany(targetEntity="ObjectProperties", mappedBy="object_id", cascade={"all"})
*/
private $objectProperties;
[...]
[...]
class SomeProperty
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
* #ORM\OneToMany(targetEntity="ObjectProperties", mappedBy="property_id", cascade={"all"})
*/
private $id;
/**
* #var string $name
*
*/
private $name;//I NEED TO GET VALUE OF $name
[...]
[...]
class ObjectProperties
{
/**
* #var integer $id
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* #ORM\ManyToOne(targetEntity="SomeObject", inversedBy="id", cascade={"all"})
* #ORM\JoinColumn(name="object_id", referencedColumnName="id")
*/
private $object_id;
/**
* #ORM\Id
* #ORM\ManyToOne(targetEntity="SomeProperty", inversedBy="id", cascade={"all"})
* #ORM\JoinColumn(name="property_id", referencedColumnName="id")
*/
private $property_id;
[...]
Setters and getters as usual.
In my controller I've got something along the lines of:
$entity = $em->getRepository('SomeTestBundle:SomeObject')->find($id);
[...]
$props = $entity->getObjectProperties();
foreach ($props as $prop){
echo '---------------------------<br>';
var_dump($prop->getPropertyId()->getName());
}
Now, getName() gives me null result, but if i replace it with getId it works as expected. Same if I try to use it in a form class. Is it because there is no doctrine association between SomeProperty->name and ObjectProperties?
I think I don't quite get the way doctrine is supposed to work. I thought that only property_id and object_id are needed in a junction table, otherwise it doesn't make much sense for me, because SomeProperty serves as a dictionary table, so I could change SomeProperty->name in one place.
I'm seriously stuck with it. Is it some sort of configuration option that is lacking or am I generally not getting the bigger picture?
Consider it a typo - I've made it work by adding missing #Column annotation in SomeProperty class:
/**
* #var string $name
* #ORM\Column(type="string")
*/
private $name;
Don't know why I missed it in the first place... I guess "Experience is something you get, after you need it."