ContentfulModel::contentfulAsset()   A
last analyzed

Complexity

Conditions 4
Paths 5

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 4
eloc 11
c 4
b 0
f 0
nc 5
nop 2
dl 0
loc 20
ccs 0
cts 15
cp 0
crap 20
rs 9.9
1
<?php
2
3
namespace Distilleries\Contentful\Models\Base;
4
5
use Illuminate\Support\Collection;
6
use Illuminate\Database\Eloquent\Model;
7
use Distilleries\Contentful\Models\Asset;
8
use Distilleries\Contentful\Models\Traits\Localable;
9
use Distilleries\Contentful\Models\EntryRelationship;
10
use Distilleries\Contentful\Helpers\NamespaceResolver;
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
     * @return void
43
     */
44
    public function __construct(array $attributes = [])
45
    {
46
        // Override fillable
47
        foreach ($this->defaultFillable() as $defaultFillable) {
48
            if (! in_array($defaultFillable, $this->fillable)) {
49
                $this->fillable[] = $defaultFillable;
50
            }
51
        }
52
53
        // Override casts
54
        foreach ($this->defaultCasts() as $field => $type) {
55
            if (! isset($this->casts[$field])) {
56
                $this->casts[$field] = $type;
57
            }
58
        }
59
60
        $this->initContentType();
61
62
        parent::__construct($attributes);
63
    }
64
65
    /**
66
     * Init model content-type if needed.
67
     *
68
     * @return void
69
     */
70
    protected function initContentType()
71
    {
72
        if (empty($this->contentType)) {
73
            $this->contentType = lcfirst(class_basename(get_class($this)));
74
        }
75
    }
76
77
    /**
78
     * Return default fillable fields.
79
     *
80
     * @return array
81
     */
82
    public function defaultFillable(): array
83
    {
84
        return [
85
            'contentful_id',
86
            'country',
87
            'locale',
88
            'payload',
89
            'created_at',
90
            'updated_at',
91
        ];
92
    }
93
94
    /**
95
     * Return default casted fields.
96
     *
97
     * @return array
98
     */
99
    public function defaultCasts(): array
100
    {
101
        return [
102
            'payload' => 'array',
103
        ];
104
    }
105
106
    // --------------------------------------------------------------------------------
107
    // --------------------------------------------------------------------------------
108
    // --------------------------------------------------------------------------------
109
110
    /**
111
     * Return payload of related Contentful asset.
112
     *
113
     * @param  string  $payload
114
     * @param  array|string|null  $link
115
     * @param  callback|null  $query
116
     * @return \Distilleries\Contentful\Models\Asset|null
117
     */
118
    protected function getAndSetPayloadContentfulAsset(string $payload, $link, $query = null): ?Asset
119
    {
120
        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...
121
            $this->attributes[$payload] = $this->contentfulAsset($link, $query);
122
            return $this->attributes[$payload];
123
        } else {
124
            if (isset($this->attributes[$payload])) {
125
                return $this->attributes[$payload];
126
            } else {
127
                return null;
128
            }
129
        }
130
    }
131
132
    /**
133
     * Return Contentful Asset for given link (sys or ID).
134
     *
135
     * @param  array|string|null  $link
136
     * @param  callback|null  $query
137
     * @return \Distilleries\Contentful\Models\Asset|null
138
     */
139
    protected function contentfulAsset($link, $query = null): ?Asset
140
    {
141
        $assetId = $this->contentfulLinkId($link);
142
143
        if (empty($assetId)) {
144
            return null;
145
        }
146
147
        $instance = (new Asset)->query()
148
            ->where('contentful_id', '=', $assetId)
149
            ->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...
150
            ->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...
151
152
        if (! empty($query)) {
153
            $instance = call_user_func($query, $instance);
154
        }
155
156
        $asset = $instance->first();
157
158
        return ! empty($asset) ? $asset : null;
159
    }
160
161
    /**
162
     * Return payload of related Contentful entries.
163
     *
164
     * @param  string  $payload
165
     * @param  array  $links
166
     * @param  mixed  $query
167
     * @return \Illuminate\Support\Collection
168
     */
169
    protected function getAndSetPayloadContentfulEntries(string $payload, array $links, $query = null): Collection
170
    {
171
        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...
172
            $this->attributes[$payload] = $this->contentfulEntries($links, $query, $payload);
173
174
            return $this->attributes[$payload];
175
        } else {
176
            if (isset($this->attributes[$payload])) {
177
                return $this->attributes[$payload];
178
            } else {
179
                return collect();
180
            }
181
        }
182
    }
183
184
    /**
185
     * Return payload of related Contentful entry.
186
     *
187
     * @param  string  $payload
188
     * @param  array  $links
189
     * @param  mixed|null  $query
190
     * @return \Distilleries\Contentful\Models\Base\ContentfulModel|null
191
     */
192
    protected function getAndSetPayloadContentfulEntry(string $payload, array $links, $query = null): ?ContentfulModel
193
    {
194
        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...
195
            $this->attributes[$payload] = $this->contentfulEntry($links, $query, $payload);
196
197
            return $this->attributes[$payload];
198
        } else {
199
            if (isset($this->attributes[$payload])) {
200
                return $this->attributes[$payload];
201
            } else {
202
                return null;
203
            }
204
        }
205
    }
206
207
    /**
208
     * Return Contentful Entry for given link (sys or ID).
209
     *
210
     * @param  array|string|null  $link
211
     * @param  mixed|null  $query
212
     * @param  mixed|null  $field
213
     * @return \Distilleries\Contentful\Models\Base\ContentfulModel|null
214
     */
215
    protected function contentfulEntry($link, $query = null, $field = null): ?ContentfulModel
216
    {
217
        $entryId = $this->contentfulLinkId($link);
218
219
        if (empty($entryId)) {
220
            return null;
221
        }
222
223
        $entries = $this->contentfulEntries([$entryId], $query, $field);
224
225
        return $entries->isNotEmpty() ? $entries->first() : null;
226
    }
227
228
    /**
229
     * Return Contentful Entries for given ID.
230
     *
231
     * @param  array  $links
232
     * @param  mixed|null  $query
233
     * @param  mixed|null  $field
234
     * @return \Illuminate\Support\Collection
235
     */
236
    protected function contentfulEntries(array $links, $query = null, $field = null): Collection
237
    {
238
        $entries = [];
239
240
        $entryIds = [];
241
        foreach ($links as $link) {
242
            $entryId = $this->contentfulLinkId($link);
243
            if (! empty($entryId)) {
244
                $entryIds[] = $entryId;
245
            }
246
        }
247
248
        if (! empty($entryIds)) {
249
            $relationships = EntryRelationship::select('related_contentful_id', 'related_contentful_type', 'order')
250
                ->distinct()
251
                ->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...
252
                ->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...
253
                ->whereIn('related_contentful_id', $entryIds)
254
                ->where('relation', $field)
255
                ->orderBy('order', 'asc')
256
                ->get();
257
258
            foreach ($relationships as $relationship) {
259
                if ($relationship->related_contentful_type === 'asset') {
260
                    $model = new Asset;
261
                } else {
262
                    $model = NamespaceResolver::model($relationship->related_contentful_type);
263
                }
264
265
                if (! empty($model)) {
266
                    $instance = $model->query()
267
                        ->where('country', '=', $this->country)
268
                        ->where('locale', '=', $this->locale)
269
                        ->where('contentful_id', '=', $relationship->related_contentful_id);
270
271
                    if (! empty($query)) {
272
                        $instance = call_user_func($query, $instance);
273
                    }
274
275
                    $instance = $instance->first();
276
                }
277
278
                if (! empty($instance)) {
279
                    $entries[] = $instance;
280
                }
281
            }
282
        }
283
284
        return collect($entries);
285
    }
286
287
    /**
288
     * Return a collection of related models for base Contentful ID.
289
     *
290
     * @param  string  $contentfulId
291
     * @param  string  $contentfulType
292
     * @return \Illuminate\Support\Collection
293
     */
294
    protected function contentfulRelatedEntries(string $contentfulId, string $contentfulType = ''): Collection
295
    {
296
        $entries = [];
297
298
        $query = EntryRelationship::select('source_contentful_id', 'source_contentful_type')
299
            ->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...
300
            ->where('related_contentful_id', '=', $contentfulId);
301
302
        if (! empty($contentfulType)) {
303
            $query = $query->where('source_contentful_type', '=', $contentfulType);
304
        }
305
306
        $relationships = $query->orderBy('order', 'asc')->get();
307
        foreach ($relationships as $relationship) {
308
            if ($relationship->source_contentful_type === 'asset') {
309
                $model = new Asset;
310
            } else {
311
                $model = NamespaceResolver::model($relationship->related_contentful_type);
312
            }
313
314
            $instance = ! empty($model) ? $model->query()
315
                ->locale($this->locale, $this->country)
316
                ->where('contentful_id', '=', $relationship->source_contentful_id)
317
                ->first() : null;
318
319
            if (! empty($instance)) {
320
                $entries[] = $instance;
321
            }
322
        }
323
324
        return collect($entries);
325
    }
326
327
    /**
328
     * Return Contentful link ID.
329
     *
330
     * @param  mixed  $link
331
     * @return string|null
332
     */
333
    protected function contentfulLinkId($link): ?string
334
    {
335
        if (empty($link)) {
336
            return null;
337
        }
338
        if (is_string($link)) {
339
            return $link;
340
        }
341
        if (is_array($link) && isset($link['sys']) && isset($link['sys']['id'])) {
342
            return $link['sys']['id'];
343
        }
344
345
        return null;
346
    }
347
348
    /**
349
     * Return model Contentful content-type.
350
     *
351
     * @return string
352
     */
353
    public function getContentType(): string
354
    {
355
        return $this->contentType;
356
    }
357
358
    /**
359
     * Return ID attribute.
360
     *
361
     * @return mixed
362
     */
363
    public function getIdAttribute()
364
    {
365
        return $this->getKey();
366
    }
367
368
    /**
369
     * Magical extended toArray().
370
     *
371
     * @return array
372
     */
373
    public function toArray()
374
    {
375
        $array = parent::toArray();
376
377
        foreach ($this->getMutatedAttributes() as $key) {
378
            if (! array_key_exists($key, $array)) {
379
                $array[$key] = $this->{$key};
380
            }
381
        }
382
383
        return $array;
384
    }
385
}
386