Viewed   79 times

This is my function where I'm trying to show the User history. For this I need to display the user's current credits along with his credit history.

This is what I am trying to do:

 public function getHistory($users) {
    $qb = $this->entityManager->createQueryBuilder();
    $qb->select(array('a','u'))
            ->from('CreditEntityUserCreditHistory', 'a')
            ->leftJoin('UserEntityUser', 'u', DoctrineORMQueryExprJoin::WITH, 'a.user = u.id')
            ->where("a.user = $users ")
            ->orderBy('a.created_at', 'DESC');

    $query = $qb->getQuery();
    $results = $query->getResult();

    return $results;
}

However, I get this error :

[Syntax Error] line 0, col 98: Error: Expected DoctrineORMQueryLexer::T_WITH, got 'ON'

Edit: I replaced 'ON' with 'WITH' in the join clause and now what I see is only 1 value from the joined column.

 Answers

5

If you have an association on a property pointing to the user (let's say CreditEntityUserCreditHistory#user, picked from your example), then the syntax is quite simple:

public function getHistory($users) {
    $qb = $this->entityManager->createQueryBuilder();
    $qb
        ->select('a', 'u')
        ->from('CreditEntityUserCreditHistory', 'a')
        ->leftJoin('a.user', 'u')
        ->where('u = :user')
        ->setParameter('user', $users)
        ->orderBy('a.created_at', 'DESC');

    return $qb->getQuery()->getResult();
}

Since you are applying a condition on the joined result here, using a LEFT JOIN or simply JOIN is the same.

If no association is available, then the query looks like following

public function getHistory($users) {
    $qb = $this->entityManager->createQueryBuilder();
    $qb
        ->select('a', 'u')
        ->from('CreditEntityUserCreditHistory', 'a')
        ->leftJoin(
            'UserEntityUser',
            'u',
            DoctrineORMQueryExprJoin::WITH,
            'a.user = u.id'
        )
        ->where('u = :user')
        ->setParameter('user', $users)
        ->orderBy('a.created_at', 'DESC');

    return $qb->getQuery()->getResult();
}

This will produce a resultset that looks like following:

array(
    array(
        0 => UserCreditHistory instance,
        1 => Userinstance,
    ),
    array(
        0 => UserCreditHistory instance,
        1 => Userinstance,
    ),
    // ...
)
Saturday, September 10, 2022
5

The solution was to change my module.config.php to be more like this:

'doctrine' => array(
    'driver' => array(
        __NAMESPACE__ . '_driver' => array(
            'class' => 'DoctrineORMMappingDriverAnnotationDriver',
            'cache' => 'array',
            'paths' => array(__DIR__ . '/../src/' . __NAMESPACE__ . '/Entity'),
        ),
        'orm_default' => array(
            'drivers' => array(
                __NAMESPACE__ . 'Entity' => __NAMESPACE__ . '_driver'
            ),
        ),
    ),
    'eventmanager' => array(
        'orm_default' => array(
            'subscribers' => array(
                'GedmoTimestampableTimestampableListener',
                'GedmoSoftDeleteableSoftDeleteableListener',
            ),
        ),
    ),
),
Sunday, September 4, 2022
2

By chance did I stumple upon this answer, which was for allowing a Fieldset to be empty but validate it if at least a single input was filled in.

By extending my own AbstractFormInputFilter and AbstractFieldsetInputFilter classes from an AbstractInputFilter class, which incorporates the answer, I'm now able to supply FielsetInputFilters, such as the AddressFieldsetInputFilter, with an additional ->setRequired(false). Which is then validated in the AbstractInputFilter, if it actually is empty.

The linked answer gives this code:

<?php
namespace ApplicationInputFilter;

use ZendInputFilter as ZFI;

class InputFilter extends ZFIInputFilter
{
    private $required = true;

    /**
     * @return boolean
     */
    public function isRequired()
    {
        return $this->required;
    }

    /**
     * @param boolean $required
     *
     * @return $this
     */
    public function setRequired($required)
    {
        $this->required = (bool) $required;
        return $this;
    }

    /**
     * @return bool
     */
    public function isValid()
    {
        if (!$this->isRequired() && empty(array_filter($this->getRawValues()))) {
            return true;
        }

        return parent::isValid();
    }
}

As I mentioned I used this code to extend my own AbstractInputFilter, allowing small changes in *FieldsetInputFilterFactory classes.

AddressFieldsetInputFilterFactory.php

class AddressFieldsetInputFilterFactory extends AbstractFieldsetInputFilterFactory
{
    /**
     * @param ServiceLocatorInterface|ControllerManager $serviceLocator
     * @return InputFilter
     */
    public function createService(ServiceLocatorInterface $serviceLocator)
    {
        parent::setupRequirements($serviceLocator, Address::class);

        /** @var CoordinatesFieldsetInputFilter $coordinatesFieldsetInputFilter */
        $coordinatesFieldsetInputFilter = $this->getServiceManager()->get('InputFilterManager')
            ->get(CoordinatesFieldsetInputFilter::class);
        $coordinatesFieldsetInputFilter->setRequired(false); // <-- Added option

        return new AddressFieldsetInputFilter(
            $coordinatesFieldsetInputFilter,
            $this->getEntityManager(),
            $this->getTranslator()
        );
    }
}

Might not be a good idea for everybody's projects, but it solves my problem of not always wanting to validate a Fieldset and it definitely solves the original issue of not creating an Entity with just an ID, as shown in the screenshot in the question.

Saturday, September 10, 2022
 
thunk
 
2

Unfortunately, This is not possible. Per here:

https://groups.google.com/forum/#!topic/doctrine-user/0rNbXlD0E_8

You can do it using IN here:

Doing a WHERE .. IN subquery in Doctrine 2

Tuesday, August 16, 2022
 
3

With dplyr, we can use left_join

library(dplyr)
left_join(df2, df1, by = c("e"="a"))
Sunday, October 30, 2022
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :