Completed
Pull Request — master (#86)
by Robbert
14:09
created

ariadne_object::ls()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1
Metric Value
dl 0
loc 4
ccs 4
cts 4
cp 1
rs 10
cc 1
eloc 3
nc 1
nop 3
crap 1
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 184
	public function init($store, $path, $data) {
45 184
		$this->store=$store;
46 184
		$this->path=$path;
47 184
		$this->data=$data;
48 184
		if ( !isset($this->data->config) ) {
49 28
			$this->data->config = new object();
50 28
		}
51 184
	}
52
53 184
	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 184
	global $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls;
72
73 184
		if ( $arCallFunction instanceof \Closure ) {
74 4
			$arCallFunctionName = 'Closure';
75 12
		} else {
76 184
			$arCallFunctionName = (string) $arCallFunction;
77
		}
78 184
		debug("pobject: ".$this->path.": call($arCallFunctionName, ".debug_serialize($arCallArgs).")","object","all","IN");
79
80
		// default to view.html
81 184
		if (!$arCallFunction) {
82 20
			$arCallFunction="view.html";
83
		}
84
		// clear previous results
85 184
		unset($ARCurrent->arResult);
86
87
		// callstack is needed for getvar()
88 184
		$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 184
		$this->pushContext( array(
91 184
			"arSuperContext" => array(),
92 184
			"arCurrentObject" => $this,
93 184
			"scope" => "php",
94
			"arCallFunction" => $arCallFunction
95 184
		) );
96
97
		// convert the deprecated urlencoded arguments to an array
98 184
		if (is_string($arCallArgs)) {
99 184
			$ARCurrent->arTemp=$arCallArgs;
100 184
			$arCallArgs=array();
101 184
			Parse_str($ARCurrent->arTemp, $arCallArgs);
102 184
		}
103
		// import the arguments in the current scope, but don't overwrite existing
104
		// variables.
105 184
		if (is_array($arCallArgs)) {
106 184
			extract($arCallArgs,EXTR_SKIP);
107 184
		}
108
		// now find the initial nls selection (CheckConfig is needed for per
109
		// tree selected defaults)
110 184
		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 184
		} else if (isset($ARConfig->cache[$this->path]) && $ARConfig->cache[$this->path]->nls->default) {
113 100
			$this->reqnls = $ARConfig->cache[$this->path]->nls->default;
114 100
		} else {
115 184
			$this->reqnls=$AR->nls->default;
116
		}
117 184
		if (isset($this->data->nls->list[$this->reqnls]) || !isset($this->data->nls)) {
118
			// the requested language is available
119 184
			$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 184
			$nls=&$this->nls;
121 184
		} else {
122
			// the requested language is not available, use default of the
123
			// current object instead.
124
			$this->nls=$this->data->nls->default;
125 4
			$nls=&$this->nls;
126
		}
127 184
		if ($nls && isset($this->data->$nls)) {
128
			// now set the data and nlsdata pointers
129 132
			$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 132
			$nlsdata=&$this->nlsdata;
131 132
			$data=&$this->data;
132 132
		} else {
133
			// this object doesn't support nls data
134 184
			$this->nlsdata=$this->data;
135 184
			$nlsdata=&$this->data;
136 184
			$data=&$this->data;
137 4
		}
138 184
		if (isset($this->data->custom['none'])) {
139 8
			$customdata=$this->data->custom['none'];
140 8
		}
141 184
		if (isset($this->data->custom[$nls])) {
142
			$customnlsdata=$this->data->custom[$nls];
143
		}
144
145 184
		$arCallFunctionOrig = $arCallFunction;
146 184
		if (strpos($arCallFunctionName,"::")!==false) {
147
			// template of a specific class defined via call("class::template");
148 24
			list($arType, $arCallFunction)=explode("::",$arCallFunctionName);
149 24
			$temp = explode(":", $arType );
150 24
			if( count($temp) > 1 ) {
151
				$libname = $temp[0];
152
				$arType = $temp[1];
153
				$arCallFunction = $libname.":".$arCallFunction;
154
			}
155 24
		} else {
156 184
			$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 184
		if ( $arCallFunction instanceof \Closure ) {
160 4
			$context = $this->getContext(ARCALLINGCONTEXT);
161 4
			if ( $context["scope"] != "pinp" ) {
162
				$arResult = $arCallFunction($this );
163
			} else {
164 4
				if ( $this->CheckSilent('read') ) {
165 4
					$arResult = $arCallFunction($this);
166 4
				}
167
			}
168 4
		} else {
169 184
			if ($arCallFunction[0] === "#") {
170 20
				$ARCurrent->arCallClassTemplate = true;
171
				$arCallFunction = substr($arCallFunction, 1);
172
			} else {
173 184
				$ARCurrent->arCallClassTemplate = false;
174
			}
175
176 184
			if( $arCallFunction == "system.get.phtml" && ( $context = $this->getContext(ARCALLINGCONTEXT) ) && $context["scope"] != "pinp" ) {
177 36
				$arResult = $this;
178 32
			} else {
179 184
				$libtemplate = strpos($arCallFunction,":");
180 184
				$codedir = $this->store->get_config("code");
181
182
				// if it is a subtype object, disk templates do not exists,
183 184
				$subcpos = strpos($arType, '.');
184 184
				if ($subcpos !== false ) {
185
					// subtype, skip looking for templates
186 24
					$arSuper = substr($arType, 0, $subcpos);
187 24
					if(!isset($AR->superClass[$arType])){
188 4
						$AR->superClass[$arType]=$arSuper;
189 4
					}
190 24
					$arType=$arSuper;
191 24
				}
192
193 184
				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 184
					$arCallTemplate=$codedir."templates/".$arType."/".$arCallFunction;
198 184
					if ($libtemplate === false && file_exists($arCallTemplate)) {
199
						//debug('found '.$arCallTemplate, 'all');
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
200
						// template found
201 184
						$arCallFunction = $arCallFunctionOrig;
202 184
						include($arCallTemplate);
203 184
						break;
204 184
					} else if (file_exists($codedir."templates/".$arType."/default.phtml")) {
205
						//debug('found default.phtml', 'all');
0 ignored issues
show
Unused Code Comprehensibility introduced by
75% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
206
						// template not found, but we did find a 'default.phtml'
207 8
						include($this->store->get_config("code")."templates/".$arType."/default.phtml");
208 12
						break;
209 24
					} else {
210 184
						if (!($arSuper=$AR->superClass[$arType])) {
211
							// no template found, no default.phtml found, try superclass.
212
213 8
							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 12
							$arSuper=get_parent_class($arType);
218
219 32
							$AR->superClass[$arType]=$arSuper;
220 8
						}
221 184
						$arType=$arSuper;
222 4
					}
223 184
				}
224
			}
225 4
		}
226 184
		array_pop($ARCurrent->arCallStack);
227 184
		$this->popContext();
228 184
		debug("pobject: call: end","all","all","OUT");
229 184
		if (isset($ARCurrent->arResult)) {
230
			// pinp templates can return results via putvar("arResult",$result);
231 20
			$arResult=$ARCurrent->arResult;
232 20
			unset($ARCurrent->arResult);
233 20
		}
234 184
		if (isset($arResult)) {
235
			// only do a return if we really have something to return
236 184
			return $arResult;
237
		}
238 24
	}
239
240 4
	public function ls($path="", $function="list.html", $args="") {
241 4
		$path=$this->store->make_path($this->path, $path);
242 4
		return $this->store->call($function, $args, $this->store->ls($path));
243 4
	}
244
245 56
	public function get($path, $function="view.html", $args="") {
246 56
		$path=$this->store->make_path($this->path, $path);
247 56
		return $this->store->call($function, $args, $this->store->get($path));
248 4
	}
249
250 8
	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 4
		if (!$top) {
254 8
			$top = $this->currentsection();
255 4
		} else {
256 8
			$top = $this->store->make_path($this->path, $top);
257
		}
258
259 4
		$path=$this->store->make_path($this->path, $path);
260
261 4
		if ($path != $this->path ) {
262 4
			$target = current($this->get($path,"system.get.phtml"));
263 4
		} else {
264 4
			$target = $this;
265
		}
266
267 4
		$parents = array();
268 4
		if (strpos($target->path, $top) === 0) {
269 4
			$parents[] = $target;
270 4
			while ($target && $target->path != $top) {
271 4
				$target = current($target->get($target->parent, "system.get.phtml"));
272 4
				$parents[] = $target;
273 8
			}
274 4
		}
275 4
		$parents = array_reverse($parents);
276 4
		$result = array();
277 8
		foreach ($parents as $parent) {
278 4
			if ( $parent ) { // might not have read access to this object
279 4
				$result[] = $parent->call($function, $args);
280 4
			}
281 4
		}
282
283 4
		return $result;
284
	}
285
286 4
	public function find($path, $criteria, $function="list.html", $args="", $limit=100, $offset=0) {
287 4
		$path = $this->store->make_path($this->path, $path);
288 4
		$objects = $this->store->find($path, $criteria, $limit, $offset);
289 4
		if (!$this->store->error) {
290 4
			$result = $this->store->call($function, $args, $objects);
291 4 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 4
		}
295 4
		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 4
	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 4
							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 4
										&& "'".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 4
						}
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 48
	private function saveCustomData($configcache, $properties) {
352 48
		$custom = $this->getdata("custom", "none");
353 48
		@parse_str($custom);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
354 48
		if (is_array($custom)) {
355
			foreach($custom as $nls=>$entries){
356
				if (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 48
		$i=0;
368 48
		if (is_array($this->data->custom)) {
369
			foreach($this->data->custom as $nls => $cdata) {
370
				foreach($cdata as $name => $value){
371
					// one index, this order (name, value, nls) ?
372
					if ($configcache->custom[$name]['containsHTML']) {
373
						$this->_load('mod_url.php');
374
						$value = URL::RAWtoAR($value, $nls);
375
						$this->data->custom[$nls][$name] = $value;
376
					}
377
					if ($configcache->custom[$name]['property']) {
378
						if (is_array($value)) {
379
							foreach($value as $valkey => $valvalue ) {
380
								$properties["custom"][$i]["name"]=$name;
381
								$properties["custom"][$i]["value"]=$valvalue;
382
								$properties["custom"][$i]["nls"]=$nls;
383
								$i++;
384
							}
385
						} else {
386
							$properties["custom"][$i]["name"]=$name;
387
							$properties["custom"][$i]["value"]=$value;
388
							$properties["custom"][$i]["nls"]=$nls;
389
							$i++;
390
						}
391
					}
392
				}
393
			}
394
		}
395 48
		return $properties;
396
	}
397
398 52
	public function save($properties="", $vtype="") {
399
	/***********************************************************************
400
	  save the current object.
401
	  if this is a new object ($this->arIsNewObject) the path is checked and
402
	  the object is saved under the new path.
403
	***********************************************************************/
404 48
	global $AR, $ARnls, $ARCurrent;
405 48
		debug("pobject: save([properties], $vtype)","object");
406 48
		debug("pobject: save: path=".$this->path,"object");
407 48
		$configcache=$this->loadConfig();
408 48
		$needsUnlock = false;
409 48
		$arIsNewObject = false;
410 48
		$result = false;
411 48
		$this->error = '';
412 48
		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...
413 24
			debug("pobject: save: new object","all");
414 24
			$this->path = $this->make_path();
415 24
			$arNewParent=$this->make_path("..");
416 24
			$arNewFilename=basename($this->path);
417 24
			$arIsNewObject = true;
418 24
			if (preg_match("|^[a-z0-9_\{\}\.\:-]+$|i",$arNewFilename)) { // no "/" allowed, these will void the 'add' grant check.
419 24
				if (!$this->exists($this->path)) { //arNewFilename)) {
420 24
					if ($this->exists($arNewParent)) {
421 24
						if (!$config = $this->data->config) {
422 24
							$config=new object();
423 24
						}
424 24
					} else {
425
						$this->error = ar::error( sprintf($ARnls["err:noparent"],$arNewParent), 1102);
426
					}
427 24
				} else {
428
					$this->error = ar::error( sprintf($ARnls["err:alreadyexists"],$arNewFilename), 1103);
429
				}
430 24
			} else {
431
				$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$arNewFilename), 1104);
432
			}
433 24
		} else { // existing object
434 48
			debug("pobject: save: existing object","all");
435 48
			if ($this->exists($this->path)) { // prevent 'funny stuff'
436 48
				if (!$this->lock()) {
437
					$this->error = ar::error( $ARnls["err:objectalreadylocked"], 1105);
438
				} else {
439 48
					$needsUnlock = true;
440 48
					$config = $this->data->config;
441
				}
442 48
			} else {
443
				$this->error = ar::error($ARnls["err:corruptpathnosave"], 1106);
444
			}
445
		}
446
		// pre checks done
447
		// return now on error
448 48
		if ($this->error) {
449
			return $result;;
450
		}
451
452
453 48
		if ($ARCurrent->arCallStack) {
454 48
			$arCallArgs = end($ARCurrent->arCallStack);
455 48
		} else {
456 20
			$arCallArgs = array();
457
		}
458
459 48
		$context = $this->getContext();
460
461 48
		$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...
462 48
		if ( $arIsNewObject) {
463 24
			$wf_object->arIsNewObject=$arIsNewObject;
464 24
		}
465
466
		// 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
467 48
		$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $wf_object));
468
469 48
		$eventData = new object();
470 48
		$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...
471 48
		$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...
472 48
		$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...
473 48
		$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...
474 48
		$eventData = ar_events::fire( 'onbeforesave', $eventData );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
475
476
		// pop the wf_object, not needed later, the extra scope might hinder other code
477 48
		$this->popContext();
478
479 48
		if ( !$eventData ) {
480
			return false; // prevent saving of the object.
481
		}
482
483
		// arguments can be altered by event handlers, only usefull when a workflow template is also defined
484 48
		$arCallArgs = $eventData->arCallArgs;
485
486
		// the properties from the eventData are the new property list
487
		// no need to merge them with $properties, just manipulate the properties array directly
488
		// in the event data. unlike the user.workflow.pre.html template
489 48
		if ( is_array( $eventData->arProperties ) ) {
490 48
			$properties = $eventData->arProperties;
491 50
		} else {
492 44
			$properties = array();
493
		}
494
495
		// pass the current properties list to the workflow template
496
		// for backwards compatibility and workflow templates that just
497
		// returned only their own properties, merge them afterwards
498
		// don't do this for the eventData arProperties!
499 48
		$arCallArgs['properties'] = $properties;
500 48
		$wf_result = $wf_object->call("user.workflow.pre.html", $arCallArgs);
501
		/* merge workflow properties */
502 50
		if ( is_array($wf_result) ){
503
			$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
504
		}
505
506 48
		$this->error = $wf_object->error;
507 48
		$this->priority = $wf_object->priority;
508 48
		$this->data = $wf_object->data;
509 48
		$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...
510 48
		$this->data->mtime=time();
511 48
		if($arIsNewObject) {
512 24
			$this->data->ctime=$this->data->mtime;
513 24
		}
514
515 48
		$this->data->muser=$AR->user->data->login;
516 48
		if( !$this->data->config->owner ) {
517 24
			if( !$this->data->config->owner_name) {
518 24
				$this->data->config->owner_name=$AR->user->data->name;
519 24
			}
520 24
			$this->data->config->owner=$AR->user->data->login;
521 24
			$properties["owner"][0]["value"]=$this->data->config->owner;
522 24
		}
523 48
		$properties["time"][0]["ctime"]=$this->data->ctime;
524 48
		$properties["time"][0]["mtime"]=$this->data->mtime;
525 48
		$properties["time"][0]["muser"]=$this->data->muser;
526
527
		/* save custom data */
528 48
		$properties = $this->saveCustomData($configcache, $properties);
529
530 48
		if (!$this->error) {
531 48
			if ($this->path=$this->store->save($this->path, $this->type, $this->data, $properties, $vtype, $this->priority)) {
532 48
				unset($this->arIsNewObject);
533 48
				$this->id=$this->exists($this->path);
534 48
				$result=$this->path;
535
536 48
				$config=$this->data->config; // need to set it again, to copy owner config data
537
538 48
				$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
539 48
				$arCallArgs = $eventData->arCallArgs; // returned from onbeforesave event
540 48
				$arCallArgs['properties'] = $properties;
541
542 48
				if ($arIsNewObject) {
543 24
					$wf_object->arIsNewObject = $arIsNewObject;
544 24
				}
545 48
				$wf_result = $wf_object->call("user.workflow.post.html", $arCallArgs);
546 48
				$this->error = $wf_object->error;
547 48
				$this->priority = $wf_object->priority;
548 48
				$this->data = $wf_object->data;
549 48
				$this->data->config = $config;
550
				/* merge workflow properties */
551
552 48
				if ( is_array($wf_result) ){
553
					$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
554
555
					if (!$this->store->save($this->path, $this->type, $this->data, $properties, $this->vtype, $this->priority)) {
556
						$this->error = ar::error( ''.$this->store->error, 1108, $this->store->error);
557
						$result = false;
558
					}
559
				}
560
				// all save actions have been done, fire onsave.
561 48
				$this->data->config = $config;
562
563
				//$this->ClearCache($this->path, true, false);
0 ignored issues
show
Unused Code Comprehensibility introduced by
74% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
564 48
				$eventData->arProperties = $properties;
565 48
				$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this));
566 48
				ar_events::fire( 'onsave', $eventData ); // nothing to prevent here, so ignore return value
567 48
				$this->popContext();
568 48 View Code Duplication
			} else {
569
				$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
570
				$result = false;
571
			}
572 48
		}
573 48
		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...
574 48
			$this->unlock();
575 48
		}
576
577 48
		if ($this->data->nls->list[$this->nls]) {
578 48
			$mynlsdata=$this->data->{$this->nls};
579 48
		} else if ($this->data->nls->default) {
580
			$mynlsdata=$this->data->{$this->data->nls->default};
581
		} else {
582
			$mynlsdata=$this->data;
583
		}
584
585 48
		unset($this->nlsdata);
586 48
		$this->nlsdata=$mynlsdata;
587
588 48
		debug("pobject: save: end","all");
589 48
		return $result;
590
	}
591
592
	public function link($to) {
593
		return $this->store->link($this->path, $this->make_path($to));
594
	}
595
596
	public function delete() {
597
	global $ARCurrent;
598
		$result	= false;
599
		$this->error = '';
600
		if ($ARCurrent->arCallStack) {
601
			$arCallArgs = end($ARCurrent->arCallStack);
602
		} else {
603
			$arCallArgs = array();
604
		}
605
		$context = $this->getContext();
606
607
		$eventData = new object();
608
		$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...
609
		$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...
610
		$eventData = ar_events::fire( 'onbeforedelete', $eventData );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

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

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
737 48
				$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...
738
			}
739
		}
740 52
		return $url;
741
	}
742
743 52
	protected function compare_hosts($url1, $url2) {
744
		// Check if hosts are equal, so that http://www.muze.nl and //www.muze.nl also match.
745
		// using preg_replace instead of parse_url() because the latter doesn't parse '//www.muze.nl' correctly.
746 52
		if (is_array($url2)) {
747
			foreach ($url2 as $url) {
748
				if ($this->compare_hosts($url1, $url)) {
749
					return true;
750
				}
751
			}
752
			return false;
753
		}
754
755
		return (
756 52
			($url1 == $url2) ||
757 52
			(preg_replace('|^[a-z:]*//|i', '', $url1) == preg_replace('|^[a-z:]*//|i', '', $url2))
758 52
		);
759
	}
760
761 48
	public function make_local_url($path="", $nls=false, $session=true, $https=null) {
762 48
		global $ARCurrent, $ARConfig;
763 48
		$site = false;
764 48
		$path = $this->make_path($path);
765 48
		$checkpath = $path;
766
767 48
		$redirects = $ARCurrent->shortcut_redirect;
768 48
		if (is_array($redirects)) {
769
			$newpath = $checkpath;
770
			$c_redirects = count($redirects);
771
			$c_redirects_done = 0;
772 View Code Duplication
			while (count($redirects) && ($redir = array_pop($redirects)) && $redir['keepurl'] && substr($newpath, 0, strlen($redir['dest'])) == $redir['dest']) {
773
				$c_redirects_done++;
774
				$newpath = $redir['src'].substr($newpath, strlen($redir['dest']));
775
			}
776
777
			if ($c_redirects_done == $c_redirects) {
778
				$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...
779
			}
780
		}
781
782
		do {
783 48 View Code Duplication
			if (!$config=$ARConfig->cache[$checkpath]) {
784
				$config=($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
785
			}
786 48
			if ($config) {
787 48
				$checkNLS = $nls;
788 48
				if (!$checkNLS) {
789
					$checkNLS = $this->nls;
790
				}
791 48
				$urlCheck = $config->root['list']['nls'][$checkNLS];
792 48
				if (!is_array($urlCheck)) {
793 48
					$urlCheck = $config->root["value"];
794 48
				}
795 48
				$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...
796
797 48
				if ($this->compare_hosts($requestedHost, $urlCheck)) {
798
					$site=$config->site;
799
				}
800 48
			}
801 48
			$prevpath=$checkpath;
802 48
			$checkpath=$this->make_path($checkpath."../");
803 48
		} while ($prevpath!=$checkpath && !$site);
804 48
		if (!$site) {
805 48
			$site='/';
806 48
		}
807 48
		$site_url=$this->make_url($site, $nls, $session, $https, true);
808 48
		if ($newpath) { // $newpath is the destination of a shortcut redirection, with keepurl on
809
			$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...
810
		} else {
811 48
			$rest=substr($path, strlen($site));
812
		}
813 48
		return $site_url.$rest;
814
	}
815
816
	public function AR_implements($implements) {
817
		$type = current(explode(".",$this->type));
818
		return $this->store->AR_implements($type, $implements);
819
	}
820
821 View Code Duplication
	public function getlocks() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
822
		global $AR;
823
		if ($this->store->mod_lock) {
824
			$result=$this->store->mod_lock->getlocks($AR->user->data->login);
825
		} else {
826
			$result="";
827
		}
828
		return $result;
829
	}
830
831 48 View Code Duplication
	public function lock($mode="O", $time=0) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
832 48
	global $AR;
833 48
		if ($this->store->mod_lock) {
834 48
			$result=$this->store->mod_lock->lock($AR->user->data->login,$this->path,$mode,$time);
835 48
		} else {
836
			$result=true; // no lock module, so lock is 'set'
837
		}
838 48
		return $result;
839
	}
840
841 48 View Code Duplication
	public function unlock() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
842 48
	global $AR;
843 48
		if ($this->store->mod_lock) {
844 48
			$result=$this->store->mod_lock->unlock($AR->user->data->login,$this->path);
845 48
		} else {
846
			$result=true;
847
		}
848 48
		return $result;
849
	}
850
851
	public function touch($id=0, $timestamp=-1) {
852
		if (!$id) {
853
			$id = $this->id;
854
		}
855
		$result = $this->store->touch($id, $timestamp);
856 View Code Duplication
		if ($this->store->error) {
857
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
858
		}
859
		return $result;
860
	}
861
862
	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...
863
		if (!$id) {
864
			$id = $this->id;
865
		}
866
		if (!$vtype) {
867
			$vtype = $type;
868
		}
869
		if (strpos($vtype, '.')!==false) {
870
			$vtype = substr($vtype, 0, strpos($vtype, '.'));
871
		}
872
		$result = $this->store->mogrify($id, $type, $vtype);
873 View Code Duplication
		if ($this->store->error) {
874
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
875
		}
876
		return $result;
877
	}
878
879
	public function can_mogrify() {
880
		if ($this->path == "/system/users/admin/") {
881
			return false;
882
		}
883
		return true;
884
	}
885
886
	public function load_properties($scope='') {
887
		return $this->store->load_properties($this->id,'',$scope);
888
	}
889
890
	public function _load_properties($scope='') {
891
		return $this->store->load_properties($this->id,'',$scope);
892
	}
893
894
	public function load_property($property, $scope='') {
895
		return $this->store->load_property($this->id,$property,$scope);
896
	}
897
898
	public function _load_property($property, $scope='') {
899
		return $this->store->load_property($this->id,$property,$scope);
900
	}
901
902 4
	public function GetValidGrants($path="") {
903
	/********************************************************************
904
905
	  This function finds all grants in effect on this object for the
906
	  logged in user! $AR->user must already be set.
907
908
	  Grants are checked in the following way:
909
	  1) First all parents of this object are checked for grants for this
910
	     specific user. The 'nearest' grants are valid, and the path of
911
	     parent that set these grants will be the upper limit for the
912
	     checking of group grants.
913
	  2) Now all groups of which the user is a member are checked for
914
	     grants. Likewise, all parents are checked for group grants, upto
915
	     but not including the upperlimit as set in 1. All group grants
916
	     found are merged into one grants list.
917
	  3) If there are gropup grants, this means that there are group
918
	     grants set in a parent nearer to this object than the user grants
919
	     and therefore the groupgrants must be merged with the
920
	     usergrants.
921
922
	  this results in:
923
	  1	/		user: read edit		group: none
924
	  2	/dir/					group: read
925
	  3	/dir2/		user: none		group: read
926
	  4	/dir/dir3/				group2: edit
927
	  case 1: the user takes precedence over the group, grants are 'read edit'
928
	  case 2: groupgrants are merged with usergrants, as its grants are set
929
	          in a 'nearer' parent (itself). grants are 'read edit'.
930
	  case 3: user takes precedence again. grants are 'none'.
931
	  case 4: All group grants are merged with the usergrants.
932
	          Therefore the grants are 'none read edit'.
933
	********************************************************************/
934
935 4
	global $AR;
936
937 4
		if ($AR->user) { 	// login and retrieval of user object
938 4
			if (!$path) {
939 4
				$path=$this->path;
940 4
			}
941 4
			if (!$AR->user->grants[$path]) {
942 4
				$grants=array();
943 4
				$userpath=$AR->user->FindGrants($path, $grants);
944
				// if not already done, find all groups of which the user is a member
945 4
				if (!is_array($AR->user->externalgroupmemberships) || count($AR->user->externalgroupmemberships)==0) {
946 4
					$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...
947 4
				} else {
948
					// Use the group memberships of external databases (e.g. LDAP)
949
					$criteria="members.login='".AddSlashes($AR->user->data->login)."'";
950
					foreach (array_keys($AR->user->externalgroupmemberships) as $group) {
951
						$criteria.=" or login.value='".AddSlashes($group)."'";
952
					}
953
				}
954 4
				if (!$AR->user->groups) {
955 4
					$groups=$this->find("/system/groups/",$criteria, "system.get.phtml");
956 4
					if (is_array($groups)) {
957 4
						foreach($groups as $group ){
958 4
							if (is_object($group)) {
959 4
								$AR->user->groups[$group->path] = $group;
960 4
							}
961 4
						}
962 4
					}
963 4
					if (is_array($AR->user->data->config->groups)) {
964 4
						foreach ($AR->user->data->config->groups as $groupPath => $groupId) {
965 4
							if (!$AR->user->groups[$groupPath]) {
966
								$AR->user->groups[$groupPath] = current($this->get($groupPath, "system.get.phtml"));
967
							}
968 4
						}
969 4
					}
970 4
					if (!$AR->user->groups["/system/groups/public/"]) {
971
						if ($public=current($this->get("/system/groups/public/", "system.get.phtml"))) {
972
							$AR->user->groups[$public->path] = $public;
973
						}
974
					}
975 4
				}
976 4
				if ($AR->user->groups) {
977
					/* check for owner grants (set by system.get.config.phtml) */
978 4
					if (is_array($AR->user->ownergrants)) {
979
						if (!$AR->user->groups["owner"]) {
980
							$AR->user->groups["owner"] = @current($this->get("/system/groups/owner/", "system.get.phtml"));
981
						}
982
						$AR->user->groups["owner"]->data->config->usergrants = $AR->user->ownergrants;
983
					}
984 4
					foreach($AR->user->groups as $group){
985 4
						$groupgrants=array();
986 4
						if (is_object($group)) {
987 4
							$group->FindGrants($path, $groupgrants, $userpath);
988 4 View Code Duplication
							if (is_array($grants)) {
989 4
								foreach($groupgrants as $gkey => $gval ){
990
									if (is_array($grants[$gkey]) && is_array($gval)) {
991
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
992
									} else
993
									if ($gval && !is_array($gval)) {
994
										$grants[$gkey] = $gval;
995
									} else
996
									if ($gval && !$grants[$gkey]) {
997
										$grants[$gkey] = $gval;
998
									}
999 4
								}
1000 4
							} else {
1001
								$grants = $groupgrants;
1002
							}
1003 4
						}
1004 4
					}
1005 4
				}
1006 4
				if( is_array($AR->sgGrants) ) {
1007
					ksort($AR->sgGrants);
1008
					$ppath = $this->make_path($path);
1009
					foreach( $AR->sgGrants as $sgpath => $sggrants) {
1010
						$sgpath = $this->make_path($sgpath);
1011
						if( substr($ppath, 0, strlen($sgpath)) == $sgpath ) { // sgpath is parent of ppath or equal to ppath
1012 View Code Duplication
							if (is_array($grants)) {
1013
								foreach($sggrants as $gkey => $gval ){
1014
									if (is_array($grants[$gkey]) && is_array($gval)) {
1015
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
1016
									} else
1017
									if ($gval && !is_array($gval)) {
1018
										$grants[$gkey] = $gval;
1019
									} else
1020
									if ($gval && !$grants[$gkey]) {
1021
										$grants[$gkey] = $gval;
1022
									}
1023
								}
1024
							} else {
1025
								$grants = $sggrants;
1026
							}
1027
						}
1028
					}
1029
				}
1030 4
				$AR->user->grants[$path]=$grants;
1031 4
			}
1032 4
			$grants=$AR->user->grants[$path];
1033
1034 4
		}
1035 4
		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...
1036 4
		return $grants;
1037
	}
1038
1039
1040 184
	public function pushContext($context) {
1041 184
	global $AR;
1042 184
		if (!$AR->context) {
1043 184
			$AR->context = array();
1044 184
		} else {
1045 72
			$context = array_merge(end($AR->context), $context);
1046
		}
1047 184
		array_push($AR->context, $context);
1048 184
	}
1049
1050
	public function setContext($context, $level=0) {
1051
	global $AR;
1052 View Code Duplication
		if (is_array($AR->context)) {
1053
			$AR->context[count($AR->context)-(1+$level)]=$context;
1054
		}
1055
	}
1056
1057 184
	public function popContext() {
1058 184
	global $AR;
1059 184
		if (is_array($AR->context)) {
1060 184
			$result = array_pop($AR->context);
1061 184
		}
1062 184
		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...
1063
	}
1064
1065 184
	public static function getContext($level=0) {
1066 184
	global $AR;
1067 184 View Code Duplication
		if (is_array($AR->context)) {
1068 184
			$result = $AR->context[count($AR->context)-(1+$level)];
1069 184
		}
1070 184
		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...
1071
	}
1072
1073 72
	public function CheckAdmin($user) {
1074 72
		if ($user->data->login == "admin") {
1075 68
			return true;
1076
		}
1077 4
		if ($user->data->groups['/system/groups/admin/']) {
1078
			return true;
1079
		}
1080 4
		return false;
1081
	}
1082
1083 60
	public function CheckLogin($grant, $modifier=ARTHISTYPE) {
1084 60
	global $AR,$ARnls,$ARConfig,$ARCurrent,$ARConfigChecked;
1085 60
		if (!$this->store->is_supported("grants")) {
1086
			debug("pobject: store doesn't support grants");
1087
			return true;
1088
		}
1089 60
		if ($modifier==ARTHISTYPE) {
1090 60
			$modifier=$this->type;
1091 60
		}
1092
1093
		/* load config cache */
1094 60
		if (!isset($ARConfig->cache[$this->path])) {
1095
			// since this is usually run before CheckConfig, make sure
1096
			// it doesn't set cache time
1097
			$realConfigChecked = $ARConfigChecked;
1098
			$ARConfigChecked = true;
1099
			$this->loadConfig();
1100
			$ARConfigChecked = $realConfigChecked;
1101
		}
1102
1103 60
		$isadmin = $this->CheckAdmin($AR->user);
1104
1105 60
		if (!$isadmin && !$AR->user->grants[$this->path]) {
1106
			$AR->user->grants[$this->path]=$this->GetValidGrants();
1107
		}
1108 60
		if ($AR->user->data->login!="public") {
1109
			// Don't remove this or MSIE users won't get uptodate pages...
1110 60
			ldSetClientCache(false);
1111 60
		}
1112
1113 60
		$grants=$AR->user->grants[$this->path];
1114 60
		if ( 	( !$grants[$grant]
1115 60
					|| ( $modifier && is_array($grants[$grant]) && !$grants[$grant][$modifier] )
1116 60
				) && !$isadmin ) {
1117
			// do login
1118
			$arLoginMessage = $ARnls["accessdenied"];
1119
			ldAccessDenied($this->path, $arLoginMessage);
1120
			$result=false;
1121
		} else {
1122 60
			$result=($grants || $isadmin);
1123
		}
1124
1125 60
		$ARCurrent->arLoginSilent=1;
1126 60
		return $result;
1127
	}
1128
1129
1130 4
	public function CheckPublic($grant, $modifier=ARTHISTYPE) {
1131 4
	global $AR;
1132
1133 4
		$result=false;
1134 4
		if (!$AR->public) {
1135 4
			$this->pushContext(array("scope" => "php"));
1136 4
				$AR->public=current($this->get("/system/users/public/", "system.get.phtml"));
1137 4
			$this->popContext();
1138 4
		}
1139 4
		if ($AR->public) {
1140 4
			$AR->private=$AR->user;
1141 4
			$AR->user=$AR->public;
1142 4
			$result=$this->CheckSilent($grant, $modifier);
1143 4
			$AR->user=$AR->private;
1144 4
		}
1145 4
		return $result;
1146
	}
1147
1148 44
	public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") {
1149 44
	global $AR, $ARConfig;
1150 44
		$path = $this->make_path($path);
1151 44
		if ($modifier==ARTHISTYPE) {
1152 44
			$modifier=$this->type;
1153 44
		}
1154
1155
		/* load config cache */
1156 44
		if (!$ARConfig->cache[$path]) {
1157 8
			$this->loadConfig($path);
1158 8
		}
1159 44
		if ($this->CheckAdmin($AR->user)) {
1160 40
			$result=1;
1161 44
		} else if ($grants=$AR->user->grants[$path]) {
1162
			$result=$grants[$grant];
1163
		} else {
1164 4
			$grants=$this->GetValidGrants();
1165 4
			$result=$grants[$grant];
1166
		}
1167 44
		if ($modifier && is_array($result)) {
1168
			$result=$result[$modifier];
1169
		}
1170 44
		return $result;
1171
	}
1172
1173
	public function CheckNewFile($newfilename) {
1174
	global $ARnls;
1175
	/**********************************************************************
1176
1177
	  This function performs all the necessary checks on a path to see
1178
	whether it's a valid path for a new object. This consists of:
1179
	1) checking for invalid characters, valid chars are "a-zA-Z0-9./_-"
1180
	2) checking whether the path starts and ends with a "/".
1181
	3) checking whether the path doesn't exist already.
1182
	4) checking whether the parent exists.
1183
1184
	if all this checks out, it returns 1. If not, $this->error is set to
1185
	the correct error message.
1186
1187
	**********************************************************************/
1188
1189
		$this->error="";
1190
		if (preg_match("|^/[a-z0-9\./_-]*/$|i",$newfilename)) {
1191
			if (!$this->store->exists($newfilename)) {
1192
				$parent=$this->store->make_path($newfilename, "..");
1193
				if ($this->store->exists($parent)) {
1194
					$result=1;
1195
				} else {
1196
					$this->error = ar::error( sprintf($ARnls["err:filenameinvalidnoparent"],$newfilename,$parent), 1102);
1197
				}
1198
			} else {
1199
				$this->error = ar::error( sprintf($ARnls["err:chooseotherfilename"],$newfilename), 1103);
1200
			}
1201
		} else {
1202
			$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$newfilename)." ".$ARnls["err:startendslash"], 1104);
1203
		}
1204
		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...
1205
	}
1206
1207 View Code Duplication
	public function resetConfig($path='') {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1208
	global $ARConfig;
1209
		$path = $this->make_path($path);
1210
		if ($ARConfig->cache[$path]) {
1211
			$path = preg_quote($path,'/');
1212
			$keys = preg_grep('/^'.$path.'/',array_keys($ARConfig->cache));
1213
			foreach ($keys as $cachepath) {
1214
				unset($ARConfig->cache[$cachepath]);
1215
				unset($ARConfig->pinpcache[$cachepath]);
1216
			}
1217
		}
1218
	}
1219
1220 36 View Code Duplication
	public function clearChildConfigs($path='') {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
1221 36
	global $ARConfig;
1222 36
		$path = $this->make_path($path);
1223 36
		if ($ARConfig->cache[$path]) {
1224 36
			$path = preg_quote($path,'/');
1225 36
			$keys = preg_grep('/^'.$path.'./',array_keys($ARConfig->cache));
1226 36
			foreach($keys as $cachepath) {
1227 4
				unset($ARConfig->cache[$cachepath]);
1228 4
				unset($ARConfig->pinpcache[$cachepath]);
1229 4
				unset($ARConfig->libraries[$cachepath]);
1230 36
			}
1231 36
		}
1232 36
	}
1233
1234 36
	protected function getConfig() {
1235 36
	global $ARConfig, $ARCurrent, $ARConfigChecked;
1236
		// $context=$this->getContext(0);
0 ignored issues
show
Unused Code Comprehensibility introduced by
70% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1237
		// debug("getConfig(".$this->path.") context: ".$context['scope'] );
0 ignored issues
show
Unused Code Comprehensibility introduced by
62% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1238
		// debug(print_r($ARConfig->nls, true));
0 ignored issues
show
Unused Code Comprehensibility introduced by
65% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1239 36
		if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) {
1240 4
			$parent = current($this->get($this->parent, "system.get.phtml"));
1241 4
			if ($parent) {
1242 4
				$parent->getConfig();
1243 4
			}
1244 4
		}
1245
1246 36
		$this->getConfigData();
1247
1248 36
		$ARConfig->pinpcache[$this->path] = $ARConfig->pinpcache[$this->parent];
1249
		// backwards compatibility when calling templates from config.ini
1250 36
		$prevArConfig = $ARCurrent->arConfig;
1251 36
		$ARCurrent->arConfig = $ARConfig->pinpcache[$this->path];
1252
1253 36
		$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...
1254
1255
		/* calling config.ini directly for each system.get.config.phtml call */
1256 36
		$loginSilent = $ARCurrent->arLoginSilent;
1257 36
		$ARCurrent->arLoginSilent = true;
1258
		// debug("getConfig:checkconfig start");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1259
1260 36
		$initialNLS = $ARCurrent->nls;
1261 36
		$initialConfigChecked = $ARConfigChecked;
1262
1263 36
		$ARConfig->cache[$this->path]->inConfigIni = true;
1264 36
		if ($ARConfig->cache[$this->path]->hasConfigIni && !$this->CheckConfig('config.ini', $arCallArgs)) {
0 ignored issues
show
Documentation introduced by
$arCallArgs is of type array<string,?,{"arConfig":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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...
1265
			//debug("pobject::getConfig() loaded config.ini @ ".$this->path);
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1266
			// debug("getConfig:checkconfig einde");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1267 4
			$arConfig = $ARCurrent->arResult;
1268 4
			if (!isset($arConfig)) {
1269
				$arConfig = $ARCurrent->arConfig;
1270
			}
1271 4
			unset($ARCurrent->arResult);
1272 4
			if (is_array($arConfig['library'])) {
1273
				if (!$ARConfig->libraries[$this->path]) {
1274
					$ARConfig->libraries[$this->path] = array();
1275
				}
1276
				foreach ($arConfig['library'] as $libName => $libPath) {
1277
					$this->loadLibrary($libName, $libPath);
1278
				}
1279
				unset($arConfig['library']);
1280
			}
1281 4
			$ARConfig->pinpcache[$this->path] = (array) $arConfig;
1282 4
		}
1283 36
		$ARConfig->cache[$this->path]->inConfigIni = false;
1284 36
		$this->clearChildConfigs( $this->path ); // remove any config data for child objects, since these are set before their parent config was set
1285 36
		$ARConfigChecked = $initialConfigChecked;
1286 36
		$ARCurrent->nls = $initialNLS;
1287
1288 36
		$arConfig = &$ARConfig->pinpcache[$this->path];
1289 36 View Code Duplication
		if (!is_array($arConfig['authentication']['userdirs'])) {
1290
			$arConfig['authentication']['userdirs'] = array('/system/users/');
1291
		} else {
1292 36
			if (reset($arConfig['authentication']['userdirs']) != '/system/users/') {
1293
				array_unshift($arConfig['authentication']['userdirs'], '/system/users/');
1294
			}
1295
		}
1296 36 View Code Duplication
		if (!is_array($arConfig['authentication']['groupdirs'])) {
1297
			$arConfig['authentication']['groupdirs'] = array('/system/groups/');
1298
		} else {
1299 36
			if (reset($arConfig['authentication']['groupdirs']) != '/system/groups/') {
1300
				array_unshift($arConfig['authentication']['groupdirs'], '/system/groups/');
1301
			}
1302
		}
1303
1304 36
		$ARCurrent->arLoginSilent = $loginSilent;
1305 36
		$ARCurrent->arConfig = $prevArConfig;
1306 36
	}
1307
1308 36
	protected function getConfigData() {
1309 36
	global $ARConfig, $AR;
1310 36
		$context = $this->getContext(0);
1311 36
		if (!$ARConfig->cache[$this->path] && $context["scope"] != "pinp") {
1312
			// first inherit parent configuration data
1313 36
			$configcache= clone $ARConfig->cache[$this->parent];
1314 36
			unset($configcache->localTemplates);
1315
			// cache default templates
1316 36
			if (isset($this->data->config->templates) && count($this->data->config->templates)) {
1317
				$configcache->templates=&$this->data->config->templates;
1318
			}
1319 36
			if (isset($this->data->config->privatetemplates) && count($this->data->config->privatetemplates)) {
1320
				$configcache->privatetemplates=&$this->data->config->privatetemplates;
1321
			}
1322
1323
			// Speedup check for config.ini
1324
1325 36 View Code Duplication
			if( !$configcache->hasDefaultConfigIni ) {
1326 36
				if( is_array($this->data->config->templates) ) {
1327 4
					foreach($this->data->config->templates as $type => $templates ) {
1328
						if( isset($templates["config.ini"]) ) {
1329
							$configcache->hasDefaultConfigIni = true;
1330
							$configcache->hasConfigIni = true;
1331
							break;
1332
						}
1333 4
					}
1334 4
				}
1335 36
			}
1336
1337 36
			if (is_array($this->data->config->templates)) {
1338 4
				$configcache->localTemplates = $this->data->config->templates;
1339 4
			}
1340
			// hasConfigIni is checked in getConfig. Only calls config.ini if set to true
1341
1342 36 View Code Duplication
			if( !$configcache->hasDefaultConfigIni ) {
1343 36
				$configcache->hasConfigIni = false;
1344 36
				if( is_array($this->data->config->pinp) ) {
1345 4
					foreach( $this->data->config->pinp as $type => $templates ) {
1346 4
						if( isset($templates["config.ini"]) ) {
1347 4
							$configcache->hasConfigIni = true;
1348 4
							break;
1349
						}
1350 4
					}
1351 4
				}
1352 36
			}
1353
1354 36
			$localcachesettings = $this->data->config->cacheSettings;
1355 36
			if (!is_array($localcachesettings) ){
1356 36
				$localcachesettings = array();
1357 36
			}
1358
1359 36
			if (!is_array($configcache->cacheSettings) ) {
1360
				$configcache->cacheSettings = array();
1361
			}
1362
1363 36
			if ($this->data->config->cacheconfig) { // When removing this part, also fix the setting below.
1364 4
				$configcache->cache=$this->data->config->cacheconfig;
1365 4
			}
1366
1367 36
			if (!isset($localcachesettings['serverCache']) && isset($this->data->config->cacheconfig)) {
1368 4
				$localcachesettings["serverCache"] = $this->data->config->cacheconfig;
1369 4
			}
1370
1371 36
			if ($localcachesettings['serverCache'] != 0 ) {
1372 4
				$localcachesettings['serverCacheDefault'] = $localcachesettings['serverCache'];
1373 4
			}
1374
1375 36
			$configcache->cacheSettings = $localcachesettings + $configcache->cacheSettings;
1376
1377
			// store the current object type
1378 36
			$configcache->type = $this->type;
1379
1380 36
			if ($this->data->config->typetree && ($this->data->config->typetree!="inherit")) {
1381
				$configcache->typetree=$this->data->config->typetree;
1382
			}
1383 36
			if (isset($this->data->config->nlsconfig->list)) {
1384 4
				$configcache->nls = clone $this->data->config->nlsconfig;
1385 4
			}
1386
1387 36
			if ($this->data->config->grants["pgroup"]["owner"]) {
1388
				$configcache->ownergrants = $this->data->config->grants["pgroup"]["owner"];
1389
			}
1390 36
			if (is_array($configcache->ownergrants)) {
1391
				if ($AR->user && $AR->user->data->login != 'public' && $AR->user->data->login === $this->data->config->owner) {
1392
					$ownergrants = $configcache->ownergrants;
1393
					if (is_array($ownergrants)) {
1394
						foreach( $ownergrants as $grant => $val ) {
1395
							$AR->user->ownergrants[$this->path][$grant] = $val;
1396
						}
1397
					}
1398
				}
1399
			}
1400
1401 36
			if (is_array($this->data->config->customconfig)) {
1402
				$configcache->custom=array_merge(is_array($configcache->custom)?$configcache->custom:array(), $this->data->config->customconfig);
1403
			}
1404 36
			$ARConfig->cache[$this->path]=$configcache;
1405
1406 36
		}
1407 36
	}
1408
1409 60
	public function loadConfig($path='') {
1410 60
	global $ARConfig, $ARConfigChecked, $ARCurrent;
1411 60
		$path=$this->make_path($path);
1412
		// debug("loadConfig($path)");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1413 60
		if (!isset($ARConfig->cache[$path]) ) {
1414 36
			$allnls = $ARCurrent->allnls;
1415 36
			$ARCurrent->allnls = true;
1416 36
			$configChecked = $ARConfigChecked;
1417 36
			if (($this->path == $path && !$this->arIsNewObject) || $this->exists($path)) {
1418 36
				$this->pushContext(array("scope" => "php"));
1419 36
				if( $this->path == $path ) {
1420
					// debug("loadConfig: currentpath $path ");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1421 36
					$this->getConfig();
1422 36
				} else {
1423
					//debug("loadConfig: get path $path ");
1424 4
					$cur_obj = current($this->get($path, "system.get.phtml"));
1425 4
					$cur_obj->getConfig();
1426
				}
1427 36
				$this->popContext();
1428 36
				$result=$ARConfig->cache[$path];
1429 36
			} else if ($path === '/') {
1430
				// special case: / doesn't exists in the store
1431
				$result=$ARConfig->cache['..'];
1432
			} else {
1433
				$parent=$this->make_path($path.'../');
1434
				if (!$ARConfig->cache[$parent]) {
1435
					$this->pushContext(array("scope" => "php"));
1436
					// debug("loadConfig: parent $parent");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1437
					$cur_obj = current($this->get($parent, "system.get.phtml"));
1438
					if( $cur_obj ) {
1439
						$cur_obj->getConfig();
1440
					}
1441
					$this->popContext();
1442
				}
1443
				$result=$ARConfig->cache[$parent];
1444
				$ARConfig->cache[ $path ] = $result;
1445
				$ARConfig->pinpcache[ $path ] = $ARConfig->pinpcache[ $parent ];
1446
			}
1447
			// restore old ARConfigChecked state
1448 36
			$ARConfigChecked = $configChecked;
1449 36
			$ARCurrent->allnls = $allnls;
1450 36
		} else {
1451
			// debug("loadConfig: exists $path ");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1452 48
			$result=$ARConfig->cache[$path];
1453
		}
1454 60
		return $result;
1455
	}
1456
1457
1458
	// TODO: look for a way to merge loadConfig and loadUserConfig into one function
1459
1460 12
	public function loadUserConfig($path='') {
1461 12
	global $ARConfig;
1462 12
		$path = $this->make_path($path);
1463 12
		$parent = $this->make_path($path.'../');
1464
1465 12
		if (!$ARConfig->cache[$path]) {
1466
			$this->loadConfig($path);
1467
		}
1468 12
		if (!$ARConfig->pinpcache[$path]) {
1469
			$config = $ARConfig->pinpcache[$parent];
1470
		} else {
1471 12
			$config = $ARConfig->pinpcache[$path];
1472
		}
1473 12
		return (array)$config;
1474
	}
1475
1476 48
	protected function getTemplateFromCache($path, $type, $function, &$arSuperContext) {
1477 48
	global $AR, $ARConfig;
1478 48
		$templatesList = $ARConfig->libraryCache[$path][$function];
1479 48
		if (!is_array($templatesList)) {
1480 48
			return false;
1481
		}
1482
		foreach ($templatesList as $checkpath => $templates) {
1483
			$arType = $type;
1484
			while ($arType!='ariadne_object') {
1485
//				echo "checking $i::$arType<br>\n";
1486
				if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType][$this->reqnls])) {
1487
					$arCallTemplate=$arType.".".$function.".".$this->reqnls;
1488
					$arCallTemplateName = $function;
1489
					$arCallTemplateNLS = $this->reqnls;
1490
					break 2;
1491 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType]['any'])) {
1492
					$arCallTemplate=$arType.".".$function.".any";
1493
					$arCallTemplateName = $function;
1494
					$arCallTemplateNLS = "any";
1495
					break 2;
1496
				} else {
1497
1498
					if (!($arSuper=$AR->superClass[$arType])) {
1499
						// no template found, no default.phtml found, try superclass.
1500
						if ($subcpos = strpos($arType, '.')) {
1501
							$arSuper = substr($arType, 0, $subcpos);
1502
						} else {
1503
							if (!class_exists($arType, false)) {
1504
								// the given class was not yet loaded, so do that now
1505
								$arTemp=$this->store->newobject('','',$arType,new object);
1506
							} else {
1507
								$arTemp=new $arType();
1508
							}
1509
							$arSuper=get_parent_class($arTemp);
1510
						}
1511
						$AR->superClass[$arType]=$arSuper;
1512
					}
1513
					$arType=$arSuper;
1514
				}
1515
			}
1516
		}
1517
1518
		$config = ($ARConfig->cache[$arTemplate["arLibraryLocalPath"]]) ? $ARConfig->cache[$arTemplate["arLibraryLocalPath"]] : $this->loadConfig($arTemplate["arLibraryLocalPath"]);
0 ignored issues
show
Bug introduced by
The variable $arTemplate 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...
1519
		$arPrivateTemplate = $config->privatetemplates[$arType][$function];
0 ignored issues
show
Bug introduced by
The variable $arType 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...
1520
1521
		return array(
1522
			"arTemplateId" => $arTemplate["arTemplateId"],
1523
			"arCallTemplate" => $arCallTemplate,
0 ignored issues
show
Bug introduced by
The variable $arCallTemplate 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...
1524
			"arCallType" => $type,
1525
			"arCallTemplateName" => $arCallTemplateName,
0 ignored issues
show
Bug introduced by
The variable $arCallTemplateName 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...
1526
			"arCallTemplateNLS" => $arCallTemplateNLS,
0 ignored issues
show
Bug introduced by
The variable $arCallTemplateNLS 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...
1527
			"arCallTemplateType" => $arType,
1528
			"arCallTemplatePath" => $arTemplate["arLibraryLocalPath"],
1529
			"arLibrary" => "current",
1530
			"arLibraryPath" => $arTemplate["arLibraryPath"],
1531
			"arPrivateTemplate" => $arPrivateTemplate
1532
		);
1533
	}
1534
1535
	public function loadLibraryCache($base, $path, $arLibraryPath = "") {
1536
	global $ARConfig;
1537
		if (!$arLibraryPath) {
1538
			$arLibraryPath = $path;
1539
		}
1540
		$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1541
		$templates = $config->localTemplates;
1542
		if (is_array($templates)) {
1543
			$list = array();
1544
			foreach ($templates as $type => $functions) {
1545
				foreach ($functions as $function => $template) {
1546
					foreach ($template as $nls => $templateId) {
1547
						$list[$function][$type][$nls] = array(
1548
								"arTemplateId" => $templateId,
1549
								"arLibraryPath" => $arLibraryPath,
1550
								"arLibraryLocalPath" => $path
1551
						);
1552
					}
1553
				}
1554
			}
1555
1556
			foreach ($list as $function => $types) {
1557
				if (!is_array($ARConfig->libraryCache[$base][$function])) {
1558
					$ARConfig->libraryCache[$base][$function] = array(
1559
						$path => $types
1560
					);
1561
				} else {
1562
					$ARConfig->libraryCache[$base][$function][$path] = $types;
1563
				}
1564
			}
1565
		}
1566
		list($basetype,) = explode('.', $config->type,2);
1567
		if ($path != '/' && $basetype != 'psection') {
1568
			$this->loadLibraryCache($base, $this->store->make_path($path, '../'), $arLibraryPath);
1569
		}
1570
	}
1571
1572 4
	public function loadLibrary($name, $path) {
1573 4
	global $ARConfig;
1574 4
		$path=$this->make_path($path);
1575 4
		debug("pobject::loadLibrary($name, $path);");
1576 4
		if ($name===ARUNNAMED) {
1577 4
			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...
1578
				return ar::error('You cannot load an unnamed library from a child object.', 1109);
1579
			} else {
1580 4
				if (!$ARConfig->libraries[$this->path]) {
1581 4
					$ARConfig->libraries[$this->path]=array();
1582 4
				}
1583 4
				array_unshift($ARConfig->libraries[$this->path],$path);
1584 4 View Code Duplication
				if (!$ARConfig->cacheableLibraries[$this->path]) {
1585 4
					$ARConfig->cacheableLibraries[$this->path] = array($path);
1586 4
				} else {
1587
					array_unshift($ARConfig->cacheableLibraries[$this->path], $path);
1588
				}
1589
			}
1590 4
		} else if ($name && is_string($name)) {
1591
			if (!$ARConfig->cache[$this->path]) {
1592
debug("loadLibrary: loading cache for $this->path");
1593
				$this->loadConfig($this->path);
1594
			}
1595
			$ARConfig->libraries[$this->path][$name]=$path;
1596
			$ARConfig->cache[$this->path]->libraries[$name]=$path;
1597
			$ARConfig->pinpcache[$this->path]["library"][$name] = $path;
1598
		} else if (is_int($name)) {
1599
			if (!$ARConfig->cache[$this->path]) {
1600
				$this->loadConfig($this->path);
1601
			}
1602
			$ARConfig->libraries[$this->path][$name]=$path;
1603 View Code Duplication
			if (!$ARConfig->cacheableLibraries[$this->path]) {
1604
				$ARConfig->cacheableLibraries[$this->path] = array($name => $path);
1605
			} else {
1606
				$ARConfig->cacheableLibraries[$this->path][$name] = $path;
1607
			}
1608
			// make sure that unnamed libraries don't get added to the configcache
1609
			unset($ARConfig->cache[$this->path]->libraries[$name]);
1610
			unset($ARConfig->pinpcache[$this->path]["library"][$name]);
1611
		} else {
1612
			return ar::error('Illegal library name: '.$name, 1110);
1613
		}
1614 4
	}
1615
1616
	// returns a list of libraries loaded on $path
1617
	public function getLibraries($path = '') {
1618
	global $ARConfig;
1619
		$path = $this->make_path($path);
1620
		return (array)$ARConfig->libraries[$path];
1621
	}
1622
1623
	public function mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1624
		$libraryName = ar::getvar('arLibrary');
1625
		if ( is_numeric($libraryName) || $libraryName == 'current' ) { // library is loaded unnamed
1626
			$libraryName = $defaultLibraryName;
1627
		}
1628
		if ( $libraryName ) {
1629
			$userConfig = ar::acquire('defaults.'.$libraryName);
1630
			if ( is_array($userConfig) ) {
1631
				$defaults = array_merge( $defaults, $userConfig );
1632
			}
1633
		}
1634
		return array_merge( $defaults, $this->getvar('arCallArgs') );
1635
	}
1636
1637
	public function _mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1638
		return $this->mergeLibraryConfig( $defaultLibraryName, $defaults );
1639
	}
1640
1641 60
	public function getPinpTemplate($arCallFunction='view.html', $path=".", $top="", $inLibrary = false, $librariesSeen = null, $arSuperContext=array()) {
1642 60
	global $ARCurrent, $ARConfig, $AR, $ARConfigChecked;
1643 60
		debug("getPinpTemplate: function: $arCallFunction; path: $path; top: $top; inLib: $inLibrary","class");
1644 60
		$result = array();
1645 60
		if (!$top) {
1646 60
			$top = '/';
1647 60
		}
1648 60
		$path = $this->make_path($path);
1649 60
		if (!is_array($arSuperContext)) {
1650
			$arSuperContext = array();
1651
		}
1652
1653 60
		if (($libpos=strpos($arCallFunction,":"))!==false && $libpos!==strpos($arCallFunction, "::")) {
1654
			// template of a specific library defined via call("library:template");
1655
			$arLibrary = substr($arCallFunction, 0, $libpos);
1656
			if ($arLibrary == 'current') {
1657
				// load the current arLibrary
1658
				$context = $this->getContext(1);
1659
				$arLibrary = $context['arLibrary'];
1660
				$arLibraryPath = $context['arLibraryPath'];
1661 View Code Duplication
			} else {
1662
				$config = (isset($ARConfig->cache[$path])) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1663
				$arLibraryPath = $config->libraries[$arLibrary];
1664
			}
1665
			$arCallFunction = substr($arCallFunction, $libpos+1);
1666
			if ($arLibraryPath) {
1667
				debug("getPinpTemplate: found library '$arLibrary'. Searching for $arCallFunction on '".$config->libraries[$arLibrary]."' up to '$top'");
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...
1668
				$librariesSeen[$arLibraryPath] = true;
1669
				$inLibrary = true;
1670
				$path = $arLibraryPath;
1671
			} else {
1672
				debug("getPinpTemplate: Failed to find library $arLibrary");
1673
				return false;
1674
			}
1675
			$path = $this->make_path($path);
1676
		}
1677 60
		if (strpos($arCallFunction,"::")!==false) {
1678
			// template of a specific class defined via call("class::template");
1679
			list($arCallType, $arCallFunction)=explode("::",$arCallFunction);
1680
		} else {
1681 60
			$arCallType=$this->type;
1682
		}
1683
1684
		/* first check current templates */
1685 60
		if ($this->path == $path) {
1686 60
			$curr_templates = $this->data->config->pinp;
1687 60
		} else {
1688
			$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1689
			$curr_templates = $config->templates;
1690
		}
1691
1692 60
		$checkpath=$path;
1693 60
		$lastcheckedpath="";
1694 60
		$arCallClassTemplate = $ARCurrent->arCallClassTemplate;
1695 60
		$arSetType = $arCallType;
1696 60
		while (!$arCallClassTemplate && !$arCallTemplate && $checkpath!=$lastcheckedpath) {
0 ignored issues
show
Bug introduced by
The variable $arCallTemplate 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...
1697 60
			$lastcheckedpath = $checkpath;
1698 60
			$arType = $arSetType;
1699 60
			while ($arType!='ariadne_object' && !$arCallTemplate) {
1700 60
				if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction][$this->reqnls])) {
1701
					$arCallTemplate=$arType.".".$arCallFunction.".".$this->reqnls;
1702
					$arCallTemplateName = $arCallFunction;
1703
					$arCallTemplateNLS = $this->reqnls;
1704 60 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction]['any'])) {
1705 12
					$arCallTemplate=$arType.".".$arCallFunction.".any";
1706 12
					$arCallTemplateName = $arCallFunction;
1707 12
					$arCallTemplateNLS = 'any';
1708 12
				} else {
1709
1710 48
					if (!($arSuper=$AR->superClass[$arType])) {
1711
						// no template found, no default.phtml found, try superclass.
1712
						if ($subcpos = strpos($arType, '.')) {
1713
							$arSuper = substr($arType, 0, $subcpos);
1714
						} else {
1715
							if (!class_exists($arType, false )) {
1716
								// the given class was not yet loaded, so do that now
1717
								$arTemp=$this->store->newobject('','',$arType,new object);
1718
							} else {
1719
								$arTemp=new $arType();
1720
							}
1721
							$arSuper=get_parent_class($arTemp);
1722
						}
1723
						$AR->superClass[$arType]=$arSuper;
1724
					}
1725 48
					$arType=$arSuper;
1726
				}
1727 60
			}
1728 60
			if ($inLibrary) {
1729
1730
				// faster matching on psection, prefix doesn't have to be a valid type
1731
				$prefix = substr($ARConfig->cache[$checkpath]->type,0,8);
1732
1733
				if ($prefix === 'psection') {
1734
					// debug("BREAKING; $arTemplateId");
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1735
					// break search operation when we have found a
1736
					// psection object
1737
					break;
1738
				}
1739
			}
1740
1741 60
			if (!$arTemplateId && $ARConfigChecked) {
0 ignored issues
show
Bug introduced by
The variable $arTemplateId 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...
1742 48
				if ($ARConfig->cacheableLibraries[$checkpath]) {
1743
					foreach ($ARConfig->cacheableLibraries[$checkpath] as $library => $path) {
1744
						if (is_int($library) && !$librariesSeen[$path]) {
1745
							$librariesSeen[$path] = true;
1746
							if ($ARConfigChecked) {
1747
								if (!$ARConfig->librariesCached[$checkpath][$path]) {
1748
									$this->loadLibraryCache($checkpath, $path);
1749
									unset($ARConfig->cacheableLibraries[$checkpath][$library]);
1750
								}
1751
							}
1752
						}
1753
					}
1754
				}
1755
1756 48
				if (isset($ARConfig->cacheableLibraries[$checkpath])) {
1757 48
					$template = $this->getTemplateFromCache($checkpath, $arCallType, $arCallFunction, $arSuperContext);
1758 48
					if ($template["arTemplateId"]) {
1759
						return $template;
1760
					}
1761 48
				}
1762 48
			}
1763 60
			if ($checkpath == $top) {
1764 48
				break;
1765
			}
1766
1767 60
			$checkpath=$this->store->make_path($checkpath, "..");
1768 60
			$config = ($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
1769 60
			$curr_templates = $config->templates;
1770 60
			$arSetType = $arCallType;
1771 60
		}
1772
1773 60
		$config = ($ARConfig->cache[$lastcheckedpath]) ? $ARConfig->cache[$lastcheckedpath] : $this->loadConfig($lastcheckedpath);
1774 60
		$arPrivateTemplate = $config->privatetemplates[$arCallType][$arCallFunction];
1775
1776
		//debug("getPinpTemplate END; $arTemplateId; $checkpath;");
1777 60
		$result["arTemplateId"] = $arTemplateId;
1778 60
		$result["arCallTemplate"] = $arCallTemplate;
1779 60
		$result["arCallType"] = $arCallType;
1780 60
		$result["arCallTemplateName"] = $arCallTemplateName;
0 ignored issues
show
Bug introduced by
The variable $arCallTemplateName 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...
1781 60
		$result["arCallTemplateNLS"] = $arCallTemplateNLS;
0 ignored issues
show
Bug introduced by
The variable $arCallTemplateNLS 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...
1782 60
		$result["arCallTemplateType"] = $arType;
0 ignored issues
show
Bug introduced by
The variable $arType 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...
1783 60
		$result["arCallTemplatePath"] = $lastcheckedpath;
1784 60
		$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...
1785 60
		$result["arLibraryPath"] = $arLibraryPath;
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...
1786 60
		$result["arLibrariesSeen"] = $librariesSeen;
1787 60
		$result["arPrivateTemplate"] = $arPrivateTemplate;
1788
1789 60
		return $result;
1790
	}
1791
1792 64
	public function CheckConfig($arCallFunction="", $arCallArgs="") {
1793
	// returns true when cache isn't up to date and no other template is
1794
	// defined for $path/$function. Else it takes care of output to the
1795
	// browser.
1796
	// All these templates must exist under a fixed directory, $AR->dir->templates
1797 64
	global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked;
1798 64
		$MAX_LOOP_COUNT=10;
1799
1800
1801
		// system templates (.phtml) have $arCallFunction=='', so the first check in the next line is to
1802
		// make sure that loopcounts don't apply to those templates.
1803 64
		if (0 && $arCallFunction && $ARBeenHere[$this->path][$arCallFunction]>$MAX_LOOP_COUNT) { // protect against infinite loops
1804
			error(sprintf($ARnls["err:maxloopexceed"],$this->path,$arCallFunction,$arCallArgs));
1805
			$this->store->close();
1806
			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...
1807
		} else {
1808 64
			$ARBeenHere[$this->path][$arCallFunction]+=1;
1809
1810
			// this will prevent the parents from setting the cache time
1811 64
			$initialConfigChecked = $ARConfigChecked;
1812 64
			$ARConfigChecked = true;
1813 64
			$config = ($ARConfig->cache[$this->path]) ? $ARConfig->cache[$this->path] : $this->loadConfig();
1814 64
			$ARConfigChecked = $initialConfigChecked;
1815 64
			$ARConfig->nls=$config->nls;
1816
1817
1818
			// if a default language is entered in a parent and no language is
1819
			// explicitly selected in the url, use that default.
1820
			// The root starts with the system default (ariadne.phtml config file)
1821 64
			if ( !$ARCurrent->nls ) {
1822 64
				if ( $config->root['nls'] ) {
1823
					$this->reqnls = $config->root['nls'];
1824
					if ( !$ARConfigChecked ) {
1825
						$ARCurrent->nls = $this->reqnls;
1826
					}
1827 64
				} else if ( $config->nls->default ) {
1828 64
					$this->reqnls = $config->nls->default;
1829 64
					$this->nls = $this->reqnls;
1830 64
					if ( !$ARConfigChecked ) {
1831
						$ARCurrent->nls = $this->nls;
1832
					}
1833 64
				}
1834 64
			} else {
1835
				$this->reqnls = $ARCurrent->nls;
1836
			}
1837 64
			$nls = &$this->nls;
1838 64
			$reqnls = &$this->reqnls;
1839
1840 64
			if (!$ARConfigChecked && is_object($ARnls)) {
1841
				$ARnls->setLanguage($ARCurrent->nls);
1842
			}
1843
1844
1845 64
			if (!$ARCurrent->arContentTypeSent) {
1846
				ldHeader("Content-Type: text/html; charset=UTF-8");
1847
				$ARCurrent->arContentTypeSent = true;
1848
			}
1849
1850
/*			// FIXME: the acceptlang code works a bit too well.. it overrides psite configuration settings.
0 ignored issues
show
Unused Code Comprehensibility introduced by
57% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
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...
1851
1852
			if ($ARCurrent->acceptlang && !$ARCurrent->nls) {
1853
				if ($ARCurrent->acceptlang && is_array($this->data->nls->list)) {
1854
					$validlangs = array_intersect(array_keys($ARCurrent->acceptlang), array_keys($this->data->nls->list));
1855
				}
1856
				if ($validlangs) {
1857
					$reqnls=array_shift($validlangs);
1858
					$ARCurrent->nls = $reqnls;
1859
				}
1860
			}
1861
*/
1862 64
			if (is_array($this->data->custom) && $this->data->custom['none']) {
1863 4
				$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...
1864 4
			}
1865 64
			if (is_array($this->data->custom) && $this->data->custom[$nls]) {
1866
				$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...
1867
			}
1868
1869 64
			if (!$ARConfigChecked) {
1870
				// this template is the first template called in this request.
1871
				$eventData = new object();
1872
				$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...
1873
				$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...
1874
1875
				$ARConfigChecked = true;
1876
				$result = ar_events::fire( 'onbeforeview', $eventData );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1877
				$ARConfigChecked = $initialConfigChecked;
1878
				if ( !$result ) { //prevent default action: view
1879
					return false;
1880
				}
1881
			}
1882
1883 64
			if (!$ARConfigChecked) {
1884
				// if this object isn't available in the requested language, show
1885
				// a language select dialog with all available languages for this object.
1886
				if (isset($this->data->nls) && !$this->data->name) {
1887
					if (!$ARCurrent->forcenls && (!isset($this->data->nls->list[$reqnls]) || !$config->nls->list[$reqnls])) {
1888
						if (!$ARCurrent->nolangcheck && $arCallFunction != 'config.ini') {
1889
							$ARCurrent->nolangcheck=1;
1890
							$eventData = new object();
1891
							$eventData->arCallFunction = $arCallFunction;
1892
							$eventData->arCallArgs = $arCallArgs;
1893
							$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...
1894
							$result = ar_events::fire( 'onlanguagenotfound', $eventData );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
1895
							if ( $result ) { // continue with default action: langaugeselect
1896
								$result->arCallArgs["arOriginalFunction"] = $result->arCallFunction;
1897
								$this->call("user.languageselect.html", $result->arCallArgs);
1898
								return false;
1899
							}
1900
						} else {
1901
							$this->nlsdata=$this->data->$nls;
1902
						}
1903
					} else {
1904
						$this->nlsdata=$this->data->$reqnls;
1905
					}
1906
				}
1907
				$ARCurrent->nolangcheck=1;
1908
			}
1909
1910
			/*
1911
				Set ARConfigChecked to true to indicate that we have been here
1912
				earlier.
1913
			*/
1914 64
			$ARConfigChecked = true;
1915 64
			if ($arCallFunction) { // don't search for templates named ''
1916
				// 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...
1917 60
				$redirects	= $ARCurrent->shortcut_redirect;
1918 60
				if (is_array($redirects)) {
1919
					$redirpath = $this->path;
1920
					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...
1921
								($redir = array_pop($redirects)) &&
1922
									$redir["keepurl"] &&
1923
										(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
1924
					) {
1925
						$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"]);
1926
						$redirpath = $redir['src'];
1927
					}
1928
1929
					if (!$template["arTemplateId"] && $redirpath) {
1930
						$template = $this->getPinpTemplate($arCallFunction, $redirpath);
1931
					}
1932
				}
1933 60
				if (!$template["arTemplateId"]) {
1934 60
					$template = $this->getPinpTemplate($arCallFunction);
1935 60
				}
1936
1937 60
				if ($template["arCallTemplate"] && $template["arTemplateId"]) {
1938 12
					if (!is_array($ARCurrent->cacheTemplateChain)) {
1939
						$ARCurrent->cacheTemplateChain = array();
1940
					}
1941 12
					if (!is_array($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) {
1942 8
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]] = array();
1943 8
					}
1944 12
					if (!is_array($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']])) {
1945 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']] = array();
1946 12
					}
1947 12
					if (!$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]) {
1948 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0;
1949 12
					}
1950 12
					$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]++;
1951
1952
1953 12
					debug("CheckConfig: arCallTemplate=".$template["arCallTemplate"].", arTemplateId=".$template["arTemplateId"],"object");
1954
					// $arCallTemplate=$this->store->get_config("files")."templates".$arCallTemplate;
0 ignored issues
show
Unused Code Comprehensibility introduced by
63% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
1955
					// check if template exists, if it doesn't exist, then continue the original template that called CheckConfig
1956 12
					$arTemplates=$this->store->get_filestore("templates");
1957
					if (
1958 12
						$arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")
1959 12
					) {
1960
						// check if the requested language exists, if not do not display anything,
1961
						// unless otherwise indicated by $ARCurrent->allnls
1962
						// This triggers only for pinp templates called by other templates,
1963
						// as the first template (in the url) will first trigger the language
1964
						// choice dialogue instead.
1965 12
						$arLibrary = $template['arLibrary'];
1966 12
						if (is_int($arLibrary)) {
1967
							// set the library name for unnamed libraries to 'current'
1968
							// so that calls using getvar('arLibrary') will keep on working
1969
							$arLibrary = "current";
1970
						}
1971
1972 12 View Code Duplication
						if (!is_string($arCallArgs)) {
1973 12
							$arCallArgs['arCallFunction'] = $arCallFunction;
1974 12
							$arCallArgs['arLibrary'] = $arLibrary;
1975 12
							$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
1976 12
						}
1977
1978 12
						$ARCurrent->arCallStack[]=$arCallArgs;
1979
						// start running a pinp template
1980
1981 12
						$this->pushContext(
1982
							array(
1983 12
								"scope" => "pinp",
1984 12
								"arLibrary" => $arLibrary,
1985 12
								"arLibraryPath" => $template['arLibraryPath'],
1986 12
								"arCallFunction" => $arCallFunction,
1987 12
								"arCurrentObject" => $this,
1988 12
								"arCallType" => $template['arCallType'],
1989 12
								"arCallTemplateName" => $template['arCallTemplateName'],
1990 12
								"arCallTemplateNLS" => $template['arCallTemplateNLS'],
1991 12
								"arCallTemplateType" => $template['arCallTemplateType'],
1992 12
								"arCallTemplatePath" => $template['arCallTemplatePath'],
1993 12
								"arLibrariesSeen" => $template['arLibrariesSeen']
1994 12
							)
1995 12
						);
1996
1997
						// 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...
1998 12
						if (count($ARCurrent->arCallStack) == 2 && $template['arPrivateTemplate']) {
1999
							// Do not allow private templates to be called first in the stack.
2000
							// echo "Bad request";
2001
2002
							// 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...
2003
							// Return true zorgt er voor dat de default 404 handler het oppikt alsof het template niet bestaat.
2004
							$this->popContext();
2005
							array_pop($ARCurrent->arCallStack);
2006
							return true;
2007 12
						} else if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) {
2008
							// the requested language is available.
2009 12
							$this->nlsdata=$this->data->$reqnls;
2010 12
							$this->nls=$reqnls;
2011 12
							$continue=true;
2012 12
						} else if (!isset($this->data->nls)) {
2013
							// the object has no language support
2014
							$this->nlsdata=$this->data;
2015
							$continue=true;
2016
						} else if (($ARCurrent->allnls) || (!$initialConfigChecked && $ARCurrent->nolangcheck)) {
2017
							// all objects must be displayed
2018
							// $this->reqnls=$this->nls; // set requested nls, for checks
0 ignored issues
show
Unused Code Comprehensibility introduced by
60% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
2019
							$this->nls = isset($this->data->nls->default) ? $this->data->nls->default : $this->reqnls;
2020
							$this->nlsdata = $this->data->$nls ?: $this->data->{$this->nls} ?: $this->data;
2021
							$continue=true;
2022
						} else {
2023
							debug("CheckConfig: requested language not available, allnls not set","object");
2024
							// -> skip this object (do not run template but do return false)
2025
							$continue=false;
2026
						}
2027 12
						if ($continue) {
2028 12
							$eventData = new object();
2029 12 View Code Duplication
							if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2030 12
								$AR->contextCallHandler = true;
2031 12
								$eventData->arCallArgs = $arCallArgs;
2032 12
								$eventData->arCallFunction = $arCallFunction;
2033 12
								$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...
2034 12
								$eventData = ar_events::fire('onbeforecall', $eventData);
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2035 12
								$ARCurrent->arResult = $eventData->arResult;
2036 12
								$AR->contextCallHandler = false;
2037 12
								$continue = ($eventData!=false);
2038 12
							}
2039 12
							if ( $continue ) {
2040 12
								if (!is_array($ARCurrent->cacheCallChainSettings)) {
2041
									$ARCurrent->cacheCallChainSettings = array();
2042
								}
2043 12
								if ($ARConfig->cache[$this->path]->inConfigIni == false) {
2044 8
									$ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings;
2045 8
								}
2046
2047 12
								if ($ARCurrent->ARShowTemplateBorders) {
2048
									echo "<!-- arTemplateStart\nData: ".$this->type." ".$this->path." \nTemplate: ".$template["arCallTemplatePath"]." ".$template["arCallTemplate"]." \nLibrary:".$template["arLibrary"]." -->";
2049
								}
2050 12
								set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2051 12
								$arResult=$arTemplates->import($template["arTemplateId"], $template["arCallTemplate"], "", $this);
2052 12
								restore_error_handler();
2053 12
								if (isset($arResult)) {
2054 12
									$ARCurrent->arResult=$arResult;
2055 12
								}
2056 12
								if ($ARCurrent->ARShowTemplateBorders) {
2057
									echo "<!-- arTemplateEnd -->";
2058
								}
2059 12 View Code Duplication
								if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2060 12
									$AR->contextCallHandler = true;
2061 12
									$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2062 12
									$eventData->arResult = $temp;
2063 12
									ar_events::fire('oncall', $eventData );
2064 12
									$ARCurrent->arResult = $temp; /* restore correct result */
2065 12
									$AR->contextCallHandler = false;
2066 12
								}
2067 12
							}
2068 12
						}
2069 12
						array_pop($ARCurrent->arCallStack);
2070 12
						$this->popContext();
2071
2072 12
						if ( !$initialConfigChecked && $arCallFunction != 'config.ini' ) {
2073
							// this template was the first template called in this request.
2074
							$eventData = new object();
2075
							$eventData->arCallArgs = $arCallArgs;
2076
							$eventData->arCallFunction = $arCallFunction;
2077
							ar_events::fire( 'onview', $eventData ); // no default action to prevent, so ignore return value.
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2078
						}
2079 12
						return false;
2080
					} else {
2081 4
						debug("pobject: CheckConfig: no such file: ".$template["arTemplateId"].$template["arCallTemplate"]."","all");
2082
					}
2083 4
				} else {
2084 48
					debug("CheckConfig: no arCallTemplate ($arCallFunction from '$this->path')","object");
2085
				}
2086
2087 52
			}
2088
		}
2089 56
		return true;
2090
	}
2091
2092
	public function ClearCache($path="", $private=true, $recurse=false) {
2093
	global $AR;
2094
		$norealnode = false;
2095
		if (!$path) {
2096
			$path=$this->path;
2097
		} else {
2098
			$realpath = current($this->get($path, "system.get.path.phtml"));
2099
			if($realpath != false) {
2100
				$path = $realpath;
2101
			} else {
2102
				$norealnode = true;
2103
			}
2104
		}
2105
2106
		if($norealnode !== true) {
2107
			/*
2108
				we don't want to recurse to the currentsite, because the path
2109
				doesn't exists in the database, so it doesn't have a currentsite
2110
2111
				the privatecache should be emptied by delete, or by the cleanup
2112
				cronjob. The current path doesn't exists in the database, so a
2113
				object id which is needed to find the node in the cache, isn't
2114
				available
2115
			*/
2116
2117
			if ($private ) {
2118
				// now remove any private cache entries.
2119
				// 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...
2120
				//        only scalable solution is storage in a database
2121
				//        but it will need the original path info to
2122
				//        remove recursively fast enough.
2123
				//        this means a change in the filestore api. -> 2.5
2124
2125
				// Use chunks of max 5000 objects at a time to be more memory-efficient;
2126
				$pcache=$this->store->get_filestore("privatecache");
2127
				if ($recurse) {
2128
					$offset = 0;
2129
					$limit = 5000;
2130
					$ids=$this->store->info($this->store->find($path, "" , $limit, $offset));
2131
					while (is_array($ids) && sizeof($ids)) {
2132
						foreach($ids as $value) {
2133
							$eventData = new object();
2134
							$eventData = ar_events::fire( 'onbeforeclearprivatecache', $eventData, $value['type'], $value['path'] );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2135
							if ( !$eventData ) {
2136
								continue;
2137
							}
2138
2139
							$pcache->purge($value["id"]);
2140
							ar_events::fire( 'onclearprivatecache', $eventData, $value['type'], $value['path'] );
2141
						}
2142
2143
						$offset += $limit;
2144
						$ids = $this->store->info($this->store->find($path, "", $limit, $offset));
2145
					}
2146
				} else {
2147
					$eventData = new object();
2148
					$eventData = ar_events::fire( 'onbeforeclearprivatecache', $eventData, $this->type, $this->path );
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2149
					if ( $eventData ) {
2150
						$pcache->purge($this->id);
2151
						ar_events::fire( 'onclearprivatecache', $eventData, $this->type, $this->path );
2152
					}
2153
				}
2154
			}
2155
2156
			// now clear all parents untill the current site
2157
			$site=$this->currentsite($path);
2158
			$project=$this->currentproject($path);
2159
			if ($path!=$site && $path != $project && $path!='/') {
2160
				$parent=$this->make_path($path.'../');
2161
				$this->ClearCache($parent, $private, false);
2162
			}
2163
		}
2164
		$recursed = array();
2165
2166
		// filesystem cache image filenames are always lower case, so
2167
		// use special path for that. Remember 'real' path name for
2168
		// recursion and stuff
2169
		$fs_path=strtolower($path);
2170
		$nlslist=$AR->nls->list;
2171
		$nlslist["."]="default";
2172
		$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...
2173
		$cache_types[] = "compressed";
2174
		$cache_types[] = "session";
2175
2176
		global $cache_config,$store_config;
2177
		$cachestore=new cache($cache_config);
2178
2179
2180
		$filestore = $this->store->get_config("files");
2181
		foreach($cache_types as $type){
2182
			foreach($nlslist as $nls => $language){
2183
				// break away if nls doesn't exists
2184
				// is dir is cached, so it should not cost more that it add's in speed
2185
				if(!is_dir($filestore."cache/$type/$nls")){
2186
					continue;
2187
				}
2188
2189
				$fpath=$filestore."cache/$type/$nls".$fs_path;
2190
				$hpath=$filestore."cacheheaders/$type/$nls".$fs_path;
2191
				if ($dir=@dir($fpath)) {
2192
					while (false !== ($entry = $dir->read())) {
2193
						if ($entry!="." && $entry!="..") {
2194
							if (is_file($fpath.$entry)) {
2195
								@unlink($fpath.$entry);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2196
								@unlink($hpath.$entry);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2197
								$cachestore->delete("/".$type."/".$nls.$fs_path.$entry);
2198
							} else if ( $recurse && !$recursed[$entry]) {
2199
								$this->ClearCache($path.$entry."/", false, true);
2200
								$recursed[$entry]=true;
2201
							}
2202
						}
2203
					}
2204
					$dir->close();
2205
					// remove empty directory entry's, hide errors about directory entry's with content
2206
					@rmdir($fpath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2207
					@rmdir($hpath);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2208
				} else if (file_exists(substr($fpath,0,-1)."=")) {
2209
					@unlink(substr($fpath,0,-1)."=");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2210
					@unlink(substr($hpath,0,-1)."=");
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2211
					$cachestore->delete("/".$type."/".$nls.substr($fs_path,0,-1)."=");
2212
				}
2213
			}
2214
		}
2215
	}
2216
2217
	public function getcache($name, $nls="") {
2218
		global $ARCurrent, $ARnls;
2219
		$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...
2220
		$this->error = '';
2221
		if ($name) {
2222
			$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...
2223
			if (!$nls) {
2224
				$nls=$this->nls;
2225
			}
2226
			$file=$nls.".".$name;
2227
2228
			$minfresh = time();
2229
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2230
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2231
			}
2232
2233
			$pcache=$this->store->get_filestore("privatecache");
2234
			if ( $pcache->exists($this->id, $file) &&
2235
			     ($pcache->mtime($this->id, $file) > ($minfresh) )  ) {
2236
2237
				$result = $pcache->read($this->id, $file);
2238
2239
				$contentType = $ARCurrent->ldHeaders['content-type'];
2240
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2241
					$contentType = $matches[1];
2242
				} else {
2243
					$contentType = '';
2244
				}
2245
2246 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2247
					require_once($this->store->get_config('code')."modules/mod_url.php");
2248
					$temp = explode('.', $file);
2249
					$imageNLS = $temp[0];
2250
					$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...
2251
				}
2252
			} else {
2253
				$result=false;
2254
				$ARCurrent->cache[]=$file;
2255
				ob_start();
2256
				/* output buffering is recursive, so this won't interfere with
2257
				   normal page caching, unless you forget to call savecache()...
2258
				   so normal pagecache needs to check $ARCurrent->cache, if it's
2259
				   not empty, issue a warning and don't cache the outputbuffer...
2260
				   savecache() must then pop the stack.
2261
				*/
2262
			}
2263
		} else {
2264
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2265
			$result = false;
2266
		}
2267
		return $result;
2268
	}
2269
2270
	public function cached($name, $nls="") {
2271
		if ($image=$this->getcache($name, $nls)) {
2272
			echo $image;
2273
			$result=true;
2274
		} else {
2275
			$result=false;
2276
		}
2277
		return $result;
2278
	}
2279
2280
	public function savecache($time="") {
2281
		global $ARCurrent, $ARnls, $DB;
2282
		$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...
2283
		$this->error = '';
2284
		if (!$time) {
2285
			$time=2; // 'freshness' in hours.
2286
		}
2287
		if ($file=array_pop($ARCurrent->cache)) {
2288
			$image=ob_get_contents();
2289
			if ($image !== false) {
2290
				$result = $image;
2291
2292
				$contentType = $ARCurrent->ldHeaders['content-type'];
2293
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2294
					$contentType = $matches[1];
2295
				} else {
2296
					$contentType = '';
2297
				}
2298
2299 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2300
					require_once($this->store->get_config('code')."modules/mod_url.php");
2301
					$temp = explode('.', $file);
2302
					$imageNLS = $temp[0];
2303
					$image = URL::RAWtoAR($image, $imageNLS);
2304
				}
2305
2306
				if( $time > 0  && $DB["wasUsed"] == 0) {
2307
					$pcache=$this->store->get_filestore("privatecache");
2308
					$pcache->write($image, $this->id, $file);
2309
					$time=time()+($time*3600);
2310 View Code Duplication
					if (!$pcache->touch($this->id, $file, $time)) {
2311
						$this->error = ar::error("savecache: ERROR: couldn't touch $file", 1113);
2312
						$result = false;
2313
					}
2314
				}
2315
				ob_end_clean();
2316
				echo $image;
2317
			} else {
2318
				debug("skipped saving cache - ob_get_contents returned false so output buffering was not active", "all");
2319
				$result = false;
2320
			}
2321
		} else {
2322
			$this->error = ar::error($ARnls["err:savecachenofile"], 1112);
2323
			$result = false;
2324
		}
2325
		return $result;
2326
	}
2327
2328
	public function getdatacache($name) {
2329
		global $ARCurrent, $ARnls;
2330
		$result=false;
2331
		$this->error = '';
2332
		if ($name) {
2333
2334
			$minfresh = time();
2335
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2336
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2337
			}
2338
2339
			$pcache=$this->store->get_filestore("privatecache");
2340
			if ( $pcache->exists($this->id, $name) &&
2341
			     ($pcache->mtime($this->id, $name) > $minfresh) ) {
2342
				$result = unserialize($pcache->read($this->id, $name));
2343
			} else {
2344
				debug("getdatacache: $name doesn't exists, returning false.","all");
2345
			}
2346
		} else {
2347
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2348
		}
2349
		return $result;
2350
	}
2351
2352
	public function savedatacache($name,$data,$time="") {
2353
		global $DB;
2354
		$this->error = '';
2355
		if (!$time) {
2356
			$time=2; // 'freshness' in hours.
2357
		}
2358
		$pcache=$this->store->get_filestore("privatecache");
2359
		if( $time > 0  && $DB["wasUsed"] == 0) {
2360
			$pcache->write(serialize($data), $this->id, $name);
2361
			$time=time()+($time*3600);
2362 View Code Duplication
			if (!$pcache->touch($this->id, $name, $time)) {
2363
				$this->error = ar::error('Could not touch '.$name, 1113);
2364
				return false;
2365
			}
2366
		}
2367
		return true;
2368
	}
2369
2370 52
	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...
2371
	// function to retrieve variables from $this->data, with the correct
2372
	// language version.
2373 52
	global $ARCurrent;
2374
2375 52
		$result = false;
2376 52
		if ($nls!="none") {
2377 48 View Code Duplication
			if ($ARCurrent->arCallStack) {
2378 48
				$arCallArgs=end($ARCurrent->arCallStack);
2379 48
				if (is_array($arCallArgs)) {
2380 48
					extract($arCallArgs);
2381 48
				} else if (is_string($arCallArgs)) {
2382
					Parse_Str($arCallArgs);
2383
				}
2384 48
			}
2385 48
			if (isset(${$nls}[$varname])) {
2386 28
				$result=${$nls}[$varname];
2387 48
			} else if (isset($ARCurrent->$nls) && isset($ARCurrent->$nls->$varname)) {
2388
				$result=$ARCurrent->$nls->$varname;
2389 48
			} else if (($values=$_POST[$nls]) && isset($values[$varname])) {
2390
				$result=$values[$varname];
2391 48
			} else if (($values=$_GET[$nls]) && isset($values[$varname])) {
2392
				$result=$values[$varname];
2393 48
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2394
				$result=$arStoreVars[$nls][$varname];
2395 48
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2396
				$result=$arStoreVars[$nls][$varname];
2397
			}
2398 48
			if ($result===false) {
2399 48
				if (isset($this->data->${nls}) && isset($this->data->${nls}->${varname})) {
2400 24
					$result=$this->data->${nls}->${varname};
2401 24
				}
2402 48
			}
2403 48
		} else { // language independant variable.
2404 52 View Code Duplication
			if ($ARCurrent->arCallStack) {
2405 52
				$arCallArgs=end($ARCurrent->arCallStack);
2406 52
				if (is_array($arCallArgs)) {
2407 48
					extract($arCallArgs);
2408 52
				} else if (is_string($arCallArgs)) {
2409
					Parse_Str($arCallArgs);
2410
				}
2411 52
			}
2412 52
			if (isset($$varname)) {
2413 24
				$result=$$varname;
2414 52
			} else if (isset($ARCurrent->$varname)) {
2415
				$result=$ARCurrent->$varname;
2416 52 View Code Duplication
			} else if (isset($_POST[$varname])) {
2417
				$result=$_POST[$varname];
2418 52
			} else if (isset($_GET[$varname])) {
2419
				$result=$_GET[$varname];
2420 52
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$varname])) {
2421
				$result=$arStoreVars[$varname];
2422 52
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$varname])) {
2423
				$result=$arStoreVars[$varname];
2424
			}
2425 52
			if ($result===false) {
2426 52
				if (isset($this->data->$varname)) {
2427
					$result=$this->data->$varname;
2428
				}
2429 52
			}
2430
		}
2431 52
		if ( $result === false ) {
2432 52
			$result = $emptyResult;
2433 52
		}
2434 52
		return $result;
2435
	}
2436
2437
	public function showdata($varname, $nls="none", $emptyResult=false) {
2438
		echo htmlspecialchars($this->getdata($varname, $nls, $emptyResult), ENT_QUOTES, 'UTF-8');
2439
	}
2440
2441
	public function setnls($nls) {
2442
		ldSetNls($nls);
2443
	}
2444
2445
	public function getcharset() {
2446
		return "UTF-8";
2447
	}
2448
2449
	public function HTTPRequest($method, $url, $postdata = "", $port=80 ) {
2450
		$maxtries = 5;
2451
		$tries = 0;
2452
		$redirecting = true;
2453
2454
		if(is_array($postdata)) {
2455
			foreach($postdata as $key=>$val) {
2456
				if(!is_integer($key)) {
2457
					$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...
2458
				}
2459
			}
2460
		} else {
2461
			$data = $postdata;
2462
		}
2463
2464
		while ($redirecting && $tries < $maxtries) {
2465
			$tries++;
2466
			// get host name and URI from URL, URI not needed though
2467
			preg_match("/^([htps]*:\/\/)?([^\/]+)(.*)/i", $url, $matches);
2468
			$host = $matches[2];
2469
			$uri = $matches[3];
2470
			if (!$matches[1]) {
2471
				$url="http://".$url;
2472
			}
2473
			$connection = @fsockopen( $host, $port, $errno, $errstr, 120);
2474
			if( $connection ) {
2475
				if( strtoupper($method) == "GET" ) {
2476
					if ($data) {
2477
						$uri .= "?" . $data;
2478
					}
2479
					fputs( $connection, "GET $uri HTTP/1.0\r\n");
2480
				} else if( strtoupper($method) == "POST" ) {
2481
					fputs( $connection, "POST $uri HTTP/1.0\r\n");
2482
				} else {
2483
					fputs( $connection, "$method $uri HTTP/1.0\r\n");
2484
				}
2485
2486
				fputs( $connection, "Host: $host\r\n");
2487
				fputs( $connection, "Accept: */*\r\n");
2488
				fputs( $connection, "Accept: image/gif\r\n");
2489
				fputs( $connection, "Accept: image/x-xbitmap\r\n");
2490
				fputs( $connection, "Accept: image/jpeg\r\n");
2491
2492
				if( strtoupper($method) == "POST" ) {
2493
					$strlength = strlen( $data);
2494
					fputs( $connection, "Content-type: application/x-www-form-urlencoded\r\n" );
2495
					fputs( $connection, "Content-length: ".$strlength."\r\n\r\n");
2496
					fputs( $connection, $data."\r\n");
2497
				}
2498
2499
				fputs( $connection, "\r\n" , 2);
2500
2501
				$headerContents = '';
2502
				$headerStart = 0;
2503
				$headerEnd = 0;
2504
				$redirecting = false;
2505
2506
				while (!feof($connection)) {
2507
					$currentLine = fgets ($connection, 1024);
2508
					if ($headerEnd && $redirecting) {
2509
						break;
2510
					} else if ($headerEnd && !$redirecting) {
2511
						//this is the html from the page
2512
						$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...
2513
					} else if ( preg_match("/^HTTP/", $currentLine) ) {
2514
						//came to the start of the header
2515
						$headerStart = 1;
2516
						$headerContents = $currentLine;
2517
					} else if ( $headerStart && preg_match('/^[\n\r\t ]*$/', $currentLine) ) {
2518
						//came to the end of the header
2519
						$headerEnd = 1;
2520
					} else {
2521
						//this is the header, if you want it...
2522
						if (preg_match("/^Location: (.+?)\n/is",$currentLine,$matches) ) {
2523
							$headerContents .= $currentLine;
2524
							//redirects are sometimes relative
2525
							$newurl = $matches[1];
2526
							if (!preg_match("/http:\/\//i", $newurl, $matches) ) {
2527
								$url .= $newurl;
2528
							} else {
2529
								$url = $newurl;
2530
							}
2531
							//extra \r's get picked up sometimes
2532
							//i think only with relative redirects
2533
							//this is a quick fix.
2534
							$url = preg_replace("/\r/s","",$url);
2535
							$redirecting = true;
2536
						} else {
2537
							$headerContents.=$currentLine;
2538
						}
2539
					}
2540
				}
2541
			} else {
2542
				$this->error="$errstr ($errno)";
2543
				$contents=false;
2544
				$url = "";
2545
			}
2546
			@fclose($connection);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2547
		}
2548
		if (($method!="GET") && ($method!="POST")) {
2549
			$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...
2550
		}
2551
		return $contents;
2552
	}
2553
2554
	public function make_filesize( $size="" ,$precision=0) {
2555
		$suffixes = array('B','KB','MB','GB','TB','PB','EB','ZB','YB');
2556
2557
		if( $size === "" ) {
2558
			$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...
2559
		}
2560
		while ( (count($suffixes) > 1) && ($size > 1024) ){
2561
			$size = $size / 1024;
2562
			array_shift($suffixes);
2563
		}
2564
		$size = round($size,$precision);
2565
		if($precision==0){ // compatible with the old make_filesize
2566
			$size = intval($size);
2567
		}
2568
		$result = $size." ".array_shift($suffixes);
2569
		return $result;
2570
	}
2571
2572
	public function convertToUTF8($data, $charset = "CP1252") {
2573
2574
		include_once($this->store->get_config("code")."modules/mod_unicode.php");
2575
2576
		if (is_array($data)) {
2577
			foreach($data as $key => $val){
2578
				$data[$key] = $this->convertToUTF8($val, $charset);
2579
			}
2580
		} else
2581
		if (is_object($data)) {
2582
			foreach($data as $key => $val){
2583
				$data->$key = $this->convertToUTF8($val, $charset);
2584
			}
2585
		} else {
2586
			$data = unicode::convertToUTF8($charset, $data);
2587
		}
2588
		return $data;
2589
	}
2590
2591 28
	public function resetloopcheck() {
2592 28
		global $ARBeenHere;
2593 28
		$ARBeenHere=array();
2594 28
	}
2595
2596
/********************************************************************
2597
2598
  "safe" functions.
2599
2600
  The following functions are safe versions of existing functions
2601
  above.
2602
  - They don't change anything in the database.
2603
    This means that to save/delete something, a user will need to call
2604
    "system.save.data.phtml" or "system.delete.phtml" which check grants.
2605
  - All functions except _get and _exists don't take a path as
2606
    argument, they use the current objects path instead.
2607
2608
  These are meant to be used by 'pinp' versions of templates,
2609
  meaning user defined templates. 'pinp' rewrites call to functions
2610
  to the form '$this->_function'.
2611
2612
  All pinp files automatically first call CheckLogin('read').
2613
2614
********************************************************************/
2615
2616
	public function _call($function, $args="") {
2617
		// remove possible path information (greedy match)
2618
		if ( !( $function instanceof \Closure ) ) {
2619
			$function = basename( (string) $function );
2620
		}
2621
		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...
Documentation introduced by
$args is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2622
	}
