Passed
Push — master ( ef1328...91a1d1 )
by Bas
13:32 queued 09:25
created

HasAliases::normalizeColumnReferences()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 7
c 0
b 0
f 0
dl 0
loc 13
ccs 8
cts 8
cp 1
rs 9.6111
cc 5
nc 4
nop 2
crap 5
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Query\Concerns;
4
5
use Illuminate\Database\Query\Builder as IluminateBuilder;
6
use Illuminate\Support\Str;
7
use LaravelFreelancerNL\Aranguent\Query\Builder;
8
use LaravelFreelancerNL\FluentAQL\Expressions\FunctionExpression;
9
use LaravelFreelancerNL\FluentAQL\QueryBuilder;
10
11
trait HasAliases
12
{
13
14
    protected $tableAliases = [];
15
16
    protected $columnAliases = [];
17
18
    /**
19
     * @param  string  $table
20
     * @param  string|null  $alias
21
     * @return string
22
     */
23 97
    public function registerTableAlias(string $table, string $alias = null): string
24
    {
25 97
        if ($alias == null && stripos($table, ' as ') !== false) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $alias of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
26
            [$table, $alias] = explode(' as ', $table);
27
        }
28 97
        if ($alias == null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $alias of type null|string against null; this is ambiguous if the string can be empty. Consider using a strict comparison === instead.
Loading history...
29 97
            $alias = $this->generateTableAlias($table);
30
        }
31 97
        $this->tableAliases[$table] = $alias;
32
33 97
        return $alias;
34
    }
35
36 84
    protected function isTableAlias(string $alias)
37
    {
38 84
        return in_array($alias, $this->tableAliases);
39
    }
40
41
    /**
42
     * @param $table
43
     * @return mixed|null
44
     */
45 92
    protected function getTableAlias($table)
46
    {
47 92
        if (isset($this->tableAliases[$table])) {
48 85
            return $this->tableAliases[$table];
49
        }
50
51 84
        return null;
52
    }
53
54
    /**
55
     * Extract table and alias from sql alias notation (entity AS `alias`)
56
     *
57
     * @param  string  $entity
58
     * @return array|false|string[]
59
     */
60 25
    protected function extractAlias(string $entity)
61
    {
62 25
        $results = preg_split("/\sas\s/i", $entity);
63 25
        if (isset($results[1])) {
64 11
            $results[1] = trim($results[1], '`');
65
        }
66 25
        if (! isset($results[1])) {
67 14
            $results[1] = $results[0];
68
        }
69
70 25
        return $results;
71
    }
72
73
    /**
74
     * @param $table
75
     * @param string $postfix
76
     *
77
     * @return mixed
78
     */
79 97
    protected function generateTableAlias($table, $postfix = 'Doc')
80
    {
81 97
        return Str::singular($table) . $postfix;
82
    }
83
84
    protected function replaceTableForAlias($reference): string
85
    {
86
        $referenceParts = explode('.', $reference);
87
        $first = array_shift($referenceParts);
88
        $alias = $this->getTableAlias($first);
89
        if ($alias == null) {
90
            $alias = $first;
91
        }
92
        array_unshift($referenceParts, $alias);
93
94
        return implode('.', $referenceParts);
95
    }
96
97
    /**
98
     * @param string  $target
99
     * @param string  $value
100
     *
101
     * @return Builder
102
     */
103
    protected function prefixAlias(string $target, string $value): string
104
    {
105
        $alias = $this->getTableAlias($target);
106
107
        if (Str::startsWith($value, $alias . '.')) {
108
            return $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $value returns the type string which is incompatible with the documented return type LaravelFreelancerNL\Aranguent\Query\Builder.
Loading history...
109
        }
110
111
        return $alias . '.' . $value;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $alias . '.' . $value returns the type string which is incompatible with the documented return type LaravelFreelancerNL\Aranguent\Query\Builder.
Loading history...
112
    }
113
114
    /**
115
     * @param  string  $column
116
     * @param  string|null  $alias
117
     * @return bool
118
     */
119 1
    public function registerColumnAlias(string $column, string $alias = null): bool
120
    {
121 1
        if (preg_match("/\sas\s/i", $column)) {
122
            [$column, $alias] = $this->extractAlias($column);
123
        }
124
125 1
        if (isset($alias)) {
126 1
            $this->columnAliases[$column] = $alias;
127 1
            return true;
128
        }
129
130
        return false;
131
    }
132
133
    /**
134
     * @param $column
135
     * @return mixed
136
     */
137
    protected function getColumnAlias(string $column)
138
    {
139
        if (isset($this->columnAliases[$column])) {
140
            return $this->columnAliases[$column];
141
        }
142
143
        return null;
144
    }
145
146
    /**
147
     * @param  IluminateBuilder  $query
148
     * @param $column
149
     * @param $table
150
     * @return string
151
     */
152 86
    protected function normalizeColumn(IluminateBuilder $query, $column, $table = null)
153
    {
154 86
        if ($table == null) {
155 86
            $table = $query->from;
156
        }
157
158 86
        if ((is_string($column) || is_numeric($column)) && key_exists($column, $query->variables)) {
159 1
            return $column;
160
        }
161
162 86
        if ($column instanceof QueryBuilder || $column instanceof FunctionExpression) {
163 2
            return $column;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $column also could return the type LaravelFreelancerNL\Flue...ions\FunctionExpression which is incompatible with the documented return type string.
Loading history...
164
        }
165
166
        // Replace SQL JSON arrow for AQL dot
167 86
        $column = str_replace('->', '.', $column);
168
169 86
        $references = explode('.', $column);
170
171
        //We check for an existing alias to determine of the first reference is a table.
172
        // In which case we replace it with the alias.
173 86
        $references = $this->normalizeColumnReferences($references, $table);
174
175 86
        return implode('.', $references);
176
    }
177
178
    /**
179
     * @param $references
180
     * @param  null  $table
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $table is correct as it would always require null to be passed?
Loading history...
181
     * @return mixed
182
     */
183 86
    protected function normalizeColumnReferences($references, $table = null)
184
    {
185 86
        $tableAlias = $this->getTableAlias($references[0]);
186 86
        if (isset($tableAlias)) {
187 49
            $references[0] = $tableAlias;
188
        }
189
190 86
        if ($tableAlias === null && $table != null && ! $this->isTableAlias($references[0])) {
0 ignored issues
show
introduced by
The condition $table != null is always false.
Loading history...
191 53
            $tableAlias = $this->generateTableAlias($table);
192 53
            array_unshift($references, $tableAlias);
193
        }
194
195 86
        return $references;
196
    }
197
}
198