Completed
Pull Request — master (#2017)
by Basil
02:19
created

RegistryTrait::getValueAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace luya\traits;
4
5
/**
6
 * Registry Trait.
7
 *
8
 * The RegistryTrait helps to handle set(), get(), has() and remove() operations for a key value based storage.
9
 * 
10
 * Can be attached to ActiveRecords with a `name` and `value` property where name is an unique identifier.
11
 *
12
 * @author Basil Suter <[email protected]>
13
 * @since 1.0.0
14
 */
15
trait RegistryTrait
16
{
17
    /**
18
     * Determines what attribute field in the corresponding model table should be used to find the identifier key.
19
     *
20
     * @return string The name attribute field defaults to `name`.
21
     */
22
    public static function getNameAttribute()
23
    {
24
        return 'name';
25
    }
26
    
27
    /**
28
     * Determines what attribute field in the corresponding model table should be used to store the identifier key and retrieve its data.
29
     *
30
     * @return string The value attribute field defaults to `value`.
31
     */
32
    public static function getValueAttribute()
33
    {
34
        return 'value';
35
    }
36
37
    private static $_data;
38
39
    /**
40
     * Loads all config data into an array.
41
     *
42
     * @return array
43
     * @since 1.3.0
44
     */
45
    protected static function getData()
46
    {
47
        if (self::$_data === null) {
48
            self::$_data = self::find()
49
                ->select([self::getValueAttribute(), self::getNameAttribute()])
50
                ->indexBy(self::getNameAttribute())
51
                ->column();
52
        }
53
54
        return self::$_data;
55
    }
56
57
    /**
58
     * Clear data array.
59
     * 
60
     * @since 1.3.0
61
     */
62
    protected static function clearData()
63
    {
64
        self::$_data = null;
65
    }
66
    
67
    /**
68
     * Check whether a config value exists or not.
69
     * 
70
     * If a value exists but is empty, has will return false.
71
     *
72
     * @param string $name The key to lookup. If not found false is returned.
73
     * @return boolean Whether the key exists or not.
74
     */
75
    public static function has($name)
76
    {
77
        return array_key_exists($name, self::getData());
78
    }
79
    
80
    /**
81
     * Get the value of a config value.
82
     * 
83
     * Returns the value from the registry for the given $name, if not found the defaultValue is returned.  
84
     *
85
     * @param string $name The key to lookup. 
86
     * @param mixed $defaultValue The default value to return if the key does not exist.
87
     * @return mixed
88
     */
89
    public static function get($name, $defaultValue = null)
90
    {
91
        if (self::has($name)) {
92
            return self::getData()[$name];
93
        }
94
    
95
        return $defaultValue;
96
    }
97
    
98
    /**
99
     * Store or Update an existing/new config value.
100
     * 
101
     * If the config value is not found, a new record will be created.
102
     *
103
     * @param string $name They config key
104
     * @param string $value They config value. When working with array data, encode the data first with Json::encode.
105
     * @return boolean Whether saving was successfull or not.
106
     */
107
    public static function set($name, $value)
108
    {
109
        $model = self::find()->where([self::getNameAttribute() => $name])->one();
110
        self::clearData();
111
        if ($model) {
112
            return (bool) $model->updateAttributes([
113
                self::getValueAttribute() => $value,
114
            ]);
115
        }
116
    
117
        $model = new self();
118
        $model->value = $value;
0 ignored issues
show
Bug introduced by
The property value does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
119
        $model->name = $name;
0 ignored issues
show
Bug introduced by
The property name does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
120
        return $model->save();
0 ignored issues
show
Bug introduced by
It seems like save() must be provided by classes using this trait. How about adding it as abstract method to this trait?

This check looks for methods that are used by a trait but not required by it.

To illustrate, let’s look at the following code example

trait Idable {
    public function equalIds(Idable $other) {
        return $this->getId() === $other->getId();
    }
}

The trait Idable provides a method equalsId that in turn relies on the method getId(). If this method does not exist on a class mixing in this trait, the method will fail.

Adding the getId() as an abstract method to the trait will make sure it is available.

Loading history...
121
    }
122
123
    /**
124
     * Remove an existing config value.
125
     * 
126
     * If the value is not found in the config, false is returned.
127
     *
128
     * @param string $name The key to remove.
129
     * @return bool If element was found and deleting was successfull true is returned, otherwise false.
130
     */
131
    public static function remove($name)
132
    {
133
        $model = self::find()->where([self::getNameAttribute() => $name])->one();
134
    
135
        if ($model) {
136
            self::clearData();
137
            return (bool) $model->delete();
138
        }
139
    
140
        return false;
141
    }
142
}
143