Completed
Push — mod_pdftk ( b4a93c...8f6776 )
by
unknown
408:33 queued 399:42
created

ariadne_object::save()   F

Complexity

Conditions 28
Paths > 20000

Size

Total Lines 194
Code Lines 123

Duplication

Lines 4
Ratio 2.06 %

Code Coverage

Tests 111
CRAP Score 39.5154

Importance

Changes 0
Metric Value
cc 28
eloc 123
nc 36904
nop 2
dl 4
loc 194
ccs 111
cts 147
cp 0.7551
crap 39.5154
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
0 ignored issues
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 38 and the first side effect is on line 36.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
    /******************************************************************
3
     pobject.phtml                                         Muze Ariadne
4
     ------------------------------------------------------------------
5
     Author: Muze ([email protected])
6
     Date: 31 october 2002
7
8
     Copyright 2002 Muze
9
10
     This file is part of Ariadne.
11
12
     Ariadne is free software; you can redistribute it and/or modify
13
     it under the terms of the GNU General Public License as published
14
     by the Free Software Foundation; either version 2 of the License,
15
     or (at your option) any later version.
16
17
     Ariadne is distributed in the hope that it will be useful,
18
     but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     GNU General Public License for more details.
21
22
     You should have received a copy of the GNU General Public License
23
     along with Ariadne; if not, write to the Free Software
24
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25
     02111-1307  USA
26
27
    -------------------------------------------------------------------
28
29
     Class inheritance: 	pobject
30
     Description:
31
32
       This is the class definition file of the pobject class.
33
34
    ******************************************************************/
35
36
debug("pobject: Load","object");
37
38
abstract class ariadne_object extends object { // ariadne_object class definition
39
40
	public $store;
41
	public $path;
42
	public $data;
43
44 70
	public function init($store, $path, $data) {
45 70
		$this->store=$store;
46 70
		$this->path=$path;
47 70
		$this->data=$data;
48 70
		if ( !isset($this->data->config) ) {
49 14
			$this->data->config = new object();
50 14
		}
51 70
	}
52
53 70
	public function call($arCallFunction="view.html", $arCallArgs=array()) {
54
	/***********************************************************************
55
	  call tries to find the template ($arCallFunction) for the current
56
	  object. If it is not defined there, call will search the superclasses
57
	  until either it or the template 'default.phtml' is found.
58
59
	  $arCallFunction must be the name of a class or object template.
60
	    it can be prepended with "{classname}::". classname must be either
61
	    a valid ariadne class (derived from pobject). call()
62
	    will then try to find the template starting at the given classname.
63
		e.g.:
64
		call("pobject::view.html") will show the view.html template of
65
	      pobject, with the data of the current object.
66
67
	  variables available to templates:
68
	  local: arCallFunction, arCallArgs, arCallTemplate, data
69
	  global: AR, ARConfig, ARCurrent, ARBeenHere, ARnls
70
	***********************************************************************/
71 70
	global $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls;
72
73 70
		if ( $arCallFunction instanceof \Closure ) {
74 2
			$arCallFunctionName = 'Closure';
75 6
		} else {
76 70
			$arCallFunctionName = (string) $arCallFunction;
77
		}
78 70
		debug("pobject: ".$this->path.": call($arCallFunctionName, ".debug_serialize($arCallArgs).")","object","all","IN");
79
80
		// default to view.html
81 70
		if (!$arCallFunction) {
82 10
			$arCallFunction="view.html";
83
		}
84
		// clear previous results
85 70
		unset($ARCurrent->arResult);
86
87
		// callstack is needed for getvar()
88 70
		$ARCurrent->arCallStack[]=&$arCallArgs;
89
		// keep track of the context (php or pinp) in which the called template runs. call always sets it php, CheckConfig sets it to pinp if necessary.
90 70
		$this->pushContext( array(
91 70
			"arSuperContext" => array(),
92 70
			"arCurrentObject" => $this,
93 70
			"scope" => "php",
94
			"arCallFunction" => $arCallFunction
95 70
		) );
96
97
		// convert the deprecated urlencoded arguments to an array
98 70
		if (isset($arCallArgs) && is_string($arCallArgs)) {
99 30
			$ARCurrent->arTemp=$arCallArgs;
100 30
			$arCallArgs=array();
101 30
			parse_str($ARCurrent->arTemp, $arCallArgs);
102 30
		}
103
		// import the arguments in the current scope, but don't overwrite existing
104
		// variables.
105 70
		if (isset($arCallArgs) && is_array($arCallArgs)) {
106 30
			extract($arCallArgs,EXTR_SKIP);
107 30
		}
108
		// now find the initial nls selection (CheckConfig is needed for per
109
		// tree selected defaults)
110 70
		if ($ARCurrent->nls) {
111
			$this->reqnls=$ARCurrent->nls;
0 ignored issues
show
Bug introduced by
The property reqnls 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...
112 70
		} else if (isset($ARConfig->cache[$this->path]) && $ARConfig->cache[$this->path]->nls->default) {
113 50
			$this->reqnls = $ARConfig->cache[$this->path]->nls->default;
114 50
		} else {
115 36
			$this->reqnls=$AR->nls->default;
116
		}
117 70
		if (isset($this->data->nls->list[$this->reqnls]) || !isset($this->data->nls)) {
118
			// the requested language is available
119 70
			$this->nls=$this->reqnls;
0 ignored issues
show
Bug introduced by
The property nls 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 70
			$nls=&$this->nls;
121 70
		} else {
122
			// the requested language is not available, use default of the
123
			// current object instead.
124
			$this->nls=$this->data->nls->default;
125 2
			$nls=&$this->nls;
126
		}
127 70
		if ($nls && isset($this->data->$nls)) {
128
			// now set the data and nlsdata pointers
129 66
			$this->nlsdata=$this->data->$nls;
0 ignored issues
show
Bug introduced by
The property nlsdata 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...
130 66
			$nlsdata=&$this->nlsdata;
131 66
			$data=&$this->data;
132 66
		} else {
133
			// this object doesn't support nls data
134 18
			$this->nlsdata=$this->data;
135 18
			$nlsdata=&$this->data;
136 18
			$data=&$this->data;
137 2
		}
138 70
		if (isset($this->data->custom['none'])) {
139 4
			$customdata=$this->data->custom['none'];
140 4
		}
141 70
		if (isset($this->data->custom[$nls])) {
142
			$customnlsdata=$this->data->custom[$nls];
143
		}
144
145 70
		$arCallFunctionOrig = $arCallFunction;
146 70
		if (strpos($arCallFunctionName,"::")!==false) {
147
			// template of a specific class defined via call("class::template");
148 12
			list($arType, $arCallFunction)=explode("::",$arCallFunctionName);
149 12
			$temp = explode(":", $arType );
150 12
			if( count($temp) > 1 ) {
151
				$libname = $temp[0];
152
				$arType = $temp[1];
153
				$arCallFunction = $libname.":".$arCallFunction;
154
			}
155 12
		} else {
156 70
			$arType=$this->type;
0 ignored issues
show
Bug introduced by
The property type 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...
157
		}
158
159 70
		if ( $arCallFunction instanceof \Closure ) {
160 2
			$context = $this->getContext(ARCALLINGCONTEXT);
161 2
			if ( $context["scope"] != "pinp" ) {
162
				$arResult = $arCallFunction($this );
163
			} else {
164 2
				if ( $this->CheckSilent('read') ) {
165 2
					$arResult = $arCallFunction($this);
166 2
				}
167
			}
168 2
		} else {
169 70
			if ($arCallFunction[0] === "#") {
170 10
				$ARCurrent->arCallClassTemplate = true;
171
				$arCallFunction = substr($arCallFunction, 1);
172
			} else {
173 70
				$ARCurrent->arCallClassTemplate = false;
174
			}
175
176 70
			if( $arCallFunction == "system.get.phtml" && ( $context = $this->getContext(ARCALLINGCONTEXT) ) && $context["scope"] != "pinp" ) {
177 18
				$arResult = $this;
178 16
			} else {
179 70
				$libtemplate = strpos($arCallFunction,":");
180 70
				$codedir = $this->store->get_config("code");
181
182
				// if it is a subtype object, disk templates do not exists,
183 70
				$subcpos = strpos($arType, '.');
184 70
				if ($subcpos !== false ) {
185
					// subtype, skip looking for templates
186 12
					$arSuper = substr($arType, 0, $subcpos);
187 12
					if(!isset($AR->superClass[$arType])){
188 2
						$AR->superClass[$arType]=$arSuper;
189 2
					}
190 12
					$arType=$arSuper;
191 12
				}
192
193 70
				while ($arType !== "ariadne_object") {
194
195
					// search for the template, stop at the root class ('ariadne_object')
196
					// (this should not happen, as pobject must have a 'default.phtml')
197 70
					$arCallTemplate=$codedir."templates/".$arType."/".$arCallFunction;
198 70
					if ($libtemplate === false && file_exists($arCallTemplate)) {
199
						//debug('found '.$arCallTemplate, 'all');
200
						// template found
201 66
						$arCallFunction = $arCallFunctionOrig;
202 66
						include($arCallTemplate);
203 66
						break;
204 68
					} else if (file_exists($codedir."templates/".$arType."/default.phtml")) {
205
						//debug('found default.phtml', 'all');
206
						// template not found, but we did find a 'default.phtml'
207 4
						include($this->store->get_config("code")."templates/".$arType."/default.phtml");
208 6
						break;
209 12
					} else {
210 68
						if (!($arSuper=$AR->superClass[$arType])) {
211
							// no template found, no default.phtml found, try superclass.
212
213 4
							if (!class_exists($arType, false)) {
214
								// the given class was not yet loaded, so do that now
215
								$this->store->newobject('','',$arType,new object);
216
							}
217 6
							$arSuper=get_parent_class($arType);
218
219 16
							$AR->superClass[$arType]=$arSuper;
220 4
						}
221 68
						$arType=$arSuper;
222 2
					}
223 68
				}
224
			}
225 2
		}
226 70
		array_pop($ARCurrent->arCallStack);
227 70
		$this->popContext();
228 70
		debug("pobject: call: end","all","all","OUT");
229 70
		if (isset($ARCurrent->arResult)) {
230
			// pinp templates can return results via putvar("arResult",$result);
231 10
			$arResult=$ARCurrent->arResult;
232 10
			unset($ARCurrent->arResult);
233 10
		}
234 70
		if (isset($arResult)) {
235
			// only do a return if we really have something to return
236 70
			return $arResult;
237
		}
238 12
	}
239
240 2
	public function ls($path="", $function="list.html", $args="") {
241 2
		$path=$this->store->make_path($this->path, $path);
242 2
		return $this->store->call($function, $args, $this->store->ls($path));
243 2
	}
244
245 28
	public function get($path, $function="view.html", $args="") {
246 28
		$path=$this->store->make_path($this->path, $path);
247 28
		return $this->store->call($function, $args, $this->store->get($path));
248 2
	}
249
250 4
	public function parents($path, $function="list.html", $args="", $top="") {
251
		/* FIXME: $this->store->parents is too slow when a lot of objects are in ariadne (2million+) */
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "$this->store->parents is too slow when a lot of objects are in ariadne (2million+) */"
Loading history...
252
		/* but this fix should be done in the store, not here */
253 2
		if (!$top) {
254 4
			$top = $this->currentsection();
255 2
		} else {
256 4
			$top = $this->store->make_path($this->path, $top);
257
		}
258
259 2
		$path=$this->store->make_path($this->path, $path);
260
261 2
		if ($path != $this->path ) {
262 2
			$target = current($this->get($path,"system.get.phtml"));
263 2
		} else {
264 2
			$target = $this;
265
		}
266
267 2
		$parents = array();
268 2
		if (strpos($target->path, $top) === 0) {
269 2
			$parents[] = $target;
270 2
			while ($target && $target->path != $top) {
271 2
				$target = current($target->get($target->parent, "system.get.phtml"));
272 2
				$parents[] = $target;
273 4
			}
274 2
		}
275 2
		$parents = array_reverse($parents);
276 2
		$result = array();
277 4
		foreach ($parents as $parent) {
278 2
			if ( $parent ) { // might not have read access to this object
279 2
				$result[] = $parent->call($function, $args);
280 2
			}
281 2
		}
282
283 2
		return $result;
284
	}
285
286 2
	public function find($path, $criteria, $function="list.html", $args="", $limit=100, $offset=0) {
287 2
		$path = $this->store->make_path($this->path, $path);
288 2
		$objects = $this->store->find($path, $criteria, $limit, $offset);
289 2
		if (!$this->store->error) {
290 2
			$result = $this->store->call($function, $args, $objects);
291 2 View Code Duplication
		} else {
292
			$this->error = ar::error( ''.$this->store->error, 1110, $this->store->error );
0 ignored issues
show
Bug introduced by
The property error 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...
293
			$result = false;
294 2
		}
295 2
		return $result;
296
	}
297
298
	public function count_find($path='', $query='') {
299
		$path=$this->store->make_path($this->path, $path);
300
		if (method_exists($this->store, 'count_find')) {
301
			$result = $this->store->count_find($path, $query, 0);
302
		} else {
303
			$result = $this->store->count($this->store->find($path, $query, 0));
304
		}
305
		return $result;
306
	}
307
308
	public function count_ls($path) {
309
		return $this->store->count($this->store->ls($path));
310
	}
311
312 2
	private function saveMergeWorkflowResult($properties, $wf_result) {
313
		foreach ($wf_result as $wf_prop_name => $wf_prop) {
314
			foreach ($wf_prop as $wf_prop_index => $wf_prop_record) {
315
				if (!isset($wf_prop_record)) {
316
					unset($properties[$wf_prop_name][$wf_prop_index]);
317
				} else {
318
					$record = array();
319 View Code Duplication
					foreach ($wf_prop_record as $wf_prop_field => $wf_prop_value) {
320
						switch (gettype($wf_prop_value)) {
321 2
							case "integer":
322
							case "boolean":
323
							case "double":
324
								$value = $wf_prop_value;
325
								break;
326
							default:
327
								$value = $wf_prop_value;
328
								// backwards compatibility, store will do the escaping from now on
329
								// will be removed in the future
330
								if (substr($wf_prop_value, 0, 1) === "'" && substr($wf_prop_value, -1) === "'"
331
										&& "'".AddSlashes(StripSlashes(substr($wf_prop_value, 1, -1)))."'" == $wf_prop_value) {
332
									$value = stripSlashes(substr($wf_prop_value,1,-1));
333
									// todo add deprecated warning
334
								}
335
336 2
						}
337
						$record[$wf_prop_field] = $value;
338
					}
339
					$properties[$wf_prop_name][] = $record;
340
				}
341
			}
342
		}
343
344
		return $properties;
345
	}
346
347
	/*
348
		saves custom data
349
		returns properties for custom data
350
	*/
351 25
	private function saveCustomData($configcache, $properties) {
352 25
		$custom = $this->getdata("custom", "none");
353 24
		@parse_str($custom);
354 24
		if (isset($custom) && is_array($custom)) {
355
			foreach($custom as $nls=>$entries){
356
				if (isset($entries) && is_array($entries)) {
357
					foreach ( $entries as $customkey => $customval ){
358
						$this->data->custom[$nls][$customkey] = $customval;
359
					}
360
				}
361
			}
362
		}
363
		// the above works because either $custom comes from the form entry, and parse_str returns an
364
		// array with the name $custom, or $custom comes from the object and is an array and as such
365
		// parse_str fails miserably thus keeping the array $custom intact.
366
367 24
		if (isset($this->data->custom) && is_array($this->data->custom)) {
368
			foreach($this->data->custom as $nls => $cdata) {
369
				foreach($cdata as $name => $value){
370
					// one index, this order (name, value, nls) ?
371
					if ($configcache->custom[$name]['containsHTML']) {
372
						$this->_load('mod_url.php');
373
						$value = URL::RAWtoAR($value, $nls);
374
						$this->data->custom[$nls][$name] = $value;
375
					}
376
					if ($configcache->custom[$name]['property']) {
377
						if (isset($value) && is_array($value)) {
378
							foreach($value as $valkey => $valvalue ) {
379
								$properties["custom"][] = [
380
									"name"  => $name,
381
									"value" => $valvalue,
382
									"nls"   => $nls,
383
								];
384
							}
385
						} else {
386
							$properties["custom"][] = [
387
								"name"  => $name,
388
								"value" => $value,
389
								"nls"   => $nls,
390
							];
391
392
						}
393
					}
394
				}
395
			}
396
		}
397 24
		return $properties;
398
	}
399
400 26
	public function save($properties="", $vtype="") {
401
	/***********************************************************************
402
	  save the current object.
403
	  if this is a new object ($this->arIsNewObject) the path is checked and
404
	  the object is saved under the new path.
405
	***********************************************************************/
406 24
	global $AR, $ARnls, $ARCurrent;
407 24
		debug("pobject: save([properties], $vtype)","object");
408 24
		debug("pobject: save: path=".$this->path,"object");
409 24
		$configcache=$this->loadConfig();
410 25
		$needsUnlock = false;
411 24
		$arIsNewObject = false;
412 24
		$result = false;
413 24
		$this->error = '';
414 24
		if ($this->arIsNewObject) { // save a new object
0 ignored issues
show
Bug introduced by
The property arIsNewObject 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...
415 12
			debug("pobject: save: new object","all");
416 12
			$this->path = $this->make_path();
417 12
			$arNewParent=$this->make_path("..");
418 12
			$arNewFilename=basename($this->path);
419 12
			$arIsNewObject = true;
420 12
			if (preg_match("|^[a-z0-9_\{\}\.\:-]+$|i",$arNewFilename)) { // no "/" allowed, these will void the 'add' grant check.
421 12
				if (!$this->exists($this->path)) { //arNewFilename)) {
422 12
					if ($this->exists($arNewParent)) {
423 12
						if (!$config = $this->data->config) {
424
							$config=new object();
425
						}
426 12
					} else {
427
						$this->error = ar::error( sprintf($ARnls["err:noparent"],$arNewParent), 1102);
428
					}
429 12
				} else {
430
					$this->error = ar::error( sprintf($ARnls["err:alreadyexists"],$arNewFilename), 1103);
431
				}
432 12
			} else {
433
				$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$arNewFilename), 1104);
434
			}
435 12
		} else { // existing object
436 24
			debug("pobject: save: existing object","all");
437 24
			if ($this->exists($this->path)) { // prevent 'funny stuff'
438 24
				if (!$this->lock()) {
439
					$this->error = ar::error( $ARnls["err:objectalreadylocked"], 1105);
440
				} else {
441 24
					$needsUnlock = true;
442 24
					$config = $this->data->config;
443
				}
444 24
			} else {
445
				$this->error = ar::error($ARnls["err:corruptpathnosave"], 1106);
446
			}
447
		}
