Completed
Branch master (49dc1a)
by Yaro
01:42
created

Version::revert()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Yaro\Jarboe\Models;
4
5
use Illuminate\Database\Eloquent\Model;
6
use Illuminate\Support\Carbon;
7
8
/**
9
 * @property int $version_id
10
 * @property string $versionable_id
11
 * @property string $versionable_type
12
 * @property int|null $user_id
13
 * @property string|null $auth_guard
14
 * @property string $model_data
15
 * @property string|null $reason
16
 * @property Carbon|null $created_at
17
 * @property Carbon|null $updated_at
18
 * @property-read $responsible_user
19
 * @property Model $versionable
20
 */
21
class Version extends Model
22
{
23
    /**
24
     * @var string
25
     */
26
    public $table = 'versions';
27
28
    /**
29
     * @var string
30
     */
31
    protected $primaryKey = 'version_id';
32
33
    private $responsibleUser = false;
34
35
    /**
36
     * Sets up the relation
37
     * @return \Illuminate\Database\Eloquent\Relations\MorphTo
38
     */
39
    public function versionable()
40
    {
41
        return $this->morphTo();
42
    }
43
44
    /**
45
     * Return the user responsible for this version
46
     * @return mixed
47
     */
48
    public function getResponsibleUserAttribute()
49
    {
50
        if ($this->responsibleUser !== false) {
51
            return $this->responsibleUser;
52
        }
53
54
        $this->responsibleUser = null;
55
56
        $isAuthGuardExists = !is_null(config('auth.guards.'. $this->auth_guard));
57
        $hasUserTrace = !is_null($this->user_id);
58
        if ($hasUserTrace && $isAuthGuardExists) {
59
            $this->responsibleUser = auth()->guard($this->auth_guard)->getProvider()->retrieveById($this->user_id);
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
        }
61
62
        return $this->responsibleUser;
63
    }
64
65
    /**
66
     * Return the versioned model
67
     * @return Model
68
     */
69
    public function getModel()
70
    {
71
        $modelData = $this->model_data;
72
        if (is_resource($this->model_data)) {
73
            $modelData = stream_get_contents($this->model_data, -1, 0);
74
        }
75
76
        $model = new $this->versionable_type();
77
        $model->unguard();
78
        $model->fill(unserialize($modelData));
79
        $model->exists = true;
80
        $model->reguard();
81
        return $model;
82
    }
83
84
85
    /**
86
     * Revert to the stored model version make it the current version
87
     *
88
     * @return Model
89
     */
90
    public function revert()
91
    {
92
        $model = $this->getModel();
93
        unset($model->{$model->getCreatedAtColumn()});
94
        unset($model->{$model->getUpdatedAtColumn()});
95
        if (method_exists($model, 'getDeletedAtColumn')) {
96
            unset($model->{$model->getDeletedAtColumn()});
97
        }
98
        $model->save();
99
100
        return $model;
101
    }
102
103
    /**
104
     * Diff the attributes of this version model against another version.
105
     * If no version is provided, it will be diffed against the current version.
106
     *
107
     * @param Version|null $againstVersion
108
     * @return array
109
     */
110
    public function diff(Version $againstVersion = null)
111
    {
112
        $model = $this->getModel();
113
        $diff = $againstVersion ? $againstVersion->getModel() : $this->versionable()->withTrashed()->first()->currentVersion()->getModel();
114
115
        $diffArray = array_diff_assoc($diff->getAttributes(), $model->getAttributes());
116
117
        if (isset($diffArray[$model->getCreatedAtColumn()])) {
118
            unset($diffArray[$model->getCreatedAtColumn()]);
119
        }
120
        if (isset($diffArray[$model->getUpdatedAtColumn()])) {
121
            unset($diffArray[$model->getUpdatedAtColumn()]);
122
        }
123
        if (method_exists($model, 'getDeletedAtColumn') && isset($diffArray[$model->getDeletedAtColumn()])) {
124
            unset($diffArray[$model->getDeletedAtColumn()]);
125
        }
126
127
        return $diffArray;
128
    }
129
}
130