Passed
Push — ft/pagefield ( b345a2...03e98d )
by Ben
17:59 queued 09:45
created

UrlHelper::allModelsExcept()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 1
CRAP Score 1

Importance

Changes 0
Metric Value
eloc 2
c 0
b 0
f 0
dl 0
loc 5
rs 10
ccs 1
cts 1
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Thinktomorrow\Chief\Urls;
6
7
use Illuminate\Support\Collection;
8
use Illuminate\Database\Eloquent\Model;
9
use Thinktomorrow\Chief\Management\Managers;
10
use Thinktomorrow\Chief\Common\Helpers\Memoize;
11
use Thinktomorrow\Chief\Concerns\Morphable\Morphables;
12
use Thinktomorrow\Chief\FlatReferences\FlatReferencePresenter;
13
14
class UrlHelper
15
{
16
    /**
17
     * Internal api for fetching all models that have an active url.
18
     * This will return a grouped values array ready for select fields
19
     *
20 8
     * @param bool $onlySingles
21
     * @param Model|null $ignoredModel
22 8
     * @return array
23
     */
24 8
    public static function allOnlineModels(bool $onlySingles = false, Model $ignoredModel = null): array
25
    {
26
        $models = static::onlineModels($onlySingles, $ignoredModel);
27
28
        return FlatReferencePresenter::toGroupedSelectValues($models)->toArray();
29
    }
30
31
    /**
32
     * Internal api for fetching all models.
33
     * This will return a grouped values array ready for select fields
34
     *
35
     * @param Model|null $ignoredModel
36
     * @return array
37
     */
38
    public static function allModelsExcept(Model $ignoredModel = null): array
39
    {
40 8
        $models = static::models(false, $ignoredModel, false);
41
42
        return FlatReferencePresenter::toGroupedSelectValues($models)->toArray();
43 8
    }
44 8
45 8
    public static function allOnlineSingles()
46
    {
47 8
        return static::allOnlineModels(true);
48
    }
49
50
    /**
51
     * Fetch all models that have an active url. Here we check on the ignored model
52 4
     * after retrieval from database so our memoized cache gets optimal usage.
53
     *
54 4
     * @param bool $onlySingles
55
     * @param Model|null $ignoredModel
56 4
     * @return Collection
57 8
     */
58 8
    public static function onlineModels(bool $onlySingles = false, Model $ignoredModel = null): Collection
59
    {
60 8
        return self::models($onlySingles, $ignoredModel, true);
61
    }
62
63 2
64
    public static function models(bool $onlySingles = false, Model $ignoredModel = null, $online = true)
65
    {
66 8
        $types = [];
67
68
        if ($onlySingles) {
69
            $types = ['singles'];
70
        }
71
72
        return self::modelsByType($types, $ignoredModel, $online);
73
    }
74
75
    public static function modelsByKeys(array $keys, Model $ignoredModel = null, $online = true)
76
    {
77
        $managers = app(Managers::class);
78
79
        $whitelistedDatabaseTypes = [];
80
81
        foreach($keys as $key) {
82
            $manager = $managers->findByKey($key);
83
            $whitelistedDatabaseTypes[] = $manager->modelInstance()->getMorphClass();
0 ignored issues
show
Bug introduced by
The method getMorphClass() does not exist on Thinktomorrow\Chief\Management\ManagedModel. Since it exists in all sub-types, consider adding an abstract or default implementation to Thinktomorrow\Chief\Management\ManagedModel. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

83
            $whitelistedDatabaseTypes[] = $manager->modelInstance()->/** @scrutinizer ignore-call */ getMorphClass();
Loading history...
84
        }
85
86
        return static::modelsByType($whitelistedDatabaseTypes, $ignoredModel, $online);
87
    }
88
89
90
    public static function modelsByType(array $types, Model $ignoredModel = null, $online = true)
91
    {
92
        $models = chiefMemoize('all-online-models', function () use ($types, $online) {
93
            $builder = UrlRecord::whereNull('redirect_id')
94
                ->select('model_type', 'model_id')
95
                ->groupBy('model_type', 'model_id');
96
97
            if (!empty($types)) {
98
                $builder->whereIn('model_type', $types);
99
            }
100
101
            return $builder->get()->mapToGroups(function ($record) {
102
                return [$record->model_type => $record->model_id];
103
            })->map(function ($record, $key) {
104
                return Morphables::instance($key)->find($record->toArray());
105
            })->map->reject(function ($model) use ($online) {
106
                if ($online) {
107
                    return is_null($model) || !$model->isPublished();
108
                } // Invalid references to archived or removed models where url record still exists.
109
110
                return is_null($model);
111
            })->flatten();
112
        });
113
114
        if ($ignoredModel) {
115
            $models = $models->reject(function ($model) use ($ignoredModel) {
116
                return (get_class($model) === get_class($ignoredModel) && $model->id === $ignoredModel->id);
117
            });
118
        }
119
120
        return $models;
121
    }
122
}
123