448
		// pre checks done
449
		// return now on error
450 24
		if ($this->error) {
451
			return $result;;
452
		}
453
454
455 24
		if ($ARCurrent->arCallStack) {
456 24
			$arCallArgs = end($ARCurrent->arCallStack);
457 24
		} else {
458 10
			$arCallArgs = array();
459
		}
460
461 24
		$context = $this->getContext();
462
463 24
		$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
0 ignored issues
show
Bug introduced by
The property parent 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...
Bug introduced by
The property id 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...
Bug introduced by
The property lastchanged 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...
Bug introduced by
The property vtype 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...
Bug introduced by
The property priority 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...
464 24
		if ( $arIsNewObject) {
465 12
			$wf_object->arIsNewObject=$arIsNewObject;
466 12
		}
467
468
		/* save custom data */
469 24
		$properties = $this->saveCustomData($configcache, $properties);
470
471
		// this makes sure the event handlers are run on $wf_object, so that $this->data changes don't change the data of the object to be saved
472 24
		$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $wf_object));
473
474 24
		$eventData = new object();
475 24
		$eventData->arCallArgs = $arCallArgs;
0 ignored issues
show
Bug introduced by
The property arCallArgs does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
476 24
		$eventData->arCallFunction	= $context['arCallFunction'];
0 ignored issues
show
Bug introduced by
The property arCallFunction does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
477 24
		$eventData->arIsNewObject = $arIsNewObject;
0 ignored issues
show
Bug introduced by
The property arIsNewObject does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
478 24
		$eventData->arProperties = $properties;
0 ignored issues
show
Bug introduced by
The property arProperties does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
479 24
		$eventData = ar_events::fire( 'onbeforesave', $eventData );
480
481
		// pop the wf_object, not needed later, the extra scope might hinder other code
482 24
		$this->popContext();
483
484 24
		if ( !$eventData ) {
485
			return false; // prevent saving of the object.
486
		}
487
488
		// arguments can be altered by event handlers, only usefull when a workflow template is also defined
489 24
		$arCallArgs = $eventData->arCallArgs;
490
491
		// the properties from the eventData are the new property list
492
		// no need to merge them with $properties, just manipulate the properties array directly
493
		// in the event data. unlike the user.workflow.pre.html template
494 24
		if (isset( $eventData->arProperties ) && is_array( $eventData->arProperties ) ) {
495 25
			$properties = $eventData->arProperties;
496 24
		} else {
497 22
			$properties = array();
498
		}
499
500
		// pass the current properties list to the workflow template
501
		// for backwards compatibility and workflow templates that just
502
		// returned only their own properties, merge them afterwards
503
		// don't do this for the eventData arProperties!
504 24
		$arCallArgs['properties'] = $properties;
505 24
		$wf_result = $wf_object->call("user.workflow.pre.html", $arCallArgs);
506
		/* merge workflow properties */
507 24
		if (isset($wf_result) && is_array($wf_result) ){
508
			$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
509
		}
510
511 24
		$this->error = $wf_object->error;
512 24
		$this->priority = $wf_object->priority;
513 24
		$this->data = $wf_object->data;
514 24
		$this->data->config = $config;
0 ignored issues
show
Bug introduced by
The variable $config 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...
515 24
		$this->data->mtime=time();
516 24
		if($arIsNewObject) {
517 12
			$this->data->ctime=$this->data->mtime;
518 12
		}
519
520 24
		$this->data->muser=$AR->user->data->login;
521 24
		if( !$this->data->config->owner ) {
522 12
			if( !$this->data->config->owner_name) {
523 12
				$this->data->config->owner_name=$AR->user->data->name;
524 12
			}
525 12
			$this->data->config->owner=$AR->user->data->login;
526 12
			$properties["owner"][0]["value"]=$this->data->config->owner;
527 12
		}
528 24
		$properties["time"][0]["ctime"]=$this->data->ctime;
529 24
		$properties["time"][0]["mtime"]=$this->data->mtime;
530 24
		$properties["time"][0]["muser"]=$this->data->muser;
531
532
533 24
		if (!$this->error) {
534 24
			if ($this->path=$this->store->save($this->path, $this->type, $this->data, $properties, $vtype, $this->priority)) {
535 24
				unset($this->arIsNewObject);
536 24
				$this->id=$this->exists($this->path);
537 24
				$result=$this->path;
538
539 24
				$config=$this->data->config; // need to set it again, to copy owner config data
540
541 24
				$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
542 24
				$arCallArgs = $eventData->arCallArgs; // returned from onbeforesave event
543 24
				$arCallArgs['properties'] = $properties;
544
545 24
				if ($arIsNewObject) {
546 12
					$wf_object->arIsNewObject = $arIsNewObject;
547 12
				}
548 24
				$wf_result = $wf_object->call("user.workflow.post.html", $arCallArgs);
549 24
				$this->error = $wf_object->error;
550 24
				$this->priority = $wf_object->priority;
551 24
				$this->data = $wf_object->data;
552 24
				$this->data->config = $config;
553
				/* merge workflow properties */
554
555 24
				if (isset($wf_result) && is_array($wf_result) ){
556
					$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
557
558
					if (!$this->store->save($this->path, $this->type, $this->data, $properties, $this->vtype, $this->priority)) {
559
						$this->error = ar::error( ''.$this->store->error, 1108, $this->store->error);
560
						$result = false;
561
					}
562
				}
563
				// all save actions have been done, fire onsave.
564 24
				$this->data->config = $config;
565
566
				//$this->ClearCache($this->path, true, false);
567 24
				$eventData->arProperties = $properties;
568 24
				$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this));
569 24
				ar_events::fire( 'onsave', $eventData ); // nothing to prevent here, so ignore return value
570 24
				$this->popContext();
571 24 View Code Duplication
			} else {
572
				$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
573
				$result = false;
574
			}
575 24
		}
576 24
		if( $needsUnlock == true ){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
577 24
			$this->unlock();
578 24
		}
579
580 24
		if ($this->data->nls->list[$this->nls]) {
581 24
			$mynlsdata=$this->data->{$this->nls};
582 24
		} else if ($this->data->nls->default) {
583
			$mynlsdata=$this->data->{$this->data->nls->default};
584
		} else {
585
			$mynlsdata=$this->data;
586
		}
587
588 24
		unset($this->nlsdata);
589 24
		$this->nlsdata=$mynlsdata;
590
591 24
		debug("pobject: save: end","all");
592 24
		return $result;
593
	}
594
595
	public function link($to) {
596
		return $this->store->link($this->path, $this->make_path($to));
597
	}
598
599
	public function delete() {
600
	global $ARCurrent;
601
		$result	= false;
602
		$this->error = '';
603
		if ($ARCurrent->arCallStack) {
604
			$arCallArgs = end($ARCurrent->arCallStack);
605
		} else {
606
			$arCallArgs = array();
607
		}
608
		$context = $this->getContext();
609
610
		$eventData = new object();
611
		$eventData->arCallArgs = $arCallArgs;
0 ignored issues
show
Bug introduced by
The property arCallArgs does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
612
		$eventData->arCallFunction = $context['arCallFunction'];
0 ignored issues
show
Bug introduced by
The property arCallFunction does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
613
		$eventData = ar_events::fire( 'onbeforedelete', $eventData );
614
		if ( !$eventData ) {
615
			return false;
616
		}
617
		$this->call("user.workflow.delete.pre.html", $eventData->arCallArgs);
618
		if (!$this->error) {
619
			if ($this->store->delete($this->path)) {
620
				$result = true;
621
				$this->call("user.workflow.delete.post.html", $eventData->arCallArgs);
622
				ar_events::fire( 'ondelete', $eventData );
623
			} else {
624
				$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
625
			}
626
		}
627
		return $result;
628
	}
629
630 28
	public function exists($path) {
631 28
		$path=$this->make_path($path);
632 28
		return $this->store->exists($path);
633
	}
634
635 36
	public function make_path($path="") {
636
		switch($path){
637 36
			case '':
638 36
			case '.':
639 36
			case $this->path:
640 36
				return $this->path;
641
				break;
642 30
			case '..':
643 12
				return $this->parent;
644
				break;
645 30
			default:
646 30
				return $this->store->make_path($this->path, $path);
647 30
		}
648
	}
649
650
	public function make_ariadne_url($path="") {
651
		global $AR;
652
		$path = $this->make_path($path);
653
		return $AR->host . $AR->root . $this->store->get_config('rootoptions') . $path;
654
	}
655
656
657 26
	public function make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
658 26
		global $ARConfig, $AR, $ARCurrent;
659
660 26
		$rootoptions=$this->store->get_config('rootoptions');
661 26
		if (!$session || ($nls !== false)) {
662 26
			$rootoptions = "";
663 26
			if ($session && isset($ARCurrent->session->id) && !$AR->hideSessionIDfromURL) {
664
				$rootoptions .= "/-".$ARCurrent->session->id."-";
665
			}
666 26
			if ($nls) {
667 24
				$rootoptions_nonls = $rootoptions;
668 24
				$rootoptions .= '/'.$nls;
669 24
			}
670 26
		}
671 26
		$path=$this->make_path($path);
672
673
		// now run CheckConfig and get the parentsite of the path found
674 26
		if (!$temp_config=$ARConfig->cache[$path]) {
675 2
			$temp_path = $path;
676 2
			while (!($temp_site = $this->currentsite($temp_path)) && $temp_path!='/') {
677
				$temp_path = $this->make_path($temp_path.'../');
678
			}
679 2
			$temp_config=$ARConfig->cache[$temp_site];
680 2
		}
681
682 26
		if ( !isset($keephost) && (
683 26
			(!$nls && $this->compare_hosts($AR->host, $temp_config->root["value"])) ||
684 26
			($nls && ($this->compare_hosts($AR->host, $temp_config->root['list']['nls'][$nls])))
685 26
		)) {
686
			$keephost = false;
687
		}
688
689 26
		if (!$keephost) {
690 26
			if ($nls) {
691 24
				$url=$temp_config->root["list"]["nls"][$nls];
692 24
				if (isset($url) && is_array($url)) {
693
					$url = current( $url );
694
				}
695 24
				if ($url) {
696 View Code Duplication
					if (substr($url, -1)=='/') {
697
						$url=substr($url, 0, -1);
698
					}
699
					$url .= $rootoptions_nonls;
0 ignored issues
show
Bug introduced by
The variable $rootoptions_nonls 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...
700
				}
701 24
			}
702 26
			if (!$url) {
0 ignored issues
show
Bug introduced by
The variable $url 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...
703 26
				$checkNLS = $nls;
704 26
				if (!$checkNLS) {
705 14
					$checkNLS = $this->nls;
706 14
				}
707 26
				$urlList = $temp_config->root['list']['nls'][$checkNLS];
708 26
				if (isset($urlList) && is_array($urlList)) {
709
					$url = reset($urlList) . $rootoptions;
710
				} else {
711 26
					$url = $temp_config->root["value"].$rootoptions;
712
				}
713 26
			}
714 26
			$url.=substr($path, strlen($temp_config->root["path"])-1);
715
716 26
			if (is_bool($https)) {
717
				if ($https) {
718
					if ($AR->https) {
719
						$url = preg_replace('/^http:/', 'https:', $url);
720
					}
721
				} else {
722
					$url = preg_replace('/^https:/', 'http:', $url);
723
				}
724
			}
725 26
		} else {
726 24
			$checkNLS = $nls;
727 24
			if (!$checkNLS) {
728
				$checkNLS = $this->nls;
729
			}
730 24
			$urlCheck = $temp_config->root['list']['nls'][$checkNLS];
731 24
			if (!is_array($urlCheck)) {
732 24
				$urlCheck = $temp_config->root["value"];
733 24
			}
734 24
			$requestedHost = ldGetRequestedHost();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $requestedHost is correct as ldGetRequestedHost() seems to always returns null.
Loading history...
735 24
			if ($this->compare_hosts($requestedHost, $urlCheck)) {
736
				$url = $requestedHost . $rootoptions;
737
				$url .= substr($path, strlen($temp_config->root["path"])-1);
738
			} else {
739
				//$url=$AR->host.$AR->root.$rootoptions.$path;
740 24
				$url = $protocol . $requestedHost . $AR->root . $rootoptions . $path;
0 ignored issues
show
Bug introduced by
The variable $protocol does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
741
			}
742
		}
743 26
		return $url;
744
	}
745
746 26
	protected function compare_hosts($url1, $url2) {
747
		// Check if hosts are equal, so that http://www.muze.nl and //www.muze.nl also match.
748
		// using preg_replace instead of parse_url() because the latter doesn't parse '//www.muze.nl' correctly.
749 26
		if (isset($url2) ) {
750 26
			if ( !is_array($url2) ){
751 26
				$url2 = array($url2);
752 26
			}
753 26
		} else {
754 24
			$url2 = array();
755
		}
756
757 26
		$prepurl1 = preg_replace('|^[a-z:]*//|i', '', $url1);
758
759 26
		foreach($url2 as $url) {
760
			if (
761 26
					$url == $url1 ||
762 26
					$prepurl1 == preg_replace('|^[a-z:]*//|i', '', $url2)
763 26
				) {
764
				return true;
765
			}
766 26
		}
767 26
		return false;
768
	}
769
770 24
	public function make_local_url($path="", $nls=false, $session=true, $https=null) {
771 24
		global $ARCurrent, $ARConfig;
772 24
		$site = false;
773 24
		$path = $this->make_path($path);
774 24
		$checkpath = $path;
775
776 24
		$redirects = $ARCurrent->shortcut_redirect;
777 24
		if (isset($redirects) && is_array($redirects)) {
778
			$newpath = $checkpath;
779
			$c_redirects = count($redirects);
780
			$c_redirects_done = 0;
781 View Code Duplication
			while (count($redirects) && ($redir = array_pop($redirects)) && $redir['keepurl'] && substr($newpath, 0, strlen($redir['dest'])) == $redir['dest']) {
782
				$c_redirects_done++;
783
				$newpath = $redir['src'].substr($newpath, strlen($redir['dest']));
784
			}
785
786
			if ($c_redirects_done == $c_redirects) {
787
				$checkpath = $redir['src'];
0 ignored issues
show
Bug introduced by
The variable $redir 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...
788
			}
789
		}
790
791
		do {
792 24
			if (!$config=$ARConfig->cache[$checkpath]) {
793
				$config=($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
794
			}
795 24
			if ($config) {
796 24
				$checkNLS = $nls;
797 24
				if (!$checkNLS) {
798
					$checkNLS = $this->nls;
799
				}
800 24
				$urlCheck = $config->root['list']['nls'][$checkNLS];
801 24
				if (!is_array($urlCheck)) {
802 24
					$urlCheck = $config->root["value"];
803 24
				}
804 24
				$requestedHost = ldGetRequestedHost();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $requestedHost is correct as ldGetRequestedHost() seems to always returns null.
Loading history...
805
806 24
				if ($this->compare_hosts($requestedHost, $urlCheck)) {
807
					$site=$config->site;
808
				}
809 24
			}
810 24
			$prevpath=$checkpath;
811 24
			$checkpath=$this->make_path($checkpath."../");
812 24
		} while ($prevpath!=$checkpath && !$site);
813 24
		if (!$site) {
814 24
			$site='/';
815 24
		}
816 24
		$site_url=$this->make_url($site, $nls, $session, $https, true);
817 24
		if ($newpath) { // $newpath is the destination of a shortcut redirection, with keepurl on
818
			$rest=substr($newpath, strlen($site));
0 ignored issues
show
Bug introduced by
The variable $newpath 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...
819
		} else {
820 24
			$rest=substr($path, strlen($site));
821
		}
822 24
		return $site_url.$rest;
823
	}
824
825
	public function AR_implements($implements) {
826
		$type = current(explode(".",$this->type));
827
		return $this->store->AR_implements($type, $implements);
828
	}
829
830 View Code Duplication
	public function getlocks() {
831
		global $AR;
832
		if ($this->store->mod_lock) {
833
			$result=$this->store->mod_lock->getlocks($AR->user->data->login);
834
		} else {
835
			$result="";
836
		}
837
		return $result;
838
	}
839
840 24 View Code Duplication
	public function lock($mode="O", $time=0) {
841 24
	global $AR;
842 24
		if ($this->store->mod_lock) {
843 24
			$result=$this->store->mod_lock->lock($AR->user->data->login,$this->path,$mode,$time);
844 24
		} else {
845
			$result=true; // no lock module, so lock is 'set'
846
		}
847 24
		return $result;
848
	}
849
850 24 View Code Duplication
	public function unlock() {
851 24
	global $AR;
852 24
		if ($this->store->mod_lock) {
853 24
			$result=$this->store->mod_lock->unlock($AR->user->data->login,$this->path);
854 24
		} else {
855
			$result=true;
856
		}
857 24
		return $result;
858
	}
859
860
	public function touch($id=0, $timestamp=-1) {
861
		if (!$id) {
862
			$id = $this->id;
863
		}
864
		$result = $this->store->touch($id, $timestamp);
865 View Code Duplication
		if ($this->store->error) {
866
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
867
		}
868
		return $result;
869
	}
870
871
	public function mogrify($id=0, $type, $vtype=null) {
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

If you place a parameter with a default value before a parameter with a default value, the default value of the first parameter will never be used as it will always need to be passed anyway:

// $a must always be passed; it's default value is never used.
function someFunction($a = 5, $b) { }
Loading history...
872
		if (!$id) {
873
			$id = $this->id;
874
		}
875
		if (!$vtype) {
876
			$vtype = $type;
877
		}
878
		if (strpos($vtype, '.')!==false) {
879
			$vtype = substr($vtype, 0, strpos($vtype, '.'));
880
		}
881
		$result = $this->store->mogrify($id, $type, $vtype);
882 View Code Duplication
		if ($this->store->error) {
883
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
884
		}
885
		return $result;
886
	}
887
888
	public function can_mogrify() {
889
		if ($this->path == "/system/users/admin/") {
890
			return false;
891
		}
892
		return true;
893
	}
894
895
	public function load_properties($scope='') {
896
		return $this->store->load_properties($this->id,'',$scope);
897
	}
898
899
	public function _load_properties($scope='') {
900
		return $this->store->load_properties($this->id,'',$scope);
901
	}
902
903
	public function load_property($property, $scope='') {
904
		return $this->store->load_property($this->id,$property,$scope);
905
	}
906
907
	public function _load_property($property, $scope='') {
908
		return $this->store->load_property($this->id,$property,$scope);
909
	}
910
911 2
	public function GetValidGrants($path="") {
912
	/********************************************************************
913
914
	  This function finds all grants in effect on this object for the
915
	  logged in user! $AR->user must already be set.
916
917
	  Grants are checked in the following way:
918
	  1) First all parents of this object are checked for grants for this
919
	     specific user. The 'nearest' grants are valid, and the path of
920
	     parent that set these grants will be the upper limit for the
921
	     checking of group grants.
922
	  2) Now all groups of which the user is a member are checked for
923
	     grants. Likewise, all parents are checked for group grants, upto
924
	     but not including the upperlimit as set in 1. All group grants
925
	     found are merged into one grants list.
926
	  3) If there are gropup grants, this means that there are group
927
	     grants set in a parent nearer to this object than the user grants
928
	     and therefore the groupgrants must be merged with the
929
	     usergrants.
930
931
	  this results in:
932
	  1	/		user: read edit		group: none
933
	  2	/dir/					group: read
934
	  3	/dir2/		user: none		group: read
935
	  4	/dir/dir3/				group2: edit
936
	  case 1: the user takes precedence over the group, grants are 'read edit'
937
	  case 2: groupgrants are merged with usergrants, as its grants are set
938
	          in a 'nearer' parent (itself). grants are 'read edit'.
939
	  case 3: user takes precedence again. grants are 'none'.
940
	  case 4: All group grants are merged with the usergrants.
941
	          Therefore the grants are 'none read edit'.
942
	********************************************************************/
943
944 2
	global $AR;
945
946 2
		if ($AR->user) { 	// login and retrieval of user object
947 2
			if (!$path) {
948 2
				$path=$this->path;
949 2
			}
950 2
			if (!$AR->user->grants[$path]) {
951 2
				$grants=array();
952 2
				$userpath=$AR->user->FindGrants($path, $grants);
953
				// if not already done, find all groups of which the user is a member
954 2
				if (!is_array($AR->user->externalgroupmemberships) || count($AR->user->externalgroupmemberships)==0) {
955 2
					$criteria["members"]["login"]["="]=$AR->user->data->login;
0 ignored issues
show
Coding Style Comprehensibility introduced by
$criteria was never initialized. Although not strictly required by PHP, it is generally a good practice to add $criteria = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
956 2
				} else {
957
					// Use the group memberships of external databases (e.g. LDAP)
958
					$criteria="members.login='".AddSlashes($AR->user->data->login)."'";
959
					foreach (array_keys($AR->user->externalgroupmemberships) as $group) {
960
						$criteria.=" or login.value='".AddSlashes($group)."'";
961
					}
962
				}
963 2
				if (!$AR->user->groups) {
964 2
					$groups=$this->find("/system/groups/",$criteria, "system.get.phtml");
965 2
					if (isset($groups) && is_array($groups)) {
966 2
						foreach($groups as $group ){
967 2
							if (is_object($group)) {
968 2
								$AR->user->groups[$group->path] = $group;
969 2
							}
970 2
						}
971 2
					}
972 2
					if (isset($AR->user->data->config->groups) && is_array($AR->user->data->config->groups)) {
973 2
						foreach ($AR->user->data->config->groups as $groupPath => $groupId) {
974 2
							if (!$AR->user->groups[$groupPath]) {
975
								$AR->user->groups[$groupPath] = current($this->get($groupPath, "system.get.phtml"));
976
							}
977 2
						}
978 2
					}
979 2
					if (!$AR->user->groups["/system/groups/public/"]) {
980
						if ($public=current($this->get("/system/groups/public/", "system.get.phtml"))) {
981
							$AR->user->groups[$public->path] = $public;
982
						}
983
					}
984 2
				}
985 2
				if ($AR->user->groups) {
986
					/* check for owner grants (set by system.get.config.phtml) */
987 2
					if (isset($AR->user->ownergrants) && is_array($AR->user->ownergrants)) {
988
						if (!$AR->user->groups["owner"]) {
989
							$AR->user->groups["owner"] = @current($this->get("/system/groups/owner/", "system.get.phtml"));
990
						}
991
						$AR->user->groups["owner"]->data->config->usergrants = $AR->user->ownergrants;
992
					}
993 2 View Code Duplication
					foreach($AR->user->groups as $group){
994 2
						$groupgrants=array();
995 2
						if (is_object($group)) {
996 2
							$group->FindGrants($path, $groupgrants, $userpath);
997 2
							if (isset($grants) && is_array($grants)) {
998 2
								foreach($groupgrants as $gkey => $gval ){
999
									if (isset($grants[$gkey]) && is_array($grants[$gkey]) && is_array($gval)) {
1000
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
1001
									} else
1002
									if ($gval && !is_array($gval)) {
1003
										$grants[$gkey] = $gval;
1004
									} else
1005
									if ($gval && !$grants[$gkey]) {
1006
										$grants[$gkey] = $gval;
1007
									}
1008 2
								}
1009 2
							} else {
1010
								$grants = $groupgrants;
1011
							}
1012 2
						}
1013 2
					}
1014 2
				}
1015 2
				if(isset($AR->sgGrants) && is_array($AR->sgGrants) ) {
1016
					ksort($AR->sgGrants);
1017
					$ppath = $this->make_path($path);
1018 View Code Duplication
					foreach( $AR->sgGrants as $sgpath => $sggrants) {
1019
						$sgpath = $this->make_path($sgpath);
1020
						if( substr($ppath, 0, strlen($sgpath)) == $sgpath ) { // sgpath is parent of ppath or equal to ppath
1021
							if (isset($grants) && is_array($grants)) {
1022
								foreach($sggrants as $gkey => $gval ){
1023
									if (isset($grants[$gkey]) && is_array($grants[$gkey]) && is_array($gval)) {
1024
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
1025
									} else
1026
									if ($gval && !is_array($gval)) {
1027
										$grants[$gkey] = $gval;
1028
									} else
1029
									if ($gval && !$grants[$gkey]) {
1030
										$grants[$gkey] = $gval;
1031
									}
1032
								}
1033
							} else {
1034
								$grants = $sggrants;
1035
							}
1036
						}
1037
					}
1038
				}
1039 2
				$AR->user->grants[$path]=$grants;
1040 2
			}
1041 2
			$grants=$AR->user->grants[$path];
1042
1043 2
		}
1044 2
		debug("pobject: GetValidGrants(user:".$AR->user->data->login."): end ( ".debug_serialize($grants)." )","all");
0 ignored issues
show
Bug introduced by
The variable $grants 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...
1045 2
		return $grants;
1046
	}
1047
1048
1049 70
	public function pushContext($context) {
1050 70
	global $AR;
1051 70
		if(!empty($AR->context)) {
1052 36
			$context = array_merge(end($AR->context), $context);
1053 36
		}
1054 70
		array_push($AR->context, $context);
1055 70
	}
1056
1057
	public function setContext($context, $level=0) {
1058
	global $AR;
1059
		$AR->context[count($AR->context)-(1+$level)]=$context;
1060
	}
1061
1062 70
	public function popContext() {
1063 70
	global $AR;
1064 70
		return array_pop($AR->context);
1065
	}
1066
1067 70
	public static function getContext($level=0) {
1068 70
	global $AR;
1069 70
		return $AR->context[count($AR->context)-(1+$level)];
1070
	}
1071
1072 36
	public function CheckAdmin($user) {
1073 36
	if ($user->data->login == "admin") {
1074 34
			return true;
1075
		}
1076 2
		if ($user->data->groups['/system/groups/admin/']) {
1077
			return true;
1078
		}
1079 2
		return false;
1080
	}
1081
1082 30
	public function CheckLogin($grant, $modifier=ARTHISTYPE) {
1083 30
	global $AR,$ARnls,$ARConfig,$ARCurrent,$ARConfigChecked;
1084 30
		if (!$this->store->is_supported("grants")) {
1085
			debug("pobject: store doesn't support grants");
1086
			return true;
1087
		}
1088 30
		if ($modifier==ARTHISTYPE) {
1089 30
			$modifier=$this->type;
1090 30
		}
1091
1092
		/* load config cache */
1093 30
		if (!isset($ARConfig->cache[$this->path])) {
1094
			// since this is usually run before CheckConfig, make sure
1095
			// it doesn't set cache time
1096
			$realConfigChecked = $ARConfigChecked;
1097
			$ARConfigChecked = true;
1098
			$this->loadConfig();
1099
			$ARConfigChecked = $realConfigChecked;
1100
		}
1101
1102 30
		$isadmin = $this->CheckAdmin($AR->user);
1103
1104 30
		if (!$isadmin && !$AR->user->grants[$this->path]) {
1105
			$grants = $this->GetValidGrants();
1106
		} else {
1107 30
			$grants = $AR->user->grants[$this->path];
1108
		}
1109
1110 30
		if ($AR->user->data->login!="public") {
1111
			// Don't remove this or MSIE users won't get uptodate pages...
1112 30
			ldSetClientCache(false);
1113 30
		}
1114
1115 30
		if ( 	( !$grants[$grant]
1116 30
					|| ( $modifier && is_array($grants[$grant]) && !$grants[$grant][$modifier] )
1117 30
				) && !$isadmin ) {
1118
			// do login
1119
			$arLoginMessage = $ARnls["accessdenied"];
1120
			ldAccessDenied($this->path, $arLoginMessage);
1121
			$result=false;
1122
		} else {
1123 30
			$result=($grants || $isadmin);
1124
		}
1125
1126 30
		$ARCurrent->arLoginSilent=1;
1127 30
		return $result;
1128
	}
1129
1130
1131 2
	public function CheckPublic($grant, $modifier=ARTHISTYPE) {
1132 2
	global $AR;
1133
1134 2
		$result=false;
1135 2
		if (!$AR->public) {
1136 2
			$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this));
1137 2
				$AR->public=current($this->get("/system/users/public/", "system.get.phtml"));
1138 2
			$this->popContext();
1139 2
		}
1140 2
		if ($AR->public) {
1141 2
			$AR->private=$AR->user;
1142 2
			$AR->user=$AR->public;
1143 2
			$result=$this->CheckSilent($grant, $modifier);
1144 2
			$AR->user=$AR->private;
1145 2
		}
1146 2
		return $result;
1147
	}
1148
1149 22
	public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") {
1150 22
	global $AR, $ARConfig;
1151 22
		$path = $this->make_path($path);
1152 22
		if ($modifier==ARTHISTYPE) {
1153 22
			$modifier=$this->type;
1154 22
		}
1155
1156
		/* load config cache */
1157 22
		if (!$ARConfig->cache[$path]) {
1158 4
			$this->loadConfig($path);
1159 4
		}
1160 22
		if ($this->CheckAdmin($AR->user)) {
1161 20
			$result=1;
1162 22
		} else if ($grants=$AR->user->grants[$path]) {
1163
			$result=$grants[$grant];
1164
		} else {
1165 2
			$grants=$this->GetValidGrants();
1166 2
			$result=$grants[$grant];
1167
		}
1168 22
		if ($modifier && is_array($result)) {
1169
			$result=$result[$modifier];
1170
		}
1171 22
		return $result;
1172
	}
1173
1174
	public function CheckNewFile($newfilename) {
1175
	global $ARnls;
1176
	/**********************************************************************
1177
1178
	  This function performs all the necessary checks on a path to see
1179
	whether it's a valid path for a new object. This consists of:
1180
	1) checking for invalid characters, valid chars are "a-zA-Z0-9./_-"
1181
	2) checking whether the path starts and ends with a "/".
1182
	3) checking whether the path doesn't exist already.
1183
	4) checking whether the parent exists.
1184
1185
	if all this checks out, it returns 1. If not, $this->error is set to
1186
	the correct error message.
1187
1188
	**********************************************************************/
1189
1190
		$this->error="";
1191
		if (preg_match("|^/[a-z0-9\./_-]*/$|i",$newfilename)) {
1192
			if (!$this->store->exists($newfilename)) {
1193
				$parent=$this->store->make_path($newfilename, "..");
1194
				if ($this->store->exists($parent)) {
1195
					$result=1;
1196
				} else {
1197
					$this->error = ar::error( sprintf($ARnls["err:filenameinvalidnoparent"],$newfilename,$parent), 1102);
1198
				}
1199
			} else {
1200
				$this->error = ar::error( sprintf($ARnls["err:chooseotherfilename"],$newfilename), 1103);
1201
			}
1202
		} else {
1203
			$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$newfilename)." ".$ARnls["err:startendslash"], 1104);
1204
		}
1205
		return $result;
0 ignored issues
show
Bug introduced by
The variable $result 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...
1206
	}
1207
1208 View Code Duplication
	public function resetConfig($path='') {
1209
	global $ARConfig;
1210
		$path = $this->make_path($path);
1211
		if ($ARConfig->cache[$path]) {
1212
			$path = preg_quote($path,'/');
1213
			$keys = preg_grep('/^'.$path.'/',array_keys($ARConfig->cache));
1214
			foreach ($keys as $cachepath) {
1215
				unset($ARConfig->cache[$cachepath]);
1216
				unset($ARConfig->pinpcache[$cachepath]);
1217
			}
1218
		}
1219
	}
1220
1221 18 View Code Duplication
	public function clearChildConfigs($path='') {
1222 18
	global $ARConfig;
1223 18
		$path = $this->make_path($path);
1224 18
		if ($ARConfig->cache[$path]) {
1225 18
			$path = preg_quote($path,'/');
1226 18
			$keys = preg_grep('/^'.$path.'./',array_keys($ARConfig->cache));
1227 18
			foreach($keys as $cachepath) {
1228 2
				unset($ARConfig->cache[$cachepath]);
1229 2
				unset($ARConfig->pinpcache[$cachepath]);
1230 2
				unset($ARConfig->libraries[$cachepath]);
1231 18
			}
1232 18
		}
1233 18
	}
1234
1235 18
	protected function getConfig() {
1236 18
	global $ARConfig, $ARCurrent, $ARConfigChecked;
1237 18
		$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this));
1238
		// $context=$this->getContext(0);
1239
		// debug("getConfig(".$this->path.") context: ".$context['scope'] );
1240
		// debug(print_r($ARConfig->nls, true));
1241 18
		if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) {
1242 2
			$parent = current($this->get($this->parent, "system.get.phtml"));
1243 2
			if ($parent) {
1244 2
				$parent->getConfig();
1245 2
			}
1246 2
		}
1247
1248 18
		$this->getConfigData();
1249
1250 18
		$ARConfig->pinpcache[$this->path] = $ARConfig->pinpcache[$this->parent];
1251
		// backwards compatibility when calling templates from config.ini
1252 18
		$prevArConfig = $ARCurrent->arConfig;
1253 18
		$ARCurrent->arConfig = $ARConfig->pinpcache[$this->path];
1254
1255 18
		$arCallArgs['arConfig'] = $ARConfig->pinpcache[$this->path];
0 ignored issues
show
Coding Style Comprehensibility introduced by
$arCallArgs was never initialized. Although not strictly required by PHP, it is generally a good practice to add $arCallArgs = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
1256
1257
		/* calling config.ini directly for each system.get.config.phtml call */
1258 18
		$loginSilent = $ARCurrent->arLoginSilent;
1259 18
		$ARCurrent->arLoginSilent = true;
1260
		// debug("getConfig:checkconfig start");
1261
1262 18
		$initialNLS = $ARCurrent->nls;
1263 18
		$initialConfigChecked = $ARConfigChecked;
1264
1265 18
		$ARConfig->cache[$this->path]->inConfigIni = true;
1266 18
		if ($ARConfig->cache[$this->path]->hasConfigIni && !$this->CheckConfig('config.ini', $arCallArgs)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->CheckConfig('config.ini', $arCallArgs) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

If an expression can have both false, and null as possible values. It is generally a good practice to always use strict comparison to clearly distinguish between those two values.

$a = canBeFalseAndNull();

// Instead of
if ( ! $a) { }

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
1267
			//debug("pobject::getConfig() loaded config.ini @ ".$this->path);
1268
			// debug("getConfig:checkconfig einde");
1269 2
			$arConfig = $ARCurrent->arResult;
1270 2
			if (!isset($arConfig)) {
1271
				$arConfig = $ARCurrent->arConfig;
1272
			}
1273 2
			unset($ARCurrent->arResult);
1274 2
			if (isset($arConfig['library']) && is_array($arConfig['library'])) {
1275
				if (!$ARConfig->libraries[$this->path]) {
1276
					$ARConfig->libraries[$this->path] = array();
1277
				}
1278
				foreach ($arConfig['library'] as $libName => $libPath) {
1279
					$this->loadLibrary($libName, $libPath);
1280
				}
1281
				unset($arConfig['library']);
1282
			}
1283 2
			$ARConfig->pinpcache[$this->path] = (array) $arConfig;
1284 2
		}
1285 18
		$ARConfig->cache[$this->path]->inConfigIni = false;
1286 18
		$this->clearChildConfigs( $this->path ); // remove any config data for child objects, since these are set before their parent config was set
1287 18
		$ARConfigChecked = $initialConfigChecked;
1288 18
		$ARCurrent->nls = $initialNLS;
1289
1290 18
		$arConfig = &$ARConfig->pinpcache[$this->path];
1291 18 View Code Duplication
		if (!is_array($arConfig['authentication']['userdirs'])) {
1292
			$arConfig['authentication']['userdirs'] = array('/system/users/');
1293
		} else {
1294 18
			if (reset($arConfig['authentication']['userdirs']) != '/system/users/') {
1295
				array_unshift($arConfig['authentication']['userdirs'], '/system/users/');
1296
			}
1297
		}
1298 18 View Code Duplication
		if (!is_array($arConfig['authentication']['groupdirs'])) {
1299
			$arConfig['authentication']['groupdirs'] = array('/system/groups/');
1300
		} else {
1301 18
			if (reset($arConfig['authentication']['groupdirs']) != '/system/groups/') {
1302
				array_unshift($arConfig['authentication']['groupdirs'], '/system/groups/');
1303
			}
1304
		}
1305
1306 18
		$ARCurrent->arLoginSilent = $loginSilent;
1307 18
		$ARCurrent->arConfig = $prevArConfig;
1308 18
		$this->popContext();
1309 18
	}
1310
1311 18
	protected function getConfigData() {
1312 18
	global $ARConfig, $AR;
1313 18
		$context = $this->getContext(0);
1314 18
		if (!$ARConfig->cache[$this->path] && $context["scope"] != "pinp") {
1315
			// first inherit parent configuration data
1316 18
			$configcache= clone $ARConfig->cache[$this->parent];
1317 18
			$configcache->localTemplates = [];
1318 18
			$configcache->pinpTemplates = [];
1319 18
			$configcache->id = $this->id;
1320
1321
			// cache default templates
1322 18
			if (isset($this->data->config->templates) && count($this->data->config->templates)) {
1323
				$configcache->pinpTemplates    = $this->data->config->pinp;
1324
				$configcache->privatetemplates = $this->data->config->privatetemplates;
1325
				$configcache->localTemplates   = $this->data->config->templates;
1326
1327
				if( !$configcache->hasDefaultConfigIni ) {
1328
					foreach($configcache->localTemplates as $type => $templates ) {
1329
						if( isset($templates["config.ini"]) ) {
1330
							$configcache->hasDefaultConfigIni = true;
1331
							$configcache->hasConfigIni = true;
1332
							break;
1333
						}
1334
					}
1335
				}
1336 18
			} else if (isset($this->data->config->pinp) && count($this->data->config->pinp)) {
1337 2
				$configcache->pinpTemplates    = $this->data->config->pinp;
1338 2
			}
1339
1340 18
			if( !$configcache->hasDefaultConfigIni ) {
1341 18
				$configcache->hasConfigIni = false;
1342 18
				if(isset($this->data->config->pinp) && is_array($this->data->config->pinp) ) {
1343 2
					foreach( $this->data->config->pinp as $type => $templates ) {
1344 2
						if( isset($templates["config.ini"]) ) {
1345 2
							$configcache->hasConfigIni = true;
1346 2
							break;
1347
						}
1348 2
					}
1349 2
				}
1350 18
			}
1351
1352 18
			$localcachesettings = $this->data->config->cacheSettings;
1353 18
			if (!is_array($localcachesettings) ){
1354 18
				$localcachesettings = array();
1355 18
			}
1356
1357 18
			if (!is_array($configcache->cacheSettings) ) {
1358
				$configcache->cacheSettings = array();
1359
			}
1360
1361 18
			if ($this->data->config->cacheconfig) { // When removing this part, also fix the setting below.
1362 2
				$configcache->cache=$this->data->config->cacheconfig;
1363 2
			}
1364
1365 18
			if (!isset($localcachesettings['serverCache']) && isset($this->data->config->cacheconfig)) {
1366 2
				$localcachesettings["serverCache"] = $this->data->config->cacheconfig;
1367 2
			}
1368
1369 18
			if ($localcachesettings['serverCache'] != 0 ) {
1370 2
				$localcachesettings['serverCacheDefault'] = $localcachesettings['serverCache'];
1371 2
			}
1372
1373 18
			$configcache->cacheSettings = $localcachesettings + $configcache->cacheSettings;
1374
1375
			// store the current object type
1376 18
			$configcache->type = $this->type;
1377
1378 18
			if ($this->data->config->typetree && ($this->data->config->typetree!="inherit")) {
1379
				$configcache->typetree=$this->data->config->typetree;
1380
			}
1381 18
			if (isset($this->data->config->nlsconfig->list)) {
1382 2
				$configcache->nls = clone $this->data->config->nlsconfig;
1383 2
			}
1384
1385 18
			if ($this->data->config->grants["pgroup"]["owner"]) {
1386
				$configcache->ownergrants = $this->data->config->grants["pgroup"]["owner"];
1387
			}
1388 18
			if (isset($configcache->ownergrants) && is_array($configcache->ownergrants)) {
1389
				if ($AR->user && $AR->user->data->login != 'public' && $AR->user->data->login === $this->data->config->owner) {
1390
					$ownergrants = $configcache->ownergrants;
1391
					if (isset($ownergrants) && is_array($ownergrants)) {
1392
						foreach( $ownergrants as $grant => $val ) {
1393
							$AR->user->ownergrants[$this->path][$grant] = $val;
1394
						}
1395
					}
1396
				}
1397
			}
1398
1399 18
			if (isset($this->data->config->customconfig) && is_array($this->data->config->customconfig)) {
1400
				$configcache->custom=array_merge(is_array($configcache->custom)?$configcache->custom:array(), $this->data->config->customconfig);
1401
			}
1402 18
			$ARConfig->cache[$this->path]=$configcache;
1403
1404 18
		}
1405 18
	}
1406
1407 32
	public function loadConfig($path='') {
1408 32
	global $ARConfig, $ARConfigChecked, $ARCurrent;
1409 32
		$path=$this->make_path($path);
1410
		// debug("loadConfig($path)");
1411 32
		if (!isset($ARConfig->cache[$path]) ) {
1412 18
			$allnls = $ARCurrent->allnls;
1413 18
			$ARCurrent->allnls = true;
1414 18
			$configChecked = $ARConfigChecked;
1415 18
			if (($this->path == $path && !$this->arIsNewObject) || $this->exists($path)) {
1416 18
				$this->pushContext(array("scope" => "php"));
1417 18
				if( $this->path == $path ) {
1418
					// debug("loadConfig: currentpath $path ");
1419 18
					$this->getConfig();
1420 18
				} else {
1421
					//debug("loadConfig: get path $path ");
1422 2
					$cur_obj = current($this->get($path, "system.get.phtml"));
1423 2
					$cur_obj->getConfig();
1424
				}
1425 18
				$this->popContext();
1426 18
				$result=$ARConfig->cache[$path];
1427 18
			} else if ($path === '/') {
1428
				// special case: / doesn't exists in the store
1429
				$result=$ARConfig->cache['..'];
1430
			} else {
1431
				$parent=$this->make_path($path.'../');
1432
				if (!$ARConfig->cache[$parent]) {
1433
					$this->pushContext(array("scope" => "php"));
1434
					// debug("loadConfig: parent $parent");
1435
					$cur_obj = current($this->get($parent, "system.get.phtml"));
1436
					if( $cur_obj ) {
1437
						$cur_obj->getConfig();
1438
					}
1439
					$this->popContext();
1440
				}
1441
				$result=$ARConfig->cache[$parent];
1442
				$ARConfig->cache[ $path ] = $result;
1443
				$ARConfig->pinpcache[ $path ] = $ARConfig->pinpcache[ $parent ];
1444
			}
1445
			// restore old ARConfigChecked state
1446 18
			$ARConfigChecked = $configChecked;
1447 18
			$ARCurrent->allnls = $allnls;
1448 18
		} else {
1449
			// debug("loadConfig: exists $path ");
1450 26
			$result=$ARConfig->cache[$path];
1451
		}
1452 32
		return $result;
1453
	}
1454
1455
1456
	// TODO: look for a way to merge loadConfig and loadUserConfig into one function
1457
1458 6
	public function loadUserConfig($path='') {
1459 6
	global $ARConfig;
1460 6
		$path = $this->make_path($path);
1461 6
		$parent = $this->make_path($path.'../');
1462
1463 6
		if (!$ARConfig->cache[$path]) {
1464
			$this->loadConfig($path);
1465
		}
1466 6
		if (!$ARConfig->pinpcache[$path]) {
1467
			$config = $ARConfig->pinpcache[$parent];
1468
		} else {
1469 6
			$config = $ARConfig->pinpcache[$path];
1470
		}
1471 6
		return (array)$config;
1472
	}
1473
1474 2
	public function loadLibrary($name, $path) {
1475 2
	global $ARConfig;
1476 2
		$path=$this->make_path($path);
1477 2
		debug("pobject::loadLibrary($name, $path);");
1478 2
		if ($name===ARUNNAMED) {
1479 2
			if (strstr($path, $this->path)===0) {
0 ignored issues
show
Unused Code Bug introduced by
The strict comparison === seems to always evaluate to false as the types of strstr($path, $this->path) (string) and 0 (integer) can never be identical. Maybe you want to use a loose comparison == instead?
Loading history...
1480
				return ar::error('You cannot load an unnamed library from a child object.', 1109);
1481
			} else {
1482 2
				if (!isset($ARConfig->libraries[$this->path])) {
1483 2
					$ARConfig->libraries[$this->path] = [ $path ];
1484 2
				} else {
1485
					array_unshift($ARConfig->libraries[$this->path],$path);
1486
				}
1487
			}
1488 2
		} else if ($name && is_string($name)) {
1489
			$ARConfig->libraries[$this->path][$name]=$path;
1490
		} else if (is_int($name)) {
1491
			$ARConfig->libraries[$this->path][$name]=$path;
1492
		} else {
1493
			return ar::error('Illegal library name: '.$name, 1110);
1494
		}
1495 2
	}
1496
1497
	// returns a list of libraries loaded on $path
1498
	public function getLibraries($path = '') {
1499
	global $ARConfig;
1500
		$path = $this->make_path($path);
1501
		return (array)$ARConfig->libraries[$path];
1502
	}
1503
1504
	public function mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1505
		$libraryName = ar::getvar('arLibrary');
1506
		if ( is_numeric($libraryName) || $libraryName == 'current' ) { // library is loaded unnamed
1507
			$libraryName = $defaultLibraryName;
1508
		}
1509
		if ( $libraryName ) {
1510
			$userConfig = ar::acquire('defaults.'.$libraryName);
1511
			if (isset($userConfig) && is_array($userConfig) ) {
1512
				$defaults = array_merge( $defaults, $userConfig );
1513
			}
1514
		}
1515
		return array_merge( $defaults, $this->getvar('arCallArgs') );
1516
	}
1517
1518
	public function _mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1519
		return $this->mergeLibraryConfig( $defaultLibraryName, $defaults );
1520
	}
1521
1522 30
	protected function findTemplateOnPath($path, $arCallFunction, $arType, $reqnls, &$arSuperContext){
1523
1524 30
		while ($arType!='ariadne_object' ) {
1525 30
			list($arMatchType,$arMatchSubType) = explode('.',$arType,2);
1526 30
			$local = ($path === $this->path);
1527 30
			$templates = ar('template')->ls($path);
1528 30
			if(isset($templates[$arCallFunction])) {
1529 6
				$template = null;
1530 6
				if (!isset($arSuperContext[$path.":".$arType.":".$arCallFunction])) {
1531
					$template = array_reduce($templates[$arCallFunction] , function($carry, $item) use ($arMatchType,$arMatchSubType, $reqnls, $local) {
1532 6
						if ( ( $item['local'] == true && $local == true ) || $item['local'] == false ) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
1533 6
							if ($item['type'] === $arMatchType && ($item['subtype'] == $arMatchSubType) ) {
1534 6
								if (isset($carry) && $carry['language'] !== 'any') {
1535
									return $carry;
1536 6
								} else if ($item['language'] === 'any' || $item['language'] === $reqnls ) {
1537 6
									return $item;
1538
								}
1539
							}
1540
						}
1541
						return $carry;
1542 6
					}, null);
1543 6
				}
1544 6
				if ( isset($template) && !isset($arSuperContext[$path.":".$arType.":".$arCallFunction])) {
1545 6
					return $template;
1546
				}
1547
			}
1548 24
			if (!isset($AR->superClass[$arType])) {
1549
				// no template found, no default.phtml found, try superclass.
1550 24
				if ($subcpos = strpos($arType, '.')) {
1551 12
					$arSuper = substr($arType, 0, $subcpos);
1552 12
				} else {
1553 24
					if (!class_exists($arType, false )) {
1554
						// the given class was not yet loaded, so do that now
1555
						$arTemp=$this->store->newobject('','',$arType,new object);
1556
					} else {
1557 24
						$arTemp=new $arType();
1558
					}
1559 24
					$arSuper=get_parent_class($arTemp);
1560
				}
1561 24
				$AR->superClass[$arType]=$arSuper;
0 ignored issues
show
Bug introduced by
The variable $AR does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
1562 24
			} else {
1563
				$arSuper=$AR->superClass[$arType];
1564
			}
1565 24
			$arType=$arSuper;
1566 24
		}
1567
1568 24
		return null;
1569
	}
1570
1571 30
	public function getPinpTemplate($arCallFunction='view.html', $path=".", $top="", $inLibrary = false, $librariesSeen = null, $arSuperContext=array()) {
1572 30
	global $ARCurrent, $ARConfig, $AR, $ARConfigChecked;
1573 30
		debug("getPinpTemplate: function: $arCallFunction; path: $path; top: $top; inLib: $inLibrary","class");
1574 30
		$result = array();
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1575 30
		if (!$top) {
1576 30
			$top = '/';
1577 30
		}
1578 30
		$path = $this->make_path($path);
1579 30
		if (!is_array($arSuperContext)) {
1580
			$arSuperContext = array();
1581
		}
1582
1583 30
		$matches = [];
1584 30
		preg_match('/^
1585
		    ( (?<libname> [^:]+) :  )?
1586
		    ( (?<calltype>[^:]+) :: )?
1587
		      (?<template>[^:]+)
1588 30
		    $/x', $arCallFunction, $matches);
1589
1590 30
		$arCallFunction = $matches['template'];
1591
1592 30
		if($matches['calltype'] != '') {
1593
			$arCallType = $matches['calltype'];
1594
		} else {
1595 30
			$arCallType = $this->type;
1596
		}
1597
1598 30
		if ( $matches['libname'] != '' ) {
1599
			$arLibrary      = $matches['libname'];
1600
1601
			if ($arLibrary == 'current') {
1602
				// load the current arLibrary
1603
				$context       = $this->getContext(1);
1604
				$arLibrary     = $context['arLibrary'];
1605
				$arLibraryPath = $context['arLibraryPath'];
1606
			} else {
1607
				$libpath = $path;
1608
				while (!isset($arLibraryPath) && $libpath!=$lastlibpath) {
0 ignored issues
show
Bug introduced by
The variable $lastlibpath 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...
1609
					$lastlibpath = $libpath;
1610
					if (isset($ARConfig->libraries[$libpath][$arLibrary])) {
1611
						$arLibraryPath = $ARConfig->libraries[$libpath][$arLibrary];
1612
					} else {
1613
						if ($libpath == $top) {
1614
							break;
1615
						}
1616
						$libpath=$this->store->make_path($libpath, "..");
1617
					}
1618
				}
1619
			}
1620
			if ($arLibraryPath) {
1621
				debug("getPinpTemplate: found library '$arLibrary'. Searching for [".$arCallType."] $arCallFunction on '".$arLibraryPath."' up to '$top'");
0 ignored issues
show
Bug introduced by
The variable $arLibraryPath 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...
1622
				$librariesSeen[$arLibraryPath] = true;
1623
				$inLibrary = true;
1624
				$path = $arLibraryPath;
1625
			} else {
1626
				debug("getPinpTemplate: Failed to find library $arLibrary");
1627
			}
1628
			$path = $this->make_path($path);
1629
		}
1630
1631 30
		$checkpath           = $path;
1632 30
		$lastcheckedpath     = "";
1633 30
		$arCallClassTemplate = $ARCurrent->arCallClassTemplate;
1634 30
		$reqnls              = $this->reqnls;
1635 30
		$template            = null;
1636 30
		while (!$arCallClassTemplate && !isset($template) && $checkpath!=$lastcheckedpath) {
1637 30
			$lastcheckedpath = $checkpath;
1638
1639 30
			$template = $this->findTemplateOnPath( $checkpath, $arCallFunction, $arCallType, $reqnls, $arSuperContext);
1640
1641 30
			if (isset($template)) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
1642
				// haal info uit template
1643
				// debug("getPinpTemplate: found ".$arCallFunction." on ".$checkpath);
1644 30
			} else if ($inLibrary) {
1645
1646
				// faster matching on psection, prefix doesn't have to be a valid type
1647
				$prefix = substr($ARConfig->cache[$checkpath]->type,0,8);
1648
1649
				if ($prefix === 'psection') {
1650
					 // debug("BREAKING; $arTemplateId");
1651
					// break search operation when we have found a
1652
					// psection object
1653
					break;
1654
				}
1655
			} else {
1656 24
				if (isset($ARConfig->libraries[$checkpath])) {
1657
					// need to check for unnamed libraries
1658 24
					$libraries = array_filter($ARConfig->libraries[$checkpath],'is_int',ARRAY_FILTER_USE_KEY);
1659 24
					foreach( $libraries as $key => $libpath ) {
1660 24
						$arLibraryPath = $libpath;
1661 24
						$arLibrary     = $key;
1662
1663 24
						$libprevpath = null;
1664 24
						while($libpath != $libprevpath ) {
1665 24
							$libprevpath = $libpath;
1666
1667 24
							$template = $this->findTemplateOnPath( $libpath, $arCallFunction, $arCallType, $reqnls, $arSuperContext);
1668 24
							if (isset($template)) {
1669
								break 2;
1670
							}
1671
1672 24
							$prefix = substr($ARConfig->cache[$libpath]->type,0,8);
1673 24
							if ($prefix === 'psection' || $top == $libpath) {
1674 24
								break;
1675
							}
1676
1677 24
							$libpath = $this->store->make_path($libpath, "..");
1678 24
						}
1679 24
					}
1680 24
					debug("getPinpTemplate: found ".$arCallFunction." on ".$template['path']);
1681 24
				}
1682
1683
			}
1684
1685 30
			if ($checkpath == $top) {
1686 24
				break;
1687
			}
1688
1689 30
			debug("getPinpTemplate: DONE checking for ".$arCallFunction." on ".$checkpath);
1690 30
			$checkpath=$this->store->make_path($checkpath, "..");
1691
			
1692 30
		}
1693 30
		$result = null;
1694 30
		if(isset($template)) {
1695 6
			$result = [];
1696
			//debug("getPinpTemplate END; ".$template['id'] .' '.$template['path']);
1697 6
			$type = $template['type'];
1698 6
			if(isset($template['subtype'])) {
1699
				$type .= '.' . $template['subtype'];
1700
			}
1701 6
			$result["arTemplateId"]       = $template['id'];
1702 6
			$result["arCallTemplate"]     = $template['filename'];
1703 6
			$result["arCallType"]         = $arCallType;
1704 6
			$result["arCallTemplateName"] = $arCallFunction;
1705 6
			$result["arCallTemplateNLS"]  = $template['language'];
1706 6
			$result["arCallTemplateType"] = $type;
1707 6
			$result["arCallTemplatePath"] = $template['path'];
1708 6
			$result["arLibrary"]          = $arLibrary;
0 ignored issues
show
Bug introduced by
The variable $arLibrary 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...
1709 6
			$result["arLibraryPath"]      = $arLibraryPath;
1710 6
			$result["arLibrariesSeen"]    = $librariesSeen;
1711 6
			$result["arPrivateTemplate"]  = $template['private'];
1712 6
		}
1713 30
		return $result;
1714
	}
1715
1716 32
	public function CheckConfig($arCallFunction="", $arCallArgs="") {
1717
	// returns true when cache isn't up to date and no other template is
1718
	// defined for $path/$function. Else it takes care of output to the
1719
	// browser.
1720
	// All these templates must exist under a fixed directory, $AR->dir->templates
1721 32
	global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked;
1722 32
		$MAX_LOOP_COUNT=10;
1723
1724
1725
		// system templates (.phtml) have $arCallFunction=='', so the first check in the next line is to
1726
		// make sure that loopcounts don't apply to those templates.
1727 32
		if (0 && $arCallFunction && $ARBeenHere[$this->path][$arCallFunction]>$MAX_LOOP_COUNT) { // protect against infinite loops
1728
			error(sprintf($ARnls["err:maxloopexceed"],$this->path,$arCallFunction,$arCallArgs));
1729
			$this->store->close();
1730
			exit();
0 ignored issues
show
Coding Style Compatibility introduced by
The method CheckConfig() 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...
1731
		} else {
1732 32
			$ARBeenHere[$this->path][$arCallFunction]+=1;
1733
1734
			// this will prevent the parents from setting the cache time
1735 32
			$initialConfigChecked = $ARConfigChecked;
1736 32
			$ARConfigChecked = true;
1737 32
			$config = ($ARConfig->cache[$this->path]) ? $ARConfig->cache[$this->path] : $this->loadConfig();
1738 32
			$ARConfigChecked = $initialConfigChecked;
1739 32
			$ARConfig->nls=$config->nls;
1740
1741
1742
			// if a default language is entered in a parent and no language is
1743
			// explicitly selected in the url, use that default.
1744
			// The root starts with the system default (ariadne.phtml config file)
1745 32
			if ( !$ARCurrent->nls ) {
1746 32
				if ( $config->root['nls'] ) {
1747
					$this->reqnls = $config->root['nls'];
1748
					if ( !$ARConfigChecked ) {
1749
						$ARCurrent->nls = $this->reqnls;
1750
					}
1751 32
				} else if ( $config->nls->default ) {
1752 32
					$this->reqnls = $config->nls->default;
1753 32
					$this->nls = $this->reqnls;
1754 32
					if ( !$ARConfigChecked ) {
1755
						$ARCurrent->nls = $this->nls;
1756
					}
1757 32
				}
1758 32
			} else {
1759
				$this->reqnls = $ARCurrent->nls;
1760
			}
1761 32
			$nls = &$this->nls;
1762 32
			$reqnls = &$this->reqnls;
1763
1764 32
			if (!$ARConfigChecked && is_object($ARnls)) {
1765
				$ARnls->setLanguage($ARCurrent->nls);
1766
			}
1767
1768
1769 32
			if (!$ARCurrent->arContentTypeSent) {
1770
				ldHeader("Content-Type: text/html; charset=UTF-8");
1771
				$ARCurrent->arContentTypeSent = true;
1772
			}
1773
1774
/*			// FIXME: the acceptlang code works a bit too well.. it overrides psite configuration settings.
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "the acceptlang code works a bit too well.. it overrides psite configuration settings"
Loading history...
1775
1776
			if ($ARCurrent->acceptlang && !$ARCurrent->nls) {
1777
				if ($ARCurrent->acceptlang && is_array($this->data->nls->list)) {
1778
					$validlangs = array_intersect(array_keys($ARCurrent->acceptlang), array_keys($this->data->nls->list));
1779
				}
1780
				if ($validlangs) {
1781
					$reqnls=array_shift($validlangs);
1782
					$ARCurrent->nls = $reqnls;
1783
				}
1784
			}
1785
*/
1786 32 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom['none']) {
1787 2
				$this->customdata=$this->data->custom['none'];
0 ignored issues
show
Bug introduced by
The property customdata 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...
1788 2
			}
1789 32 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom[$nls]) {
1790
				$this->customnlsdata=$this->data->custom[$nls];
0 ignored issues
show
Bug introduced by
The property customnlsdata does not seem to exist. Did you mean nlsdata?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1791
			}
1792
1793 32
			if (!$ARConfigChecked) {
1794
				// this template is the first template called in this request.
1795
				$eventData = new object();
1796
				$eventData->arCallArgs = $arCallArgs;
0 ignored issues
show
Bug introduced by
The property arCallArgs does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1797
				$eventData->arCallFunction = $arCallFunction;
0 ignored issues
show
Bug introduced by
The property arCallFunction does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1798
1799
				$ARConfigChecked = true;
1800
				$result = ar_events::fire( 'onbeforeview', $eventData );
1801
				$ARConfigChecked = $initialConfigChecked;
1802
				if ( !$result ) { //prevent default action: view
1803
					return false;
1804
				}
1805
			}
1806
1807 32
			if (!$ARConfigChecked) {
1808
				// if this object isn't available in the requested language, show
1809
				// a language select dialog with all available languages for this object.
1810
				if (isset($this->data->nls) && !$this->data->name) {
1811
					if (!$ARCurrent->forcenls && (!isset($this->data->nls->list[$reqnls]) || !$config->nls->list[$reqnls])) {
1812
						if (!$ARCurrent->nolangcheck && $arCallFunction != 'config.ini') {
1813
							$ARCurrent->nolangcheck=1;
1814
							$eventData = new object();
1815
							$eventData->arCallFunction = $arCallFunction;
1816
							$eventData->arCallArgs = $arCallArgs;
1817
							$eventData->arRequestedNLS = $reqnls;
0 ignored issues
show
Bug introduced by
The property arRequestedNLS does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1818
							$result = ar_events::fire( 'onlanguagenotfound', $eventData );
1819
							if ( $result ) { // continue with default action: langaugeselect
1820
								$result->arCallArgs["arOriginalFunction"] = $result->arCallFunction;
1821
								$this->call("user.languageselect.html", $result->arCallArgs);
1822
								return false;
1823
							}
1824
						} else {
1825
							$this->nlsdata=$this->data->$nls;
1826
						}
1827
					} else {
1828
						$this->nlsdata=$this->data->$reqnls;
1829
					}
1830
				}
1831
				$ARCurrent->nolangcheck=1;
1832
			}
1833
1834
			/*
1835
				Set ARConfigChecked to true to indicate that we have been here
1836
				earlier.
1837
			*/
1838 32
			$ARConfigChecked = true;
1839 32
			if ($arCallFunction) { // don't search for templates named ''
1840
				// FIXME: Redirect code has to move to getPinpTemplate()
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "Redirect code has to move to getPinpTemplate"
Loading history...
1841 30
				$redirects	= $ARCurrent->shortcut_redirect;
1842 30
				if (isset($redirects) && is_array($redirects)) {
1843
					$redirpath = $this->path;
1844
					while (!$template['arTemplateId'] &&
0 ignored issues
show
Bug introduced by
The variable $template 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...
1845
							($redir = array_pop($redirects)) &&
1846
							$redir["keepurl"] &&
1847
							(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
1848
					) {
1849
						$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"]);
1850
						$redirpath = $redir['src'];
1851
					}
1852
1853
					if (!$template["arTemplateId"] && $redirpath) {
1854
						$template = $this->getPinpTemplate($arCallFunction, $redirpath);
1855
					}
1856
				}
1857 30
				if (!$template["arTemplateId"]) {
1858 30
					$template = $this->getPinpTemplate($arCallFunction);
1859 30
				}
1860
1861 30
				if ($template["arCallTemplate"] && $template["arTemplateId"]) {
1862 6
					if (!isset($ARCurrent->cacheTemplateChain)) {
1863
						$ARCurrent->cacheTemplateChain = array();
1864
					}
1865 6
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) {
1866 4
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]] = array();
1867 4
					}
1868 6
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']])) {
1869 6
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']] = array();
1870 6
					}
1871 6
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']])) {
1872 6
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0;
1873 6
					}
1874 6
					$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]++;
1875
1876
1877 6
					debug("CheckConfig: arCallTemplate=".$template["arCallTemplate"].", arTemplateId=".$template["arTemplateId"],"object");
1878
					// $arCallTemplate=$this->store->get_config("files")."templates".$arCallTemplate;
1879
					// check if template exists, if it doesn't exist, then continue the original template that called CheckConfig
1880 6
					$arTemplates=$this->store->get_filestore("templates");
0 ignored issues
show
Unused Code introduced by
$arTemplates is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
1881 6
					$exists = ar('template')->exists($template['arCallTemplatePath'],$template["arCallTemplate"]);
1882 6
					if ( $exists ) {
1883
						// check if the requested language exists, if not do not display anything,
1884
						// unless otherwise indicated by $ARCurrent->allnls
1885
						// This triggers only for pinp templates called by other templates,
1886
						// as the first template (in the url) will first trigger the language
1887
						// choice dialogue instead.
1888 6
						$arLibrary = $template['arLibrary'];
1889 6
						if (is_int($arLibrary)) {
1890
							// set the library name for unnamed libraries to 'current'
1891
							// so that calls using getvar('arLibrary') will keep on working
1892
							$arLibrary = "current";
1893
						}
1894
1895 6 View Code Duplication
						if (!is_string($arCallArgs)) {
1896 6
							$arCallArgs['arCallFunction'] = $arCallFunction;
1897 6
							$arCallArgs['arLibrary']      = $arLibrary;
1898 6
							$arCallArgs['arLibraryPath']  = $template["arLibraryPath"];
1899 6
						}
1900
1901 6
						$ARCurrent->arCallStack[]=$arCallArgs;
1902
						// start running a pinp template
1903
1904 6
						$this->pushContext(
1905
							array(
1906 6
								"scope"              => "pinp",
1907 6
								"arLibrary"          => $arLibrary,
1908 6
								"arLibraryPath"      => $template['arLibraryPath'],
1909 6
								"arCallFunction"     => $arCallFunction,
1910 6
								"arCurrentObject"    => $this,
1911 6
								"arCallType"         => $template['arCallType'],
1912 6
								"arCallTemplateName" => $template['arCallTemplateName'],
1913 6
								"arCallTemplateNLS"  => $template['arCallTemplateNLS'],
1914 6
								"arCallTemplateType" => $template['arCallTemplateType'],
1915 6
								"arCallTemplatePath" => $template['arCallTemplatePath'],
1916 6
								"arLibrariesSeen"    => $template['arLibrariesSeen']
1917 6
							)
1918 6
						);
1919
1920
						// FIXME: is 2 het correcte getal? Kan dit minder magisch?
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "is 2 het correcte getal? Kan dit minder magisch?"
Loading history...
1921 6
						if (count($ARCurrent->arCallStack) == 2 && true === $template['arPrivateTemplate']) {
1922
							// Do not allow private templates to be called first in the stack.
1923
							// echo "Bad request";
1924
1925
							// FIXME: Echte header sturen? Of gewoon niet uitvoeren? Wat is het correcte gedrag?
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "Echte header sturen? Of gewoon niet uitvoeren? Wat is het correcte gedrag?"
Loading history...
1926
							// Return true zorgt er voor dat de default 404 handler het oppikt alsof het template niet bestaat.
1927
							$this->popContext();
1928
							array_pop($ARCurrent->arCallStack);
1929
							return true;
1930 6
						} else if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) {
1931
							// the requested language is available.
1932 6
							$this->nlsdata=$this->data->$reqnls;
1933 6
							$this->nls=$reqnls;
1934 6
							$continue=true;
1935 6
						} else if (!isset($this->data->nls)) {
1936
							// the object has no language support
1937
							$this->nlsdata=$this->data;
1938
							$continue=true;
1939
						} else if (($ARCurrent->allnls) || (!$initialConfigChecked && $ARCurrent->nolangcheck)) {
1940
							// all objects must be displayed
1941
							// $this->reqnls=$this->nls; // set requested nls, for checks
1942
							$this->nls = isset($this->data->nls->default) ? $this->data->nls->default : $this->reqnls;
1943
							$this->nlsdata = $this->data->$nls ?: $this->data->{$this->nls} ?: $this->data;
1944
							$continue=true;
1945
						} else {
1946
							debug("CheckConfig: requested language not available, allnls not set","object");
1947
							// -> skip this object (do not run template but do return false)
1948
							$continue=false;
1949
						}
1950 6
						if ($continue) {
1951 6
							$eventData = new object();
1952 6 View Code Duplication
							if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
1953 6
								$AR->contextCallHandler = true;
1954 6
								$eventData->arCallArgs = $arCallArgs;
1955 6
								$eventData->arCallFunction = $arCallFunction;
1956 6
								$eventData->arContext = $this->getContext();
0 ignored issues
show
Bug introduced by
The property arContext does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
1957 6
								$eventData = ar_events::fire('onbeforecall', $eventData);
1958 6
								$ARCurrent->arResult = $eventData->arResult;
1959 6
								$AR->contextCallHandler = false;
1960 6
								$continue = ($eventData!=false);
1961 6
							}
1962 6
							if ( $continue ) {
1963 6
								if (!isset($ARCurrent->cacheCallChainSettings)) {
1964
									$ARCurrent->cacheCallChainSettings = array();
1965
								}
1966 6
								if ($ARConfig->cache[$this->path]->inConfigIni == false) {
1967 4
									$ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings;
1968 4
								}
1969
1970 6
								if ($ARCurrent->ARShowTemplateBorders) {
1971
									echo "<!-- arTemplateStart\nData: ".$this->type." ".$this->path." \nTemplate: ".$template["arCallTemplatePath"]." ".$template["arCallTemplate"]." \nLibrary:".$template["arLibrary"]." -->";
1972
								}
1973 6
								set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
1974 6
								$func = ar('template')->get($template['arCallTemplatePath'],$template['arCallTemplate']);
1975 6
								if(is_callable($func)){
1976 6
									$arResult = $func($this);
1977 6
								}
1978 6
								restore_error_handler();
1979 6
								if (isset($arResult)) {
1980 6
									$ARCurrent->arResult=$arResult;
1981 6
								}
1982 6
								if ($ARCurrent->ARShowTemplateBorders) {
1983
									echo "<!-- arTemplateEnd -->";
1984
								}
1985 6 View Code Duplication
								if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
1986 6
									$AR->contextCallHandler = true;
1987 6
									$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
1988 6
									$eventData->arResult = $temp;
1989 6
									ar_events::fire('oncall', $eventData );
1990 6
									$ARCurrent->arResult = $temp; /* restore correct result */
1991 6
									$AR->contextCallHandler = false;
1992 6
								}
1993 6
							}
1994 6
						}
1995 6
						array_pop($ARCurrent->arCallStack);
1996 6
						$this->popContext();
1997
1998 6
						if ( !$initialConfigChecked && $arCallFunction != 'config.ini' ) {
1999
							// this template was the first template called in this request.
2000
							$eventData = new object();
2001
							$eventData->arCallArgs = $arCallArgs;
2002
							$eventData->arCallFunction = $arCallFunction;
2003
							ar_events::fire( 'onview', $eventData ); // no default action to prevent, so ignore return value.
2004
						}
2005 6
						return false;
2006
					} else {
2007 2
						debug("pobject: CheckConfig: no such file: ".$template["arTemplateId"].$template["arCallTemplate"]."","all");
2008
					}
2009 2
				} else {
2010 24
					debug("CheckConfig: no arCallTemplate ($arCallFunction from '$this->path')","object");
2011
				}
2012
2013 26
			}
2014
		}
2015 28
		return true;
2016
	}
