Test Failed
Push — fix/localized-img-bug ( a16f3e...daa57d )
by Ben
21:18
created

UrlRecord::findByModel()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
dl 0
loc 13
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
namespace Thinktomorrow\Chief\Urls;
4
5
use Illuminate\Database\Eloquent\Model;
6
7
class UrlRecord extends Model
8
{
9
    public $table = 'chief_urls';
10
11
    public $guarded = [];
12
13
    /**
14
     * Find matching url record for passed slug and locale. The locale parameter will try
15
     * to match specific given locales first and records without locale as fallback.
16
     *
17
     * @param string $slug
18
     * @param string $locale
19
     * @return UrlRecord
20
     * @throws UrlRecordNotFound
21
     */
22
    public static function findBySlug(string $slug, string $locale): UrlRecord
23
    {
24
        // Clear the input from any trailing slashes.
25
        if ($slug != '/') {
26
            $slug = trim($slug, '/');
27
        }
28
29
        $record = static::where('slug', $slug)
30
                        ->where('locale', $locale)
31
                        ->orderBy('redirect_id', 'ASC')
32
                        ->first();
33
34
        if (!$record) {
35
            throw new UrlRecordNotFound('No url record found by slug ['.$slug.'] for locale ['.$locale.'].');
36
        }
37
38
        return $record;
39
    }
40
41
    /**
42
     * Find matching url record for passed slug and locale. The locale parameter will try
43
     * to match specific given locales first and records without locale as fallback.
44
     *
45
     * @param Model $model
46
     * @param string $locale
47
     * @return UrlRecord
48
     * @throws UrlRecordNotFound
49
     */
50
    public static function findByModel(Model $model, string $locale): UrlRecord
51
    {
52
        $record = static::where('model_type', $model->getMorphClass())
53
            ->where('model_id', $model->id)
54
            ->where('locale', $locale)
55
            ->orderBy('redirect_id', 'ASC')
56
            ->first();
57
58
        if (!$record) {
59
            throw new UrlRecordNotFound('No url record found for model ['.$model->getMorphClass().'@'.$model->id.'] for locale ['.$locale.'].');
60
        }
61
62
        return $record;
63
    }
64
65
    public static function getByModel(Model $model)
66
    {
67
        return static::where('model_type', $model->getMorphClass())
68
                     ->where('model_id', $model->id)
69
                     ->get();
70
    }
71
72
    public static function findRecentRedirect(Model $model, string $locale): ?self
73
    {
74
        return static::where('model_type', $model->getMorphClass())
75
            ->where('model_id', $model->id)
76
            ->where('locale', $locale)
77
            ->where('redirect_id', '<>', null)
78
            ->orderBy('updated_at', 'DESC')
79
            ->first();
80
    }
81
82
    public function replaceAndRedirect(array $values): UrlRecord
83
    {
84
        $newRecord = static::create(array_merge([
85
            'locale'              => $this->locale,
86
            'model_type'          => $this->model_type,
87
            'model_id'            => $this->model_id,
88
        ], $values));
89
90
        $this->redirectTo($newRecord);
91
92
        return $newRecord;
93
    }
94
95
    public function redirectTo(self $record = null): ?UrlRecord
96
    {
97
        if (!$record) {
98
            return $this->isRedirect() ? static::find($this->redirect_id) : null;
99
        }
100
101
        $this->redirect_id = $record->id;
102
        $this->save();
103
104
        return null;
105
    }
106
107
    // Remove all urls that came after this one
108
    public function revert()
109
    {
110
        if (!$this->isRedirect()) {
111
            return;
112
        }
113
114
        // Remove this redirect relation so it's no longer cascading when main url is getting deleted.
115
        $redirect_id = $this->redirect_id;
116
        $this->redirect_id = null;
117
        $this->save();
118
119
        if ($record = static::where('id', $redirect_id)->first()) {
120
            $record->revert();
121
            $record->delete();
122
        }
123
    }
124
125
    public function isRedirect(): bool
126
    {
127
        return !!($this->redirect_id);
128
    }
129
130
    public function isHomepage(): bool
131
    {
132
        return $this->slug === '/';
133
    }
134
135
    public static function existsIgnoringRedirects($slug, string $locale = null, Model $ignoredModel = null): bool
136
    {
137
        return static::exists($slug, $locale, $ignoredModel, false);
138
    }
139
140
    public static function exists($slug, string $locale = null, Model $ignoredModel = null, bool $includeRedirects = true): bool
141
    {
142
        $builder = static::where('slug', $slug);
143
144
        if ($locale) {
145
            $builder->where('locale', $locale);
146
        }
147
148
        if (! $includeRedirects) {
149
            $builder->whereNull('redirect_id');
150
        }
151
152
        if ($ignoredModel) {
153
            $builder->whereNotIn('id', function ($query) use ($ignoredModel) {
154
                $query->select('id')
155
                      ->from('chief_urls')
156
                      ->where('model_type', '=', $ignoredModel->getMorphClass())
157
                      ->where('model_id', '=', $ignoredModel->id);
158
            });
159
        }
160
161
        return ($builder->count() > 0);
162
    }
163
}
164