Completed
Push — php7.2-travis ( 2bd3b2 )
by
unknown
15:40 queued 09:23
created

store::is_supported()   B

Complexity

Conditions 6
Paths 7

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 6.3949

Importance

Changes 0
Metric Value
cc 6
eloc 15
nc 7
nop 1
dl 0
loc 24
ccs 14
cts 18
cp 0.7778
crap 6.3949
rs 8.5125
c 0
b 0
f 0
1
<?php
2
/******************************************************************************
3
  Generic Store 1.0						Ariadne
4
5
  Copyright (C) 1998-2005  Muze
6
7
  This program is free software; you can redistribute it and/or
8
  modify it under the terms of the GNU General Public License
9
  as published by the Free Software Foundation; either version 2
10
  of the License, or (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU General Public License for more details.
16
17
  You should have received a copy of the GNU General Public License
18
  along with this program; if not, write to the Free Software
19
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20
21
  --------------------------------------------------------------------------
22
23
  This Is a Generic implementation of the store, all generic functions are defined here
24
25
  the implemented functions are
26
27
	function get_config($field)
28
	function is_supported($feature)
29
	function newobject($path, $parent, $type, $data, $id=0, $lastchanged=0, $vtype="", $size=0, $priority=0)
30
	function close()
31
	function make_path($curr_dir, $path)
32
	function save_properties($properties, $id)
33
	function get_filestore($name)
34
35
*******************************************************************************/
36
37
38
abstract class store {
39
40
	public $error;
41
	public $root;
42
	public $rootoptions;
43
	public $mod_lock;
44
	public $total;
45
	protected $code;
46
	protected $files;
47
	protected $_filestores;
48
	protected $config;
49
50
51
52
	public function __construct($path, $config) {
0 ignored issues
show
Unused Code introduced by
The parameter $path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $config is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
53
		echo "You have not configured the store properly. Please check your configuration files.";
54
		exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method __construct() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
55
	}
56
57
	/*  abstract functions
58
		 need implementation in your implementation of this store
59
	*/
60
61
	public abstract function call($template, $args, $objects);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
62
63
	public abstract function count($objects);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
64
65
	public abstract function info($objects);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
66
67
	public abstract function get($path);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
68
	/**********************************************************************************
69
	 This function takes as argument a path to an object in the store and will retrieve
70
	 all the necessary data and return this in the objectlist type needed for
71
	 store->call(). If the requested path does not exist, it will retrieve the object
72
	 with the longest matching path.
73
74
	 $path should always start and end with a '/'.
75
	 **********************************************************************************/
76
77
	public abstract function touch($id, $timestamp = -1);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
78
	/**********************************************************************************
79
	 This function takes as argument a path to an object (or id of an object)
80
     in the store and will set the timestamp to $timestamp.
81
82
	 $path should always start and end with a '/'.
83
	 **********************************************************************************/
84
85
	public abstract function ls($path);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
86
	/**********************************************************************************
87
	 This function takes as argument a path to an object in the store and will retrieve
88
	 all the objects and their data which have this object as their parent. It will
89
	 then return this in the objectlist type needed for store->call(). If the requested
90
	 path does not exist, it will retrieve the object with the longest matching path.
91
92
	 $path should always start and end with a '/'.
93
	 **********************************************************************************/
94
95
	public abstract function parents($path, $top="/");
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
96
	/**********************************************************************************
97
	 This function takes as argument a path to an object in the store. It will return
98
	 all objects with a path which is a substring of the given path. The resulsts are
99
	 ordered by path (length), shortest paths first.
100
	 In effect all parents of an object in the tree are called, in order, starting at
101
	 the root.
102
103
	 $path should always start and end with a '/'.
104
	 **********************************************************************************/
105
106
	public abstract function find($path, $criteria, $limit=100, $offset=0);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
107
	/**********************************************************************************
108
	 This function takes as arguments a path to an object in the store and some search
109
	 criteria. It will search for all matching objects under the given path. If the
110
	 given path is not in this store but in a substore it will not automatically search
111
	 that substore.
112
113
	 $criteria is of the form
114
115
	 $criteria ::= ({ $property_name => ({ $valuename => ({ $compare_function, $value }) }) })
116
117
	 e.g.: $criteria["status"]["value"][">"]="published";
118
119
	 $path should always start and end with a '/'.
120
121
	 **********************************************************************************/
122
123
124
	public abstract function save($path, $type, $data, $properties="", $vtype="", $priority=false);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
125
	/***************************************************************
126
		This function takes as argument a path, type, objectdata and
127
		possibly a properties list and vtype (virtual type).
128
		If there exists no object with the given path, a new object is
129
		saved with the given type, data, properties and vtype, and a
130
		new path is saved pointing to it.
131
		If there does exist an object with the given path, it's object
132
		data is overwritten with the given data and if vtype is set the
133
		current vtype is overwritten with the new one.
134
135
		$path must be an absolute path (containing no '..' and starting
136
			with '/')
137
		$type must be a valid type
138
		$data can be any string (usually a serialized object.)
139
		$properties is a multidimensional hash of the following form:
140
			$properties[{property_name}][][{value_name}]={value}
141
			{property_name} must be a valid property name
142
			{value_name} must be a valid value name for this property
143
			{value} can be a number, boolean or string.
144
		example:
145
			$properties["name"][0]["value"]="A name";
146
			$properties["name"][1]["value"]="A second name!";
147
		if $properties["name"]=1 then all properties for property name
148
			will be removed.
149
150
		$vtype must be a valid type.
151
152
		if $properties or $vtype are not set or empty ("",0 or false)
153
		they will be ignored. $vtype defaults to $type.
154
		Only those properties listed in $properties will be updated.
155
		Any other property set will remain as it was.
156
	***************************************************************/
157
158
159
	protected abstract function purge($path);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
160
	/**********************************************************************
161
		This function will delete the object pointed to by $path and all
162
	other paths pointing to that object. It will then remove any property
163
	for this object from all property tables.
164
		The function returns the number of paths found and removed or 1 if
165
	there was no path found (meaning that the object doesn't exist and
166
	therefor purge succeeded while doing nothing.)
167
168
	 $path should always start and end with a '/'.
169
	**********************************************************************/
170
171
	public abstract function delete($path);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
172
	/**********************************************************************
173
		This function deletes the path given. If this is the last path pointing
174
	to an object, the object will be purged instead.
175
176
	$path should always start and end with a '/'.
177
	**********************************************************************/
178
179
	abstract function exists($path);
180
	/**********************************************************************
181
		This function checks the given path to see if it exists. If it does
182
	it returns the id of the object to which it points. Otherwise it returns
183
	0.
184
185
	$path should always start and end with a '/'.
186
	**********************************************************************/
187
188
189
	public abstract function link($source, $destination);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
190
	/**********************************************************************
191
		Link adds an extra path to an already existing object. It has two
192
	arguments: $source and $destination. $source is an existing path of
193
	an object, $destination is the new path. $destination must not already
194
	exist.
195
196
	$destination should always start and end with a '/'.
197
	**********************************************************************/
198
199
	public abstract function move($source, $destination);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
200
	/**********************************************************************
201
	$destination should always start and end with a '/'.
202
	**********************************************************************/
203
204
205
	public abstract function list_paths($path);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
206
	/**********************************************************************
207
		This function returns an array of all paths pointing to the same object
208
	as $path does.
209
	**********************************************************************/
210
211
	public abstract function AR_implements($type, $implements);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
212
	/**********************************************************************
213
		This function returns 1 if the $type implements the type or
214
	interface in $implements. Otherwise it returns 0.
215
	**********************************************************************/
216
217
	public abstract function load_properties($object, $values="");
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
218
219
	public abstract function load_property($object, $property, $values="");
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
220
221
	public abstract function add_property($object, $property, $values);
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
222
223
	public abstract function del_property($object, $property="", $values="");
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
224
225
	protected abstract function get_nextid($path, $mask="{5:id}");
0 ignored issues
show
Coding Style introduced by
The abstract declaration must precede the visibility declaration
Loading history...
226
	/**********************************************************************
227
		'private' function of mysql store. This will return the next
228
		'autoid' for $path.
229
	**********************************************************************/
230
231
232
233
	/*
234
		Implemented functions
235
	*/
236
237 35
	public function get_config($field) {
238
		switch ($field) {
239 35
			case 'code':
240 35
			case 'files':
241 35
			case 'root':
242 35
			case 'rootoptions':
243 35
				$result = $this->$field;
244 35
				break;
245
			default:
246
				$result =  null;
247
				debug("store::get_config: undefined field $field requested","store");
248
				break;
249
		}
250 35
		return $result;
251
	}
252
253 30
	public function is_supported($feature) {
254
	/**********************************************************************************
255
		This function takes as argument a feature description and returns
256
		true if this feature is supported and false otherwise
257
	**********************************************************************************/
258 30
		$result = false;
259
		switch($feature) {
260
			// features depending on config values
261 30
			case 'fulltext_boolean':
262 30
			case 'fulltext':
263 24
				if ($this->config[$feature]) {
264 12
					$result = true;
265 12
				} else {
266 12
					$result = false;
267
				}
268 24
			break;
269
			// features depending store implementation, if stores don't implements this, they have to override this function
270 30
			case 'grants':
271 30
			case 'regexp':
272 30
				$result = true;
273 30
			break;
274
		}
275 30
		return $result;
276
	}
277
278
	/**********************************************************************************
279
		This functions creates a new ariadne object
280
	**********************************************************************************/
281 70
	public function newobject($path, $parent, $type, $data, $id=0, $lastchanged=0, $vtype="", $size=0, $priority=0) {
282 70
		global $ARnls;
283 70
		$class = $type;
284 70
		if ($subcpos = strpos($type, '.')) {
285 12
			$class = substr($type, 0, $subcpos);
286 12
			$vtype = $class;
287 12
		}
288 70
		if (!class_exists($class, false)) {
289
			include_once($this->code."objects/".$class.".phtml");
290
		}
291 70
		$object=new $class;
292 70
		$object->type=$type;
293 70
		$object->parent=$parent;
294 70
		$object->id=(int)$id;
295 70
		$object->lastchanged=(int)$lastchanged;
296 70
		$object->vtype=$vtype;
297 70
		$object->size=(int)$size;
298 70
		$object->priority=(int)$priority;
299 70
		$object->ARnls = $ARnls;
300 70
		$object->init($this, $path, $data);
301 70
		return $object;
302
	}
303
304 52
	public function close() {
305
		// This is the destructor function, nothing much to see :)
306 52
		if (is_array($this->_filestores)) {
307
			foreach ($this->_filestores as $filestore) {
308
				$filestore->close();
309
			}
310
		}
311 52
	}
312
313 52
	public function __destruct() {
314 52
		$this->close();
315 52
	}
316
317 56
	public function make_path($curr_dir, $path) {
318 56
		return \arc\path::collapse($path, $curr_dir);
319
	}
320
321 34
	public function save_properties($properties, $id) {
322
	/********************************************************************
323
		'private' function of mysql.phtml. It updates all property tables
324
		defined in $properties and sets the values to the values in
325
		$properties.
326
	********************************************************************/
327
328 34
		if ($properties && (is_array($properties)) && (is_numeric($id))) {
329 24
			foreach ( $properties as $property => $property_set ) {
330 24
				$this->del_property((int)$id, $property);
331 24
				if (is_array($property_set)) {
332 24
					$property_set = array_unique($property_set,SORT_REGULAR);
333 24
					foreach ( $property_set as $values ) {
334 24
						$this->add_property((int)$id, $property, $values);
335 24
					}
336 24
				}
337 24
			}
338 24
		}
339 34
	}
340
341
342 51
	public function get_filestore($name) {
343 51
		global $AR;
344 51
		if (!$this->_filestores[$name]) {
345 51
			if ($AR->SVN->enabled && ($name == "templates")) {
346
				require_once($this->code."modules/mod_filestore_svn.phtml");
347
				$this->_filestores[$name]=new filestore_svn($name, $this->files, $this);
348
			} else {
349 51
				require_once($this->code."modules/mod_filestore.phtml");
350 51
				$this->_filestores[$name]=new filestore($name, $this->files, $this);
351
			}
352 51
		}
353 51
		return $this->_filestores[$name];
354
	}
355
356 14
	public function get_filestore_svn($name) {
357 14
		require_once($this->code."modules/mod_filestore_svn.phtml");
358 14
		if (!$this->_filestores["svn_" . $name]) {
359 14
			$this->_filestores["svn_" . $name] = new filestore_svn($name, $this->files, $this);
360 14
		}
361 14
		return $this->_filestores["svn_" . $name];
362
	}
363
364 13
	protected function compilerFactory(){
365 13
		switch($this->config["dbms"]){
366 13
			case 'axstore':
367
				return false;
368 13
			default:
369 13
				$compiler = $this->config["dbms"].'_compiler';
370 13
				return new $compiler($this,$this->tbl_prefix);
0 ignored issues
show
Bug introduced by
The property tbl_prefix 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...
371 13
		}
372
	}
373
374 34
	protected function serialize($value, $path) {
375 34
		if ($value->failedDecrypt && $value->originalData) {
376
			$value = $value->originalData;
377
			return $value;
378
		}
379
380
		// Notice: When upgrading to a new crypto format, prepend the object data with a key of the crypto. This way you can be backwards compatible but new objects will be saved in the new crypto.
381 34
		if ($this->config['crypto'] instanceof \Closure) {
382
			$crypto = $this->config['crypto']();
383
			// use the last crypto configured;
384
			$cryptoConfig = end($crypto);
385
			if (is_array($cryptoConfig['paths'])) {
386
				foreach ($cryptoConfig['paths'] as $cryptoPath) {
387
					if (strpos($path, $cryptoPath) === 0) {
388
						$value->ARcrypted = true;
389
						switch ($cryptoConfig['method']) {
390
							case 'ar_crypt':
391
								$key = base64_decode($cryptoConfig['key']);
392
								$crypto = new ar_crypt($key,$cryptoConfig['crypto'],1);
393
								$cryptedValue = $crypto->crypt(serialize($value));
394
								if($cryptedValue !== false ) {
395
									return $cryptoConfig['token'] . ":" . $cryptedValue;
396
								}
397
							break;
398
							default:
399
							break;
400
						}
401
402
					}
403
				}
404
			}
405
		}
406 34
		unset($value->ARcrypted);
407 34
		return serialize($value);
408
	}
409
410 70
	protected function unserialize($value, $path) {
0 ignored issues
show
Unused Code introduced by
The parameter $path is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
411 70
		if ($value[0] === "O" && $value[1] === ":") {
412 70
			return unserialize($value);
413
		} else if ($this->config['crypto'] instanceof \Closure) {
414
			$crypto = $this->config['crypto']();
415
			list($token,$datavalue) = explode(':', $value, 2);
416
			foreach ($crypto as $cryptoConfig) {
417
				$cryptoToken = $cryptoConfig['token'];
418
				if ($token === $cryptoToken ) {
419
					$value = $datavalue;
420
					switch ($cryptoConfig['method']) {
421
						case 'ar_crypt':
422
							$key = base64_decode($cryptoConfig['key']);
423
							$crypto = new ar_crypt($key,$cryptoConfig['crypto'],1);
424
							$decryptedValue =  $crypto->decrypt($value);
425
						break;
426
						default:
427
						break;
428
					}
429
				}
430
			}
431
432
			if ($decryptedValue[0] === "O" && $decryptedValue[1] === ":") {
433
				return unserialize($decryptedValue);
0 ignored issues
show
Bug introduced by
The variable $decryptedValue does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
434
			} else {
435
				$dummy = unserialize('O:6:"object":7:{s:5:"value";s:0:"";s:3:"nls";O:6:"object":2:{s:7:"default";s:2:"nl";s:4:"list";a:1:{s:2:"nl";s:10:"Nederlands";}}s:2:"nl";O:6:"object":1:{s:4:"name";s:14:"Crypted object";}s:6:"config";O:6:"object":2:{s:10:"owner_name";s:6:"Nobody";s:5:"owner";s:6:"nobody";}s:5:"mtime";i:0;s:5:"ctime";i:0;s:5:"muser";s:6:"nobody";}');
436
				$dummy->failedDecrypt = true;
437
				$dummy->originalData = $value;
438
				return $dummy;
439
			}
440
		}
441
	}
442
443
} 
444