2623
2624
	public function _call_super($arCallArgs="") {
2625
	global $ARCurrent, $AR;
2626
		$context = $this->getContext();
2627
		if (!$arCallArgs) {
2628
			$arCallArgs = end($ARCurrent->arCallStack);
2629
		}
2630
		$arSuperContext = (array)$context['arSuperContext'];
2631
		$arLibrary		= $context['arLibrary'];
2632
		$arLibraryPath	= $context['arLibraryPath'];
2633
		$arCallType		= $context['arCallTemplateType'];
2634
		$arSuperPath	= $context['arCallTemplatePath'];
2635
		$arLibrariesSeen = $context['arLibrariesSeen'];
2636
		$arCallFunction = $arSuperFunction = $context['arCallFunction'];
2637
		if ($arLibrary) {
2638
			$arSuperFunction = str_replace($arLibrary.':', '', $arCallFunction);
2639
		}
2640
		if (strpos($arSuperFunction, "::") !== false) {
2641
			// template of a specific class defined via call("class::template");
2642
			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...
2643
		}
2644
		// remove current library path from the arLibrariesSeen array so that
2645
		// Ariadne will be able to re-enter the library and toggle the arSuperContext boolean there.
2646
		unset($arLibrariesSeen[$arLibraryPath]);
2647
		$arSuperContext[$arSuperPath.":".$arCallType.":".$arSuperFunction] = true;
2648
2649
		debug("call_super: searching for the template following (path: $arSuperPath; type: $arCallType; function: $arCallFunction) from $this->path");
2650
		// 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...
2651
		$redirects	= $ARCurrent->shortcut_redirect;
2652
		if (is_array($redirects)) {
2653
			$redirpath = $this->path;
2654
			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...
2655
						($redir = array_pop($redirects)) &&
2656
							$redir["keepurl"] &&
2657
								(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
2658
			) {
2659
				debug("call_super: following shortcut redirect: $redirpath; to ".$redir["dest"]);
2660
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"], false, $arLibrariesSeen, $arSuperContext);
2661
				$redirpath = $redir['src'];
2662
			}
2663 View Code Duplication
			if (!$template["arTemplateId"]) {
2664
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, '', false, $arLibrariesSeen, $arSuperContext);
2665
			}
2666
		}
2667 View Code Duplication
		if (!$template["arTemplateId"]) {
2668
			$template = $this->getPinpTemplate($arCallFunction, $this->path, '', false, $arLibrariesSeen, $arSuperContext);
2669
		}
2670
		if ($template["arCallTemplate"] && $template["arTemplateId"]) {
2671
			$arTemplates=$this->store->get_filestore("templates");
2672
			if ($arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")) {
2673
				debug("call_super: found template ".$template["arCallTemplate"]." on object with id ".$template["arTemplateId"]);
2674
				$arLibrary = $template['arLibrary'];
2675
				debug("call_super: found template on ".$template["arTemplateId"]);
2676
				if (is_int($arLibrary)) {
2677
					// set the library name for unnamed libraries to 'current'
2678
					// so that calls using getvar('arLibrary') will keep on working
2679
					$arLibrary = "current";
2680
				}
2681 View Code Duplication
				if (!is_string($arCallArgs)) {
2682
					$arCallArgs['arCallFunction'] = $arCallFunction;
2683
					$arCallArgs['arLibrary'] = $arLibrary;
2684
					$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
2685
				}
2686
				$ARCurrent->arCallStack[]=$arCallArgs;
2687
				$this->pushContext(
2688
					array(
2689
						"scope" => "pinp",
2690
						"arSuperContext" => $arSuperContext,
2691
						"arLibrary" => $arLibrary,
2692
						"arLibraryPath" => $template['arLibraryPath'],
2693
						"arCallFunction" => $arCallFunction,
2694
						"arCurrentObject" => $this,
2695
						"arCallType" => $template['arCallType'],
2696
						"arCallTemplateName" => $template['arCallTemplateName'],
2697
						"arCallTemplateNLS"  => $template['arCallTemplateNLS'],
2698
						"arCallTemplateType" => $template['arCallTemplateType'],
2699
						"arCallTemplatePath" => $template['arCallTemplatePath']
2700
					)
2701
				);
2702
				$continue = true;
2703
				$eventData = new object();
2704 View Code Duplication
				if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2705
					$AR->contextCallHandler = true;
2706
					$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...
2707
					$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...
2708
					$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...
2709
					$eventData = ar_events::fire('onbeforecall', $eventData);
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2710
					$ARCurrent->arResult = $eventData->arResult;
2711
					$AR->contextCallHandler = false;
2712
					$continue = ($eventData!=false);
2713
				}
2714
				if ( $continue ) {
2715
					set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2716
					$arResult = $arTemplates->import($template["arTemplateId"], $template["arCallTemplate"], "", $this);
2717
					restore_error_handler();
2718
2719 View Code Duplication
					if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2720
						$AR->contextCallHandler = true;
2721
						$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2722
						$eventData->arResult = $arResult;
2723
						ar_events::fire('oncall', $eventData );
2724
						$ARCurrent->arResult = $temp; /* restore correct result */
2725
						$AR->contextCallHandler = false;
2726
					}
2727
				}
2728
				array_pop($ARCurrent->arCallStack);
2729
				$this->popContext();
2730
			}
2731
		}
2732
2733
		return $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...
2734
	}
2735
2736
	public function _get($path, $function="view.html", $args="") {
2737
		// remove possible path information (greedy match)
2738
		if ( !($function instanceof \Closure) ) {
2739
			$function = basename( (string) $function);
2740
		}
2741
		return $this->store->call($function, $args,
2742
			$this->store->get(
2743
				$this->make_path($path)));
2744
	}
2745
2746
	public function _call_object($object, $function, $args="") {
2747
		return $object->call($function, $args);
2748
	}
2749
2750 View Code Duplication
	public function _ls($function="list.html", $args="") {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
2751
		// remove possible path information (greedy match)
2752
		if ( ! ( $function instanceof \Closure ) ) {
2753
			$function = basename( (string) $function );
2754
		}
2755
		return $this->store->call($function, $args,
2756
			$this->store->ls($this->path));
2757
	}
2758
2759 View Code Duplication
	public function _parents($function="list.html", $args="", $top="") {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
2760
		// remove possible path information (greedy match)
2761
		if ( !($function instanceof \Closure ) ) {
2762
			$function = basename( (string) $function);
2763
		}
2764
		return $this->parents($this->path, $function, $args, $top);
2765
	}
2766
2767
	public function _find($criteria, $function="list.html", $args="", $limit=100, $offset=0) {
2768
		$this->error = '';
2769
		// remove possible path information (greedy match)
2770
		if ( !($function instanceof \Closure ) ) {
2771
			$function = basename( (string) $function);
2772
		}
2773
		$result = $this->store->call($function, $args,
2774
			$this->store->find($this->path, $criteria, $limit, $offset));
2775 View Code Duplication
		if ($this->store->error) {
2776
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error );
2777
		}
2778
		return $result;
2779
	}
2780
2781
	public function _exists($path) {
2782
		return $this->store->exists($this->make_path($path));
2783
	}
2784
2785
	public function _implements($implements) {
2786
		return $this->AR_implements($implements);
2787
	}
2788
2789 52
	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...
2790 52
	global $ARCurrent, $ARConfig; // Warning: if you add other variables here, make sure you cannot get at it through $$var.
2791
2792 52 View Code Duplication
		if ($ARCurrent->arCallStack) {
2793 48
			$arCallArgs=end($ARCurrent->arCallStack);
2794 48
			if (is_array($arCallArgs)) {
2795 36
				extract($arCallArgs);
2796 48
			} else if (is_string($arCallArgs)) {
2797
				Parse_Str($arCallArgs);
2798
			}
2799 48
		}
2800 52
		if (isset($$var) && ($var!='ARConfig')) {
2801 16
			$result=$$var;
2802 52
		} else if (isset($ARCurrent->$var)) {
2803
			$result=$ARCurrent->$var;
2804 52
		} else if (isset($ARConfig->pinpcache[$this->path][$var])) {
2805
			$result=$ARConfig->pinpcache[$this->path][$var];
2806 52 View Code Duplication
		} else if (isset($_POST[$var])) {
2807
			$result=$_POST[$var];
2808 52
		} else if (isset($_GET[$var])) {
2809
			$result=$_GET[$var];
2810 52
		} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$var])) {
2811
			$result=$arStoreVars[$var];
2812 52
		} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$var])) {
2813
			$result=$arStoreVars[$var];
2814
		}
2815 52
		return $result;
2816
	}
2817
2818
	public function _getvar($var) {
2819
		return $this->getvar($var);
2820
	}
2821
2822
	public function putvar($var, $value) {
2823
		global $ARCurrent;
2824
2825
		$ARCurrent->$var=$value;
2826
	}
2827
2828
	public function _putvar($var, $value) {
2829
		return $this->putvar($var, $value);
2830
	}
2831
2832
	public function _setnls($nls) {
2833
		$this->setnls($nls);
2834
	}
2835
2836
	// not exposed to pinp for obvious reasons
2837
	public function sgKey($grants) {
2838
		global $AR;
2839
		if( !$AR->sgSalt || !$this->CheckSilent("config") ) {
2840
			return false;
2841
		}
2842
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2843
		$this->_load("mod_grant.php");
2844
		$mg = new mod_grant();
2845
		$grantsarray = array();
2846
		$mg->compile($grants, $grantsarray);
2847
		$grants = serialize($grantsarray);
2848
		return sha1( $AR->sgSalt . $grants . $this->path);
2849
	}
2850
2851
	public function sgBegin($grants, $key = '', $path = '.') {
2852
		global $AR;
2853
		$result = false;
2854
		$context = $this->getContext();
2855
		$path    = $this->make_path($path);
2856
2857
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2858
		$this->_load("mod_grant.php");
2859
		$mg = new mod_grant();
2860
		$grantsarray = array();
2861
		$mg->compile($grants, $grantsarray);
2862
2863
		if ($context['scope'] == 'pinp') {
2864
			$checkgrants = serialize($grantsarray);
2865
			$check = ( $AR->sgSalt ? sha1( $AR->sgSalt . $checkgrants . $path) : false ); // not using suKey because that checks for config grant
2866
		} else {
2867
			$check = true;
2868
			$key = true;
2869
		}
2870
		if( $check !== false && $check === $key ) {
2871
			$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2872
			$grantsarray = (array)$AR->sgGrants[$path];
2873
			$mg->compile($grants, $grantsarray);
2874
			$AR->sgGrants[$path] = $grantsarray;
2875
			$result = true;
2876
		}
2877
		return $result;
2878
	}
2879
2880
	public function sgEnd($path = '.') {
2881
		global $AR;
2882
		$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2883
		$path = $this->make_path( $path );
2884
		unset($AR->sgGrants[$path]);
2885
		return true; // temp return true;
0 ignored issues
show
Unused Code Comprehensibility introduced by
43% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
2886
	}
2887
2888
	public function sgCall($grants, $key, $function="view.html", $args="") {
2889
		$result = false;
2890
		if( $this->sgBegin($grants, $key ) ) {
2891
			$result = $this->call($function, $args);
0 ignored issues
show
Documentation introduced by
$args is of type string, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2892
			$this->sgEnd();
2893
		}
2894
		return $result;
2895
	}
2896
2897
	public function _sgBegin($grants, $key, $path = '.') {
2898
		return $this->sgBegin($grants, $key, $path);
2899
	}
2900
2901
	public function _sgEnd($path = '.') {
2902
		return $this->sgEnd($path);
2903
	}
2904
2905
	public function _sgCall($grants, $key, $function="view.html", $args="") {
2906
		return $this->sgCall($grants, $key, $function, $args);
2907
	}
2908
2909
	public function _widget($arWidgetName, $arWidgetTemplate, $arWidgetArgs="", $arWidgetType="lib") {
2910
	global $AR, $ARConfig, $ARCurrent, $ARnls;
2911
2912
		$arWidgetName=preg_replace("/[^a-zA-Z0-9\/]/","",$arWidgetName);
2913
		$arWidgetTemplate=preg_replace("/[^a-zA-Z0-9\.]/","",$arWidgetTemplate);
2914
		$wgResult=null;
2915
		if ($arWidgetType=="www") {
2916
			$coderoot=$AR->dir->root;
2917
		} else {
2918
			$coderoot=$this->store->get_config("code");
2919
		}
2920
		if (file_exists($coderoot."widgets/$arWidgetName")) {
2921
			if (file_exists($coderoot."widgets/$arWidgetName/$arWidgetTemplate")) {
2922
				if (is_array($arWidgetArgs)) {
2923
					extract($arWidgetArgs);
2924
				} else if (is_string($arWidgetArgs)) {
2925
					Parse_str($arWidgetArgs);
2926
				}
2927
				include($coderoot."widgets/$arWidgetName/$arWidgetTemplate");
2928
			} else {
2929
				error("Template $arWidgetTemplate for widget $arWidgetName not found.");
2930
			}
2931
		} else {
2932
			error(sprintf($ARnls["err:widgetnotfound"],$arWidgetName));
2933
		}
2934
		if ($wgResult) {
2935
			return $wgResult;
2936
		}
2937
	}
2938
2939
	public function _getdata($varname, $nls="none", $emptyResult=false) {
2940
		return $this->getdata($varname, $nls, $emptyResult);
2941
	}
2942
2943
	public function _showdata($varname, $nls="none", $emptyResult=false) {
2944
		$this->showdata($varname, $nls, $emptyResult);
2945
	}
2946
2947
	public function _gettext($index=false) {
2948
	global $ARnls;
2949
		if (!$index) {
2950
			return $ARnls;
2951
		} else {
2952
			return $ARnls[$index];
2953
		}
2954
	}
2955
2956
	public function _loadtext($nls, $section="") {
2957
	global $ARnls, $ARCurrent;
2958
		if( is_object($ARnls) ) {
2959
			$ARnls->load($section, $nls);
2960
			$ARnls->setLanguage($nls);
2961
			$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...
2962
		} else { // older loaders and other shizzle
2963
2964
			$nls = preg_replace('/[^a-z]*/i','',$nls);
2965
			$section = preg_replace('/[^a-z0-9\._:-]*/i','',$section);
2966
			if (!$section) {
2967
				include($this->store->get_config("code")."nls/".$nls);
2968
				$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2969
			} else {
2970
				$nlsfile = $this->store->get_config("code")."nls/".$section.".".$nls;
2971
				if(strpos($nlsfile, ':') === false && file_exists($nlsfile)) {
2972
					include($nlsfile);
2973
					$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2974
				} else {
2975
					// current result;
2976
					$arResult = $ARCurrent->arResult;
2977
					$this->pushContext(array());
2978
						$oldnls = $this->reqnls;
2979
						$this->reqnls = $nls;
2980
						$this->CheckConfig($section, array('nls' => $nls));
0 ignored issues
show
Documentation introduced by
array('nls' => $nls) is of type array<string,?,{"nls":"?"}>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2981
						$this->reqnls = $oldnls;
2982
					$this->popContext();
2983
					// reset current result (CheckConfig may have changed it when it should not have).
2984
					$ARCurrent->arResult = $arResult;
2985
				}
2986
			}
2987
		}
2988
	}
2989
2990
	public function _startsession() {
2991
	global $ARCurrent;
2992
		ldStartSession(0);
2993
		return $ARCurrent->session->id;
2994
	}
2995
2996
	public function _putsessionvar($varname, $varvalue) {
2997
	global $ARCurrent;
2998
2999
		if ($ARCurrent->session) {
3000
			return $ARCurrent->session->put($varname, $varvalue);
3001
		} else {
3002
			return false;
3003
		}
3004
	}
3005
3006
	public function _getsessionvar($varname) {
3007
	global $ARCurrent;
3008
3009
		if ($ARCurrent->session) {
3010
			return $ARCurrent->session->get($varname);
3011
		} else {
3012
			return false;
3013
		}
3014
	}
3015
3016
	public function _setsessiontimeout($timeout = 0) {
3017
	global $ARCurrent;
3018
		if ($ARCurrent->session) {
3019
			return $ARCurrent->session->setTimeout($timeout);
3020
		} else {
3021
			return false;
3022
		}
3023
	}
3024
3025
	public function _killsession() {
3026
	global $ARCurrent;
3027
3028
		if ($ARCurrent->session) {
3029
			$ARCurrent->session->kill();
3030
			unset($ARCurrent->session);
3031
		}
3032
	}
3033
3034
	public function _sessionid() {
3035
	global $ARCurrent;
3036
		if ($ARCurrent->session) {
3037
			return $ARCurrent->session->id;
3038
		} else {
3039
			return 0;
3040
		}
3041
	}
3042
3043
	public function _resetloopcheck() {
3044
		return $this->resetloopcheck();
3045
	}
3046
3047
	public function _make_path($path="") {
3048
		return $this->make_path($path);
3049
	}
3050
3051
	public function _make_ariadne_url($path="") {
3052
		return $this->make_ariadne_url($path);
3053
	}
3054
3055
	public function _make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
3056
		return $this->make_url($path, $nls, $session, $https, $keephost);
3057
	}
3058
3059
	public function _make_local_url($path="", $nls=false, $session=true, $https=null) {
3060
		return $this->make_local_url($path, $nls, $session, $https);
3061
	}
3062
3063
	public function _getcache($name, $nls='') {
3064
		return $this->getcache($name, $nls);
3065
	}
3066
3067
	public function _cached($name, $nls='') {
3068
		return $this->cached($name, $nls);
3069
	}
