Skip to content

Instantly share code, notes, and snippets.

@bwaidelich
Last active December 16, 2015 12:19
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bwaidelich/5433673 to your computer and use it in GitHub Desktop.
Save bwaidelich/5433673 to your computer and use it in GitHub Desktop.
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
Copy link
Author

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
Copy link

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
Copy link
Author

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
Copy link

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
Copy link

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