Search code examples
doctrinecriteriasymfony-3.4arraycollectiondoctrine-collection

Doctrine ArrayCollection matching criteria function results in Undefined property: MyEntity::$1 (Symfony 3.4)


I defined an Entity "TrainingProgressEntry" as an @ORM\Entity and a "training" property like this:

/**
 * @ORM\ManyToOne(targetEntity="Training", inversedBy="training_progress")
 * @ORM\JoinColumn(name="training_id", referencedColumnName="id")
 */
protected $training;

The matching @ORM\Entity "Training" defines a property "training_progress" like

/**
 * @ORM\OneToMany(targetEntity="TrainingProgressEntry", mappedBy="training", cascade={"remove"})
 * @ORM\OrderBy({"entry_date" = "ASC"})
 */
protected $training_progress;

and a getter method for it like this

/**
 * Get trainingProgress
 *
 * @return \Doctrine\Common\Collections\ArrayCollection
 */
public function getTrainingProgress()
{
    return $this->training_progress;
}

Finaly I define a getter method intended to return only entries which have a date newer then some reference date:

/**
 * @return \Doctrine\Common\Collections\ArrayCollection
 */
public function getTrainingProgressSinceStart()
{
    $startTime = $this->getUser()->getStart();
    $criteria = Criteria::create()
        ->andWhere(Criteria::expr()->gt('entry_date', $startTime))
        ->orderBy(['entry_date', 'ASC']);
    return $this->getTrainingProgress()->matching($criteria);
}

When using this last function I get the following "ContextErrorException":

Notice: Undefined property: AppBundle\Entity\TrainingProgressEntry::$1

coming from

vendor\doctrine\collections\lib\Doctrine\Common\Collections\Expr\ClosureExpressionVisitor.php

when trying to "return $object->$field".

The trace shows that it is caused by the above mentioned function "getTrainingProgressSinceStart()" in the line

return $this->getTrainingProgress()->matching($criteria);

For some reason the matching function doesn't seem to be recognized ors something... I don't really know what to look for now. Any hints are very welcome.


Solution

  • You probably already solved this, but I will answer it either way for reference for other people.

    The method: orderBy of criteria accepts an array with the Key, being the field and the sorting order being the value, so where you have:

    /**
     * @return \Doctrine\Common\Collections\ArrayCollection
     */
    public function getTrainingProgressSinceStart()
    {
        $startTime = $this->getUser()->getStart();
        $criteria = Criteria::create()
            ->andWhere(Criteria::expr()->gt('entry_date', $startTime))
            ->orderBy(['entry_date', 'ASC']);
        return $this->getTrainingProgress()->matching($criteria);
    }
    

    It should really be ['entry_date' => 'ASC']:

    /**
     * @return \Doctrine\Common\Collections\ArrayCollection
     */
    public function getTrainingProgressSinceStart()
    {
        $startTime = $this->getUser()->getStart();
        $criteria = Criteria::create()
            ->andWhere(Criteria::expr()->gt('entry_date', $startTime))
            ->orderBy(['entry_date' => 'ASC']);
        return $this->getTrainingProgress()->matching($criteria);
    }
    

    Source: https://github.com/doctrine/collections/blob/c23e14f69b6d2d1d1e389bc8868500efc447af7b/lib/Doctrine/Common/Collections/Criteria.php#L152