2017
2018 12
	public function ClearCache($path="", $private=true, $recurse=false) {
2019 12
	global $AR;
2020 12
		$norealnode = false;
2021 12
		if (!$path) {
2022
			$path=$this->path;
2023
		} else {
2024 12
			$realpath = current($this->get($path, "system.get.path.phtml"));
2025 12
			if($realpath != false) {
2026 12
				$path = $realpath;
2027 12
			} else {
2028
				$norealnode = true;
2029
			}
2030
		}
2031
2032 12
		if($norealnode !== true) {
2033
			/*
2034
				we don't want to recurse to the currentsite, because the path
2035
				doesn't exists in the database, so it doesn't have a currentsite
2036
2037
				the privatecache should be emptied by delete, or by the cleanup
2038
				cronjob. The current path doesn't exists in the database, so a
2039
				object id which is needed to find the node in the cache, isn't
2040
				available
2041
			*/
2042
2043 12
			if ($private ) {
2044
				// now remove any private cache entries.
2045
				// FIXME: this doesn't scale very well.
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "this doesn't scale very well"
Loading history...
2046
				//        only scalable solution is storage in a database
2047
				//        but it will need the original path info to
2048
				//        remove recursively fast enough.
2049
				//        this means a change in the filestore api. -> 2.5
2050
2051
				// Use chunks of max 5000 objects at a time to be more memory-efficient;
2052 12
				$pcache=$this->store->get_filestore("privatecache");
2053 12
				if ($recurse) {
2054
					$offset = 0;
2055
					$limit = 5000;
2056
					$ids=$this->store->info($this->store->find($path, "" , $limit, $offset));
2057
					while (is_array($ids) && count($ids)) {
2058
						foreach($ids as $value) {
2059
							$eventData = new object();
2060
							$eventData = ar_events::fire( 'onbeforeclearprivatecache', $eventData, $value['type'], $value['path'] );
2061
							if ( !$eventData ) {
2062
								continue;
2063
							}
2064
2065
							$pcache->purge($value["id"]);
2066
							ar_events::fire( 'onclearprivatecache', $eventData, $value['type'], $value['path'] );
2067
						}
2068
2069
						$offset += $limit;
2070
						$ids = $this->store->info($this->store->find($path, "", $limit, $offset));
2071
					}
2072
				} else {
2073 12
					$eventData = new object();
2074 12
					$eventData = ar_events::fire( 'onbeforeclearprivatecache', $eventData, $this->type, $this->path );
2075 12
					if ( $eventData ) {
2076 12
						$pcache->purge($this->id);
2077 12
						ar_events::fire( 'onclearprivatecache', $eventData, $this->type, $this->path );
2078 12
					}
2079
				}
2080 12
			}
2081
2082
			// now clear all parents untill the current site
2083 12
			$site=$this->currentsite($path);
2084 12
			$project=$this->currentproject($path);
2085 12
			if ($path!=$site && $path != $project && $path!='/') {
2086 12
				$parent=$this->make_path($path.'../');
2087 12
				$this->ClearCache($parent, $private, false);
2088 12
			}
2089 12
		}
2090 12
		$recursed = array();
2091
2092
		// filesystem cache image filenames are always lower case, so
2093
		// use special path for that. Remember 'real' path name for
2094
		// recursion and stuff
2095 12
		$fs_path=strtolower($path);
2096 12
		$nlslist=$AR->nls->list;
2097 12
		$nlslist["."]="default";
2098 12
		$cache_types[] = "normal";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$cache_types was never initialized. Although not strictly required by PHP, it is generally a good practice to add $cache_types = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
2099 12
		$cache_types[] = "compressed";
2100 12
		$cache_types[] = "session";
2101
2102 12
		global $cache_config,$store_config;
2103 12
		$cachestore=new cache($cache_config);
2104
2105
2106 12
		$filestore = $this->store->get_config("files");
2107 12
		foreach($cache_types as $type){
2108 12
			foreach($nlslist as $nls => $language){
2109
				// break away if nls doesn't exists
2110
				// is dir is cached, so it should not cost more that it add's in speed
2111 12
				if(!is_dir($filestore."cache/$type/$nls")){
2112 12
					continue;
2113
				}
2114
2115
				$fpath=$filestore."cache/$type/$nls".$fs_path;
2116
				$hpath=$filestore."cacheheaders/$type/$nls".$fs_path;
2117
				if ($dir=@dir($fpath)) {
2118
					while (false !== ($entry = $dir->read())) {
2119
						if ($entry!="." && $entry!="..") {
2120
							if (is_file($fpath.$entry)) {
2121
								@unlink($fpath.$entry);
2122
								@unlink($hpath.$entry);
2123
								$cachestore->delete("/".$type."/".$nls.$fs_path.$entry);
2124
							} else if ( $recurse && !$recursed[$entry]) {
2125
								$this->ClearCache($path.$entry."/", false, true);
2126
								$recursed[$entry]=true;
2127
							}
2128
						}
2129
					}
2130
					$dir->close();
2131
					// remove empty directory entry's, hide errors about directory entry's with content
2132
					@rmdir($fpath);
2133
					@rmdir($hpath);
2134
				} else if (file_exists(substr($fpath,0,-1)."=")) {
2135
					@unlink(substr($fpath,0,-1)."=");
2136
					@unlink(substr($hpath,0,-1)."=");
2137
					$cachestore->delete("/".$type."/".$nls.substr($fs_path,0,-1)."=");
2138
				}
2139 12
			}
2140 12
		}
2141 12
	}
2142
2143
	public function getcache($name, $nls="") {
2144
		global $ARCurrent, $ARnls;
2145
		$result=false;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2146
		$this->error = '';
2147
		if ($name) {
2148
			$result=false;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2149
			if (!$nls) {
2150
				$nls=$this->nls;
2151
			}
2152
			$file=$nls.".".$name;
2153
2154
			$minfresh = time();
2155
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2156
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2157
			}
2158
2159
			$pcache=$this->store->get_filestore("privatecache");
2160
			if ( $pcache->exists($this->id, $file) &&
2161
			     ($pcache->mtime($this->id, $file) > ($minfresh) )  ) {
2162
2163
				$result = $pcache->read($this->id, $file);
2164
2165
				$contentType = $ARCurrent->ldHeaders['content-type'];
2166
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2167
					$contentType = $matches[1];
2168
				} else {
2169
					$contentType = '';
2170
				}
2171
2172 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2173
					require_once($this->store->get_config('code')."modules/mod_url.php");
2174
					$temp = explode('.', $file);
2175
					$imageNLS = $temp[0];
2176
					$result = URL::ARtoRAW($result, $imageNLS);
0 ignored issues
show
Unused Code introduced by
The call to URL::ARtoRAW() has too many arguments starting with $imageNLS.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
2177
				}
2178
			} else {
2179
				$result=false;
2180
				$ARCurrent->cache[]=$file;
2181
				ob_start();
2182
				/* output buffering is recursive, so this won't interfere with
2183
				   normal page caching, unless you forget to call savecache()...
2184
				   so normal pagecache needs to check $ARCurrent->cache, if it's
2185
				   not empty, issue a warning and don't cache the outputbuffer...
2186
				   savecache() must then pop the stack.
2187
				*/
2188
			}
2189
		} else {
2190
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2191
			$result = false;
2192
		}
2193
		return $result;
2194
	}
2195
2196
	public function cached($name, $nls="") {
2197
		if ($image=$this->getcache($name, $nls)) {
2198
			echo $image;
2199
			$result=true;
2200
		} else {
2201
			$result=false;
2202
		}
2203
		return $result;
2204
	}
2205
2206
	public function savecache($time="") {
2207
		global $ARCurrent, $ARnls, $DB;
2208
		$result = false;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
2209
		$this->error = '';
2210
		if (!$time) {
2211
			$time=2; // 'freshness' in hours.
2212
		}
2213
		if ($file=array_pop($ARCurrent->cache)) {
2214
			$image=ob_get_contents();
2215
			if ($image !== false) {
2216
				$result = true;
2217
				$origimage = $image;
2218
2219
				$contentType = $ARCurrent->ldHeaders['content-type'];
2220
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2221
					$contentType = $matches[1];
2222
				} else {
2223
					$contentType = '';
2224
				}
2225
2226 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2227
					require_once($this->store->get_config('code')."modules/mod_url.php");
2228
					$temp = explode('.', $file);
2229
					$imageNLS = $temp[0];
2230
					$image = URL::RAWtoAR($image, $imageNLS);
2231
				}
2232
2233
				if( $time > 0  && $DB["wasUsed"] == 0) {
2234
					$pcache=$this->store->get_filestore("privatecache");
2235
					$pcache->write($image, $this->id, $file);
2236
					$time=time()+($time*3600);
2237 View Code Duplication
					if (!$pcache->touch($this->id, $file, $time)) {
2238
						$this->error = ar::error("savecache: ERROR: couldn't touch $file", 1113);
2239
						$result = false;
2240
					}
2241
				}
2242
				ob_end_clean();
2243
				echo $origimage;
2244
			} else {
2245
				debug("skipped saving cache - ob_get_contents returned false so output buffering was not active", "all");
2246
				$result = false;
2247
			}
2248
		} else {
2249
			$this->error = ar::error($ARnls["err:savecachenofile"], 1112);
2250
			$result = false;
2251
		}
2252
		return $result;
2253
	}
2254
2255
	public function getdatacache($name) {
2256
		global $ARCurrent, $ARnls;
2257
		$result=false;
2258
		$this->error = '';
2259
		if ($name) {
2260
2261
			$minfresh = time();
2262
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2263
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2264
			}
2265
2266
			$pcache=$this->store->get_filestore("privatecache");
2267
			if ( $pcache->exists($this->id, $name) &&
2268
			     ($pcache->mtime($this->id, $name) > $minfresh) ) {
2269
				$result = unserialize($pcache->read($this->id, $name));
2270
			} else {
2271
				debug("getdatacache: $name doesn't exists, returning false.","all");
2272
			}
2273
		} else {
2274
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2275
		}
2276
		return $result;
2277
	}
2278
2279
	public function savedatacache($name,$data,$time="") {
2280
		global $DB;
2281
		$this->error = '';
2282
		if (!$time) {
2283
			$time=2; // 'freshness' in hours.
2284
		}
2285
		$pcache=$this->store->get_filestore("privatecache");
2286
		if( $time > 0  && $DB["wasUsed"] == 0) {
2287
			$pcache->write(serialize($data), $this->id, $name);
2288
			$time=time()+($time*3600);
2289 View Code Duplication
			if (!$pcache->touch($this->id, $name, $time)) {
2290
				$this->error = ar::error('Could not touch '.$name, 1113);
2291
				return false;
2292
			}
2293
		}
2294
		return true;
2295
	}
2296
2297 26
	public function getdata($varname, $nls="none", $emptyResult=false) {
0 ignored issues
show
Coding Style introduced by
getdata uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getdata uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
2298
	// function to retrieve variables from $this->data, with the correct
2299
	// language version.
2300 26
	global $ARCurrent;
2301
2302 26
		$result = false;
2303 26
		if ($nls!="none") {
2304 24 View Code Duplication
			if ($ARCurrent->arCallStack) {
2305 24
				$arCallArgs=end($ARCurrent->arCallStack);
2306 24
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2307 24
					extract($arCallArgs);
2308 24
				} else if (is_string($arCallArgs)) {
2309
					Parse_Str($arCallArgs);
2310
				}
2311 24
			}
2312 24
			if (isset(${$nls}[$varname])) {
2313 14
				$result=${$nls}[$varname];
2314 24
			} else if (isset($ARCurrent->$nls) && isset($ARCurrent->$nls->$varname)) {
2315
				$result=$ARCurrent->$nls->$varname;
2316 24
			} else if (($values=$_POST[$nls]) && isset($values[$varname])) {
2317
				$result=$values[$varname];
2318 24
			} else if (($values=$_GET[$nls]) && isset($values[$varname])) {
2319
				$result=$values[$varname];
2320 24
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2321
				$result=$arStoreVars[$nls][$varname];
2322 24
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2323
				$result=$arStoreVars[$nls][$varname];
2324
			}
2325 24
			if ($result===false) {
2326 24
				if (isset($this->data->${nls}) && isset($this->data->${nls}->${varname})) {
2327 12
					$result=$this->data->${nls}->${varname};
2328 12
				}
2329 24
			}
2330 24
		} else { // language independant variable.
2331 26 View Code Duplication
			if ($ARCurrent->arCallStack) {
2332 26
				$arCallArgs=end($ARCurrent->arCallStack);
2333 26
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2334 24
					extract($arCallArgs);
2335 26
				} else if (is_string($arCallArgs)) {
2336
					Parse_Str($arCallArgs);
2337
				}
2338 26
			}
2339 26
			if (isset($$varname)) {
2340 12
				$result=$$varname;
2341 26
			} else if (isset($ARCurrent->$varname)) {
2342
				$result=$ARCurrent->$varname;
2343 26 View Code Duplication
			} else if (isset($_POST[$varname])) {
2344
				$result=$_POST[$varname];
2345 26
			} else if (isset($_GET[$varname])) {
2346
				$result=$_GET[$varname];
2347 26
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$varname])) {
2348
				$result=$arStoreVars[$varname];
2349 26
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$varname])) {
2350
				$result=$arStoreVars[$varname];
2351
			}
2352 26
			if ($result===false) {
2353 26
				if (isset($this->data->$varname)) {
2354 12
					$result=$this->data->$varname;
2355 12
				}
2356 26
			}
2357
		}
2358 26
		if ( $result === false ) {
2359 26
			$result = $emptyResult;
2360 26
		}
2361 26
		return $result;
2362
	}
2363
2364
	public function showdata($varname, $nls="none", $emptyResult=false) {
2365
		echo htmlspecialchars($this->getdata($varname, $nls, $emptyResult), ENT_QUOTES, 'UTF-8');
2366
	}
2367
2368
	public function setnls($nls) {
2369
		ldSetNls($nls);
2370
	}
2371
2372
	public function getcharset() {
2373
		return "UTF-8";
2374
	}
2375
2376
	public function HTTPRequest($method, $url, $postdata = "", $port=80 ) {
2377
		$maxtries = 5;
2378
		$tries = 0;
2379
		$redirecting = true;
2380
2381
		if(isset($postdata) && is_array($postdata)) {
2382
			foreach($postdata as $key=>$val) {
2383
				if(!is_integer($key)) {
2384
					$data .= "$key=".urlencode($val)."&";
0 ignored issues
show
Bug introduced by
The variable $data 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...
2385
				}
2386
			}
2387
		} else {
2388
			$data = $postdata;
2389
		}
2390
2391
		while ($redirecting && $tries < $maxtries) {
2392
			$tries++;
2393
			// get host name and URI from URL, URI not needed though
2394
			preg_match("/^([htps]*:\/\/)?([^\/]+)(.*)/i", $url, $matches);
2395
			$host = $matches[2];
2396
			$uri = $matches[3];
2397
			if (!$matches[1]) {
2398
				$url="http://".$url;
2399
			}
2400
			$connection = @fsockopen( $host, $port, $errno, $errstr, 120);
2401
			if( $connection ) {
2402
				if( strtoupper($method) == "GET" ) {
2403
					if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
2404
						$uri .= "?" . $data;
2405
					}
2406
					fputs( $connection, "GET $uri HTTP/1.0\r\n");
2407
				} else if( strtoupper($method) == "POST" ) {
2408
					fputs( $connection, "POST $uri HTTP/1.0\r\n");
2409
				} else {
2410
					fputs( $connection, "$method $uri HTTP/1.0\r\n");
2411
				}
2412
2413
				fputs( $connection, "Host: $host\r\n");
2414
				fputs( $connection, "Accept: */*\r\n");
2415
				fputs( $connection, "Accept: image/gif\r\n");
2416
				fputs( $connection, "Accept: image/x-xbitmap\r\n");
2417
				fputs( $connection, "Accept: image/jpeg\r\n");
2418
2419
				if( strtoupper($method) == "POST" ) {
2420
					$strlength = strlen( $data);
2421
					fputs( $connection, "Content-type: application/x-www-form-urlencoded\r\n" );
2422
					fputs( $connection, "Content-length: ".$strlength."\r\n\r\n");
2423
					fputs( $connection, $data."\r\n");
2424
				}
2425
2426
				fputs( $connection, "\r\n" , 2);
2427
2428
				$headerContents = '';
2429
				$headerStart = 0;
2430
				$headerEnd = 0;
2431
				$redirecting = false;
2432
2433
				while (!feof($connection)) {
2434
					$currentLine = fgets ($connection, 1024);
2435
					if ($headerEnd && $redirecting) {
2436
						break;
2437
					} else if ($headerEnd && !$redirecting) {
2438
						//this is the html from the page
2439
						$contents = $contents . $currentLine;
0 ignored issues
show
Bug introduced by
The variable $contents 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...
2440
					} else if ( preg_match("/^HTTP/", $currentLine) ) {
2441
						//came to the start of the header
2442
						$headerStart = 1;
2443
						$headerContents = $currentLine;
2444
					} else if ( $headerStart && preg_match('/^[\n\r\t ]*$/', $currentLine) ) {
2445
						//came to the end of the header
2446
						$headerEnd = 1;
2447
					} else {
2448
						//this is the header, if you want it...
2449
						if (preg_match("/^Location: (.+?)\n/is",$currentLine,$matches) ) {
2450
							$headerContents .= $currentLine;
2451
							//redirects are sometimes relative
2452
							$newurl = $matches[1];
2453
							if (!preg_match("/http:\/\//i", $newurl, $matches) ) {
2454
								$url .= $newurl;
2455
							} else {
2456
								$url = $newurl;
2457
							}
2458
							//extra \r's get picked up sometimes
2459
							//i think only with relative redirects
2460
							//this is a quick fix.
2461
							$url = preg_replace("/\r/s","",$url);
2462
							$redirecting = true;
2463
						} else {
2464
							$headerContents.=$currentLine;
2465
						}
2466
					}
2467
				}
2468
			} else {
2469
				$this->error="$errstr ($errno)";
2470
				$contents=false;
2471
				$url = "";
2472
			}
2473
			@fclose($connection);
2474
		}
2475
		if (($method!="GET") && ($method!="POST")) {
2476
			$contents=$headerContents."\n".$contents;
0 ignored issues
show
Bug introduced by
The variable $headerContents 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...
2477
		}
2478
		return $contents;
2479
	}
2480
2481
	public function make_filesize( $size="" ,$precision=0) {
2482
		$suffixes = array('B','KB','MB','GB','TB','PB','EB','ZB','YB');
2483
2484
		if( $size === "" ) {
2485
			$size = $this->size;
0 ignored issues
show
Bug introduced by
The property size 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...
2486
		}
2487
		while ( (count($suffixes) > 1) && ($size > 1024) ){
2488
			$size = $size / 1024;
2489
			array_shift($suffixes);
2490
		}
2491
		$size = round($size,$precision);
2492
		if($precision==0){ // compatible with the old make_filesize
2493
			$size = intval($size);
2494
		}
2495
		$result = $size." ".array_shift($suffixes);
2496
		return $result;
2497
	}
2498
2499
	public function convertToUTF8($data, $charset = "CP1252") {
2500
2501
		include_once($this->store->get_config("code")."modules/mod_unicode.php");
2502
2503
		if (isset($data) && is_array($data)) {
2504
			foreach($data as $key => $val){
2505
				$data[$key] = $this->convertToUTF8($val, $charset);
2506
			}
2507
		} else
2508
		if (is_object($data)) {
2509
			foreach($data as $key => $val){
2510
				$data->$key = $this->convertToUTF8($val, $charset);
2511
			}
2512
		} else {
2513
			$data = unicode::convertToUTF8($charset, $data);
2514
		}
2515
		return $data;
2516
	}
2517
2518 14
	public function resetloopcheck() {
2519 14
		global $ARBeenHere;
2520 14
		$ARBeenHere=array();
2521 14
	}
2522
2523
/********************************************************************
2524
2525
  "safe" functions.
2526
2527
  The following functions are safe versions of existing functions
2528
  above.
2529
  - They don't change anything in the database.
2530
    This means that to save/delete something, a user will need to call
2531
    "system.save.data.phtml" or "system.delete.phtml" which check grants.
2532
  - All functions except _get and _exists don't take a path as
2533
    argument, they use the current objects path instead.
2534
2535
  These are meant to be used by 'pinp' versions of templates,
2536
  meaning user defined templates. 'pinp' rewrites call to functions
2537
  to the form '$this->_function'.
2538
2539
  All pinp files automatically first call CheckLogin('read').
2540
2541
********************************************************************/
2542
2543
	public function _call($function, $args="") {
2544
		// remove possible path information (greedy match)
2545
		if ( !( $function instanceof \Closure ) ) {
2546
			$function = basename( (string) $function );
2547
		}
2548
		return $this->call($function, $args);
0 ignored issues
show
Bug introduced by
It seems like $function can also be of type object<Closure>; however, ariadne_object::call() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
2549
	}
2550
2551
	public function _call_super($arCallArgs="") {
2552
	global $ARCurrent, $AR;
2553
		$context = $this->getContext();
2554
		if (!$arCallArgs) {
2555
			$arCallArgs = end($ARCurrent->arCallStack);
2556
		}
2557
		$arSuperContext  = (array)$context['arSuperContext'];
2558
		$arLibrary       = $context['arLibrary'];
2559
		$arLibraryPath   = $context['arLibraryPath'];
2560
		$arCallType      = $context['arCallTemplateType'];
2561
		$arSuperPath     = $context['arCallTemplatePath'];
2562
		$arLibrariesSeen = $context['arLibrariesSeen'];
2563
		$arCallFunction  = $arSuperFunction = $context['arCallFunction'];
2564
		if ($arLibrary) {
2565
			$arSuperFunction = str_replace($arLibrary.':', '', $arCallFunction);
2566
		}
2567
		if (strpos($arSuperFunction, "::") !== false) {
2568
			// template of a specific class defined via call("class::template");
2569
			list($arBaseType, $arSuperFunction)=explode("::", $arSuperFunction);
0 ignored issues
show
Unused Code introduced by
The assignment to $arBaseType is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
2570
		}
2571
		// remove current library path from the arLibrariesSeen array so that
2572
		// Ariadne will be able to re-enter the library and toggle the arSuperContext boolean there.
2573
		unset($arLibrariesSeen[$arLibraryPath]);
2574
		$arSuperContext[$arSuperPath.":".$arCallType.":".$arSuperFunction] = true;
2575
2576
		debug("call_super: searching for the template following (path: $arSuperPath; type: $arCallType; function: $arCallFunction) from $this->path");
2577
		// FIXME: Redirect code has to move to getPinpTemplate()
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "Redirect code has to move to getPinpTemplate"
Loading history...
2578
		$redirects	= $ARCurrent->shortcut_redirect;
2579
		if (isset($redirects) && is_array($redirects)) {
2580
			$redirpath = $this->path;
2581
			while (!$template['arTemplateId'] &&
0 ignored issues
show
Bug introduced by
The variable $template 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...
2582
				($redir = array_pop($redirects)) &&
2583
				$redir["keepurl"] &&
2584
				(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
2585
			) {
2586
				debug("call_super: following shortcut redirect: $redirpath; to ".$redir["dest"]);
2587
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"], false, $arLibrariesSeen, $arSuperContext);
2588
				$redirpath = $redir['src'];
2589
			}
2590 View Code Duplication
			if (!$template["arTemplateId"]) {
2591
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, '', false, $arLibrariesSeen, $arSuperContext);
2592
			}
2593
		}
2594 View Code Duplication
		if (!$template["arTemplateId"]) {
2595
			$template = $this->getPinpTemplate($arCallFunction, $this->path, '', false, $arLibrariesSeen, $arSuperContext);
2596
		}
2597
		if ($template["arCallTemplate"] && $template["arTemplateId"]) {
2598
			$exists = ar('template')->exists($template['arCallTemplatePath'],$template["arCallTemplate"]);
2599
			if ( $exists ) {
2600
				debug("call_super: found template ".$template["arCallTemplate"]." on object with id ".$template["arTemplateId"]);
2601
				$arLibrary = $template['arLibrary'];
2602
				debug("call_super: found template on ".$template["arTemplateId"]);
2603
				if (is_int($arLibrary)) {
2604
					// set the library name for unnamed libraries to 'current'
2605
					// so that calls using getvar('arLibrary') will keep on working
2606
					$arLibrary = "current";
2607
				}
2608 View Code Duplication
				if (!is_string($arCallArgs)) {
2609
					$arCallArgs['arCallFunction'] = $arCallFunction;
2610
					$arCallArgs['arLibrary'] = $arLibrary;
2611
					$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
2612
				}
2613
				$ARCurrent->arCallStack[]=$arCallArgs;
2614
				$this->pushContext(
2615
					array(
2616
						"scope"              => "pinp",
2617
						"arSuperContext"     => $arSuperContext,
2618
						"arLibrary"          => $arLibrary,
2619
						"arLibraryPath"      => $template['arLibraryPath'],
2620
						"arCallFunction"     => $arCallFunction,
2621
						"arCurrentObject"    => $this,
2622
						"arCallType"         => $template['arCallType'],
2623
						"arCallTemplateName" => $template['arCallTemplateName'],
2624
						"arCallTemplateNLS"  => $template['arCallTemplateNLS'],
2625
						"arCallTemplateType" => $template['arCallTemplateType'],
2626
						"arCallTemplatePath" => $template['arCallTemplatePath']
2627
					)
2628
				);
2629
				$continue = true;
2630
				$eventData = new object();
2631 View Code Duplication
				if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2632
					$AR->contextCallHandler = true;
2633
					$eventData->arCallArgs = $arCallArgs;
0 ignored issues
show
Bug introduced by
The property arCallArgs does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2634
					$eventData->arCallFunction = $arCallFunction;
0 ignored issues
show
Bug introduced by
The property arCallFunction does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2635
					$eventData->arContext = $this->getContext();
0 ignored issues
show
Bug introduced by
The property arContext does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
2636
					$eventData = ar_events::fire('onbeforecall', $eventData);
2637
					$ARCurrent->arResult = $eventData->arResult;
2638
					$AR->contextCallHandler = false;
2639
					$continue = ($eventData!=false);
2640
				}
2641
				if ( $continue ) {
2642
					set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2643
					$func = ar('template')->get($template['arCallTemplatePath'],$template['arCallTemplate']);
2644
					if(is_callable($func)){
2645
						$arResult = $func($this);
2646
					}
2647
					restore_error_handler();
2648
2649 View Code Duplication
					if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2650
						$AR->contextCallHandler = true;
2651
						$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2652
						$eventData->arResult = $arResult;
0 ignored issues
show
Bug introduced by
The variable $arResult 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...
2653
						ar_events::fire('oncall', $eventData );
2654
						$ARCurrent->arResult = $temp; /* restore correct result */
2655
						$AR->contextCallHandler = false;
2656
					}
2657
				}
2658
				array_pop($ARCurrent->arCallStack);
2659
				$this->popContext();
2660
			}
2661
		}
2662
		return $arResult;
2663
	}
2664
2665
	public function _get($path, $function="view.html", $args="") {
2666
		// remove possible path information (greedy match)
2667
		if ( !($function instanceof \Closure) ) {
2668
			$function = basename( (string) $function);
2669
		}
2670
		return $this->store->call($function, $args,
2671
			$this->store->get(
2672
				$this->make_path($path)));
2673
	}
2674
2675
	public function _call_object($object, $function, $args="") {
2676
		return $object->call($function, $args);
2677
	}
2678
2679 View Code Duplication
	public function _ls($function="list.html", $args="") {
2680
		// remove possible path information (greedy match)
2681
		if ( ! ( $function instanceof \Closure ) ) {
2682
			$function = basename( (string) $function );
2683
		}
2684
		return $this->store->call($function, $args,
2685
			$this->store->ls($this->path));
2686
	}
2687
2688 View Code Duplication
	public function _parents($function="list.html", $args="", $top="") {
2689
		// remove possible path information (greedy match)
2690
		if ( !($function instanceof \Closure ) ) {
2691
			$function = basename( (string) $function);
2692
		}
2693
		return $this->parents($this->path, $function, $args, $top);
2694
	}
2695
2696
	public function _find($criteria, $function="list.html", $args="", $limit=100, $offset=0) {
2697
		$this->error = '';
2698
		// remove possible path information (greedy match)
2699
		if ( !($function instanceof \Closure ) ) {
2700
			$function = basename( (string) $function);
2701
		}
2702
		$result = $this->store->call($function, $args,
2703
			$this->store->find($this->path, $criteria, $limit, $offset));
2704 View Code Duplication
		if ($this->store->error) {
2705
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error );
2706
		}
2707
		return $result;
2708
	}
2709
2710
	public function _exists($path) {
2711
		return $this->store->exists($this->make_path($path));
2712
	}
2713
2714
	public function _implements($implements) {
2715
		return $this->AR_implements($implements);
2716
	}
2717
2718 26
	public function getvar($var) {
0 ignored issues
show
Coding Style introduced by
getvar uses the super-global variable $_POST which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
Coding Style introduced by
getvar uses the super-global variable $_GET which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
2719 26
	global $ARCurrent, $ARConfig; // Warning: if you add other variables here, make sure you cannot get at it through $$var.
2720
2721 26 View Code Duplication
		if ($ARCurrent->arCallStack) {
2722 24
			$arCallArgs=end($ARCurrent->arCallStack);
2723 24
			if (isset($arCallArgs) && is_array($arCallArgs)) {
2724 18
				extract($arCallArgs);
2725 24
			} else if (is_string($arCallArgs)) {
2726
				Parse_Str($arCallArgs);
2727
			}
2728 24
		}
2729 26
		if (isset($$var) && ($var!='ARConfig')) {
2730 8
			$result=$$var;
2731 26
		} else if (isset($ARCurrent->$var)) {
2732
			$result=$ARCurrent->$var;
2733 26
		} else if (isset($ARConfig->pinpcache[$this->path][$var])) {
2734
			$result=$ARConfig->pinpcache[$this->path][$var];
2735 26 View Code Duplication
		} else if (isset($_POST[$var])) {
2736
			$result=$_POST[$var];
2737 26
		} else if (isset($_GET[$var])) {
2738
			$result=$_GET[$var];
2739 26
		} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$var])) {
2740
			$result=$arStoreVars[$var];
2741 26
		} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$var])) {
2742
			$result=$arStoreVars[$var];
2743
		}
2744 26
		return $result;
2745
	}
2746
2747
	public function _getvar($var) {
2748
		return $this->getvar($var);
2749
	}
2750
2751
	public function putvar($var, $value) {
2752
		global $ARCurrent;
2753
2754
		$ARCurrent->$var=$value;
2755
	}
2756
2757
	public function _putvar($var, $value) {
2758
		return $this->putvar($var, $value);
2759
	}
2760
2761
	public function _setnls($nls) {
2762
		$this->setnls($nls);
2763
	}
2764
2765
	// not exposed to pinp for obvious reasons
2766
	public function sgKey($grants) {
2767
		global $AR;
2768
		if( !$AR->sgSalt || !$this->CheckSilent("config") ) {
2769
			return false;
2770
		}
2771
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2772
		$this->_load("mod_grant.php");
2773
		$mg = new mod_grant();
2774
		$grantsarray = array();
2775
		$mg->compile($grants, $grantsarray);
2776
		$grants = serialize($grantsarray);
2777
		return sha1( $AR->sgSalt . $grants . $this->path);
2778
	}
2779
2780
	public function sgBegin($grants, $key = '', $path = '.') {
2781
		global $AR;
2782
		$result = false;
2783
		$context = $this->getContext();
2784
		$path    = $this->make_path($path);
2785
2786
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2787
		$this->_load("mod_grant.php");
2788
		$mg = new mod_grant();
2789
		$grantsarray = array();
2790
		$mg->compile($grants, $grantsarray);
2791
2792
		if ($context['scope'] == 'pinp') {
2793
			$checkgrants = serialize($grantsarray);
2794
			$check = ( $AR->sgSalt ? sha1( $AR->sgSalt . $checkgrants . $path) : false ); // not using suKey because that checks for config grant
2795
		} else {
2796
			$check = true;
2797
			$key = true;
2798
		}
2799
		if( $check !== false && $check === $key ) {
2800
			$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2801
			$grantsarray = (array)$AR->sgGrants[$path];
2802
			$mg->compile($grants, $grantsarray);
2803
			$AR->sgGrants[$path] = $grantsarray;
2804
			$result = true;
2805
		}
2806
		return $result;
2807
	}
2808
2809
	public function sgEnd($path = '.') {
2810
		global $AR;
2811
		$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2812
		$path = $this->make_path( $path );
2813
		unset($AR->sgGrants[$path]);
2814
		return true; // temp return true;
2815
	}
2816
2817
	public function sgCall($grants, $key, $function="view.html", $args="") {
2818
		$result = false;
2819
		if( $this->sgBegin($grants, $key ) ) {
2820
			$result = $this->call($function, $args);
2821
			$this->sgEnd();
2822
		}
2823
		return $result;
2824
	}
2825
2826
	public function _sgBegin($grants, $key, $path = '.') {
2827
		return $this->sgBegin($grants, $key, $path);
2828
	}
2829
2830
	public function _sgEnd($path = '.') {
2831
		return $this->sgEnd($path);
2832
	}
2833
2834
	public function _sgCall($grants, $key, $function="view.html", $args="") {
2835
		return $this->sgCall($grants, $key, $function, $args);
2836
	}
2837
2838
	public function _widget($arWidgetName, $arWidgetTemplate, $arWidgetArgs="", $arWidgetType="lib") {
2839
	global $AR, $ARConfig, $ARCurrent, $ARnls;
2840
2841
		$arWidgetName=preg_replace("/[^a-zA-Z0-9\/]/","",$arWidgetName);
2842
		$arWidgetTemplate=preg_replace("/[^a-zA-Z0-9\.]/","",$arWidgetTemplate);
2843
		$wgResult=null;
2844
		if ($arWidgetType=="www") {
2845
			$coderoot=$AR->dir->root;
2846
		} else {
2847
			$coderoot=$this->store->get_config("code");
2848
		}
2849
		if (file_exists($coderoot."widgets/$arWidgetName")) {
2850
			if (file_exists($coderoot."widgets/$arWidgetName/$arWidgetTemplate")) {
2851
				if (isset($arWidgetArgs) && is_array($arWidgetArgs)) {
2852
					extract($arWidgetArgs);
2853
				} else if (is_string($arWidgetArgs)) {
2854
					Parse_str($arWidgetArgs);
2855
				}
2856
				include($coderoot."widgets/$arWidgetName/$arWidgetTemplate");
2857
			} else {
2858
				error("Template $arWidgetTemplate for widget $arWidgetName not found.");
2859
			}
2860
		} else {
2861
			error(sprintf($ARnls["err:widgetnotfound"],$arWidgetName));
2862
		}
2863
		if ($wgResult) {
2864
			return $wgResult;
2865
		}
2866
	}
2867
2868
	public function _getdata($varname, $nls="none", $emptyResult=false) {
2869
		return $this->getdata($varname, $nls, $emptyResult);
2870
	}
2871
2872
	public function _showdata($varname, $nls="none", $emptyResult=false) {
2873
		$this->showdata($varname, $nls, $emptyResult);
2874
	}
2875
2876
	public function _gettext($index=false) {
2877
	global $ARnls;
2878
		if (!$index) {
2879
			return $ARnls;
2880
		} else {
2881
			return $ARnls[$index];
2882
		}
2883
	}
2884
2885
	public function _loadtext($nls, $section="") {
2886
	global $ARnls, $ARCurrent;
2887
		if( is_object($ARnls) ) {
2888
			$ARnls->load($section, $nls);
2889
			$ARnls->setLanguage($nls);
2890
			$this->ARnls = $ARnls;
0 ignored issues
show
Bug introduced by
The property ARnls 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...
2891
		} else { // older loaders and other shizzle
2892
2893
			$nls = preg_replace('/[^a-z]*/i','',$nls);
2894
			$section = preg_replace('/[^a-z0-9\._:-]*/i','',$section);
2895
			if (!$section) {
2896
				include($this->store->get_config("code")."nls/".$nls);
2897
				$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2898
			} else {
2899
				$nlsfile = $this->store->get_config("code")."nls/".$section.".".$nls;
2900
				if(strpos($nlsfile, ':') === false && file_exists($nlsfile)) {
2901
					include($nlsfile);
2902
					$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2903
				} else {
2904
					// current result;
2905
					$arResult = $ARCurrent->arResult;
2906
					$this->pushContext(array());
2907
						$oldnls = $this->reqnls;
2908
						$this->reqnls = $nls;
2909
						$this->CheckConfig($section, array('nls' => $nls));
2910
						$this->reqnls = $oldnls;
2911
					$this->popContext();
2912
					// reset current result (CheckConfig may have changed it when it should not have).
2913
					$ARCurrent->arResult = $arResult;
2914
				}
2915
			}
2916
		}
2917
	}
2918
2919
	public function _startsession() {
2920
	global $ARCurrent;
2921
		ldStartSession(0);
2922
		return $ARCurrent->session->id;
2923
	}
2924
2925
	public function _putsessionvar($varname, $varvalue) {
2926
	global $ARCurrent;
2927
2928
		if ($ARCurrent->session) {
2929
			return $ARCurrent->session->put($varname, $varvalue);
2930
		} else {
2931
			return false;
2932
		}
2933
	}
2934
2935
	public function _getsessionvar($varname) {
2936
	global $ARCurrent;
2937
2938
		if ($ARCurrent->session) {
2939
			return $ARCurrent->session->get($varname);
2940
		} else {
2941
			return false;
2942
		}
2943
	}
2944
2945
	public function _setsessiontimeout($timeout = 0) {
2946
	global $ARCurrent;
2947
		if ($ARCurrent->session) {
2948
			return $ARCurrent->session->setTimeout($timeout);
2949
		} else {
2950
			return false;
2951
		}
2952
	}
2953
2954
	public function _killsession() {
2955
	global $ARCurrent;
2956
2957
		if ($ARCurrent->session) {
2958
			$ARCurrent->session->kill();
2959
			unset($ARCurrent->session);
2960
		}
2961
	}
2962
2963
	public function _sessionid() {
2964
	global $ARCurrent;
2965
		if ($ARCurrent->session) {
2966
			return $ARCurrent->session->id;
2967
		} else {
2968
			return 0;
2969
		}
2970
	}
