Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
This snippet shows you how you can use Fluid widgets with DQL queries in TYPO3.Flow today with a little hack
<?php
namespace Your\Package\Domain\Repository;
use TYPO3\Flow\Annotations as Flow;
use TYPO3\Flow\Persistence\Doctrine\Repository;
use TYPO3\Flow\Reflection\ObjectAccess;
/**
* @Flow\Scope("singleton")
*/
class ProductRepository extends Repository {
/**
* @param string $foo
* @return \TYPO3\Flow\Persistence\QueryResultInterface
*/
public function findByFoo($foo) {
$query = $this->createQuery();
/** @var $queryBuilder \Doctrine\ORM\QueryBuilder **/
// TODO !hack alarm! replace this once API is available in TYPO3.Flow:
$queryBuilder = ObjectAccess::getProperty($query, 'queryBuilder', TRUE);
$queryBuilder
->resetDQLParts()
->select('product')
->from('Your\Package\Domain\Model\Product', 'product')
->where('product.active = 1');
->andWhere('product.foo = :foo')
->orderBy('product.title')
->addOrderBy('product.price', 'DESC')
->setParameter('foo', $foo)
return $query->execute();
}
}
?>
@bwaidelich

This comment has been minimized.

Copy link
Owner Author

@bwaidelich bwaidelich commented Apr 22, 2013

DISCLAIMER: This currently requires a hack to access the QueryBuilder from Query. We're working on making that accessible via the API asap and when that's the case you should replace the code in question (line 21 in this example).

Notes:

  1. You need to extend \TYPO3\Flow\Persistence\Doctrine\Repository not \TYPO3\Flow\Persistence\Repository
  2. \TYPO3\Flow\Persistence\Doctrine\Query initializes the QueryBuilder with SELECT, FROM and ORDER BY (if defaultOrderings are defined). This is why you first need to reset the DQL (line 23). We try to make this unnecessary in the framework
  3. ..As a result of this defaultOrderings won't have an effect and you need to set orderings in the DQL (line 28 & 29)
  4. You won't be able to use raw DQL directly, but AFAIK with QueryBuilder you can access all the functionality (even sub selects) and personally I find it even more readable than DQL
  5. Query::execute() returns an instance of \TYPO3\Flow\Persistence\QueryResultInterface which is compatible with Fluid widgets. Depending on your queries the widget won't work anyways (e.g. a paginate widget doesn't make sense if your query only counts entities.. By the way: in this case you should replace the ->select('COUNT()') with the regular select and call ->count() on the result, which will in fact rewrite the query for the count case)
@christianjul

This comment has been minimized.

Copy link

@christianjul christianjul commented Sep 22, 2013

Hey Basti, nice trick. We should find some way too support DQL directly though. Was wondering if 1. is really necessary? Doesn't the generic repository use a Doctrine querybuilder anyway? Unless you use some other persistence but then DQL wont work anyway.

@bwaidelich

This comment has been minimized.

Copy link
Owner Author

@bwaidelich bwaidelich commented Feb 21, 2014

Julle, just see your comment now ;)
You're right, it should work with the generic base repository, too.
BTW: Instead of using the fluent interface, you can also set raw DQL or use $queryBuilder->add()

@christian-fries

This comment has been minimized.

Copy link

@christian-fries christian-fries commented Dec 19, 2014

Is there an update on how to use DQL with Flow? Do we still have to use the ObjectAccess::getProperty() hack or is there some API in the meantime?

@itskevinsam

This comment has been minimized.

Copy link

@itskevinsam itskevinsam commented Jan 5, 2015

Is there an update on how to use DQL with Flow? Do we still have to use the ObjectAccess::getProperty() hack or is there some API in the meantime?

http://stackoverflow.com/questions/27443604/get-table-name-of-an-entity-for-a-query-in-typo3-flow

See the first answer.

Edit:

  • @flow\Inject
  • @var \Doctrine\Common\Persistence\ObjectManager

protected $entityManager;

$dql = 'SELECT COUNT(e) FROM Vendor\Package\Domain\Model\Entity e WHERE e.property = :property';
$query = $this->entityManager->createQuery($dql);
$query->setParameters(array('property' => $property));
$result = $query->execute();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment