ExpressionFieldTrait::fieldIdentifiers()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 10
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Charcoal\Source;
4
5
use InvalidArgumentException;
6
7
// From 'charcoal-property'
8
use Charcoal\Property\PropertyInterface;
9
use Charcoal\Property\StorablePropertyInterface;
10
11
// From 'charcoal-core'
12
use Charcoal\Source\Expression;
13
14
/**
15
 * Provides the field and table properties.
16
 *
17
 * Satisfies {@see ExpressionFieldInterface}.
18
 */
19
trait ExpressionFieldTrait
20
{
21
    /**
22
     * The model property name or field name or expression to be used in the left hand side of the operator.
23
     *
24
     * @var string|PropertyInterface|null
25
     */
26
    protected $property;
27
28
    /**
29
     * The table related to the field identifier.
30
     *
31
     * @var string|null
32
     */
33
    protected $table;
34
35
    /**
36
     * Set model property key or source field key.
37
     *
38
     * @param  string|PropertyInterface $property The related property.
39
     * @throws InvalidArgumentException If the parameter is invalid.
40
     * @return self
41
     */
42
    public function setProperty($property)
43
    {
44
        if ($property === null) {
45
            $this->property = $property;
0 ignored issues
show
Documentation Bug introduced by
It seems like $property of type void is incompatible with the declared type Charcoal\Property\PropertyInterface|null|string of property $property.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
46
            return $this;
47
        }
48
49
        if ($property instanceof PropertyInterface) {
50
            if (empty($property->ident())) {
51
                throw new InvalidArgumentException(
52
                    'Property must have an identifier.'
53
                );
54
            }
55
56
            $this->property = $property;
57
            return $this;
58
        }
59
60
        if (!is_string($property)) {
0 ignored issues
show
introduced by
The condition is_string($property) is always true.
Loading history...
61
            throw new InvalidArgumentException(
62
                'Property must be a string.'
63
            );
64
        }
65
66
        if ($property === '') {
67
            throw new InvalidArgumentException(
68
                'Property can not be empty.'
69
            );
70
        }
71
72
        $this->property = $property;
73
        return $this;
74
    }
75
76
    /**
77
     * Determine if a model property or source field key is assigned.
78
     *
79
     * @return boolean
80
     */
81
    public function hasProperty()
82
    {
83
        return !empty($this->property);
84
    }
85
86
    /**
87
     * Retrieve the model property or source field key.
88
     *
89
     * @return string|PropertyInterface|null The related property.
90
     */
91
    public function property()
92
    {
93
        return $this->property;
94
    }
95
96
    /**
97
     * Set the reference to the table related to the field.
98
     *
99
     * @param  string $table The table name or alias.
100
     * @throws InvalidArgumentException If the parameter is not a string.
101
     * @return self
102
     */
103
    public function setTable($table)
104
    {
105
        if ($table === null) {
0 ignored issues
show
introduced by
The condition $table === null is always false.
Loading history...
106
            $this->table = $table;
107
            return $this;
108
        }
109
110
        if (!is_string($table)) {
0 ignored issues
show
introduced by
The condition is_string($table) is always true.
Loading history...
111
            throw new InvalidArgumentException(
112
                'Table reference must be a string.'
113
            );
114
        }
115
116
        if ($table === '') {
117
            throw new InvalidArgumentException(
118
                'Table reference can not be empty.'
119
            );
120
        }
121
122
        $this->table = $table;
123
        return $this;
124
    }
125
126
    /**
127
     * Determine if a table is assigned.
128
     *
129
     * @return boolean
130
     */
131
    public function hasTable()
132
    {
133
        return !empty($this->table);
134
    }
135
136
    /**
137
     * Retrieve the table related to the field.
138
     *
139
     * @return string|null The related table.
140
     */
141
    public function table()
142
    {
143
        return $this->table;
144
    }
145
146
    /**
147
     * Determine if the model property has any fields.
148
     *
149
     * @return boolean
150
     */
151
    public function hasFields()
152
    {
153
        if ($this->hasProperty()) {
154
            $property = $this->property();
155
            if ($property instanceof StorablePropertyInterface) {
156
                return (count($property->fieldNames()) > 0);
157
            } else {
158
                return true;
159
            }
160
        }
161
162
        return false;
163
    }
164
165
    /**
166
     * Retrieve the model property's field names.
167
     *
168
     * @todo Load Property from associated model metadata.
169
     * @return array
170
     */
171
    public function fieldNames()
172
    {
173
        if ($this->hasProperty()) {
174
            $property = $this->property();
175
            if ($property instanceof StorablePropertyInterface) {
176
                return $property->fieldNames();
177
            } else {
178
                // Ensure snake_case
179
                $property = strtolower(preg_replace('/(?<!^)[A-Z]/', '_$0', $property));
180
                return [ $property ];
181
            }
182
        }
183
184
        return [];
185
    }
186
187
    /**
188
     * Retrieve the property's field name.
189
     *
190
     * @return string|null
191
     */
192
    public function fieldName()
193
    {
194
        $property = $this->property();
195
        if ($property instanceof PropertyInterface) {
196
            return $property->ident();
197
        } else {
198
            return $property;
199
        }
200
    }
201
202
    /**
203
     * Retrieve the property's fully-qualified field names.
204
     *
205
     * @return string[]
206
     */
207
    public function fieldIdentifiers()
208
    {
209
        $identifiers = [];
210
        $tableName   = $this->table();
211
        $fieldNames  = $this->fieldNames();
212
        foreach ($fieldNames as $fieldName) {
213
            $identifiers[] = Expression::quoteIdentifier($fieldName, $tableName);
214
        }
215
216
        return $identifiers;
217
    }
218
219
    /**
220
     * Retrieve the fully-qualified field name.
221
     *
222
     * @return string
223
     */
224
    public function fieldIdentifier()
225
    {
226
        $tableName = $this->table();
227
        $fieldName = $this->fieldName();
228
229
        return Expression::quoteIdentifier($fieldName, $tableName);
230
    }
231
}
232