2971
2972
	public function _resetloopcheck() {
2973
		return $this->resetloopcheck();
2974
	}
2975
2976
	public function _make_path($path="") {
2977
		return $this->make_path($path);
2978
	}
2979
2980
	public function _make_ariadne_url($path="") {
2981
		return $this->make_ariadne_url($path);
2982
	}
2983
2984
	public function _make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
2985
		return $this->make_url($path, $nls, $session, $https, $keephost);
2986
	}
2987
2988
	public function _make_local_url($path="", $nls=false, $session=true, $https=null) {
2989
		return $this->make_local_url($path, $nls, $session, $https);
2990
	}
2991
2992
	public function _getcache($name, $nls='') {
2993
		return $this->getcache($name, $nls);
2994
	}
2995
2996
	public function _cached($name, $nls='') {
2997
		return $this->cached($name, $nls);
2998
	}
2999
3000
	public function _savecache($time="") {
3001
		return $this->savecache($time);
3002
	}
3003
3004
	public function _getdatacache($name) {
3005
		return $this->getdatacache($name);
3006
	}
3007
3008
	public function _savedatacache($name,$data,$time="")
3009
	{
3010
		return $this->savedatacache($name,$data,$time);
3011
	}
3012
3013 28
	public function currentsite($path="", $skipRedirects = false) {
3014 28
		global $ARCurrent, $ARConfig;
3015 28
		if (!$path) {
3016 24
			$path=$this->path;
3017 24
		}
3018 28
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3019 28
		if (!$skipRedirects && @count($ARCurrent->shortcut_redirect)) {
3020
			$redir = end($ARCurrent->shortcut_redirect);
3021
			if ($redir["keepurl"] && substr($path, 0, strlen($redir["dest"])) == $redir["dest"]) {
3022
				if (substr($config->site, 0, strlen($redir["dest"]))!=$redir["dest"]) {
3023
					// search currentsite from the reference
3024
					$config = ($ARConfig->cache[$redir['src']]) ? $ARConfig->cache[$redir['src']] : $this->loadConfig($redir['src']);
3025
				}
3026
			}
3027
		}
3028 28
		return $config->site;
3029
	}
3030
3031
	public function parentsite($site) {
3032
	global $ARConfig;
3033
		$path=$this->store->make_path($site, "..");
3034
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3035
		return $config->site;
3036
	}
3037
3038 2 View Code Duplication
	public function currentsection($path="") {
3039 2
	global $ARConfig;
3040 2
		if (!$path) {
3041 2
			$path=$this->path;
3042 2
		}
3043 2
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3044 2
		return $config->section;
3045
	}
3046
3047 View Code Duplication
	public function parentsection($path) {
3048
	global $ARConfig;
3049
		$path=$this->store->make_path($path, "..");
3050
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3051
		return $config->section;
3052
	}
3053
3054 12 View Code Duplication
	public function currentproject($path="") {
3055 12
	global $ARConfig;
3056 12
		if (!$path) {
3057
			$path=$this->path;
3058
		}
3059 12
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3060 12
		return $config->project;
3061
	}
3062
3063
	public function parentproject($path) {
3064
	global $ARConfig;
3065
		$path=$this->store->make_path($path, "..");
3066
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3067
		return $config->project;
3068
	}
3069
3070
	public function validateFormSecret() {
3071
		global $ARCurrent;
3072
		if (!$ARCurrent->session) {
3073
			return true;
3074
		}
3075
3076
		if ($ARCurrent->session && $ARCurrent->session->data && $ARCurrent->session->data->formSecret) {
3077
			$formSecret = $this->getvar("formSecret");
3078
			return ($formSecret === $ARCurrent->session->data->formSecret);
3079
		}
3080
		return false;
3081
	}
3082
3083
	public function _validateFormSecret() {
3084
		return $this->validateFormSecret();
3085
	}
3086
3087
	public function getValue($name, $nls=false) {
3088
	global $ARCurrent;
3089
		switch ($nls) {
3090
			case "none":
3091
				$result = $this->data->$name;
3092
			break;
3093
			case false:
0 ignored issues
show
Coding Style introduced by
There must be a comment when fall-through is intentional in a non-empty case body
Loading history...
3094
				$nls = $ARCurrent->nls;
3095
				if (!isset($this->data->$nls) || !isset($this->data->$nls->$name)) {
3096
					$result = $this->data->$name;
3097
					break;
3098
				}
3099
			default:
3100
				$result = $this->data->$nls->$name;
3101
		}
3102
		return $result;
3103
	}
3104
3105
	public function setValue($name, $value, $nls=false) {
3106
3107
	global $AR, $ARConfig;
3108
		if ($value === null) {
3109
			if ($nls && $nls!="none") {
3110
				unset($this->data->$nls->$name);
3111
				if (!count(get_object_vars($this->data->$nls))) {
3112
					unset($this->data->$nls);
3113
					unset($this->data->nls->list[$nls]);
3114
					if (!count($this->data->nls->list)) {
3115
						unset($this->data->nls->list);
3116
						unset($this->data->nls);
3117
					} else {
3118
						if ($this->data->nls->default == $nls) {
3119
							if ($this->data->nls->list[$ARConfig->nls->default]) {
3120
								$this->data->nls->default = $ARConfig->nls->default;
3121
							} else {
3122
								list($this->data->nls->default) = each($this->data->nls->list);
3123
							}
3124
						}
3125
					}
3126
				}
3127
			} else {
3128
				unset($this->data->$name);
3129
			}
3130
		} else
3131
		if (!$nls) {
3132
			$this->data->$name = $value;
3133
		} else {
3134
			if (!$this->data->$nls) {
3135
				$this->data->$nls = new object;
3136
				if (!$this->data->nls) {
3137
					$this->data->nls = new object;
3138
					$this->data->nls->default = $nls;
0 ignored issues
show
Bug introduced by
The property default does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
3139
				}
3140
				$this->data->nls->list[$nls] = $AR->nls->list[$nls];
0 ignored issues
show
Bug introduced by
The property list does not seem to exist in object.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
3141
			}
3142
			$this->data->$nls->$name = $value;
3143
		}
3144
	}
3145
3146
	public function showValue($name, $nls=false) {
3147
		$result = $this->getValue($name, $nls);
3148
		echo $result;
3149
		return $result;
3150
	}
3151
3152
	public function _getValue($name, $nls=false) {
3153
		return $this->getValue($name, $nls);
3154
	}
3155
3156
	public function _setValue($name, $value, $nls=false) {
3157
		return $this->setValue($name, $value, $nls);
3158
	}
3159
3160
	public function _showValue($name, $nls=false) {
3161
		return $this->showValue($name, $nls);
3162
	}
3163
3164
	public function _currentsite($path="", $skipRedirects = false) {
3165
		return $this->currentsite( $path, $skipRedirects );
3166
	}
3167
3168
	public function _parentsite($site) {
3169
		return $this->parentsite($site);
3170
	}
3171
3172
	public function _currentsection() {
3173
		return $this->currentsection();
3174
	}
3175
3176
	public function _parentsection($section) {
3177
		return $this->parentsection($section);
3178
	}
3179
3180
	public function _currentproject() {
3181
		return $this->currentproject();
3182
	}
3183
3184
	public function _parentproject($path) {
3185
		return $this->parentproject($path);
3186
	}
3187
3188
	public function _checkAdmin($user) {
3189
		return $this->CheckAdmin($user);
3190
	}
3191
3192
	public function _checkgrant($grant, $modifier=ARTHISTYPE, $path=".") {
3193
		// as this is called within a pinp template,
3194
		// all the grants are already loaded, so
3195
		// checksilent will fullfill our needs
3196
		$this->pushContext(array("scope" => "php"));
3197
			$result = $this->CheckSilent($grant, $modifier, $path);
3198
		$this->popContext();
3199
		return $result;
3200
	}
3201
3202
	public function _checkpublic($grant, $modifier=ARTHISTYPE) {
3203
3204
		return $this->CheckPublic($grant, $modifier);
3205
	}
3206
3207
	public function _getcharset() {
3208
		return $this->getcharset();
3209
	}
3210
3211
	public function _count_find($query='') {
3212
		return $this->count_find($this->path, $query);
3213
	}
3214
3215
	public function _count_ls() {
3216
		return $this->count_ls($this->path);
3217
	}
3218
3219
	public function _HTTPRequest($method, $url, $postdata = "", $port=80) {
3220
		return $this->HTTPRequest($method, $url, $postdata, $port);
3221
	}
3222
3223
	public function _make_filesize( $size="" ,$precision=0) {
3224
		return $this->make_filesize( $size ,$precision);
3225
	}
3226
3227
	public function _convertToUTF8($data, $charset = "CP1252") {
3228
		return $this->convertToUTF8($data,$charset);
3229
	}
3230
3231
	public function _getuser() {
3232
	global $AR;
3233
		if ($AR->pinp_user && $AR->pinp_user->data->login == $AR->user->data->login) {
3234
			$user = $AR->pinp_user;
3235
		} else {
3236
			$this->pushContext(array("scope" => "php"));
3237
				if ( $AR->user instanceof ariadne_object ) {
3238
					$user = current($AR->user->get(".", "system.get.phtml"));
3239
				} else {
3240
					$user = $AR->user;
3241
				}
3242
				$AR->pinp_user = $user;
3243
			$this->popContext();
3244
		}
3245
		return $user;
3246
	}
3247
3248
	public function ARinclude($file) {
3249
		include($file);
3250
	}
3251
3252 2
	public function _load($class) {
3253
		// only allow access to modules in the modules directory.
3254 2
		$class = preg_replace('/[^a-z0-9\._]/i','',$class);
3255 2
		include_once($this->store->get_config("code")."modules/".$class);
3256 2
	}
3257
3258
	public function _import($class) {
3259
		// deprecated
3260
		return $this->_load($class);
3261
	}
3262
3263 14
	public function html_to_text($text) {
3264 14
		$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
3265 14
		$cb  = function($matches) use ($trans) {
3266
			return strtr($matches[1],$trans);
3267 14
		};
3268
		//strip nonbreaking space, strip script and style blocks, strip html tags, convert html entites, strip extra white space
3269 14
		$search_clean = array("%&nbsp;%i", "%<(script|style)[^>]*>.*?<\/(script|style)[^>]*>%si", "%<[\/]*[^<>]*>%Usi", "%\s+%");
3270 14
		$replace_clean = array(" ", " ", " ", " ");
3271
3272 14
		$text = preg_replace_callback(
3273 14
			"%(\&[a-zA-Z0-9\#]+;)%s",
3274 14
			$cb,
3275
			$text
3276 14
		);
3277 14
		$text = preg_replace($search_clean, $replace_clean, $text);
3278 14
		return $text;
3279
	}
3280
3281
	public function _html_to_text($text) {
3282
		return $this->html_to_text($text);
3283
	}
3284
3285
	public function _newobject($filename, $type) {
3286
		$newpath=$this->make_path($filename);
3287
		$newparent=$this->store->make_path($newpath, "..");
3288
		$data=new object;
3289
		$object=$this->store->newobject($newpath, $newparent, $type, $data);
3290
		$object->arIsNewObject=true;
3291
		return $object;
3292
	}
3293
3294
	public function _save($properties="", $vtype="") {
3295
		if (isset($properties) && is_array($properties)) {
3296
			// isn't this double work, the save function doesn this again
3297
			foreach ($properties as $prop_name => $prop) {
3298
				foreach ($prop as $prop_index => $prop_record) {
3299
					$record = array();
3300 View Code Duplication
					foreach ($prop_record as $prop_field => $prop_value) {
3301
						switch (gettype($prop_value)) {
3302
							case "integer":
3303
							case "boolean":
3304
							case "double":
3305
								$value = $prop_value;
3306
							break;
3307
							default:
3308
								$value = $prop_value;
3309
								if (substr($prop_value, 0, 1) === "'" && substr($prop_value, -1) === "'"
3310
										&& "'".AddSlashes(StripSlashes(substr($prop_value, 1, -1)))."'" == $prop_value) {
3311
									$value = stripSlashes(substr($prop_value,1,-1));
3312
									// todo add deprecated warning
3313
								}
3314
						}
3315
						$record[$prop_field] = $value;
3316
					}
3317
					$properties[$prop_name][$prop_index] = $record;
3318
				}
3319
			}
3320
		}
3321
3322
		if ($this->arIsNewObject && $this->CheckSilent('add', $this->type)) {
3323
			unset($this->data->config);
3324
			$result = $this->save($properties, $vtype);
0 ignored issues
show
Bug introduced by
It seems like $properties can also be of type array or null; however, ariadne_object::save() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3325
		} else if (!$this->arIsNewObject && $this->CheckSilent('edit', $this->type)) {
3326
			$this->data->config = current($this->get('.', 'system.get.data.config.phtml'));
3327
			$result = $this->save($properties, $vtype);
0 ignored issues
show
Bug introduced by
It seems like $properties can also be of type array or null; however, ariadne_object::save() does only seem to accept string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
3328
		}
3329
		return $result;
0 ignored issues
show
Bug introduced by
The variable $result 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...
3330
	}
3331
3332
	public function _is_supported($feature) {
3333
		return $this->store->is_supported($feature);
3334
	}
3335
3336
	/*
3337
		since the preg_replace() function is able to execute normal php code
3338
		we have to intercept all preg_replace() calls and parse the
3339
		php code with the pinp parser.
3340
	*/
3341
3342
3343
	/*	this is a private function used by the _preg_replace wrapper */
3344
	// FIXME: remove this function when the minimal php version for ariadne is raised to php 7.0
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "remove this function when the minimal php version for ariadne is raised to php 7.0"
Loading history...
3345
	protected function preg_replace_compile($pattern, $replacement) {
3346
	global $AR;
3347
		include_once($this->store->get_config("code")."modules/mod_pinp.phtml");
3348
		preg_match("/^\s*(.)/", $pattern, $regs);
3349
		$delim = $regs[1];
3350
		if (@eregi("\\${delim}[^$delim]*\\${delim}.*e.*".'$', $pattern)) {
3351
			$pinp = new pinp($AR->PINP_Functions, 'local->', '$AR_this->_');
3352
			return substr($pinp->compile("<pinp>$replacement</pinp>"), 5, -2);
3353
		} else {
3354
			return $replacement;
3355
		}
3356
	}
3357
3358
	public function _preg_replace($pattern, $replacement, $text, $limit = -1) {
3359
		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
3360
			if (isset($pattern) && is_array($pattern)) {
3361
				$newrepl = array();
3362
				reset($replacement);
3363
				foreach ($pattern as $i_pattern) {
3364
					list(, $i_replacement) = each($replacement);
3365
					$newrepl[] = $this->preg_replace_compile($i_pattern, $i_replacement);
3366
				}
3367
			} else {
3368
				$newrepl = $this->preg_replace_compile($pattern, $replacement);
3369
			}
3370
		} else {
3371
			// php7 is safe, no more eval
3372
			$newrepl = $replacement;
3373
		}
3374
		return preg_replace($pattern, $newrepl, $text, $limit);
3375
	}
3376
3377
	/* ob_start accepts a callback but we don't want that
3378
	 * this wrapper removes the arguments from the ob_start call
3379
	 */
3380
	public function _ob_start() {
3381
		return ob_start();
3382
	}
3383
3384
	public function _loadConfig($path='') {
3385
		return clone $this->loadConfig($path);
3386
	}
3387
3388
	public function _loadUserConfig($path='') {
3389
		return $this->loadUserConfig($path);
3390
	}
3391
3392
	public function _loadLibrary($name, $path) {
3393 2
		return $this->loadLibrary($name, $path);
3394
	}
3395
3396
	public function _resetConfig($path='') {
3397
		return $this->resetConfig($path);
3398
	}
3399
3400
	public function _getLibraries($path = '') {
3401
		return $this->getLibraries($path);
3402
	}
3403
3404
3405
	public function _getSetting($setting) {
3406
	global $AR;
3407
3408
		switch ($setting) {
3409
			case 'www':
3410
			case 'dir:www':
3411
				return $AR->dir->www;
3412
			case 'images':
3413
			case 'dir:images':
3414
				return $AR->dir->images;
3415
			case 'ARSessionKeyCheck':
3416
				$result = null;
3417
				if (function_exists('ldGenerateSessionKeyCheck')) {
3418
					$result = ldGenerateSessionKeyCheck();
3419
				}
3420
				return $result;
3421
			break;
3422
			case 'nls:list':
3423
				return $AR->nls->list;
3424
			break;
3425
			case 'nls:default':
3426
				return $AR->nls->default;
3427
			break;
3428
			case 'svn':
3429
				return $AR->SVN->enabled;
3430
			break;
3431
		}
3432
	}
3433
3434
	public function __call($name,$arguments) {
3435
		if ( $name[0] == '_' ) {
3436
			$fname = substr($name, 1);
3437
			if ( isset($this->{$fname}) && $this->{$fname} instanceof \Closure ) {
3438
				\Closure::bind( $this->{$fname}, $this );
3439
				return call_user_func_array( $this->{$fname}, $arguments);
3440
			}
3441
		}
3442
		switch($name) {
3443
			case "implements":
3444
				return $this->AR_implements($arguments[0]);
3445
			break;
3446
			default:
3447
				trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $name), E_USER_ERROR);
3448
				return false;
3449
			break;
3450
		}
3451
	}
3452
3453
	static public function pinpErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) {
0 ignored issues
show
Unused Code introduced by
The parameter $errfile 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 $errcontext 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...
Coding Style introduced by
As per PSR2, the static declaration should come after the visibility declaration.
Loading history...
3454 3
		global $nocache;
3455 3
		if (($errno & error_reporting()) == 0) {
3456 3
			return true;
3457
		}
3458
3459
		$nocache = true;
3460
		$context = pobject::getContext();
3461
		if ($context["arLibraryPath"]) { //  != null) {
3462
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." in library ".$context["arLibraryPath"] ."\n".$errstr."\n";
3463
		} else {
3464
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." on object ".$context['arCurrentObject']->path."\n".$errstr."\n";
3465
		}
3466
		$display = ini_get('display_errors');
3467
3468
		if($display) {
3469
			echo $msg;
3470
		}
3471
		error_log($msg);
3472
3473
		return false;
3474
	}
3475
3476
} // end of ariadne_object class definition
3477