Completed
Push — 1.0 ( f155d9...8e07ac )
by Peter
08:03
created

PlatformFunction::transform()   A

Complexity

Conditions 6
Paths 3

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.0777
c 0
b 0
f 0
cc 6
nc 3
nop 2
1
<?php
2
3
namespace Happyr\DoctrineSpecification\Operand;
4
5
use Doctrine\ORM\QueryBuilder;
6
use Happyr\DoctrineSpecification\Exception\InvalidArgumentException;
7
8
class PlatformFunction implements Operand
9
{
10
    /**
11
     * Doctrine internal functions.
12
     *
13
     * @see \Doctrine\ORM\Query\Parser
14
     *
15
     * @var string[]
16
     */
17
    private static $doctrineFunctions = [
18
        // String functions
19
        'concat',
20
        'substring',
21
        'trim',
22
        'lower',
23
        'upper',
24
        'identity',
25
        // Numeric functions
26
        'length',
27
        'locate',
28
        'abs',
29
        'sqrt',
30
        'mod',
31
        'size',
32
        'date_diff',
33
        'bit_and',
34
        'bit_or',
35
        // Aggregate functions
36
        'min',
37
        'max',
38
        'avg',
39
        'sum',
40
        'count',
41
        // Datetime functions
42
        'current_date',
43
        'current_time',
44
        'current_timestamp',
45
        'date_add',
46
        'date_sub',
47
    ];
48
49
    /**
50
     * @var string
51
     */
52
    private $functionName = '';
53
54
    /**
55
     * @var array
56
     */
57
    private $arguments = [];
58
59
    /**
60
     * @param string $functionName
61
     * @param mixed  $arguments
62
     */
63
    public function __construct($functionName, $arguments = [])
64
    {
65
        if (2 === func_num_args()) {
66
            $this->functionName = $functionName;
67
            $this->arguments = (array) $arguments;
68
        } else {
69
            $arguments = func_get_args();
70
            $this->functionName = array_shift($arguments);
71
            $this->arguments = $arguments;
72
        }
73
    }
74
75
    /**
76
     * @param QueryBuilder $qb
77
     * @param string       $dqlAlias
78
     *
79
     * @return string
80
     */
81
    public function transform(QueryBuilder $qb, $dqlAlias)
82
    {
83
        if (!in_array(strtolower($this->functionName), self::$doctrineFunctions) &&
84
            !$qb->getEntityManager()->getConfiguration()->getCustomStringFunction($this->functionName) &&
85
            !$qb->getEntityManager()->getConfiguration()->getCustomNumericFunction($this->functionName) &&
86
            !$qb->getEntityManager()->getConfiguration()->getCustomDatetimeFunction($this->functionName)
87
        ) {
88
            throw new InvalidArgumentException(sprintf('"%s" is not a valid function name.', $this->functionName));
89
        }
90
91
        $arguments = ArgumentToOperandConverter::convert($this->arguments);
92
        foreach ($arguments as $key => $argument) {
93
            $arguments[$key] = $argument->transform($qb, $dqlAlias);
94
        }
95
96
        return sprintf('%s(%s)', $this->functionName, implode(', ', $arguments));
97
    }
98
}
99