Passed
Push — feature/permission-manager ( 41e93d )
by
unknown
09:00
created

Model::scopeAccessible()   B

Complexity

Conditions 7
Paths 5

Size

Total Lines 29
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 7
eloc 15
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 29
rs 8.8333
1
<?php
2
3
namespace A17\Twill\Models;
4
5
use A17\Twill\Models\Behaviors\HasPresenter;
6
use A17\Twill\Services\Capsules\HasCapsules;
7
use A17\Twill\Models\Behaviors\IsTranslatable;
8
use A17\Twill\Models\Permission;
9
use Auth;
10
use Carbon\Carbon;
11
use Cartalyst\Tags\TaggableInterface;
12
use Cartalyst\Tags\TaggableTrait;
13
use Illuminate\Database\Eloquent\Model as BaseModel;
14
use Illuminate\Database\Eloquent\Relations\MorphToMany;
15
use Illuminate\Database\Eloquent\SoftDeletes;
16
use Illuminate\Support\Str;
17
18
abstract class Model extends BaseModel implements TaggableInterface
19
{
20
    use HasPresenter, SoftDeletes, TaggableTrait, IsTranslatable, HasCapsules;
0 ignored issues
show
Bug introduced by
The trait A17\Twill\Services\Capsules\HasCapsules requires the property $command which is not provided by A17\Twill\Models\Model.
Loading history...
Bug introduced by
The trait A17\Twill\Models\Behaviors\IsTranslatable requires the property $translatedAttributes which is not provided by A17\Twill\Models\Model.
Loading history...
introduced by
The trait Cartalyst\Tags\TaggableTrait requires some properties which are not provided by A17\Twill\Models\Model: $tags, $count
Loading history...
21
22
    public $timestamps = true;
23
24
    protected function isTranslationModel()
25
    {
26
        return Str::endsWith(get_class($this), 'Translation');
27
    }
28
29
    public function scopePublished($query)
30
    {
31
        return $query->where("{$this->getTable()}.published", true);
32
    }
33
34
    public function scopeAccessible($query)
35
    {
36
        if (!config('twill.enabled.permissions-management')) {
37
            return $query;
38
        }
39
40
        $model = get_class($query->getModel());
41
        $moduleName = isPermissionableModule(getModuleNameByModel($model));
42
43
        if ($moduleName && !Auth::user()->isSuperAdmin()) {
0 ignored issues
show
Bug introduced by
The method isSuperAdmin() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User. ( Ignorable by Annotation )

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

43
        if ($moduleName && !Auth::user()->/** @scrutinizer ignore-call */ isSuperAdmin()) {
Loading history...
44
            // Get all permissions the logged in user has regards to the model.
45
            $allPermissions = Auth::user()->allPermissions();
0 ignored issues
show
Bug introduced by
The method allPermissions() does not exist on Illuminate\Contracts\Auth\Authenticatable. It seems like you code against a sub-type of Illuminate\Contracts\Auth\Authenticatable such as Illuminate\Foundation\Auth\User. ( Ignorable by Annotation )

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

45
            $allPermissions = Auth::user()->/** @scrutinizer ignore-call */ allPermissions();
Loading history...
46
            $allModelPermissions = (clone $allPermissions)->ofModel($model);
47
48
            // If the user has any module permissions, or global manage all modules permissions, all items will be return
49
            if ((clone $allModelPermissions)->module()->whereIn('name', Permission::available(Permission::SCOPE_MODULE))->exists()
50
                || (clone $allPermissions)->global()->where('name', 'manage-modules')->exists()) {
51
                return $query;
52
            }
53
54
            // If the module is submodule, skip the scope.
55
            if (strpos($moduleName, '.')) {
0 ignored issues
show
Bug introduced by
It seems like $moduleName can also be of type true; however, parameter $haystack of strpos() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

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

55
            if (strpos(/** @scrutinizer ignore-type */ $moduleName, '.')) {
Loading history...
56
                return $query;
57
            };
58
59
            $authorizedItemsIds = $allModelPermissions->moduleItem()->pluck('permissionable_id');
60
            return $query->whereIn($this->getTable() . '.id', $authorizedItemsIds);
61
        }
62
        return $query;
63
    }
64
65
    public function scopePublishedInListings($query)
66
    {
67
        if ($this->isFillable('public')) {
68
            $query->where("{$this->getTable()}.public", true);
69
70
        }
71
72
        return $query->published()->visible();
73
    }
74
75
    public function scopeVisible($query)
76
    {
77
        if ($this->isFillable('publish_start_date')) {
78
            $query->where(function ($query) {
79
                $query->whereNull("{$this->getTable()}.publish_start_date")->orWhere("{$this->getTable()}.publish_start_date", '<=', Carbon::now());
80
            });
81
82
            if ($this->isFillable('publish_end_date')) {
83
                $query->where(function ($query) {
84
                    $query->whereNull("{$this->getTable()}.publish_end_date")->orWhere("{$this->getTable()}.publish_end_date", '>=', Carbon::now());
85
                });
86
            }
87
        }
88
89
        return $query;
90
    }
91
92
    public function setPublishStartDateAttribute($value)
93
    {
94
        $this->attributes['publish_start_date'] = $value ?? Carbon::now();
95
    }
96
97
    public function scopeDraft($query)
98
    {
99
        return $query->where("{$this->getTable()}.published", false);
100
    }
101
102
    public function scopeOnlyTrashed($query)
103
    {
104
        return $query->whereNotNull("{$this->getTable()}.deleted_at");
105
    }
106
107
    public function getFillable()
108
    {
109
        // If the fillable attribute is filled, just use it
110
        $fillable = $this->fillable;
111
112
        // If fillable is empty
113
        // and it's a translation model
114
        // and the baseModel was defined
115
        // Use the list of translatable attributes on our base model
116
        if (
117
            blank($fillable) &&
118
            $this->isTranslationModel() &&
119
            property_exists($this, 'baseModuleModel')
120
        ) {
121
            $fillable = (new $this->baseModuleModel)->getTranslatedAttributes();
0 ignored issues
show
Bug introduced by
The property baseModuleModel does not seem to exist on A17\Twill\Models\Model. 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...
122
123
            if (!collect($fillable)->contains('locale')) {
124
                $fillable[] = 'locale';
125
            }
126
127
            if (!collect($fillable)->contains('active')) {
128
                $fillable[] = 'active';
129
            }
130
        }
131
132
        return $fillable;
133
    }
134
135
    public function getTranslatedAttributes()
136
    {
137
        return $this->translatedAttributes ?? [];
0 ignored issues
show
Bug introduced by
The property translatedAttributes does not seem to exist on A17\Twill\Models\Model. 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...
138
    }
139
140
    protected static function bootTaggableTrait()
141
    {
142
        static::$tagsModel = Tag::class;
143
    }
144
145
    /**
146
     * {@inheritdoc}
147
     */
148
    public function tags(): MorphToMany
149
    {
150
        return $this->morphToMany(
151
            static::$tagsModel,
152
            'taggable',
153
            config('twill.tagged_table', 'tagged'),
154
            'taggable_id',
155
            'tag_id'
156
        );
157
    }
158
}
159