3 // -------------------------------------------------
4 // Complete support of GROUP_CONCAT in Doctrine2
5 // -------------------------------------------------
6 // Original Article: http://habrahabr.ru/post/181666/
7 // Automated translation to English: http://sysmagazine.com/posts/181666/
8 // Original github commit: https://github.com/denisvmedia/DoctrineExtensions/blob/d1caf21cd7c71cc557e60c26e9bf25323a194dd1/lib/DoctrineExtensions/Query/Mysql/GroupConcat.php
11 * DoctrineExtensions Mysql Function Pack
15 * This source file is subject to the new BSD license that is bundled
16 * with this package in the file LICENSE.txt.
17 * If you did not receive a copy of the license and are unable to
18 * obtain it through the world-wide-web, please send an email
19 * to kontakt@beberlei.de so I can send you a copy immediately.
22 namespace UVd\DoctrineFunction;
24 use Doctrine\ORM\Query\AST\Functions\FunctionNode,
25 Doctrine\ORM\Query\Lexer;
30 * GROUP_CONCAT([DISTINCT] expr [,expr ...]
31 * [ORDER BY {unsigned_integer | col_name | expr}
32 * [ASC | DESC] [,col_name ...]]
33 * [SEPARATOR str_val])
36 class GroupConcat extends FunctionNode
38 public $isDistinct = false;
39 public $pathExp = null;
40 public $separator = null;
41 public $orderBy = null;
43 public function parse(\Doctrine\ORM\Query\Parser $parser)
45 $parser->match(Lexer::T_IDENTIFIER);
46 $parser->match(Lexer::T_OPEN_PARENTHESIS);
48 $lexer = $parser->getLexer();
49 if ($lexer->isNextToken(Lexer::T_DISTINCT)) {
50 $parser->match(Lexer::T_DISTINCT);
52 $this->isDistinct = true;
55 // first Path Expression is mandatory
56 $this->pathExp = array();
57 $this->pathExp[] = $parser->SingleValuedPathExpression();
59 while ($lexer->isNextToken(Lexer::T_COMMA)) {
60 $parser->match(Lexer::T_COMMA);
61 $this->pathExp[] = $parser->StringPrimary();
64 if ($lexer->isNextToken(Lexer::T_ORDER)) {
65 $this->orderBy = $parser->OrderByClause();
68 if ($lexer->isNextToken(Lexer::T_IDENTIFIER)) {
69 if (strtolower($lexer->lookahead['value']) !== 'separator') {
70 $parser->syntaxError('separator');
72 $parser->match(Lexer::T_IDENTIFIER);
74 $this->separator = $parser->StringPrimary();
77 $parser->match(Lexer::T_CLOSE_PARENTHESIS);
80 public function getSql(\Doctrine\ORM\Query\SqlWalker $sqlWalker)
82 $result = 'GROUP_CONCAT(' . ($this->isDistinct ? 'DISTINCT ' : '');
85 foreach ($this->pathExp as $pathExp) {
86 $fields[] = $pathExp->dispatch($sqlWalker);
89 $result .= sprintf('%s', implode(', ', $fields));
92 $result .= ' ' . $sqlWalker->walkOrderByClause($this->orderBy);
95 if ($this->separator) {
96 $result .= ' SEPARATOR ' . $sqlWalker->walkStringPrimary($this->separator);