3070
3071
	public function _savecache($time="") {
3072
		return $this->savecache($time);
3073
	}
3074
3075
	public function _getdatacache($name) {
3076
		return $this->getdatacache($name);
3077
	}
3078
3079
	public function _savedatacache($name,$data,$time="")
3080
	{
3081
		return $this->savedatacache($name,$data,$time);
3082
	}
3083
3084 56
	public function currentsite($path="", $skipRedirects = false) {
3085 56
		global $ARCurrent, $ARConfig;
3086 56
		if (!$path) {
3087 48
			$path=$this->path;
3088 48
		}
3089 56
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3090 56
		if (!$skipRedirects && @count($ARCurrent->shortcut_redirect)) {
3091
			$redir = end($ARCurrent->shortcut_redirect);
3092
			if ($redir["keepurl"] && substr($path, 0, strlen($redir["dest"])) == $redir["dest"]) {
3093
				if (substr($config->site, 0, strlen($redir["dest"]))!=$redir["dest"]) {
3094
					// search currentsite from the reference
3095
					$config = ($ARConfig->cache[$redir['src']]) ? $ARConfig->cache[$redir['src']] : $this->loadConfig($redir['src']);
3096
				}
3097
			}
3098
		}
3099 56
		return $config->site;
3100
	}
3101
3102
	public function parentsite($site) {
3103
	global $ARConfig;
3104
		$path=$this->store->make_path($site, "..");
3105
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3106
		return $config->site;
3107
	}
3108
3109 4 View Code Duplication
	public function currentsection($path="") {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
3110 4
	global $ARConfig;
3111 4
		if (!$path) {
3112 4
			$path=$this->path;
3113 4
		}
3114 4
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3115 4
		return $config->section;
3116
	}
3117
3118 View Code Duplication
	public function parentsection($path) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
3119
	global $ARConfig;
3120
		$path=$this->store->make_path($path, "..");
3121
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3122
		return $config->section;
3123
	}
3124
3125 View Code Duplication
	public function currentproject($path="") {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

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

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

Loading history...
3126
	global $ARConfig;
3127
		if (!$path) {
3128
			$path=$this->path;
3129
		}
3130
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3131
		return $config->project;
3132
	}
3133
3134
	public function parentproject($path) {
3135
	global $ARConfig;
3136
		$path=$this->store->make_path($path, "..");
3137
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3138
		return $config->project;
3139
	}
3140
3141
	public function validateFormSecret() {
3142
		global $ARCurrent;
3143
		if (!$ARCurrent->session) {
3144
			return true;
3145
		}
3146
3147
		if ($ARCurrent->session && $ARCurrent->session->data && $ARCurrent->session->data->formSecret) {
3148
			$formSecret = $this->getvar("formSecret");
3149
			return ($formSecret === $ARCurrent->session->data->formSecret);
3150
		}
3151
		return false;
3152
	}
3153
3154
	public function _validateFormSecret() {
3155
		return $this->validateFormSecret();
3156
	}
3157
3158
	public function getValue($name, $nls=false) {
3159
	global $ARCurrent;
3160
		switch ($nls) {
3161
			case "none":
3162
				$result = $this->data->$name;
3163
			break;
3164
			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...
3165
				$nls = $ARCurrent->nls;
3166
				if (!isset($this->data->$nls) || !isset($this->data->$nls->$name)) {
3167
					$result = $this->data->$name;
3168
					break;
3169
				}
3170
			default:
3171
				$result = $this->data->$nls->$name;
3172
		}
3173
		return $result;
3174
	}
3175
3176
	public function setValue($name, $value, $nls=false) {
3177
3178
	global $AR, $ARConfig;
3179
		if ($value === null) {
3180
			if ($nls && $nls!="none") {
3181
				unset($this->data->$nls->$name);
3182
				if (!count(get_object_vars($this->data->$nls))) {
3183
					unset($this->data->$nls);
3184
					unset($this->data->nls->list[$nls]);
3185
					if (!count($this->data->nls->list)) {
3186
						unset($this->data->nls->list);
3187
						unset($this->data->nls);
3188
					} else {
3189
						if ($this->data->nls->default == $nls) {
3190
							if ($this->data->nls->list[$ARConfig->nls->default]) {
3191
								$this->data->nls->default = $ARConfig->nls->default;
3192
							} else {
3193
								list($this->data->nls->default) = each($this->data->nls->list);
3194
							}
3195
						}
3196
					}
3197
				}
3198
			} else {
3199
				unset($this->data->$name);
3200
			}
3201
		} else
3202
		if (!$nls) {
3203
			$this->data->$name = $value;
3204
		} else {
3205
			if (!$this->data->$nls) {
3206
				$this->data->$nls = new object;
3207
				if (!$this->data->nls) {
3208
					$this->data->nls = new object;
3209
					$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...
3210
				}
3211
				$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...
3212
			}
3213
			$this->data->$nls->$name = $value;
3214
		}
3215
	}
3216
3217
	public function showValue($name, $nls=false) {
3218
		$result = $this->getValue($name, $nls);
3219
		echo $result;
3220
		return $result;
3221
	}
3222
3223
	public function _getValue($name, $nls=false) {
3224
		return $this->getValue($name, $nls);
3225
	}
3226
3227
	public function _setValue($name, $value, $nls=false) {
3228
		return $this->setValue($name, $value, $nls);
3229
	}
3230
3231
	public function _showValue($name, $nls=false) {
3232
		return $this->showValue($name, $nls);
3233
	}
3234
3235
	public function _currentsite($path="", $skipRedirects = false) {
3236
		return $this->currentsite( $path, $skipRedirects );
3237
	}
3238
3239
	public function _parentsite($site) {
3240
		return $this->parentsite($site);
3241
	}
3242
3243
	public function _currentsection() {
3244
		return $this->currentsection();
3245
	}
3246
3247
	public function _parentsection($section) {
3248
		return $this->parentsection($section);
3249
	}
3250
3251
	public function _currentproject() {
3252
		return $this->currentproject();
3253
	}
3254
3255
	public function _parentproject($path) {
3256
		return $this->parentproject($path);
3257
	}
3258
3259
	public function _checkAdmin($user) {
3260
		return $this->CheckAdmin($user);
3261
	}
3262
3263
	public function _checkgrant($grant, $modifier=ARTHISTYPE, $path=".") {
3264
		// as this is called within a pinp template,
3265
		// all the grants are already loaded, so
3266
		// checksilent will fullfill our needs
3267
		$this->pushContext(array("scope" => "php"));
3268
			$result = $this->CheckSilent($grant, $modifier, $path);
3269
		$this->popContext();
3270
		return $result;
3271
	}
3272
3273
	public function _checkpublic($grant, $modifier=ARTHISTYPE) {
3274
3275
		return $this->CheckPublic($grant, $modifier);
3276
	}
3277
3278
	public function _getcharset() {
3279
		return $this->getcharset();
3280
	}
3281
3282
	public function _count_find($query='') {
3283
		return $this->count_find($this->path, $query);
3284
	}
3285
3286
	public function _count_ls() {
3287
		return $this->count_ls($this->path);
3288
	}
3289
3290
	public function _HTTPRequest($method, $url, $postdata = "", $port=80) {
3291
		return $this->HTTPRequest($method, $url, $postdata, $port);
3292
	}
3293
3294
	public function _make_filesize( $size="" ,$precision=0) {
3295
		return $this->make_filesize( $size ,$precision);
3296
	}
3297
3298
	public function _convertToUTF8($data, $charset = "CP1252") {
3299
		return $this->convertToUTF8($data,$charset);
3300
	}
3301
3302
	public function _getuser() {
3303
	global $AR;
3304
		if ($AR->pinp_user && $AR->pinp_user->data->login == $AR->user->data->login) {
3305
			$user = $AR->pinp_user;
3306
		} else {
3307
			$this->pushContext(array("scope" => "php"));
3308
				if ( $AR->user instanceof ariadne_object ) {
3309
					$user = current($AR->user->get(".", "system.get.phtml"));
3310
				} else {
3311
					$user = $AR->user;
3312
				}
3313
				$AR->pinp_user = $user;
3314
			$this->popContext();
3315
		}
3316
		return $user;
3317
	}
3318
3319
	public function ARinclude($file) {
3320
		include($file);
3321
	}
3322
3323 4
	public function _load($class) {
3324
		// only allow access to modules in the modules directory.
3325 4
		$class = preg_replace('/[^a-z0-9\._]/i','',$class);
3326 4
		include_once($this->store->get_config("code")."modules/".$class);
3327 4
	}
3328
3329
	public function _import($class) {
3330
		// deprecated
3331
		return $this->_load($class);
3332
	}
3333
3334 52
	public function html_to_text($text) {
3335 52
		$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
3336 52
		$cb  = function($matches) use ($trans) {
3337
			return strtr($matches[1],$trans);
3338 52
		};
3339
		//strip nonbreaking space, strip script and style blocks, strip html tags, convert html entites, strip extra white space
3340 52
		$search_clean = array("%&nbsp;%i", "%<(script|style)[^>]*>.*?<\/(script|style)[^>]*>%si", "%<[\/]*[^<>]*>%Usi", "%\s+%");
3341 52
		$replace_clean = array(" ", " ", " ", " ");
3342
3343 52
		$text = preg_replace_callback(
3344 52
			"%(\&[a-zA-Z0-9\#]+;)%s",
3345 52
			$cb,
3346
			$text
3347 52
		);
3348 52
		$text = preg_replace($search_clean, $replace_clean, $text);
3349 52
		return $text;
3350
	}
3351
3352
	public function _html_to_text($text) {
3353
		return $this->html_to_text($text);
3354
	}
3355
3356
	public function _newobject($filename, $type) {
3357
		$newpath=$this->make_path($filename);
3358
		$newparent=$this->store->make_path($newpath, "..");
3359
		$data=new object;
3360
		$object=$this->store->newobject($newpath, $newparent, $type, $data);
3361
		$object->arIsNewObject=true;
3362
		return $object;
3363
	}
3364
3365
	public function _save($properties="", $vtype="") {
3366
		if (is_array($properties)) {
3367
			// isn't this double work, the save function doesn this again
3368
			foreach ($properties as $prop_name => $prop) {
3369
				foreach ($prop as $prop_index => $prop_record) {
3370
					$record = array();
3371 View Code Duplication
					foreach ($prop_record as $prop_field => $prop_value) {
3372
						switch (gettype($prop_value)) {
3373
							case "integer":
3374
							case "boolean":
3375
							case "double":
3376
								$value = $prop_value;
3377
							break;
3378
							default:
3379
								$value = $prop_value;
3380
								if (substr($prop_value, 0, 1) === "'" && substr($prop_value, -1) === "'"
3381
										&& "'".AddSlashes(StripSlashes(substr($prop_value, 1, -1)))."'" == $prop_value) {
3382
									$value = stripSlashes(substr($prop_value,1,-1));
3383
									// todo add deprecated warning
3384
								}
3385
						}
3386
						$record[$prop_field] = $value;
3387
					}
3388
					$properties[$prop_name][$prop_index] = $record;
3389
				}
3390
			}
3391
		}
3392
3393
		if ($this->arIsNewObject && $this->CheckSilent('add', $this->type)) {
3394
			unset($this->data->config);
3395
			$result = $this->save($properties, $vtype);
0 ignored issues
show
Bug introduced by
It seems like $properties can also be of type array; 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...
3396
		} else if (!$this->arIsNewObject && $this->CheckSilent('edit', $this->type)) {
3397
			$this->data->config = current($this->get('.', 'system.get.data.config.phtml'));
3398
			$result = $this->save($properties, $vtype);
0 ignored issues
show
Bug introduced by
It seems like $properties can also be of type array; 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...
3399
		}
3400
		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...
3401
	}
3402
3403
	public function _is_supported($feature) {
3404
		return $this->store->is_supported($feature);
3405
	}
3406
3407
	/*
3408
		since the preg_replace() function is able to execute normal php code
3409
		we have to intercept all preg_replace() calls and parse the
3410
		php code with the pinp parser.
3411
	*/
3412
3413
3414
	/*	this is a private function used by the _preg_replace wrapper */
3415
3416
	protected function preg_replace_compile($pattern, $replacement) {
3417
	global $AR;
3418
		include_once($this->store->get_config("code")."modules/mod_pinp.phtml");
3419
		preg_match("/^\s*(.)/", $pattern, $regs);
3420
		$delim = $regs[1];
3421
		// TODO: fixme deze eregi vervangen door iets wat niet eregi is
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "deze eregi vervangen door iets wat niet eregi is"
Loading history...
3422
		if (@eregi("\\${delim}[^$delim]*\\${delim}.*e.*".'$', $pattern)) {
3423
			$pinp = new pinp($AR->PINP_Functions, 'local->', '$AR_this->_');
3424
			return substr($pinp->compile("<pinp>$replacement</pinp>"), 5, -2);
3425
		} else {
3426
			return $replacement;
3427
		}
3428
	}
3429
3430
	public function _preg_replace($pattern, $replacement, $text, $limit = -1) {
3431
		if (is_array($pattern)) {
3432
			$newrepl = array();
3433
			reset($replacement);
3434
			foreach ($pattern as $i_pattern) {
3435
				list(, $i_replacement) = each($replacement);
3436
				$newrepl[] = $this->preg_replace_compile($i_pattern, $i_replacement);
3437
			}
3438
		} else {
3439
			$newrepl = $this->preg_replace_compile($pattern, $replacement);
3440
		}
3441
		return preg_replace($pattern, $newrepl, $text, $limit);
3442
	}
3443
3444
	/* ob_start accepts a callback but we don't want that
3445
	 * this wrapper removes the arguments from the ob_start call
3446
	 */
3447
	public function _ob_start() {
3448
		return ob_start();
3449
	}
3450
3451
	public function _loadConfig($path='') {
3452
		return clone $this->loadConfig($path);
3453
	}
3454
3455
	public function _loadUserConfig($path='') {
3456
		return $this->loadUserConfig($path);
3457
	}
3458
3459
	public function _loadLibrary($name, $path) {
3460 4
		return $this->loadLibrary($name, $path);
3461
	}
3462
3463
	public function _resetConfig($path='') {
3464
		return $this->resetConfig($path);
3465
	}
3466
3467
	public function _getLibraries($path = '') {
3468
		return $this->getLibraries($path);
3469
	}
3470
3471
3472
	public function _getSetting($setting) {
3473
	global $AR;
3474
3475
		switch ($setting) {
3476
			case 'www':
3477
			case 'dir:www':
3478
				return $AR->dir->www;
3479
			case 'images':
3480
			case 'dir:images':
3481
				return $AR->dir->images;
3482
			case 'ARSessionKeyCheck':
3483
				$result = null;
3484
				if (function_exists('ldGenerateSessionKeyCheck')) {
3485
					$result = ldGenerateSessionKeyCheck();
3486
				}
3487
				return $result;
3488
			break;
3489
			case 'nls:list':
3490
				return $AR->nls->list;
3491
			break;
3492
			case 'nls:default':
3493
				return $AR->nls->default;
3494
			break;
3495
			case 'svn':
3496
				return $AR->SVN->enabled;
3497
			break;
3498
		}
3499
	}
3500
3501
	public function __call($name,$arguments) {
3502
		if ( $name[0] == '_' ) {
3503
			$fname = substr($name, 1);
3504
			if ( isset($this->{$fname}) && $this->{$fname} instanceof \Closure ) {
3505
				\Closure::bind( $this->{$fname}, $this );
3506
				return call_user_func_array( $this->{$fname}, $arguments);
3507
			}
3508
		}
3509
		switch($name) {
3510
			case "implements":
3511
				return $this->AR_implements($arguments[0]);
3512
			break;
3513
			default:
3514
				trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $name), E_USER_ERROR);
3515
				return false;
3516
			break;
3517
		}
3518
	}
3519
3520
	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...
3521 4
		global $nocache;
3522 4
		if (($errno & error_reporting()) == 0) {
3523 4
			return true;
3524
		}
3525
3526
		$nocache = true;
3527
		$context = pobject::getContext();
3528
		if ($context["arLibraryPath"]) { //  != null) {
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
3529
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." in library ".$context["arLibraryPath"] ."\n".$errstr."\n";
3530
		} else {
3531
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." on object ".$context['arCurrentObject']->path."\n".$errstr."\n";
3532
		}
3533
		$display = ini_get('display_errors');
3534
3535
		if($display) {
3536
			echo $msg;
3537
		}
3538
		error_log($msg);
3539
3540
		return false;
3541
	}
3542
3543
} // end of ariadne_object class definition
3544