Passed
Push — master ( a37889...b0889b )
by Georgi
03:24
created

CommonData::clearCache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
c 0
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
namespace Epesi\Base\CommonData\Database\Models;
4
5
use Kalnoy\Nestedset\NodeTrait;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Database\Eloquent\Collection;
8
9
class CommonDataNotFound extends \Exception {}
10
11
class CommonData extends Model {
12
    use NodeTrait;
0 ignored issues
show
Bug introduced by
The trait Kalnoy\Nestedset\NodeTrait requires the property $forceDeleting which is not provided by Epesi\Base\CommonData\Database\Models\CommonData.
Loading history...
13
    
14
    protected $table = 'commondata';
15
    public $timestamps = false;
16
    protected static $unguarded = true;
17
    
18
    protected static $cache = [
19
    		'id' => [],
20
    		'value' => [],
21
    		'array' => []
22
    ];
23
    
24
    public static function getId($path, $clearCache = false)
25
    {
26
    	$parentId = null;
27
    	foreach(explode('/', trim($path,'/')) as $nodeKey) {
28
    		if ($nodeKey === '') continue; //ignore empty paths
29
    		
30
    		if ($clearCache || empty(self::$cache['id'][$parentId][$nodeKey])) {
31
    			if (! $node = self::where('parent_id', $parentId)->where('key', $nodeKey)->first()) {
32
    				return false;
33
    			}
34
35
    			self::$cache['id'][$parentId][$nodeKey] = $node->id;
36
    		}
37
    		
38
    		$parentId = $id = self::$cache['id'][$parentId][$nodeKey];
39
    	}
40
    	
41
    	return $id;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $id does not seem to be defined for all execution paths leading up to this point.
Loading history...
42
    }
43
   
44
    public static function newId($path, $readonly = false)
45
    {
46
    	if (! $path = trim($path,'/')) return false;
47
48
    	$id = $parentId = null;
49
    	foreach(explode('/', $path) as $nodeKey) {
50
    		if ($nodeKey === '') continue;
51
52
    		if (! $node = self::where('parent_id', $parentId)->where('key', $nodeKey)->first()) {
53
    			$node = self::create([
54
    					'parent_id' => $parentId,
55
    					'key' => $nodeKey,
56
    					'readonly' => $readonly,
57
    					'position' => self::where('parent_id', $parentId)->count()
58
    			], $parentId? self::find($parentId): null);
59
    		}
60
    		
61
    		$parentId = $id = $node->id;
62
    	}
63
    	
64
    	return $id;
65
    }
66
    
67
    public static function setValue($path, $value, $overwrite = true, $readonly = false)
68
    {
69
    	if (! $id = self::getId($path)) {
70
    		if (! $id = self::newId($path, $readonly)) return false;
71
    	} else {
72
    		if (! $overwrite) return false;
73
    	}
74
75
    	self::findOrFail($id)->update(compact('value', 'readonly'));
76
    	
77
    	self::clearCache();
78
    	
79
    	return true;
80
    }
81
    
82
    public static function clearCache()
83
    {
84
    	self::$cache = array_fill_keys(array_keys(self::$cache), []);
85
    }
86
    
87
    public static function getValue($path, $translate = false)
88
    {
89
    	$key = md5(serialize($path));
90
    	
91
    	if (! isset(self::$cache['value'][$key])) {
92
    		if(! $id = self::getId($path)) return false;
93
94
    		self::$cache['value'][$key] = self::find($id)->value;
95
	    }
96
	    
97
	    return $translate? __(self::$cache['value'][$key]): self::$cache['value'][$key];
98
    }
99
        
100
    /**
101
     * Creates new array for common use.
102
     *
103
     * @param $path string
104
     * @param $array array initialization value
105
     * @param $overwrite bool whether method should overwrite if array already exists, otherwise the data will be appended
106
     * @param $readonly bool do not allow user to change this array from GUI
107
     */
108
    public static function newArray($path, $array, $overwrite = false, $readonly = false)
109
    {
110
    	self::validateArrayKeys($array);
111
    		
112
    	$path = trim($path, '/');
113
    	
114
		if ($id = self::getId($path)) {
115
    		if (! $overwrite) {
116
    			self::extendArray($path, $array);
117
    			return true;
118
    		}
119
    				
120
    		self::find($id)->delete();
121
    	}
122
    			
123
    	if(! $id = self::newId($path, $readonly)) return false;
124
    			
125
    	if ($overwrite) {
126
    		self::find($id)->update(compact('readonly'));
127
    	}
128
    			
129
    	foreach ($array as $key => $value) {
130
    		self::setValue($path . '/' . $key, $value, true, $readonly);
131
    	}
132
    			
133
    	return true;
134
    }
135
136
    /**
137
     * Extends common data array.
138
     *
139
     * @param $path string
140
     * @param $array array values to insert
141
     * @param $overwrite bool whether method should overwrite data if array key already exists, otherwise the data will be preserved
142
     */
143
    public static function extendArray($path, $array, $overwrite=false, $readonly=false)
144
    {
145
    	self::validateArrayKeys($array);
146
    	
147
    	$path = trim($path, '/');
148
    			
149
    	if (! self::getId($path)){
150
    		return self::newArray($path, $array, $overwrite, $readonly);
151
    	}
152
153
    	foreach ($array as $key => $value) {
154
    		self::setValue($path . '/' . $key, $value, $overwrite, $readonly);
155
    	}
156
    }
157
        
158
    /**
159
     * Returns common data array.
160
     *
161
     * @param string array name
162
     * @return mixed returns an array if such array exists, false otherwise
163
     */
164
    public static function getArray($path, $sortColumn = 'position', $silent = false)
165
    {
166
    	return self::getCollection($path, $silent)->sortBy($sortColumn)->pluck('value', 'key')->all();
167
    }
168
169
    /**
170
     * Removes common data array or entry.
171
     *
172
     * @param $path string
173
     * @return true on success, false otherwise
174
     */
175
    public static function deleteArray($path){
176
    	if (! $id = self::getId($path, true)) return false;
0 ignored issues
show
Bug Best Practice introduced by
The expression return false returns the type false which is incompatible with the documented return type true.
Loading history...
177
    	
178
    	self::find($id)->delete();
179
    	
180
    	self::clearCache();
181
    }
182
183
    /**
184
     * Returns common data collection.
185
     *
186
     * @param $path string
187
     * @return Collection
188
     */
189
    public static function getCollection($path, $silent = false)
190
    {
191
    	if(isset(self::$cache['array'][$path])) {
192
    		return self::$cache['array'][$path];
193
    	}
194
    	
195
    	if (! $id = self::getId($path)) {
196
    		if ($silent) return collect();
197
    		
198
    		throw new CommonDataNotFound('Invalid CommonData::getArray() request: ' . $path);
199
    	}
200
    	
201
    	return self::$cache['array'][$path] = self::where('parent_id', $id)->get();
202
    }
203
    
204
    protected static function validateArrayKeys($array)
205
    {
206
    	foreach($array as $key => $value) {
207
    		if (strpos($key, '/') === false) continue;
208
    		
209
    		\Exception('Invalid common data key: '. $key);
0 ignored issues
show
Bug introduced by
The function Exception was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

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

209
    		/** @scrutinizer ignore-call */ 
210
      \Exception('Invalid common data key: '. $key);
Loading history...
210
    	}
211
    }
212
}