Completed
Pull Request — master (#6)
by
unknown
04:43
created

ContentfulModel::getIdAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Distilleries\Contentful\Models\Base;
4
5
use Distilleries\Contentful\Helpers\NamespaceResolver;
6
use Illuminate\Support\Collection;
7
use Illuminate\Database\Eloquent\Model;
8
use Distilleries\Contentful\Models\Asset;
9
use Distilleries\Contentful\Models\Traits\Localable;
10
use Distilleries\Contentful\Models\EntryRelationship;
11
12
abstract class ContentfulModel extends Model
13
{
14
    use Localable;
15
16
    /**
17
     * {@inheritdoc}
18
     */
19
    protected $primaryKey = 'contentful_id';
20
21
    /**
22
     * The content-type ID.
23
     *
24
     * @var string
25
     */
26
    protected $contentType = null;
27
28
    /**
29
     * {@inheritdoc}
30
     */
31
    protected $keyType = 'string';
32
33
    /**
34
     * {@inheritdoc}
35
     */
36
    public $incrementing = false;
37
38
    /**
39
     * ContentfulModel constructor.
40
     *
41
     * @param  array $attributes
42
     */
43
    public function __construct(array $attributes = [])
44
    {
45
        // Override fillable
46
        foreach ($this->defaultFillable() as $defaultFillable) {
47
            if (!in_array($defaultFillable, $this->fillable)) {
48
                $this->fillable[] = $defaultFillable;
49
            }
50
        }
51
52
        // Override casts
53
        foreach ($this->defaultCasts() as $field => $type) {
54
            if (!isset($this->casts[$field])) {
55
                $this->casts[$field] = $type;
56
            }
57
        }
58
59
        $this->initContentType();
60
61
        parent::__construct($attributes);
62
    }
63
64
    /**
65
     * Init model content-type if needed.
66
     *
67
     * @return void
68
     */
69
    protected function initContentType()
70
    {
71
        if (empty($this->contentType)) {
72
            $this->contentType = lcfirst(class_basename(get_class($this)));
73
        }
74
    }
75
76
    /**
77
     * Return default fillable fields.
78
     *
79
     * @return array
80
     */
81
    public function defaultFillable(): array
82
    {
83
        return [
84
            'contentful_id',
85
            'country',
86
            'locale',
87
            'payload',
88
            'created_at',
89
            'updated_at',
90
        ];
91
    }
92
93
    /**
94
     * Return default casted fields.
95
     *
96
     * @return array
97
     */
98
    public function defaultCasts(): array
99
    {
100
        return [
101
            'payload' => 'array',
102
        ];
103
    }
104
105
    // --------------------------------------------------------------------------------
106
    // --------------------------------------------------------------------------------
107
    // --------------------------------------------------------------------------------
108
109
    protected function getAndSetPayloadContentfulAsset(string $payload, $link, $query = null): ?Asset
110
    {
111
        if (!isset($this->attributes[$payload]) && isset($this->payload[$payload])) {
0 ignored issues
show
Bug introduced by
The property payload does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
112
            $this->attributes[$payload] = $this->contentfulAsset($link, $query);
113
            return $this->attributes[$payload];
114
        } else {
115
            if (isset($this->attributes[$payload])) {
116
                return $this->attributes[$payload];
117
            } else {
118
                return null;
119
            }
120
        }
121
    }
122
123
124
    /**
125
     * Return Contentful Asset for given link (sys or ID).
126
     *
127
     * @param  array|string|null $link
128
     * @param  callback|null $query
129
     * @return \Distilleries\Contentful\Models\Asset|null
130
     */
131
    protected function contentfulAsset($link, $query = null): ?Asset
132
    {
133
        $assetId = $this->contentfulLinkId($link);
134
135
        if (empty($assetId)) {
136
            return null;
137
        }
138
139
        $instance = (new Asset)->query()
140
            ->where('contentful_id', '=', $assetId)
141
            ->where('locale', '=', $this->locale)
0 ignored issues
show
Bug introduced by
The property locale does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
142
            ->where('country', '=', $this->country);
0 ignored issues
show
Bug introduced by
The property country does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
143
144
        if (!empty($query)) {
145
            $instance = call_user_func($query, $instance);
146
        }
147
148
        $asset = $instance->first();
149
150
        return !empty($asset) ? $asset : null;
151
    }
152
153
    /**
154
     * Return payload of related Contentful entries.
155
     *
156
     * @param  string $payload
157
     * @param  array $links
158
     * @param  mixed $query
159
     * @return \Illuminate\Support\Collection
160
     */
161
    protected function getAndSetPayloadContentfulEntries(string $payload, array $links, $query = null): Collection
162
    {
163
        if (!isset($this->attributes[$payload]) && isset($this->payload[$payload])) {
0 ignored issues
show
Bug introduced by
The property payload does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
164
            $this->attributes[$payload] = $this->contentfulEntries($links, $query, $payload);
165
            return $this->attributes[$payload];
166
        } else {
167
            if (isset($this->attributes[$payload])) {
168
                return $this->attributes[$payload];
169
            } else {
170
                return collect();
171
            }
172
        }
173
    }
174
175
    /**
176
     * Return payload of related Contentful entry.
177
     *
178
     * @param  string $payload
179
     * @param  array $links
180
     * @param  mixed $query
181
     * @return \Distilleries\Contentful\Models\Base\ContentfulModel|null
182
     */
183
    protected function getAndSetPayloadContentfulEntry(string $payload, array $links, $query = null): ?ContentfulModel
184
    {
185
        if (!isset($this->attributes[$payload]) && isset($this->payload[$payload])) {
0 ignored issues
show
Bug introduced by
The property payload does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
186
            $this->attributes[$payload] = $this->contentfulEntry($links, $query, $payload);
187
            return $this->attributes[$payload];
188
        } else {
189
            if (isset($this->attributes[$payload])) {
190
                return $this->attributes[$payload];
191
            } else {
192
                return null;
193
            }
194
        }
195
    }
196
197
    /**
198
     * Return Contentful Entry for given link (sys or ID).
199
     *
200
     * @param  array|string|null $link
201
     * @param  mixed $query
202
     * @param  mixed $field
203
     * @return \Distilleries\Contentful\Models\Base\ContentfulModel|null
204
     */
205
    protected function contentfulEntry($link, $query = null, $field = null): ?ContentfulModel
206
    {
207
        $entryId = $this->contentfulLinkId($link);
208
209
        if (empty($entryId)) {
210
            return null;
211
        }
212
213
        $entries = $this->contentfulEntries([$entryId], $query, $field);
214
215
        return $entries->isNotEmpty() ? $entries->first() : null;
216
    }
217
218
    /**
219
     * Return Contentful Entries for given ID.
220
     *
221
     * @param  array $links
222
     * @param  mixed $query
223
     * @param  mixed $field
224
     * @return \Illuminate\Support\Collection
225
     */
226
    protected function contentfulEntries(array $links, $query = null, $field = null): Collection
227
    {
228
        $entries = [];
229
230
        $entryIds = [];
231
        foreach ($links as $link) {
232
            $entryId = $this->contentfulLinkId($link);
233
            if (!empty($entryId)) {
234
                $entryIds[] = $entryId;
235
            }
236
        }
237
238
        if (!empty($entryIds)) {
239
            $relationships = EntryRelationship::select('related_contentful_id', 'related_contentful_type')
240
                ->distinct()
241
                ->locale($this->locale, $this->country)
0 ignored issues
show
Bug introduced by
The property locale does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
Bug introduced by
The property country does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
242
                ->where('source_contentful_id', '=', $this->contentful_id)
0 ignored issues
show
Bug introduced by
The property contentful_id does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
243
                ->whereIn('related_contentful_id', $entryIds)
244
                ->where('relation', $field)
245
                ->orderBy('order', 'asc')
246
                ->get();
247
248
            foreach ($relationships as $relationship) {
249
                if ($relationship->related_contentful_type === 'asset') {
250
                    $model = new Asset;
251
                } else {
252
                    $model = NamespaceResolver::model($relationship->related_contentful_type);
253
                }
254
255
                if (!empty($model)) {
256
                    $instance = $model->query()
257
                        ->where('country', '=', $this->country)
258
                        ->where('locale', '=', $this->locale)
259
                        ->where('contentful_id', '=', $relationship->related_contentful_id);
260
261
                    if (!empty($query)) {
262
                        $instance = call_user_func($query, $instance);
263
                    }
264
265
                    $instance = $instance->first();
266
267
                }
268
269
                if (!empty($instance)) {
270
                    $entries[] = $instance;
271
                }
272
            }
273
        }
274
275
        return collect($entries);
276
    }
277
278
    /**
279
     * Return a collection of related models for base Contentful ID.
280
     *
281
     * @param  string $contentfulId
282
     * @param  string $contentfulType
283
     * @return \Illuminate\Support\Collection
284
     */
285
    protected function contentfulRelatedEntries(string $contentfulId, string $contentfulType = ''): Collection
286
    {
287
        $entries = [];
288
289
        $query = EntryRelationship::select('source_contentful_id', 'source_contentful_type')
290
            ->locale($this->locale, $this->country)
0 ignored issues
show
Bug introduced by
The property country does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
Bug introduced by
The property locale does not seem to exist on Distilleries\Contentful\...ls\Base\ContentfulModel. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
291
            ->where('related_contentful_id', '=', $contentfulId);
292
293
        if (!empty($contentfulType)) {
294
            $query = $query->where('source_contentful_type', '=', $contentfulType);
295
        }
296
297
        $relationships = $query->orderBy('order', 'asc')->get();
298
        foreach ($relationships as $relationship) {
299
            if ($relationship->source_contentful_type === 'asset') {
300
                $model = new Asset;
301
            } else {
302
                $model = NamespaceResolver::model($relationship->related_contentful_type);
303
            }
304
305
            $instance = !empty($model) ? $model->query()
306
                ->locale($this->locale, $this->country)
307
                ->where('contentful_id', '=', $relationship->source_contentful_id)
308
                ->first() : null;
309
310
            if (!empty($instance)) {
311
                $entries[] = $instance;
312
            }
313
        }
314
315
        return collect($entries);
316
    }
317
318
    /**
319
     * Return Contentful link ID.
320
     *
321
     * @param  mixed $link
322
     * @return string|null
323
     */
324
    protected function contentfulLinkId($link): ?string
325
    {
326
        if (empty($link)) {
327
            return null;
328
        }
329
330
        if (is_string($link)) {
331
            return $link;
332
        }
333
334
        if (is_array($link) && isset($link['sys']) && isset($link['sys']['id'])) {
335
            return $link['sys']['id'];
336
        }
337
338
        return null;
339
    }
340
341
    /**
342
     * Return model Contentful content-type.
343
     *
344
     * @return string
345
     */
346
    public function getContentType(): string
347
    {
348
        return $this->contentType;
349
    }
350
351
    /**
352
     * Return ID attribute.
353
     *
354
     * @return mixed
355
     */
356
    public function getIdAttribute()
357
    {
358
        return $this->getKey();
359
    }
360
361
    /**
362
     * Magical extended toArray().
363
     *
364
     * @return array
365
     */
366
    public function toArray()
367
    {
368
        $array = parent::toArray();
369
370
        foreach ($this->getMutatedAttributes() as $key) {
371
            if (!array_key_exists($key, $array)) {
372
                $array[$key] = $this->{$key};
373
            }
374
        }
375
376
        return $array;
377
    }
378
}
379