Auditable::bootAuditable()   B
last analyzed

Complexity

Conditions 7
Paths 1

Size

Total Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 15
rs 8.8333
cc 7
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Cortex\Foundation\Traits;
6
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Builder;
9
use Illuminate\Database\Eloquent\Relations\MorphTo;
10
11
trait Auditable
12
{
13
    /**
14
     * Register a creating model event with the dispatcher.
15
     *
16
     * @param \Closure|string $callback
17
     *
18
     * @return void
19
     */
20
    abstract public static function creating($callback);
21
22
    /**
23
     * Register an updating model event with the dispatcher.
24
     *
25
     * @param \Closure|string $callback
26
     *
27
     * @return void
28
     */
29
    abstract public static function updating($callback);
30
31
    /**
32
     * Define a polymorphic, inverse one-to-one or many relationship.
33
     *
34
     * @param string $name
0 ignored issues
show
Documentation introduced by
Should the type for parameter $name not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
35
     * @param string $type
0 ignored issues
show
Documentation introduced by
Should the type for parameter $type not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
36
     * @param string $id
0 ignored issues
show
Documentation introduced by
Should the type for parameter $id not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
37
     * @param string $ownerKey
0 ignored issues
show
Documentation introduced by
Should the type for parameter $ownerKey not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
38
     *
39
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
40
     */
41
    abstract public function morphTo($name = null, $type = null, $id = null, $ownerKey = null);
42
43
    /**
44
     * Boot the Auditable trait for the model.
45
     *
46
     * @return void
47
     */
48
    public static function bootAuditable()
49
    {
50
        static::creating(function (Model $model) {
51
            $model->created_by_id || $model->created_by_id = optional(auth()->guard(request()->route('guard'))->user())->getKey();
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Contracts\Auth\Factory, but not in Illuminate\Contracts\Auth\Guard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
52
            $model->created_by_type || $model->created_by_type = optional(auth()->guard(request()->route('guard'))->user())->getMorphClass();
53
54
            $model->updated_by_id || $model->updated_by_id = optional(auth()->guard(request()->route('guard'))->user())->getKey();
55
            $model->updated_by_type || $model->updated_by_type = optional(auth()->guard(request()->route('guard'))->user())->getMorphClass();
56
        });
57
58
        static::updating(function (Model $model) {
59
            $model->isDirty('updated_by_id') || $model->updated_by_id = optional(auth()->guard(request()->route('guard'))->user())->getKey();
0 ignored issues
show
Bug introduced by
The method guard does only exist in Illuminate\Contracts\Auth\Factory, but not in Illuminate\Contracts\Auth\Guard.

It seems like the method you are trying to call exists only in some of the possible types.

Let’s take a look at an example:

class A
{
    public function foo() { }
}

class B extends A
{
    public function bar() { }
}

/**
 * @param A|B $x
 */
function someFunction($x)
{
    $x->foo(); // This call is fine as the method exists in A and B.
    $x->bar(); // This method only exists in B and might cause an error.
}

Available Fixes

  1. Add an additional type-check:

    /**
     * @param A|B $x
     */
    function someFunction($x)
    {
        $x->foo();
    
        if ($x instanceof B) {
            $x->bar();
        }
    }
    
  2. Only allow a single type to be passed if the variable comes from a parameter:

    function someFunction(B $x) { /** ... */ }
    
Loading history...
60
            $model->isDirty('updated_by_type') || $model->updated_by_type = optional(auth()->guard(request()->route('guard'))->user())->getMorphClass();
61
        });
62
    }
63
64
    /**
65
     * Get the owning creator.
66
     *
67
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
68
     */
69
    public function creator(): MorphTo
70
    {
71
        return $this->morphTo('creator', 'creator_type', 'creator_id');
72
    }
73
74
    /**
75
     * Get the owning updater.
76
     *
77
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
78
     */
79
    public function updater(): MorphTo
80
    {
81
        return $this->morphTo('updater', 'updater_type', 'updater_id');
82
    }
83
84
    /**
85
     * Get audits of the given creator.
86
     *
87
     * @param \Illuminate\Database\Eloquent\Builder $builder
88
     * @param \Illuminate\Database\Eloquent\Model   $user
89
     *
90
     * @return \Illuminate\Database\Eloquent\Builder
91
     */
92
    public function scopeOfCreator(Builder $builder, Model $user): Builder
93
    {
94
        return $builder->where('created_by_type', $user->getMorphClass())->where('created_by_id', $user->getKey());
95
    }
96
97
    /**
98
     * Get audits of the given updater.
99
     *
100
     * @param \Illuminate\Database\Eloquent\Builder $builder
101
     * @param \Illuminate\Database\Eloquent\Model   $user
102
     *
103
     * @return \Illuminate\Database\Eloquent\Builder
104
     */
105
    public function scopeOfUpdater(Builder $builder, Model $user): Builder
106
    {
107
        return $builder->where('updated_by_type', $user->getMorphClass())->where('updated_by_id', $user->getKey());
108
    }
109
}
110