Completed
Push — 2.0 ( 3fe951...5877a9 )
by Peter
07:19 queued 12s
created

Trim   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 108
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 15
lcom 1
cbo 3
dl 0
loc 108
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 14 3
B transform() 0 33 6
A execute() 0 15 6
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * This file is part of the Happyr Doctrine Specification package.
6
 *
7
 * (c) Tobias Nyholm <[email protected]>
8
 *     Kacper Gunia <[email protected]>
9
 *     Peter Gribanov <[email protected]>
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace Happyr\DoctrineSpecification\Operand\PlatformFunction;
16
17
use Doctrine\ORM\QueryBuilder;
18
use Happyr\DoctrineSpecification\Exception\InvalidArgumentException;
19
use Happyr\DoctrineSpecification\Operand\ArgumentToOperandConverter;
20
use Happyr\DoctrineSpecification\Operand\Operand;
21
22
/**
23
 * Trim the string by the given trim char, defaults to whitespaces.
24
 */
25
final class Trim implements Operand
26
{
27
    public const LEADING = 'LEADING';
28
    public const TRAILING = 'TRAILING';
29
    public const BOTH = 'BOTH';
30
31
    private const MODES = [
32
        self::LEADING,
33
        self::TRAILING,
34
        self::BOTH,
35
    ];
36
37
    /**
38
     * @var string|Operand
39
     */
40
    private $string;
41
42
    /**
43
     * @var string
44
     */
45
    private $mode;
46
47
    /**
48
     * @var string
49
     */
50
    private $characters;
51
52
    /**
53
     * @param Operand|string $string
54
     * @param string         $mode
55
     * @param string         $characters
56
     */
57
    public function __construct($string, string $mode = '', string $characters = '')
58
    {
59
        if ('' !== $mode && !in_array(strtoupper($mode), self::MODES, true)) {
60
            throw new InvalidArgumentException(sprintf(
61
                'The TRIM() function support "%s" mode, got "%s" instead.',
62
                implode('", "', self::MODES),
63
                $mode
64
            ));
65
        }
66
67
        $this->string = $string;
68
        $this->mode = $mode;
69
        $this->characters = $characters;
70
    }
71
72
    /**
73
     * @param QueryBuilder $qb
74
     * @param string       $context
75
     *
76
     * @return string
77
     */
78
    public function transform(QueryBuilder $qb, string $context): string
79
    {
80
        $string = ArgumentToOperandConverter::toField($this->string)->transform($qb, $context);
81
82
        $expression = '';
83
84
        switch ($this->mode) {
85
            case self::LEADING:
86
                $expression = 'LEADING ';
87
88
                break;
89
90
            case self::TRAILING:
91
                $expression = 'TRAILING ';
92
93
                break;
94
95
            case self::BOTH:
96
                $expression = 'BOTH ';
97
98
                break;
99
        }
100
101
        if ('' !== $this->characters) {
102
            $expression .= sprintf('\'%s\' ', $this->characters);
103
        }
104
105
        if ('' !== $expression) {
106
            $expression .= 'FROM ';
107
        }
108
109
        return sprintf('TRIM(%s%s)', $expression, $string);
110
    }
111
112
    /**
113
     * @param mixed[]|object $candidate
114
     *
115
     * @return string
116
     */
117
    public function execute($candidate): string
118
    {
119
        $string = ArgumentToOperandConverter::toField($this->string)->execute($candidate);
120
121
        switch ($this->mode) {
122
            case self::LEADING:
123
                return $this->characters ? ltrim($string, $this->characters) : ltrim($string);
124
125
            case self::TRAILING:
126
                return $this->characters ? rtrim($string, $this->characters) : rtrim($string);
127
128
            default:
129
                return $this->characters ? trim($string, $this->characters) : trim($string);
130
        }
131
    }
132
}
133