Completed
Push — 0.3 ( efdb4a...76853c )
by Ben
152:21 queued 145:31
created

UrlRecord   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 153
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
wmc 21
eloc 63
c 4
b 2
f 0
dl 0
loc 153
ccs 72
cts 72
cp 1
rs 10

11 Methods

Rating   Name   Duplication   Size   Complexity  
A getByModel() 0 5 1
A findByModel() 0 13 2
A findBySlug() 0 17 3
A replaceAndRedirect() 0 11 1
A findRecentRedirect() 0 8 1
A redirectTo() 0 10 3
A revert() 0 13 3
A isRedirect() 0 3 1
A existsIgnoringRedirects() 0 3 1
A exists() 0 22 4
A isHomepage() 0 3 1
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 29
    public static function findBySlug(string $slug, string $locale): UrlRecord
23
    {
24
        // Clear the input from any trailing slashes.
25 29
        if ($slug != '/') {
26 27
            $slug = trim($slug, '/');
27
        }
28
29 29
        $record = static::where('slug', $slug)
30 29
                        ->where('locale', $locale)
31 29
                        ->orderBy('redirect_id', 'ASC')
32 29
                        ->first();
33
34 29
        if (!$record) {
35 4
            throw new UrlRecordNotFound('No url record found by slug ['.$slug.'] for locale ['.$locale.'].');
36
        }
37
38 25
        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 55
    public static function findByModel(Model $model, string $locale): UrlRecord
51
    {
52 55
        $record = static::where('model_type', $model->getMorphClass())
53 55
            ->where('model_id', $model->id)
54 55
            ->where('locale', $locale)
55 55
            ->orderBy('redirect_id', 'ASC')
56 55
            ->first();
57
58 55
        if (!$record) {
59 21
            throw new UrlRecordNotFound('No url record found for model ['.$model->getMorphClass().'@'.$model->id.'] for locale ['.$locale.'].');
60
        }
61
62 36
        return $record;
63
    }
64
65 71
    public static function getByModel(Model $model)
66
    {
67 71
        return static::where('model_type', $model->getMorphClass())
68 71
                     ->where('model_id', $model->id)
69 71
                     ->get();
70
    }
71
72 1
    public static function findRecentRedirect(Model $model, string $locale): ?self
73
    {
74 1
        return static::where('model_type', $model->getMorphClass())
75 1
            ->where('model_id', $model->id)
76 1
            ->where('locale', $locale)
77 1
            ->where('redirect_id', '<>', null)
78 1
            ->orderBy('redirect_id', 'ASC')
79 1
            ->first();
80
    }
81
82 17
    public function replaceAndRedirect(array $values): UrlRecord
83
    {
84 17
        $newRecord = static::create(array_merge([
85 17
            'locale'              => $this->locale,
86 17
            'model_type'          => $this->model_type,
87 17
            'model_id'            => $this->model_id,
88 17
        ], $values));
89
90 17
        $this->redirectTo($newRecord);
91
92 17
        return $newRecord;
93
    }
94
95 18
    public function redirectTo(self $record = null): ?UrlRecord
96
    {
97 18
        if (!$record) {
98 3
            return $this->isRedirect() ? static::find($this->redirect_id) : null;
99
        }
100
101 18
        $this->redirect_id = $record->id;
102 18
        $this->save();
103
104 18
        return null;
105
    }
106
107
    // Remove all urls that came after this one
108 1
    public function revert()
109
    {
110 1
        if (!$this->isRedirect()) {
111 1
            return;
112
        }
113
114 1
        if ($record = static::where('id', $this->redirect_id)->first()) {
115 1
            $record->revert();
116 1
            $record->delete();
117
        }
118
119 1
        $this->redirect_id = null;
120 1
        $this->save();
121 1
    }
122
123 71
    public function isRedirect(): bool
124
    {
125 71
        return !!($this->redirect_id);
126
    }
127
128 62
    public function isHomepage(): bool
129
    {
130 62
        return $this->slug === '/';
131
    }
132
133 62
    public static function existsIgnoringRedirects($slug, string $locale = null, Model $ignoredModel = null): bool
134
    {
135 62
        return static::exists($slug, $locale, $ignoredModel, false);
136
    }
137
138 62
    public static function exists($slug, string $locale = null, Model $ignoredModel = null, bool $includeRedirects = true): bool
139
    {
140 62
        $builder = static::where('slug', $slug);
141
142 62
        if ($locale) {
143 62
            $builder->where('locale', $locale);
144
        }
145
146 62
        if (! $includeRedirects) {
147 62
            $builder->whereNull('redirect_id');
148
        }
149
150 62
        if ($ignoredModel) {
151
            $builder->whereNotIn('id', function ($query) use ($ignoredModel) {
152 44
                $query->select('id')
153 44
                      ->from('chief_urls')
154 44
                      ->where('model_type', '=', $ignoredModel->getMorphClass())
155 44
                      ->where('model_id', '=', $ignoredModel->id);
156 44
            });
157
        }
158
159 62
        return ($builder->count() > 0);
160
    }
161
}
162