Completed
Push — master ( 86ece3...f34c1c )
by Nekrasov
02:29
created

ArrayableModel::getAccessorForLanguageField()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 3
nc 4
nop 1
1
<?php
2
3
namespace Arrilot\BitrixModels\Models;
4
5
use ArrayAccess;
6
use ArrayIterator;
7
use Arrilot\BitrixModels\Models\Traits\HidesAttributes;
8
use Illuminate\Contracts\Support\Arrayable;
9
use Illuminate\Contracts\Support\Jsonable;
10
use IteratorAggregate;
11
12
abstract class ArrayableModel implements ArrayAccess, Arrayable, Jsonable, IteratorAggregate
13
{
14
    use HidesAttributes;
15
16
    /**
17
     * ID of the model.
18
     *
19
     * @var null|int
20
     */
21
    public $id;
22
23
    /**
24
     * Array of model fields.
25
     *
26
     * @var null|array
27
     */
28
    public $fields;
29
30
    /**
31
     * Array of original model fields.
32
     *
33
     * @var null|array
34
     */
35
    protected $original;
36
37
    /**
38
     * Array of accessors to append during array transformation.
39
     *
40
     * @var array
41
     */
42
    protected $appends = [];
43
    
44
    /**
45
     * Array of language fields with auto accessors.
46
     *
47
     * @var array
48
     */
49
    protected $languageAccessors = [];
50
51
    /**
52
     * Array related models indexed by the relation names.
53
     *
54
     * @var array
55
     */
56
    public $related = [];
57
58
    /**
59
     * Set method for ArrayIterator.
60
     *
61
     * @param $offset
62
     * @param $value
63
     *
64
     * @return void
65
     */
66
    public function offsetSet($offset, $value)
67
    {
68
        if (is_null($offset)) {
69
            $this->fields[] = $value;
70
        } else {
71
            $this->fields[$offset] = $value;
72
        }
73
    }
74
75
    /**
76
     * Exists method for ArrayIterator.
77
     *
78
     * @param $offset
79
     *
80
     * @return bool
81
     */
82
    public function offsetExists($offset)
83
    {
84
        return $this->getAccessor($offset) || $this->getAccessorForLanguageField($offset)
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->getAccessor($offset) of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
Bug Best Practice introduced by
The expression $this->getAccessorForLanguageField($offset) of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
85
            ? true : isset($this->fields[$offset]);
86
    }
87
88
    /**
89
     * Unset method for ArrayIterator.
90
     *
91
     * @param $offset
92
     *
93
     * @return void
94
     */
95
    public function offsetUnset($offset)
96
    {
97
        unset($this->fields[$offset]);
98
    }
99
100
    /**
101
     * Get method for ArrayIterator.
102
     *
103
     * @param $offset
104
     *
105
     * @return mixed
106
     */
107
    public function offsetGet($offset)
108
    {
109
        $fieldValue = isset($this->fields[$offset]) ? $this->fields[$offset] : null;
110
        $accessor = $this->getAccessor($offset);
111
        if ($accessor) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $accessor of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
112
            return $this->$accessor($fieldValue);
113
        }
114
115
        $accessorForLanguageField = $this->getAccessorForLanguageField($offset);
116
        if ($accessorForLanguageField) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $accessorForLanguageField of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
117
            return $this->$accessorForLanguageField($offset);
118
        }
119
120
        return $fieldValue;
121
    }
122
123
    /**
124
     * Get an iterator for fields.
125
     *
126
     * @return ArrayIterator
127
     */
128
    public function getIterator()
129
    {
130
        return new ArrayIterator($this->fields);
131
    }
132
133
    /**
134
     * Get accessor method name if it exists.
135
     *
136
     * @param string $field
137
     *
138
     * @return string|false
139
     */
140
    private function getAccessor($field)
141
    {
142
        $method = 'get'.camel_case($field).'Attribute';
143
144
        return method_exists($this, $method) ? $method : false;
145
    }
146
    
147
    /**
148
     * Get accessor for language field method name if it exists.
149
     *
150
     * @param string $field
151
     *
152
     * @return string|false
153
     */
154
    private function getAccessorForLanguageField($field)
155
    {
156
        $method = 'getValueFromLanguageField';
157
158
        return in_array($field, $this->languageAccessors) && method_exists($this, $method) ? $method : false;
159
    }
160
161
    /**
162
     * Add value to append.
163
     *
164
     * @param  array|string  $attributes
165
     * @return $this
166
     */
167
    public function append($attributes)
168
    {
169
        $this->appends = array_unique(
170
            array_merge($this->appends, is_string($attributes) ? func_get_args() : $attributes)
171
        );
172
173
        return $this;
174
    }
175
176
    /**
177
     * Setter for appends.
178
     *
179
     * @param  array  $appends
180
     * @return $this
181
     */
182
    public function setAppends(array $appends)
183
    {
184
        $this->appends = $appends;
185
186
        return $this;
187
    }
188
189
    /**
190
     * Cast model to array.
191
     *
192
     * @return array
193
     */
194
    public function toArray()
195
    {
196
        $array = $this->fields;
197
198
        foreach ($this->appends as $accessor) {
199
            if (isset($this[$accessor])) {
200
                $array[$accessor] = $this[$accessor];
201
            }
202
        }
203
204
        foreach ($this->related as $key => $value) {
205
            if (is_object($value) && method_exists($value, 'toArray')) {
206
                $array[$key] = $value->toArray();
207
            } elseif (is_null($value) || $value === false) {
208
                $array[$key] = $value;
209
            }
210
        }
211
212
        if (count($this->getVisible()) > 0) {
213
            $array = array_intersect_key($array, array_flip($this->getVisible()));
214
        }
215
216
        if (count($this->getHidden()) > 0) {
217
            $array = array_diff_key($array, array_flip($this->getHidden()));
218
        }
219
220
        return $array;
221
    }
222
223
    /**
224
     * Convert model to json.
225
     *
226
     * @param int $options
227
     *
228
     * @return string
229
     */
230
    public function toJson($options = 0)
231
    {
232
        return json_encode($this->toArray(), $options);
233
    }
234
}
235