Revision   A
last analyzed

Complexity

Total Complexity 16

Size/Duplication

Total Lines 145
Duplicated Lines 3.45 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 2
Bugs 0 Features 0
Metric Value
wmc 16
c 2
b 0
f 0
lcom 1
cbo 1
dl 5
loc 145
rs 10

10 Methods

Rating   Name   Duplication   Size   Complexity  
A getUpdated() 0 4 1
A isUpdated() 0 4 1
A getOldAttribute() 0 4 1
A getNewAttribute() 0 4 1
A getFromArray() 0 4 1
A boot() 0 9 1
A getDiff() 0 12 2
A getTable() 0 6 3
A setCustomTable() 0 6 2
A __call() 5 14 3

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php namespace Sofa\Revisionable\Laravel;
2
3
use Illuminate\Database\Eloquent\Model;
4
use Illuminate\Database\Eloquent\Collection;
5
6
class Revision extends Model
7
{
8
    /**
9
     * The database table used by the model.
10
     *
11
     * @var string
12
     */
13
    protected static $customTable;
14
15
    /**
16
     * Allow mass assignement.
17
     *
18
     * @var array
19
     */
20
    protected $fillable = ['*'];
21
22
    /**
23
     * {@inheritdoc}
24
     */
25
    public static function boot()
26
    {
27
        parent::boot();
28
29
        // Make it read-only
30
        static::saving(function () {
31
            return false;
32
        });
33
    }
34
35
    /**
36
     * Get array of updated fields.
37
     *
38
     * @return array
39
     */
40
    public function getUpdated()
41
    {
42
        return array_keys(array_diff_assoc($this->new, $this->old));
0 ignored issues
show
Documentation introduced by
The property new does not exist on object<Sofa\Revisionable\Laravel\Revision>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property old does not exist on object<Sofa\Revisionable\Laravel\Revision>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
43
    }
44
45
    /**
46
     * Get diff of the old/new arrays.
47
     *
48
     * @return array
49
     */
50
    public function getDiff()
51
    {
52
        $diff = [];
53
54
        foreach ($this->getUpdated() as $key) {
55
            $diff[$key]['old'] = $this->old($key);
0 ignored issues
show
Documentation Bug introduced by
The method old does not exist on object<Sofa\Revisionable\Laravel\Revision>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
56
57
            $diff[$key]['new'] = $this->new($key);
0 ignored issues
show
Documentation Bug introduced by
The method new does not exist on object<Sofa\Revisionable\Laravel\Revision>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
58
        }
59
60
        return $diff;
61
    }
62
63
    /**
64
     * Determine whether field was updated during current action.
65
     *
66
     * @param  string $key
67
     * @return boolean
68
     */
69
    public function isUpdated($key)
70
    {
71
        return in_array($key, $this->getUpdated());
72
    }
73
74
    /**
75
     * Accessor for old property
76
     *
77
     * @return array
78
     */
79
    public function getOldAttribute($old)
80
    {
81
        return (array) json_decode($old);
82
    }
83
84
    /**
85
     * Accessor for new property
86
     *
87
     * @return array
88
     */
89
    public function getNewAttribute($new)
90
    {
91
        return (array) json_decode($new);
92
    }
93
94
    /**
95
     * Get single value from the new/old array.
96
     *
97
     * @param  string $version
98
     * @param  string $key
99
     * @return string
100
     */
101
    protected function getFromArray($version, $key)
102
    {
103
        return array_get($this->{$version}, $key);
104
    }
105
106
    /**
107
     * {@inheritdoc}
108
     */
109
    public function getTable()
110
    {
111
        $table = $this->table ?: static::$customTable;
112
113
        return ($table) ?: parent::getTable();
114
    }
115
116
    /**
117
     * Set custom table name for the model.
118
     *
119
     * @param  string  $table
120
     * @return void
121
     */
122
    public static function setCustomTable($table)
123
    {
124
        if (!isset(static::$customTable)) {
125
            static::$customTable = $table;
126
        }
127
    }
128
129
    /**
130
     * Handle dynamic method calls.
131
     *
132
     * @param  string $method
133
     * @param  array $parameters
134
     * @return mixed
135
     */
136
    public function __call($method, $parameters)
137
    {
138 View Code Duplication
        if (in_array($method, ['new', 'old'])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
            array_unshift($parameters, $method);
140
141
            return call_user_func_array([$this, 'getFromArray'], $parameters);
142
        }
143
144
        if ($method == 'label') {
145
            return reset($parameters);
146
        }
147
148
        return parent::__call($method, $parameters);
149
    }
150
}
151