Completed
Pull Request — master (#101)
by Robbert
63:07
created

ariadne_object::saveCustomData()   D

Complexity

Conditions 16
Paths 4

Size

Total Lines 48
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 147.072

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 48
ccs 8
cts 40
cp 0.2
rs 4.9765
cc 16
eloc 28
nc 4
nop 2
crap 147.072

How to fix   Complexity   

Long Method

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

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

Commonly applied refactorings include:

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

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

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

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

Loading history...
2
    /******************************************************************
3
     pobject.phtml                                         Muze Ariadne
4
     ------------------------------------------------------------------
5
     Author: Muze ([email protected])
6
     Date: 31 october 2002
7
8
     Copyright 2002 Muze
9
10
     This file is part of Ariadne.
11
12
     Ariadne is free software; you can redistribute it and/or modify
13
     it under the terms of the GNU General Public License as published
14
     by the Free Software Foundation; either version 2 of the License,
15
     or (at your option) any later version.
16
17
     Ariadne is distributed in the hope that it will be useful,
18
     but WITHOUT ANY WARRANTY; without even the implied warranty of
19
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
     GNU General Public License for more details.
21
22
     You should have received a copy of the GNU General Public License
23
     along with Ariadne; if not, write to the Free Software
24
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25
     02111-1307  USA
26
27
    -------------------------------------------------------------------
28
29
     Class inheritance: 	pobject
30
     Description:
31
32
       This is the class definition file of the pobject class.
33
34
    ******************************************************************/
35
36
debug("pobject: Load","object");
37
38
abstract class ariadne_object extends object { // ariadne_object class definition
39
40
	public $store;
41
	public $path;
42
	public $data;
43
44 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 14
		}
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 6
		} 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 10
			$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 92
			"arCallFunction" => $arCallFunction
95 92
		) );
96
97
		// convert the deprecated urlencoded arguments to an array
98 184
		if (isset($arCallArgs) && is_string($arCallArgs)) {
99 184
			$ARCurrent->arTemp=$arCallArgs;
100 184
			$arCallArgs=array();
101 184
			parse_str($ARCurrent->arTemp, $arCallArgs);
102 92
		}
103
		// import the arguments in the current scope, but don't overwrite existing
104
		// variables.
105 184
		if (isset($arCallArgs) && is_array($arCallArgs)) {
106 184
			extract($arCallArgs,EXTR_SKIP);
107 92
		}
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 50
		} 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 92
		} else {
122
			// the requested language is not available, use default of the
123
			// current object instead.
124
			$this->nls=$this->data->nls->default;
125 2
			$nls=&$this->nls;
126
		}
127 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 66
		} 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 2
		}
138 184
		if (isset($this->data->custom['none'])) {
139 6
			$customdata=$this->data->custom['none'];
140 4
		}
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 12
				$arCallFunction = $libname.":".$arCallFunction;
154
			}
155 12
		} 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 2
				}
167
			}
168 2
		} else {
169 184
			if ($arCallFunction[0] === "#") {
170 10
				$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 34
				$arResult = $this;
178 16
			} 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 2
					}
190 24
					$arType=$arSuper;
191 12
				}
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 10
						break;
209 12
					} 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 10
							$arSuper=get_parent_class($arType);
218
219 20
							$AR->superClass[$arType]=$arSuper;
220 4
						}
221 184
						$arType=$arSuper;
222 2
					}
223 92
				}
224
			}
225 2
		}
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 10
		}
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 2
	public function ls($path="", $function="list.html", $args="") {
241 2
		$path=$this->store->make_path($this->path, $path);
242 2
		return $this->store->call($function, $args, $this->store->ls($path));
243 2
	}
244
245 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 2
	}
249
250 6
	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 6
			$top = $this->currentsection();
255 2
		} else {
256 6
			$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 2
		} 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 4
			}
274 2
		}
275 4
		$parents = array_reverse($parents);
276 4
		$result = array();
277 6
		foreach ($parents as $parent) {
278 4
			if ( $parent ) { // might not have read access to this object
279 4
				$result[] = $parent->call($function, $args);
280 2
			}
281 2
		}
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 2 View Code Duplication
		} else {
292
			$this->error = ar::error( ''.$this->store->error, 1110, $this->store->error );
0 ignored issues
show
Bug introduced by
The property error does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
293
			$result = false;
294 2
		}
295 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 2
	private function saveMergeWorkflowResult($properties, $wf_result) {
313
		foreach ($wf_result as $wf_prop_name => $wf_prop) {
314
			foreach ($wf_prop as $wf_prop_index => $wf_prop_record) {
315
				if (!isset($wf_prop_record)) {
316
					unset($properties[$wf_prop_name][$wf_prop_index]);
317
				} else {
318
					$record = array();
319 View Code Duplication
					foreach ($wf_prop_record as $wf_prop_field => $wf_prop_value) {
320
						switch (gettype($wf_prop_value)) {
321 2
							case "integer":
322
							case "boolean":
323
							case "double":
324
								$value = $wf_prop_value;
325
								break;
326
							default:
327
								$value = $wf_prop_value;
328
								// backwards compatibility, store will do the escaping from now on
329
								// will be removed in the future
330
								if (substr($wf_prop_value, 0, 1) === "'" && substr($wf_prop_value, -1) === "'"
331
										&& "'".AddSlashes(StripSlashes(substr($wf_prop_value, 1, -1)))."'" == $wf_prop_value) {
332
									$value = stripSlashes(substr($wf_prop_value,1,-1));
333
									// todo add deprecated warning
334
								}
335
336 2
						}
337
						$record[$wf_prop_field] = $value;
338
					}
339
					$properties[$wf_prop_name][] = $record;
340
				}
341
			}
342
		}
343
344
		return $properties;
345
	}
346
347
	/*
348
		saves custom data
349
		returns properties for custom data
350
	*/
351 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 (isset($custom) && is_array($custom)) {
355
			foreach($custom as $nls=>$entries){
356
				if (isset($entries) && is_array($entries)) {
357
					foreach ( $entries as $customkey => $customval ){
358
						$this->data->custom[$nls][$customkey] = $customval;
359
					}
360
				}
361
			}
362
		}
363
		// the above works because either $custom comes from the form entry, and parse_str returns an
364
		// array with the name $custom, or $custom comes from the object and is an array and as such
365
		// parse_str fails miserably thus keeping the array $custom intact.
366
367 48
		if (isset($this->data->custom) && is_array($this->data->custom)) {
368 48
			foreach($this->data->custom as $nls => $cdata) {
369
				foreach($cdata as $name => $value){
370
					// one index, this order (name, value, nls) ?
371
					if ($configcache->custom[$name]['containsHTML']) {
372
						$this->_load('mod_url.php');
373
						$value = URL::RAWtoAR($value, $nls);
374
						$this->data->custom[$nls][$name] = $value;
375
					}
376
					if ($configcache->custom[$name]['property']) {
377
						if (isset($value) && is_array($value)) {
378
							foreach($value as $valkey => $valvalue ) {
379
								$properties["custom"][] = [
380
									"name"  => $name,
381
									"value" => $valvalue,
382
									"nls"   => $nls,
383
								];
384
							}
385
						} else {
386
							$properties["custom"][] = [
387
								"name"  => $name,
388
								"value" => $value,
389
								"nls"   => $nls,
390
							];
391
392
						}
393
					}
394
				}
395 48
			}
396
		}
397
		return $properties;
398 50
	}
399
400
	public function save($properties="", $vtype="") {
401
	/***********************************************************************
402
	  save the current object.
403
	  if this is a new object ($this->arIsNewObject) the path is checked and
404 48
	  the object is saved under the new path.
405 48
	***********************************************************************/
406 50
	global $AR, $ARnls, $ARCurrent;
407 48
		debug("pobject: save([properties], $vtype)","object");
408 48
		debug("pobject: save: path=".$this->path,"object");
409 48
		$configcache=$this->loadConfig();
410 48
		$needsUnlock = false;
411 48
		$arIsNewObject = false;
412 48
		$result = false;
413 24
		$this->error = '';
414 24
		if ($this->arIsNewObject) { // save a new object
0 ignored issues
show
Bug introduced by
The property arIsNewObject does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
415 24
			debug("pobject: save: new object","all");
416 24
			$this->path = $this->make_path();
417 24
			$arNewParent=$this->make_path("..");
418 24
			$arNewFilename=basename($this->path);
419 24
			$arIsNewObject = true;
420 24
			if (preg_match("|^[a-z0-9_\{\}\.\:-]+$|i",$arNewFilename)) { // no "/" allowed, these will void the 'add' grant check.
421 24
				if (!$this->exists($this->path)) { //arNewFilename)) {
422 12
					if ($this->exists($arNewParent)) {
423
						if (!$config = $this->data->config) {
424 12
							$config=new object();
425 12
						}
426
					} else {
427 12
						$this->error = ar::error( sprintf($ARnls["err:noparent"],$arNewParent), 1102);
428 12
					}
429
				} else {
430 12
					$this->error = ar::error( sprintf($ARnls["err:alreadyexists"],$arNewFilename), 1103);
431 12
				}
432
			} else {
433 12
				$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$arNewFilename), 1104);
434 48
			}
435 48
		} else { // existing object
436 48
			debug("pobject: save: existing object","all");
437
			if ($this->exists($this->path)) { // prevent 'funny stuff'
438
				if (!$this->lock()) {
439 48
					$this->error = ar::error( $ARnls["err:objectalreadylocked"], 1105);
440 48
				} else {
441
					$needsUnlock = true;
442 24
					$config = $this->data->config;
443
				}
444
			} else {
445
				$this->error = ar::error($ARnls["err:corruptpathnosave"], 1106);
446
			}
447
		}
448 48
		// pre checks done
449
		// return now on error
450
		if ($this->error) {
451
			return $result;;
452
		}
453 48
454 48
455 24
		if ($ARCurrent->arCallStack) {
456 20
			$arCallArgs = end($ARCurrent->arCallStack);
457
		} else {
458
			$arCallArgs = array();
459 48
		}
460
461 48
		$context = $this->getContext();
462 48
463 24
		$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
0 ignored issues
show
Bug introduced by
The property parent does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property id does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property lastchanged does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property vtype does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
Bug introduced by
The property priority does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
464 12
		if ( $arIsNewObject) {
465
			$wf_object->arIsNewObject=$arIsNewObject;
466
		}
467 48
468
		/* save custom data */
469 48
		$properties = $this->saveCustomData($configcache, $properties);
470 48
471 48
		// this makes sure the event handlers are run on $wf_object, so that $this->data changes don't change the data of the object to be saved
472 48
		$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $wf_object));
473 48
474 48
		$eventData = new object();
475
		$eventData->arCallArgs = $arCallArgs;
0 ignored issues
show
Bug introduced by
The property arCallArgs does not seem to exist in object.

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

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

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

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

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

Loading history...
477 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...
478
		$eventData->arProperties = $properties;
0 ignored issues
show
Bug introduced by
The property arProperties does not seem to exist in object.

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

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

Loading history...
479 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...
480
481
		// pop the wf_object, not needed later, the extra scope might hinder other code
482
		$this->popContext();
483
484 48
		if ( !$eventData ) {
485
			return false; // prevent saving of the object.
486
		}
487
488
		// arguments can be altered by event handlers, only usefull when a workflow template is also defined
489 48
		$arCallArgs = $eventData->arCallArgs;
490 48
491 24
		// the properties from the eventData are the new property list
492 44
		// no need to merge them with $properties, just manipulate the properties array directly
493
		// in the event data. unlike the user.workflow.pre.html template
494
		if (isset( $eventData->arProperties ) && is_array( $eventData->arProperties ) ) {
495
			$properties = $eventData->arProperties;
496
		} else {
497
			$properties = array();
498
		}
499 48
500 48
		// pass the current properties list to the workflow template
501
		// for backwards compatibility and workflow templates that just
502 48
		// returned only their own properties, merge them afterwards
503
		// don't do this for the eventData arProperties!
504
		$arCallArgs['properties'] = $properties;
505
		$wf_result = $wf_object->call("user.workflow.pre.html", $arCallArgs);
506 48
		/* merge workflow properties */
507 48
		if (isset($wf_result) && is_array($wf_result) ){
508 48
			$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
509 48
		}
510 48
511 48
		$this->error = $wf_object->error;
512 24
		$this->priority = $wf_object->priority;
513 12
		$this->data = $wf_object->data;
514
		$this->data->config = $config;
0 ignored issues
show
Bug introduced by
The variable $config does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
515 48
		$this->data->mtime=time();
516 48
		if($arIsNewObject) {
517 24
			$this->data->ctime=$this->data->mtime;
518 24
		}
519 12
520 24
		$this->data->muser=$AR->user->data->login;
521 24
		if( !$this->data->config->owner ) {
522 12
			if( !$this->data->config->owner_name) {
523 48
				$this->data->config->owner_name=$AR->user->data->name;
524 48
			}
525 48
			$this->data->config->owner=$AR->user->data->login;
526
			$properties["owner"][0]["value"]=$this->data->config->owner;
527
		}
528 48
		$properties["time"][0]["ctime"]=$this->data->ctime;
529
		$properties["time"][0]["mtime"]=$this->data->mtime;
530 48
		$properties["time"][0]["muser"]=$this->data->muser;
531 48
532 48
533 48
		if (!$this->error) {
534 48
			if ($this->path=$this->store->save($this->path, $this->type, $this->data, $properties, $vtype, $this->priority)) {
535
				unset($this->arIsNewObject);
536 48
				$this->id=$this->exists($this->path);
537
				$result=$this->path;
538 48
539 48
				$config=$this->data->config; // need to set it again, to copy owner config data
540 48
541
				$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
542 48
				$arCallArgs = $eventData->arCallArgs; // returned from onbeforesave event
543 24
				$arCallArgs['properties'] = $properties;
544 12
545 48
				if ($arIsNewObject) {
546 48
					$wf_object->arIsNewObject = $arIsNewObject;
547 48
				}
548 48
				$wf_result = $wf_object->call("user.workflow.post.html", $arCallArgs);
549 48
				$this->error = $wf_object->error;
550
				$this->priority = $wf_object->priority;
551
				$this->data = $wf_object->data;
552 48
				$this->data->config = $config;
553
				/* merge workflow properties */
554
555
				if (isset($wf_result) && is_array($wf_result) ){
556
					$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
557
558
					if (!$this->store->save($this->path, $this->type, $this->data, $properties, $this->vtype, $this->priority)) {
559
						$this->error = ar::error( ''.$this->store->error, 1108, $this->store->error);
560
						$result = false;
561 48
					}
562
				}
563
				// all save actions have been done, fire onsave.
564 48
				$this->data->config = $config;
565 48
566 48
				//$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...
567 48
				$eventData->arProperties = $properties;
568 24
				$this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this));
569
				ar_events::fire( 'onsave', $eventData ); // nothing to prevent here, so ignore return value
570
				$this->popContext();
571 View Code Duplication
			} else {
572 24
				$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
573 48
				$result = false;
574 48
			}
575 24
		}
576
		if( $needsUnlock == true ){
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

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

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

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

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

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

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

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

Loading history...
613
		$eventData = ar_events::fire( 'onbeforedelete', $eventData );
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...
614
		if ( !$eventData ) {
615
			return false;
616
		}
617
		$this->call("user.workflow.delete.pre.html", $eventData->arCallArgs);
618
		if (!$this->error) {
619
			if ($this->store->delete($this->path)) {
620
				$result = true;
621
				$this->call("user.workflow.delete.post.html", $eventData->arCallArgs);
622
				ar_events::fire( 'ondelete', $eventData );
623
			} else {
624
				$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
625
			}
626
		}
627 56
		return $result;
628 56
	}
629 56
630
	public function exists($path) {
631
		$path=$this->make_path($path);
632 72
		return $this->store->exists($path);
633
	}
634 72
635 36
	public function make_path($path="") {
636 68
		switch($path){
637 72
			case '':
638
			case '.':
639 60
			case $this->path:
640 24
				return $this->path;
641
				break;
642 30
			case '..':
643 60
				return $this->parent;
644 30
				break;
645
			default:
646
				return $this->store->make_path($this->path, $path);
647
		}
648
	}
649
650
	public function make_ariadne_url($path="") {
651
		global $AR;
652
		$path = $this->make_path($path);
653
		return $AR->host . $AR->root . $this->store->get_config('rootoptions') . $path;
654 52
	}
655 52
656
657 52
	public function make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
658 52
		global $ARConfig, $AR, $ARCurrent;
659 52
660 52
		$rootoptions=$this->store->get_config('rootoptions');
661
		if (!$session || ($nls !== false)) {
662
			$rootoptions = "";
663 52
			if ($session && isset($ARCurrent->session->id) && !$AR->hideSessionIDfromURL) {
664 48
				$rootoptions .= "/-".$ARCurrent->session->id."-";
665 48
			}
666 24
			if ($nls) {
667 26
				$rootoptions_nonls = $rootoptions;
668 52
				$rootoptions .= '/'.$nls;
669
			}
670
		}
671 52
		$path=$this->make_path($path);
672 4
673 4
		// now run CheckConfig and get the parentsite of the path found
674
		if (!$temp_config=$ARConfig->cache[$path]) {
675
			$temp_path = $path;
676 4
			while (!($temp_site = $this->currentsite($temp_path)) && $temp_path!='/') {
677 2
				$temp_path = $this->make_path($temp_path.'../');
678
			}
679 52
			$temp_config=$ARConfig->cache[$temp_site];
680 52
		}
681 52
682 26
		if ( !isset($keephost) && (
683
			(!$nls && $this->compare_hosts($AR->host, $temp_config->root["value"])) ||
684
			($nls && ($this->compare_hosts($AR->host, $temp_config->root['list']['nls'][$nls])))
685
		)) {
686 52
			$keephost = false;
687 52
		}
688 48
689 48
		if (!$keephost) {
690
			if ($nls) {
691
				$url=$temp_config->root["list"]["nls"][$nls];
692 48
				if (isset($url) && is_array($url)) {
693
					$url = current( $url );
694
				}
695
				if ($url) {
696 View Code Duplication
					if (substr($url, -1)=='/') {
697
						$url=substr($url, 0, -1);
698 24
					}
699 52
					$url .= $rootoptions_nonls;
0 ignored issues
show
Bug introduced by
The variable $rootoptions_nonls does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
700 52
				}
701 52
			}
702 28
			if (!$url) {
0 ignored issues
show
Bug introduced by
The variable $url does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
703 14
				$checkNLS = $nls;
704 52
				if (!$checkNLS) {
705 52
					$checkNLS = $this->nls;
706
				}
707
				$urlList = $temp_config->root['list']['nls'][$checkNLS];
708 52
				if (isset($urlList) && is_array($urlList)) {
709
					$url = reset($urlList) . $rootoptions;
710 26
				} else {
711 52
					$url = $temp_config->root["value"].$rootoptions;
712
				}
713 52
			}
714
			$url.=substr($path, strlen($temp_config->root["path"])-1);
715
716
			if (is_bool($https)) {
717
				if ($https) {
718
					if ($AR->https) {
719 26
						$url = preg_replace('/^http:/', 'https:', $url);
720
					}
721
				} else {
722 26
					$url = preg_replace('/^https:/', 'http:', $url);
723 48
				}
724 48
			}
725
		} else {
726
			$checkNLS = $nls;
727 48
			if (!$checkNLS) {
728 48
				$checkNLS = $this->nls;
729 48
			}
730 24
			$urlCheck = $temp_config->root['list']['nls'][$checkNLS];
731 48
			if (!is_array($urlCheck)) {
732 48
				$urlCheck = $temp_config->root["value"];
733
			}
734
			$requestedHost = ldGetRequestedHost();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $requestedHost is correct as ldGetRequestedHost() seems to always returns null.
Loading history...
735
			if ($this->compare_hosts($requestedHost, $urlCheck)) {
736
				$url = $requestedHost . $rootoptions;
737 48
				$url .= substr($path, strlen($temp_config->root["path"])-1);
738
			} else {
739
				//$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...
740 52
				$url = $protocol . $requestedHost . $AR->root . $rootoptions . $path;
0 ignored issues
show
Bug introduced by
The variable $protocol does not exist. Did you forget to declare it?

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

Loading history...
741
			}
742
		}
743 52
		return $url;
744
	}
745
746 52
	protected function compare_hosts($url1, $url2) {
747 52
		// Check if hosts are equal, so that http://www.muze.nl and //www.muze.nl also match.
748 52
		// using preg_replace instead of parse_url() because the latter doesn't parse '//www.muze.nl' correctly.
749 26
		if (isset($url2) ) {
750 26
			if ( !is_array($url2) ){
751 48
				$url2 = array($url2);
752
			}
753
		} else {
754 52
			$url2 = array();
755
		}
756 52
757
		$prepurl1 = preg_replace('|^[a-z:]*//|i', '', $url1);
758 52
759 52
		foreach($url2 as $url) {
760 26
			if (
761 26
					$url == $url1 ||
762
					$prepurl1 == preg_replace('|^[a-z:]*//|i', '', $url2)
763 26
				) {
764 52
				return true;
765
			}
766
		}
767 48
		return false;
768 48
	}
769 48
770 48
	public function make_local_url($path="", $nls=false, $session=true, $https=null) {
771 48
		global $ARCurrent, $ARConfig;
772
		$site = false;
773 48
		$path = $this->make_path($path);
774 48
		$checkpath = $path;
775
776
		$redirects = $ARCurrent->shortcut_redirect;
777
		if (isset($redirects) && is_array($redirects)) {
778
			$newpath = $checkpath;
779
			$c_redirects = count($redirects);
780
			$c_redirects_done = 0;
781 View Code Duplication
			while (count($redirects) && ($redir = array_pop($redirects)) && $redir['keepurl'] && substr($newpath, 0, strlen($redir['dest'])) == $redir['dest']) {
782
				$c_redirects_done++;
783
				$newpath = $redir['src'].substr($newpath, strlen($redir['dest']));
784
			}
785
786
			if ($c_redirects_done == $c_redirects) {
787
				$checkpath = $redir['src'];
0 ignored issues
show
Bug introduced by
The variable $redir does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
788
			}
789 48
		}
790
791
		do {
792 48 View Code Duplication
			if (!$config=$ARConfig->cache[$checkpath]) {
793 48
				$config=($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
794 48
			}
795
			if ($config) {
796
				$checkNLS = $nls;
797 48
				if (!$checkNLS) {
798 48
					$checkNLS = $this->nls;
799 48
				}
800 24
				$urlCheck = $config->root['list']['nls'][$checkNLS];
801 48
				if (!is_array($urlCheck)) {
802
					$urlCheck = $config->root["value"];
803 48
				}
804
				$requestedHost = ldGetRequestedHost();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $requestedHost is correct as ldGetRequestedHost() seems to always returns null.
Loading history...
805
806 24
				if ($this->compare_hosts($requestedHost, $urlCheck)) {
807 48
					$site=$config->site;
808 48
				}
809 48
			}
810 48
			$prevpath=$checkpath;
811 48
			$checkpath=$this->make_path($checkpath."../");
812 24
		} while ($prevpath!=$checkpath && !$site);
813 48
		if (!$site) {
814 48
			$site='/';
815
		}
816
		$site_url=$this->make_url($site, $nls, $session, $https, true);
817 48
		if ($newpath) { // $newpath is the destination of a shortcut redirection, with keepurl on
818
			$rest=substr($newpath, strlen($site));
0 ignored issues
show
Bug introduced by
The variable $newpath does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
819 48
		} else {
820
			$rest=substr($path, strlen($site));
821
		}
822
		return $site_url.$rest;
823
	}
824
825
	public function AR_implements($implements) {
826
		$type = current(explode(".",$this->type));
827
		return $this->store->AR_implements($type, $implements);
828
	}
829
830 View Code Duplication
	public function getlocks() {
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...
831
		global $AR;
832
		if ($this->store->mod_lock) {
833
			$result=$this->store->mod_lock->getlocks($AR->user->data->login);
834
		} else {
835
			$result="";
836
		}
837 48
		return $result;
838 48
	}
839 48
840 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...
841 24
	global $AR;
842
		if ($this->store->mod_lock) {
843
			$result=$this->store->mod_lock->lock($AR->user->data->login,$this->path,$mode,$time);
844 48
		} else {
845
			$result=true; // no lock module, so lock is 'set'
846
		}
847 48
		return $result;
848 48
	}
849 48
850 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...
851 24
	global $AR;
852
		if ($this->store->mod_lock) {
853
			$result=$this->store->mod_lock->unlock($AR->user->data->login,$this->path);
854 48
		} else {
855
			$result=true;
856
		}
857
		return $result;
858
	}
859
860
	public function touch($id=0, $timestamp=-1) {
861
		if (!$id) {
862
			$id = $this->id;
863
		}
864
		$result = $this->store->touch($id, $timestamp);
865 View Code Duplication
		if ($this->store->error) {
866
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
867
		}
868
		return $result;
869
	}
870
871
	public function mogrify($id=0, $type, $vtype=null) {
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

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

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

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

Let’s take a look at an example:

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

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

    // do something with $myArray
}

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

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

Loading history...
956
				} else {
957
					// Use the group memberships of external databases (e.g. LDAP)
958
					$criteria="members.login='".AddSlashes($AR->user->data->login)."'";
959
					foreach (array_keys($AR->user->externalgroupmemberships) as $group) {
960 4
						$criteria.=" or login.value='".AddSlashes($group)."'";
961 4
					}
962 4
				}
963 4
				if (!$AR->user->groups) {
964 4
					$groups=$this->find("/system/groups/",$criteria, "system.get.phtml");
965 4
					if (isset($groups) && is_array($groups)) {
966 2
						foreach($groups as $group ){
967 2
							if (is_object($group)) {
968 2
								$AR->user->groups[$group->path] = $group;
969 4
							}
970 4
						}
971 4
					}
972 2
					if (isset($AR->user->data->config->groups) && is_array($AR->user->data->config->groups)) {
973
						foreach ($AR->user->data->config->groups as $groupPath => $groupId) {
974 2
							if (!$AR->user->groups[$groupPath]) {
975 2
								$AR->user->groups[$groupPath] = current($this->get($groupPath, "system.get.phtml"));
976 4
							}
977
						}
978
					}
979
					if (!$AR->user->groups["/system/groups/public/"]) {
980
						if ($public=current($this->get("/system/groups/public/", "system.get.phtml"))) {
981 2
							$AR->user->groups[$public->path] = $public;
982 4
						}
983
					}
984 4
				}
985
				if ($AR->user->groups) {
986
					/* check for owner grants (set by system.get.config.phtml) */
987
					if (isset($AR->user->ownergrants) && is_array($AR->user->ownergrants)) {
988
						if (!$AR->user->groups["owner"]) {
989
							$AR->user->groups["owner"] = @current($this->get("/system/groups/owner/", "system.get.phtml"));
990 4
						}
991 4
						$AR->user->groups["owner"]->data->config->usergrants = $AR->user->ownergrants;
992 4
					}
993 4 View Code Duplication
					foreach($AR->user->groups as $group){
994 4
						$groupgrants=array();
995 4
						if (is_object($group)) {
996
							$group->FindGrants($path, $groupgrants, $userpath);
997
							if (isset($grants) && is_array($grants)) {
998
								foreach($groupgrants as $gkey => $gval ){
999
									if (isset($grants[$gkey]) && is_array($grants[$gkey]) && is_array($gval)) {
1000
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
1001
									} else
1002
									if ($gval && !is_array($gval)) {
1003 2
										$grants[$gkey] = $gval;
1004
									} else
1005 2
									if ($gval && !$grants[$gkey]) {
1006 2
										$grants[$gkey] = $gval;
1007 2
									}
1008
								}
1009 2
							} else {
1010 2
								$grants = $groupgrants;
1011 2
							}
1012 4
						}
1013
					}
1014
				}
1015
				if(isset($AR->sgGrants) && is_array($AR->sgGrants) ) {
1016
					ksort($AR->sgGrants);
1017
					$ppath = $this->make_path($path);
1018 View Code Duplication
					foreach( $AR->sgGrants as $sgpath => $sggrants) {
1019
						$sgpath = $this->make_path($sgpath);
1020
						if( substr($ppath, 0, strlen($sgpath)) == $sgpath ) { // sgpath is parent of ppath or equal to ppath
1021
							if (isset($grants) && is_array($grants)) {
1022
								foreach($sggrants as $gkey => $gval ){
1023
									if (isset($grants[$gkey]) && is_array($grants[$gkey]) && is_array($gval)) {
1024
										$grants[$gkey]=array_merge($gval, $grants[$gkey]);
1025
									} else
1026
									if ($gval && !is_array($gval)) {
1027
										$grants[$gkey] = $gval;
1028
									} else
1029
									if ($gval && !$grants[$gkey]) {
1030
										$grants[$gkey] = $gval;
1031
									}
1032
								}
1033
							} else {
1034
								$grants = $sggrants;
1035
							}
1036 4
						}
1037 2
					}
1038 4
				}
1039
				$AR->user->grants[$path]=$grants;
1040 2
			}
1041 4
			$grants=$AR->user->grants[$path];
1042 4
1043
		}
1044
		debug("pobject: GetValidGrants(user:".$AR->user->data->login."): end ( ".debug_serialize($grants)." )","all");
0 ignored issues
show
Bug introduced by
The variable $grants does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1045
		return $grants;
1046 184
	}
1047 184
1048 184
1049 72
	public function pushContext($context) {
1050 36
	global $AR;
1051 184
		if(!empty($AR->context)) {
1052 184
			$context = array_merge(end($AR->context), $context);
1053
		}
1054
		array_push($AR->context, $context);
1055
	}
1056
1057
	public function setContext($context, $level=0) {
1058
	global $AR;
1059 184
		$AR->context[count($AR->context)-(1+$level)]=$context;
1060 184
	}
1061 184
1062
	public function popContext() {
1063
	global $AR;
1064 184
		return array_pop($AR->context);
1065 184
	}
1066 184
1067
	public static function getContext($level=0) {
1068
	global $AR;
1069 72
		return $AR->context[count($AR->context)-(1+$level)];
1070 72
	}
1071 68
1072
	public function CheckAdmin($user) {
1073 4
	if ($user->data->login == "admin") {
1074
			return true;
1075
		}
1076 4
		if ($user->data->groups['/system/groups/admin/']) {
1077
			return true;
1078
		}
1079 60
		return false;
1080 60
	}
1081 60
1082
	public function CheckLogin($grant, $modifier=ARTHISTYPE) {
1083
	global $AR,$ARnls,$ARConfig,$ARCurrent,$ARConfigChecked;
1084
		if (!$this->store->is_supported("grants")) {
1085 60
			debug("pobject: store doesn't support grants");
1086 60
			return true;
1087 30
		}
1088
		if ($modifier==ARTHISTYPE) {
1089
			$modifier=$this->type;
1090 60
		}
1091
1092
		/* load config cache */
1093
		if (!isset($ARConfig->cache[$this->path])) {
1094
			// since this is usually run before CheckConfig, make sure
1095
			// it doesn't set cache time
1096
			$realConfigChecked = $ARConfigChecked;
1097
			$ARConfigChecked = true;
1098
			$this->loadConfig();
1099 60
			$ARConfigChecked = $realConfigChecked;
1100
		}
1101 60
1102
		$isadmin = $this->CheckAdmin($AR->user);
1103
1104 60
		if (!$isadmin && !$AR->user->grants[$this->path]) {
1105
			$AR->user->grants[$this->path]=$this->GetValidGrants();
1106 60
		}
1107 30
		if ($AR->user->data->login!="public") {
1108
			// Don't remove this or MSIE users won't get uptodate pages...
1109 60
			ldSetClientCache(false);
1110 60
		}
1111 60
1112 60
		$grants=$AR->user->grants[$this->path];
1113
		if ( 	( !$grants[$grant]
1114
					|| ( $modifier && is_array($grants[$grant]) && !$grants[$grant][$modifier] )
1115
				) && !$isadmin ) {
1116
			// do login
1117
			$arLoginMessage = $ARnls["accessdenied"];
1118 60
			ldAccessDenied($this->path, $arLoginMessage);
1119
			$result=false;
1120
		} else {
1121 60
			$result=($grants || $isadmin);
1122 60
		}
1123
1124
		$ARCurrent->arLoginSilent=1;
1125
		return $result;
1126 4
	}
1127 4
1128
1129 4
	public function CheckPublic($grant, $modifier=ARTHISTYPE) {
1130 4
	global $AR;
1131 4
1132 4
		$result=false;
1133 4
		if (!$AR->public) {
1134 2
			$this->pushContext(array("scope" => "php"));
1135 4
				$AR->public=current($this->get("/system/users/public/", "system.get.phtml"));
1136 4
			$this->popContext();
1137 4
		}
1138 4
		if ($AR->public) {
1139 4
			$AR->private=$AR->user;
1140 2
			$AR->user=$AR->public;
1141 4
			$result=$this->CheckSilent($grant, $modifier);
1142
			$AR->user=$AR->private;
1143
		}
1144 44
		return $result;
1145 44
	}
1146 44
1147 44
	public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") {
1148 44
	global $AR, $ARConfig;
1149 22
		$path = $this->make_path($path);
1150
		if ($modifier==ARTHISTYPE) {
1151
			$modifier=$this->type;
1152 44
		}
1153 8
1154 4
		/* load config cache */
1155 44
		if (!$ARConfig->cache[$path]) {
1156 40
			$this->loadConfig($path);
1157 24
		}
1158
		if ($this->CheckAdmin($AR->user)) {
1159
			$result=1;
1160 4
		} else if ($grants=$AR->user->grants[$path]) {
1161 4
			$result=$grants[$grant];
1162
		} else {
1163 44
			$grants=$this->GetValidGrants();
1164
			$result=$grants[$grant];
1165
		}
1166 44
		if ($modifier && is_array($result)) {
1167
			$result=$result[$modifier];
1168
		}
1169
		return $result;
1170
	}
1171
1172
	public function CheckNewFile($newfilename) {
1173
	global $ARnls;
1174
	/**********************************************************************
1175
1176
	  This function performs all the necessary checks on a path to see
1177
	whether it's a valid path for a new object. This consists of:
1178
	1) checking for invalid characters, valid chars are "a-zA-Z0-9./_-"
1179
	2) checking whether the path starts and ends with a "/".
1180
	3) checking whether the path doesn't exist already.
1181
	4) checking whether the parent exists.
1182
1183
	if all this checks out, it returns 1. If not, $this->error is set to
1184
	the correct error message.
1185
1186
	**********************************************************************/
1187
1188
		$this->error="";
1189
		if (preg_match("|^/[a-z0-9\./_-]*/$|i",$newfilename)) {
1190
			if (!$this->store->exists($newfilename)) {
1191
				$parent=$this->store->make_path($newfilename, "..");
1192
				if ($this->store->exists($parent)) {
1193
					$result=1;
1194
				} else {
1195
					$this->error = ar::error( sprintf($ARnls["err:filenameinvalidnoparent"],$newfilename,$parent), 1102);
1196
				}
1197
			} else {
1198
				$this->error = ar::error( sprintf($ARnls["err:chooseotherfilename"],$newfilename), 1103);
1199
			}
1200
		} else {
1201
			$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$newfilename)." ".$ARnls["err:startendslash"], 1104);
1202
		}
1203
		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...
1204
	}
1205
1206 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...
1207
	global $ARConfig;
1208
		$path = $this->make_path($path);
1209
		if ($ARConfig->cache[$path]) {
1210
			$path = preg_quote($path,'/');
1211
			$keys = preg_grep('/^'.$path.'/',array_keys($ARConfig->cache));
1212
			foreach ($keys as $cachepath) {
1213
				unset($ARConfig->cache[$cachepath]);
1214
				unset($ARConfig->pinpcache[$cachepath]);
1215
			}
1216 36
		}
1217 36
	}
1218 36
1219 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...
1220 36
	global $ARConfig;
1221 36
		$path = $this->make_path($path);
1222 36
		if ($ARConfig->cache[$path]) {
1223 4
			$path = preg_quote($path,'/');
1224 4
			$keys = preg_grep('/^'.$path.'./',array_keys($ARConfig->cache));
1225 4
			foreach($keys as $cachepath) {
1226 18
				unset($ARConfig->cache[$cachepath]);
1227 18
				unset($ARConfig->pinpcache[$cachepath]);
1228 36
				unset($ARConfig->libraries[$cachepath]);
1229
			}
1230 36
		}
1231 36
	}
1232
1233
	protected function getConfig() {
1234
	global $ARConfig, $ARCurrent, $ARConfigChecked;
1235 36
		// $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...
1236 4
		// 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...
1237 4
		// 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...
1238 4
		if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) {
1239 2
			$parent = current($this->get($this->parent, "system.get.phtml"));
1240 2
			if ($parent) {
1241
				$parent->getConfig();
1242 36
			}
1243
		}
1244 36
1245
		$this->getConfigData();
1246 36
1247 36
		$ARConfig->pinpcache[$this->path] = $ARConfig->pinpcache[$this->parent];
1248
		// backwards compatibility when calling templates from config.ini
1249 36
		$prevArConfig = $ARCurrent->arConfig;
1250
		$ARCurrent->arConfig = $ARConfig->pinpcache[$this->path];
1251
1252 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...
1253 36
1254
		/* calling config.ini directly for each system.get.config.phtml call */
1255
		$loginSilent = $ARCurrent->arLoginSilent;
1256 36
		$ARCurrent->arLoginSilent = true;
1257 36
		// 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...
1258
1259 36
		$initialNLS = $ARCurrent->nls;
1260 36
		$initialConfigChecked = $ARConfigChecked;
1261
1262
		$ARConfig->cache[$this->path]->inConfigIni = true;
1263 4
		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...
1264 4
			//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...
1265
			// 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...
1266
			$arConfig = $ARCurrent->arResult;
1267 4
			if (!isset($arConfig)) {
1268 4
				$arConfig = $ARCurrent->arConfig;
1269
			}
1270
			unset($ARCurrent->arResult);
1271
			if (isset($arConfig['library']) && is_array($arConfig['library'])) {
1272
				if (!$ARConfig->libraries[$this->path]) {
1273
					$ARConfig->libraries[$this->path] = array();
1274
				}
1275
				foreach ($arConfig['library'] as $libName => $libPath) {
1276
					$this->loadLibrary($libName, $libPath);
1277 4
				}
1278 2
				unset($arConfig['library']);
1279 36
			}
1280 36
			$ARConfig->pinpcache[$this->path] = (array) $arConfig;
1281 36
		}
1282 36
		$ARConfig->cache[$this->path]->inConfigIni = false;
1283
		$this->clearChildConfigs( $this->path ); // remove any config data for child objects, since these are set before their parent config was set
1284 36
		$ARConfigChecked = $initialConfigChecked;
1285 36
		$ARCurrent->nls = $initialNLS;
1286
1287
		$arConfig = &$ARConfig->pinpcache[$this->path];
1288 36 View Code Duplication
		if (!is_array($arConfig['authentication']['userdirs'])) {
1289
			$arConfig['authentication']['userdirs'] = array('/system/users/');
1290
		} else {
1291
			if (reset($arConfig['authentication']['userdirs']) != '/system/users/') {
1292 36
				array_unshift($arConfig['authentication']['userdirs'], '/system/users/');
1293
			}
1294
		}
1295 36 View Code Duplication
		if (!is_array($arConfig['authentication']['groupdirs'])) {
1296
			$arConfig['authentication']['groupdirs'] = array('/system/groups/');
1297
		} else {
1298
			if (reset($arConfig['authentication']['groupdirs']) != '/system/groups/') {
1299
				array_unshift($arConfig['authentication']['groupdirs'], '/system/groups/');
1300 36
			}
1301 36
		}
1302 36
1303
		$ARCurrent->arLoginSilent = $loginSilent;
1304 36
		$ARCurrent->arConfig = $prevArConfig;
1305 36
	}
1306 36
1307 36
	protected function getConfigData() {
1308
	global $ARConfig, $AR;
1309 36
		$context = $this->getContext(0);
1310 36
		if (!$ARConfig->cache[$this->path] && $context["scope"] != "pinp") {
1311
			// first inherit parent configuration data
1312 36
			$configcache= clone $ARConfig->cache[$this->parent];
1313
			unset($configcache->localTemplates);
1314
			// cache default templates
1315 36
			if (isset($this->data->config->templates) && count($this->data->config->templates)) {
1316
				$configcache->templates=&$this->data->config->templates;
1317
			}
1318
			if (isset($this->data->config->privatetemplates) && count($this->data->config->privatetemplates)) {
1319
				$configcache->privatetemplates=&$this->data->config->privatetemplates;
1320
			}
1321 36
1322 4
			// Speedup check for config.ini
1323 4
1324 4
			if(isset($this->data->config->templates) && is_array($this->data->config->templates) ) {
1325
				$configcache->localTemplates = $this->data->config->templates;
1326
				if( !$configcache->hasDefaultConfigIni ) {
1327
					foreach($this->data->config->templates as $type => $templates ) {
1328
						if( isset($templates["config.ini"]) ) {
1329
							$configcache->hasDefaultConfigIni = true;
1330 2
							$configcache->hasConfigIni = true;
1331 2
							break;
1332 2
						}
1333
					}
1334 36
				}
1335 36
			}
1336 36
1337 4
			if( !$configcache->hasDefaultConfigIni ) {
1338 4
				$configcache->hasConfigIni = false;
1339 4
				if(isset($this->data->config->pinp) && is_array($this->data->config->pinp) ) {
1340 4
					foreach( $this->data->config->pinp as $type => $templates ) {
1341
						if( isset($templates["config.ini"]) ) {
1342 2
							$configcache->hasConfigIni = true;
1343 2
							break;
1344 18
						}
1345
					}
1346 36
				}
1347 36
			}
1348 36
1349 18
			$localcachesettings = $this->data->config->cacheSettings;
1350
			if (!is_array($localcachesettings) ){
1351 36
				$localcachesettings = array();
1352
			}
1353
1354
			if (!is_array($configcache->cacheSettings) ) {
1355 36
				$configcache->cacheSettings = array();
1356 4
			}
1357 2
1358
			if ($this->data->config->cacheconfig) { // When removing this part, also fix the setting below.
1359 36
				$configcache->cache=$this->data->config->cacheconfig;
1360 4
			}
1361 2
1362
			if (!isset($localcachesettings['serverCache']) && isset($this->data->config->cacheconfig)) {
1363 36
				$localcachesettings["serverCache"] = $this->data->config->cacheconfig;
1364 4
			}
1365 2
1366
			if ($localcachesettings['serverCache'] != 0 ) {
1367 36
				$localcachesettings['serverCacheDefault'] = $localcachesettings['serverCache'];
1368
			}
1369
1370 36
			$configcache->cacheSettings = $localcachesettings + $configcache->cacheSettings;
1371
1372 36
			// store the current object type
1373
			$configcache->type = $this->type;
1374
1375 36
			if ($this->data->config->typetree && ($this->data->config->typetree!="inherit")) {
1376 4
				$configcache->typetree=$this->data->config->typetree;
1377 2
			}
1378
			if (isset($this->data->config->nlsconfig->list)) {
1379 36
				$configcache->nls = clone $this->data->config->nlsconfig;
1380
			}
1381
1382 36
			if ($this->data->config->grants["pgroup"]["owner"]) {
1383
				$configcache->ownergrants = $this->data->config->grants["pgroup"]["owner"];
1384
			}
1385
			if (isset($configcache->ownergrants) && is_array($configcache->ownergrants)) {
1386
				if ($AR->user && $AR->user->data->login != 'public' && $AR->user->data->login === $this->data->config->owner) {
1387
					$ownergrants = $configcache->ownergrants;
1388
					if (isset($ownergrants) && is_array($ownergrants)) {
1389
						foreach( $ownergrants as $grant => $val ) {
1390
							$AR->user->ownergrants[$this->path][$grant] = $val;
1391
						}
1392
					}
1393 36
				}
1394
			}
1395
1396 36
			if (isset($this->data->config->customconfig) && is_array($this->data->config->customconfig)) {
1397
				$configcache->custom=array_merge(is_array($configcache->custom)?$configcache->custom:array(), $this->data->config->customconfig);
1398 18
			}
1399 36
			$ARConfig->cache[$this->path]=$configcache;
1400
1401 60
		}
1402 60
	}
1403 60
1404
	public function loadConfig($path='') {
1405 60
	global $ARConfig, $ARConfigChecked, $ARCurrent;
1406 36
		$path=$this->make_path($path);
1407 36
		// 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...
1408 36
		if (!isset($ARConfig->cache[$path]) ) {
1409 36
			$allnls = $ARCurrent->allnls;
1410 36
			$ARCurrent->allnls = true;
1411 36
			$configChecked = $ARConfigChecked;
1412
			if (($this->path == $path && !$this->arIsNewObject) || $this->exists($path)) {
1413 36
				$this->pushContext(array("scope" => "php"));
1414 18
				if( $this->path == $path ) {
1415
					// 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...
1416 4
					$this->getConfig();
1417 4
				} else {
1418
					//debug("loadConfig: get path $path ");
1419 36
					$cur_obj = current($this->get($path, "system.get.phtml"));
1420 36
					$cur_obj->getConfig();
1421 18
				}
1422
				$this->popContext();
1423
				$result=$ARConfig->cache[$path];
1424
			} else if ($path === '/') {
1425
				// special case: / doesn't exists in the store
1426
				$result=$ARConfig->cache['..'];
1427
			} else {
1428
				$parent=$this->make_path($path.'../');
1429
				if (!$ARConfig->cache[$parent]) {
1430
					$this->pushContext(array("scope" => "php"));
1431
					// 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...
1432
					$cur_obj = current($this->get($parent, "system.get.phtml"));
1433
					if( $cur_obj ) {
1434
						$cur_obj->getConfig();
1435
					}
1436
					$this->popContext();
1437
				}
1438
				$result=$ARConfig->cache[$parent];
1439
				$ARConfig->cache[ $path ] = $result;
1440 36
				$ARConfig->pinpcache[ $path ] = $ARConfig->pinpcache[ $parent ];
1441 36
			}
1442 18
			// restore old ARConfigChecked state
1443
			$ARConfigChecked = $configChecked;
1444 48
			$ARCurrent->allnls = $allnls;
1445
		} else {
1446 60
			// 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...
1447
			$result=$ARConfig->cache[$path];
1448
		}
1449
		return $result;
1450
	}
1451
1452 12
1453 12
	// TODO: look for a way to merge loadConfig and loadUserConfig into one function
1454 12
1455 12
	public function loadUserConfig($path='') {
1456
	global $ARConfig;
1457 12
		$path = $this->make_path($path);
1458
		$parent = $this->make_path($path.'../');
1459
1460 12
		if (!$ARConfig->cache[$path]) {
1461
			$this->loadConfig($path);
1462
		}
1463 12
		if (!$ARConfig->pinpcache[$path]) {
1464
			$config = $ARConfig->pinpcache[$parent];
1465 12
		} else {
1466
			$config = $ARConfig->pinpcache[$path];
1467
		}
1468 48
		return (array)$config;
1469 48
	}
1470 48
1471 48
	protected function getTemplateFromCache($path, $type, $function, &$arSuperContext) {
1472 48
	global $AR, $ARConfig;
1473
		$templatesList = $ARConfig->libraryCache[$path][$function];
1474
		if (!is_array($templatesList)) {
1475
			return false;
1476
		}
1477
		foreach ($templatesList as $checkpath => $templates) {
1478
			$arType = $type;
1479
			while ($arType!='ariadne_object') {
1480
//				echo "checking $i::$arType<br>\n";
1481
				if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType][$this->reqnls])) {
1482
					$arCallTemplate=$arType.".".$function.".".$this->reqnls;
1483
					$arCallTemplateName = $function;
1484
					$arCallTemplateNLS = $this->reqnls;
1485
					break 2;
1486 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType]['any'])) {
1487
					$arCallTemplate=$arType.".".$function.".any";
1488
					$arCallTemplateName = $function;
1489
					$arCallTemplateNLS = "any";
1490
					break 2;
1491
				} else {
1492
1493
					if (!($arSuper=$AR->superClass[$arType])) {
1494
						// no template found, no default.phtml found, try superclass.
1495
						if ($subcpos = strpos($arType, '.')) {
1496
							$arSuper = substr($arType, 0, $subcpos);
1497
						} else {
1498
							if (!class_exists($arType, false)) {
1499
								// the given class was not yet loaded, so do that now
1500
								$arTemp=$this->store->newobject('','',$arType,new object);
1501
							} else {
1502
								$arTemp=new $arType();
1503
							}
1504
							$arSuper=get_parent_class($arTemp);
1505
						}
1506
						$AR->superClass[$arType]=$arSuper;
1507
					}
1508
					$arType=$arSuper;
1509
				}
1510
			}
1511
		}
1512
1513
		$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...
1514
		$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...
1515
1516
		return array(
1517
			"arTemplateId" => $arTemplate["arTemplateId"],
1518
			"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...
1519
			"arCallType" => $type,
1520
			"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...
1521
			"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...
1522
			"arCallTemplateType" => $arType,
1523
			"arCallTemplatePath" => $arTemplate["arLibraryLocalPath"],
1524
			"arLibrary" => "current",
1525
			"arLibraryPath" => $arTemplate["arLibraryPath"],
1526
			"arPrivateTemplate" => $arPrivateTemplate
1527
		);
1528
	}
1529
1530
	public function loadLibraryCache($base, $path, $arLibraryPath = "") {
1531
	global $ARConfig;
1532
		if (!$arLibraryPath) {
1533
			$arLibraryPath = $path;
1534
		}
1535
		$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1536
		$templates = $config->localTemplates;
1537
		if (isset($templates) && is_array($templates)) {
1538
			$list = array();
1539
			foreach ($templates as $type => $functions) {
1540
				foreach ($functions as $function => $template) {
1541
					foreach ($template as $nls => $templateId) {
1542
						$list[$function][$type][$nls] = array(
1543
								"arTemplateId" => $templateId,
1544
								"arLibraryPath" => $arLibraryPath,
1545
								"arLibraryLocalPath" => $path
1546
						);
1547
					}
1548
				}
1549
			}
1550
1551
			foreach ($list as $function => $types) {
1552
				if (!is_array($ARConfig->libraryCache[$base][$function])) {
1553
					$ARConfig->libraryCache[$base][$function] = array(
1554
						$path => $types
1555
					);
1556
				} else {
1557
					$ARConfig->libraryCache[$base][$function][$path] = $types;
1558
				}
1559
			}
1560
		}
1561
		list($basetype,) = explode('.', $config->type,2);
1562
		if ($path != '/' && $basetype != 'psection') {
1563
			$this->loadLibraryCache($base, $this->store->make_path($path, '../'), $arLibraryPath);
1564 4
		}
1565 4
	}
1566 4
1567 4
	public function loadLibrary($name, $path) {
1568 4
	global $ARConfig;
1569 4
		$path=$this->make_path($path);
1570
		debug("pobject::loadLibrary($name, $path);");
1571
		if ($name===ARUNNAMED) {
1572 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...
1573 4
				return ar::error('You cannot load an unnamed library from a child object.', 1109);
1574 2
			} else {
1575 4
				if (!$ARConfig->libraries[$this->path]) {
1576 4
					$ARConfig->libraries[$this->path]=array();
1577 4
				}
1578 2
				array_unshift($ARConfig->libraries[$this->path],$path);
1579 2 View Code Duplication
				if (!$ARConfig->cacheableLibraries[$this->path]) {
1580
					$ARConfig->cacheableLibraries[$this->path] = array($path);
1581
				} else {
1582 2
					array_unshift($ARConfig->cacheableLibraries[$this->path], $path);
1583
				}
1584
			}
1585
		} else if ($name && is_string($name)) {
1586
			if (!$ARConfig->cache[$this->path]) {
1587
debug("loadLibrary: loading cache for $this->path");
1588
				$this->loadConfig($this->path);
1589
			}
1590
			$ARConfig->libraries[$this->path][$name]=$path;
1591
			$ARConfig->cache[$this->path]->libraries[$name]=$path;
1592
			$ARConfig->pinpcache[$this->path]["library"][$name] = $path;
1593
		} else if (is_int($name)) {
1594
			if (!$ARConfig->cache[$this->path]) {
1595
				$this->loadConfig($this->path);
1596
			}
1597
			$ARConfig->libraries[$this->path][$name]=$path;
1598 View Code Duplication
			if (!$ARConfig->cacheableLibraries[$this->path]) {
1599
				$ARConfig->cacheableLibraries[$this->path] = array($name => $path);
1600
			} else {
1601
				$ARConfig->cacheableLibraries[$this->path][$name] = $path;
1602
			}
1603
			// make sure that unnamed libraries don't get added to the configcache
1604
			unset($ARConfig->cache[$this->path]->libraries[$name]);
1605
			unset($ARConfig->pinpcache[$this->path]["library"][$name]);
1606 4
		} else {
1607
			return ar::error('Illegal library name: '.$name, 1110);
1608
		}
1609
	}
1610
1611
	// returns a list of libraries loaded on $path
1612
	public function getLibraries($path = '') {
1613
	global $ARConfig;
1614
		$path = $this->make_path($path);
1615
		return (array)$ARConfig->libraries[$path];
1616
	}
1617
1618
	public function mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1619
		$libraryName = ar::getvar('arLibrary');
1620
		if ( is_numeric($libraryName) || $libraryName == 'current' ) { // library is loaded unnamed
1621
			$libraryName = $defaultLibraryName;
1622
		}
1623
		if ( $libraryName ) {
1624
			$userConfig = ar::acquire('defaults.'.$libraryName);
1625
			if (isset($userConfig) && is_array($userConfig) ) {
1626
				$defaults = array_merge( $defaults, $userConfig );
1627
			}
1628
		}
1629
		return array_merge( $defaults, $this->getvar('arCallArgs') );
1630
	}
1631
1632
	public function _mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1633 60
		return $this->mergeLibraryConfig( $defaultLibraryName, $defaults );
1634 60
	}
1635 60
1636 60
	public function getPinpTemplate($arCallFunction='view.html', $path=".", $top="", $inLibrary = false, $librariesSeen = null, $arSuperContext=array()) {
1637 60
	global $ARCurrent, $ARConfig, $AR, $ARConfigChecked;
1638 60
		debug("getPinpTemplate: function: $arCallFunction; path: $path; top: $top; inLib: $inLibrary","class");
1639 30
		$result = array();
1640 60
		if (!$top) {
1641 60
			$top = '/';
1642
		}
1643
		$path = $this->make_path($path);
1644
		if (!is_array($arSuperContext)) {
1645 60
			$arSuperContext = array();
1646
		}
1647
1648
		if (($libpos=strpos($arCallFunction,":"))!==false && $libpos!==strpos($arCallFunction, "::")) {
1649
			// template of a specific library defined via call("library:template");
1650
			$arLibrary = substr($arCallFunction, 0, $libpos);
1651
			if ($arLibrary == 'current') {
1652
				// load the current arLibrary
1653
				$context = $this->getContext(1);
1654
				$arLibrary = $context['arLibrary'];
1655
				$arLibraryPath = $context['arLibraryPath'];
1656 View Code Duplication
			} else {
1657
				$config = (isset($ARConfig->cache[$path])) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1658
				$arLibraryPath = $config->libraries[$arLibrary];
1659
			}
1660
			$arCallFunction = substr($arCallFunction, $libpos+1);
1661
			if ($arLibraryPath) {
1662
				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...
1663
				$librariesSeen[$arLibraryPath] = true;
1664
				$inLibrary = true;
1665
				$path = $arLibraryPath;
1666
			} else {
1667
				debug("getPinpTemplate: Failed to find library $arLibrary");
1668
				return false;
1669 60
			}
1670
			$path = $this->make_path($path);
1671
		}
1672
		if (strpos($arCallFunction,"::")!==false) {
1673 60
			// template of a specific class defined via call("class::template");
1674
			list($arCallType, $arCallFunction)=explode("::",$arCallFunction);
1675
		} else {
1676
			$arCallType=$this->type;
1677 60
		}
1678 60
1679 30
		/* first check current templates */
1680
		if ($this->path == $path) {
1681
			$curr_templates = $this->data->config->pinp;
1682
		} else {
1683
			$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1684 60
			$curr_templates = $config->templates;
1685 60
		}
1686 60
1687 60
		$checkpath=$path;
1688 60
		$lastcheckedpath="";
1689 60
		$arCallClassTemplate = $ARCurrent->arCallClassTemplate;
1690 60
		$arSetType = $arCallType;
1691 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...
1692 60
			$lastcheckedpath = $checkpath;
1693
			$arType = $arSetType;
1694
			while ($arType!='ariadne_object' && !$arCallTemplate) {
1695
				if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction][$this->reqnls])) {
1696 60
					$arCallTemplate=$arType.".".$arCallFunction.".".$this->reqnls;
1697 12
					$arCallTemplateName = $arCallFunction;
1698 12
					$arCallTemplateNLS = $this->reqnls;
1699 12 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction]['any'])) {
1700 6
					$arCallTemplate=$arType.".".$arCallFunction.".any";
1701
					$arCallTemplateName = $arCallFunction;
1702 48
					$arCallTemplateNLS = 'any';
1703
				} else {
1704
1705
					if (!($arSuper=$AR->superClass[$arType])) {
1706
						// no template found, no default.phtml found, try superclass.
1707
						if ($subcpos = strpos($arType, '.')) {
1708
							$arSuper = substr($arType, 0, $subcpos);
1709
						} else {
1710
							if (!class_exists($arType, false )) {
1711
								// the given class was not yet loaded, so do that now
1712
								$arTemp=$this->store->newobject('','',$arType,new object);
1713
							} else {
1714
								$arTemp=new $arType();
1715
							}
1716
							$arSuper=get_parent_class($arTemp);
1717 48
						}
1718
						$AR->superClass[$arType]=$arSuper;
1719 30
					}
1720 60
					$arType=$arSuper;
1721
				}
1722
			}
1723
			if ($inLibrary) {
1724
1725
				// faster matching on psection, prefix doesn't have to be a valid type
1726
				$prefix = substr($ARConfig->cache[$checkpath]->type,0,8);
1727
1728
				if ($prefix === 'psection') {
1729
					// 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...
1730
					// break search operation when we have found a
1731
					// psection object
1732
					break;
1733 60
				}
1734 48
			}
1735
1736
			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...
1737
				if ($ARConfig->cacheableLibraries[$checkpath]) {
1738
					foreach ($ARConfig->cacheableLibraries[$checkpath] as $library => $path) {
1739
						if (is_int($library) && !$librariesSeen[$path]) {
1740
							$librariesSeen[$path] = true;
1741
							if ($ARConfigChecked) {
1742
								if (!$ARConfig->librariesCached[$checkpath][$path]) {
1743
									$this->loadLibraryCache($checkpath, $path);
1744
									unset($ARConfig->cacheableLibraries[$checkpath][$library]);
1745
								}
1746
							}
1747
						}
1748 48
					}
1749 48
				}
1750 48
1751
				if (isset($ARConfig->cacheableLibraries[$checkpath])) {
1752
					$template = $this->getTemplateFromCache($checkpath, $arCallType, $arCallFunction, $arSuperContext);
1753 24
					if ($template["arTemplateId"]) {
1754 24
						return $template;
1755 60
					}
1756 48
				}
1757
			}
1758
			if ($checkpath == $top) {
1759 60
				break;
1760 60
			}
1761 60
1762 60
			$checkpath=$this->store->make_path($checkpath, "..");
1763 30
			$config = ($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
1764
			$curr_templates = $config->templates;
1765 60
			$arSetType = $arCallType;
1766 60
		}
1767
1768
		$config = ($ARConfig->cache[$lastcheckedpath]) ? $ARConfig->cache[$lastcheckedpath] : $this->loadConfig($lastcheckedpath);
1769 60
		$arPrivateTemplate = $config->privatetemplates[$arCallType][$arCallFunction];
1770 60
1771 60
		//debug("getPinpTemplate END; $arTemplateId; $checkpath;");
1772 60
		$result["arTemplateId"] = $arTemplateId;
1773 60
		$result["arCallTemplate"] = $arCallTemplate;
1774 60
		$result["arCallType"] = $arCallType;
1775 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...
1776 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...
1777 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...
1778 60
		$result["arCallTemplatePath"] = $lastcheckedpath;
1779 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...
1780
		$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...
1781 60
		$result["arLibrariesSeen"] = $librariesSeen;
1782
		$result["arPrivateTemplate"] = $arPrivateTemplate;
1783
1784 64
		return $result;
1785
	}
1786
1787
	public function CheckConfig($arCallFunction="", $arCallArgs="") {
1788
	// returns true when cache isn't up to date and no other template is
1789 64
	// defined for $path/$function. Else it takes care of output to the
1790 64
	// browser.
1791
	// All these templates must exist under a fixed directory, $AR->dir->templates
1792
	global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked;
1793
		$MAX_LOOP_COUNT=10;
1794
1795 64
1796
		// system templates (.phtml) have $arCallFunction=='', so the first check in the next line is to
1797
		// make sure that loopcounts don't apply to those templates.
1798
		if (0 && $arCallFunction && $ARBeenHere[$this->path][$arCallFunction]>$MAX_LOOP_COUNT) { // protect against infinite loops
1799
			error(sprintf($ARnls["err:maxloopexceed"],$this->path,$arCallFunction,$arCallArgs));
1800 64
			$this->store->close();
1801
			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...
1802
		} else {
1803 64
			$ARBeenHere[$this->path][$arCallFunction]+=1;
1804 64
1805 64
			// this will prevent the parents from setting the cache time
1806 64
			$initialConfigChecked = $ARConfigChecked;
1807 64
			$ARConfigChecked = true;
1808
			$config = ($ARConfig->cache[$this->path]) ? $ARConfig->cache[$this->path] : $this->loadConfig();
1809
			$ARConfigChecked = $initialConfigChecked;
1810
			$ARConfig->nls=$config->nls;
1811
1812
1813 64
			// if a default language is entered in a parent and no language is
1814 64
			// explicitly selected in the url, use that default.
1815
			// The root starts with the system default (ariadne.phtml config file)
1816
			if ( !$ARCurrent->nls ) {
1817
				if ( $config->root['nls'] ) {
1818
					$this->reqnls = $config->root['nls'];
1819 64
					if ( !$ARConfigChecked ) {
1820 64
						$ARCurrent->nls = $this->reqnls;
1821 64
					}
1822 64
				} else if ( $config->nls->default ) {
1823 32
					$this->reqnls = $config->nls->default;
1824
					$this->nls = $this->reqnls;
1825 32
					if ( !$ARConfigChecked ) {
1826 32
						$ARCurrent->nls = $this->nls;
1827
					}
1828
				}
1829 64
			} else {
1830 64
				$this->reqnls = $ARCurrent->nls;
1831
			}
1832 64
			$nls = &$this->nls;
1833
			$reqnls = &$this->reqnls;
1834
1835
			if (!$ARConfigChecked && is_object($ARnls)) {
1836
				$ARnls->setLanguage($ARCurrent->nls);
1837 64
			}
1838
1839
1840
			if (!$ARCurrent->arContentTypeSent) {
1841
				ldHeader("Content-Type: text/html; charset=UTF-8");
1842
				$ARCurrent->arContentTypeSent = true;
1843
			}
1844
1845
/*			// FIXME: the acceptlang code works a bit too well.. it overrides psite configuration settings.
0 ignored issues
show
Unused Code Comprehensibility introduced by
56% 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...
1846
1847
			if ($ARCurrent->acceptlang && !$ARCurrent->nls) {
1848
				if ($ARCurrent->acceptlang && is_array($this->data->nls->list)) {
1849
					$validlangs = array_intersect(array_keys($ARCurrent->acceptlang), array_keys($this->data->nls->list));
1850
				}
1851
				if ($validlangs) {
1852
					$reqnls=array_shift($validlangs);
1853
					$ARCurrent->nls = $reqnls;
1854 64
				}
1855 4
			}
1856 2
*/
1857 64 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom['none']) {
1858
				$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...
1859
			}
1860 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom[$nls]) {
1861 64
				$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...
1862
			}
1863
1864
			if (!$ARConfigChecked) {
1865
				// this template is the first template called in this request.
1866
				$eventData = new object();
1867
				$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...
1868
				$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...
1869
1870
				$ARConfigChecked = true;
1871
				$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...
1872
				$ARConfigChecked = $initialConfigChecked;
1873
				if ( !$result ) { //prevent default action: view
1874
					return false;
1875 64
				}
1876
			}
1877
1878
			if (!$ARConfigChecked) {
1879
				// if this object isn't available in the requested language, show
1880
				// a language select dialog with all available languages for this object.
1881
				if (isset($this->data->nls) && !$this->data->name) {
1882
					if (!$ARCurrent->forcenls && (!isset($this->data->nls->list[$reqnls]) || !$config->nls->list[$reqnls])) {
1883
						if (!$ARCurrent->nolangcheck && $arCallFunction != 'config.ini') {
1884
							$ARCurrent->nolangcheck=1;
1885
							$eventData = new object();
1886
							$eventData->arCallFunction = $arCallFunction;
1887
							$eventData->arCallArgs = $arCallArgs;
1888
							$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...
1889
							$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...
1890
							if ( $result ) { // continue with default action: langaugeselect
1891
								$result->arCallArgs["arOriginalFunction"] = $result->arCallFunction;
1892
								$this->call("user.languageselect.html", $result->arCallArgs);
1893
								return false;
1894
							}
1895
						} else {
1896
							$this->nlsdata=$this->data->$nls;
1897
						}
1898
					} else {
1899
						$this->nlsdata=$this->data->$reqnls;
1900
					}
1901
				}
1902
				$ARCurrent->nolangcheck=1;
1903
			}
1904
1905
			/*
1906 64
				Set ARConfigChecked to true to indicate that we have been here
1907 64
				earlier.
1908
			*/
1909 60
			$ARConfigChecked = true;
1910 60
			if ($arCallFunction) { // don't search for templates named ''
1911
				// 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...
1912
				$redirects	= $ARCurrent->shortcut_redirect;
1913
				if (isset($redirects) && is_array($redirects)) {
1914
					$redirpath = $this->path;
1915
					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...
1916
								($redir = array_pop($redirects)) &&
1917
									$redir["keepurl"] &&
1918
										(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
1919
					) {
1920
						$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"]);
1921
						$redirpath = $redir['src'];
1922
					}
1923
1924
					if (!$template["arTemplateId"] && $redirpath) {
1925 60
						$template = $this->getPinpTemplate($arCallFunction, $redirpath);
1926 60
					}
1927 30
				}
1928
				if (!$template["arTemplateId"]) {
1929 60
					$template = $this->getPinpTemplate($arCallFunction);
1930 12
				}
1931
1932
				if ($template["arCallTemplate"] && $template["arTemplateId"]) {
1933 12
					if (!isset($ARCurrent->cacheTemplateChain)) {
1934 8
						$ARCurrent->cacheTemplateChain = array();
1935 4
					}
1936 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) {
1937 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]] = array();
1938 6
					}
1939 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']])) {
1940 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']] = array();
1941 6
					}
1942 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']])) {
1943
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0;
1944
					}
1945 12
					$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]++;
1946
1947
1948 12
					debug("CheckConfig: arCallTemplate=".$template["arCallTemplate"].", arTemplateId=".$template["arTemplateId"],"object");
1949
					// $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...
1950 12
					// check if template exists, if it doesn't exist, then continue the original template that called CheckConfig
1951 6
					$arTemplates=$this->store->get_filestore("templates");
1952
					if (
1953
						$arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")
1954
					) {
1955
						// check if the requested language exists, if not do not display anything,
1956
						// unless otherwise indicated by $ARCurrent->allnls
1957 12
						// This triggers only for pinp templates called by other templates,
1958 12
						// as the first template (in the url) will first trigger the language
1959
						// choice dialogue instead.
1960
						$arLibrary = $template['arLibrary'];
1961
						if (is_int($arLibrary)) {
1962
							// set the library name for unnamed libraries to 'current'
1963
							// so that calls using getvar('arLibrary') will keep on working
1964 12
							$arLibrary = "current";
1965 12
						}
1966 12
1967 12 View Code Duplication
						if (!is_string($arCallArgs)) {
1968 6
							$arCallArgs['arCallFunction'] = $arCallFunction;
1969
							$arCallArgs['arLibrary'] = $arLibrary;
1970 12
							$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
1971
						}
1972
1973 12
						$ARCurrent->arCallStack[]=$arCallArgs;
1974
						// start running a pinp template
1975 12
1976 12
						$this->pushContext(
1977 12
							array(
1978 12
								"scope" => "pinp",
1979 12
								"arLibrary" => $arLibrary,
1980 12
								"arLibraryPath" => $template['arLibraryPath'],
1981 12
								"arCallFunction" => $arCallFunction,
1982 12
								"arCurrentObject" => $this,
1983 12
								"arCallType" => $template['arCallType'],
1984 12
								"arCallTemplateName" => $template['arCallTemplateName'],
1985 12
								"arCallTemplateNLS" => $template['arCallTemplateNLS'],
1986 6
								"arCallTemplateType" => $template['arCallTemplateType'],
1987 6
								"arCallTemplatePath" => $template['arCallTemplatePath'],
1988
								"arLibrariesSeen" => $template['arLibrariesSeen']
1989
							)
1990 12
						);
1991
1992
						// 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...
1993
						if (count($ARCurrent->arCallStack) == 2 && $template['arPrivateTemplate']) {
1994
							// Do not allow private templates to be called first in the stack.
1995
							// echo "Bad request";
1996
1997
							// 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...
1998
							// Return true zorgt er voor dat de default 404 handler het oppikt alsof het template niet bestaat.
1999 12
							$this->popContext();
2000
							array_pop($ARCurrent->arCallStack);
2001 12
							return true;
2002 12
						} else if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) {
2003 12
							// the requested language is available.
2004 6
							$this->nlsdata=$this->data->$reqnls;
2005
							$this->nls=$reqnls;
2006
							$continue=true;
2007
						} else if (!isset($this->data->nls)) {
2008
							// the object has no language support
2009
							$this->nlsdata=$this->data;
2010
							$continue=true;
2011
						} else if (($ARCurrent->allnls) || (!$initialConfigChecked && $ARCurrent->nolangcheck)) {
2012
							// all objects must be displayed
2013
							// $this->reqnls=$this->nls; // set requested nls, for checks
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...
2014
							$this->nls = isset($this->data->nls->default) ? $this->data->nls->default : $this->reqnls;
2015
							$this->nlsdata = $this->data->$nls ?: $this->data->{$this->nls} ?: $this->data;
2016
							$continue=true;
2017
						} else {
2018
							debug("CheckConfig: requested language not available, allnls not set","object");
2019 12
							// -> skip this object (do not run template but do return false)
2020 12
							$continue=false;
2021 12
						}
2022 12
						if ($continue) {
2023 12
							$eventData = new object();
2024 12 View Code Duplication
							if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2025 12
								$AR->contextCallHandler = true;
2026 12
								$eventData->arCallArgs = $arCallArgs;
2027 12
								$eventData->arCallFunction = $arCallFunction;
2028 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...
2029 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...
2030 6
								$ARCurrent->arResult = $eventData->arResult;
2031 12
								$AR->contextCallHandler = false;
2032 12
								$continue = ($eventData!=false);
2033
							}
2034
							if ( $continue ) {
2035 12
								if (!isset($ARCurrent->cacheCallChainSettings)) {
2036 8
									$ARCurrent->cacheCallChainSettings = array();
2037 4
								}
2038
								if ($ARConfig->cache[$this->path]->inConfigIni == false) {
2039 12
									$ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings;
2040
								}
2041
2042 12
								if ($ARCurrent->ARShowTemplateBorders) {
2043 12
									echo "<!-- arTemplateStart\nData: ".$this->type." ".$this->path." \nTemplate: ".$template["arCallTemplatePath"]." ".$template["arCallTemplate"]." \nLibrary:".$template["arLibrary"]." -->";
2044 12
								}
2045 12
								set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2046 12
								$arResult=$arTemplates->import($template["arTemplateId"], $template["arCallTemplate"], "", $this);
2047 6
								restore_error_handler();
2048 12
								if (isset($arResult)) {
2049
									$ARCurrent->arResult=$arResult;
2050
								}
2051 12
								if ($ARCurrent->ARShowTemplateBorders) {
2052 12
									echo "<!-- arTemplateEnd -->";
2053 12
								}
2054 12 View Code Duplication
								if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2055 12
									$AR->contextCallHandler = true;
2056 12
									$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2057 12
									$eventData->arResult = $temp;
2058 6
									ar_events::fire('oncall', $eventData );
2059 6
									$ARCurrent->arResult = $temp; /* restore correct result */
2060 6
									$AR->contextCallHandler = false;
2061 12
								}
2062 12
							}
2063
						}
2064 12
						array_pop($ARCurrent->arCallStack);
2065
						$this->popContext();
2066
2067
						if ( !$initialConfigChecked && $arCallFunction != 'config.ini' ) {
2068
							// this template was the first template called in this request.
2069
							$eventData = new object();
2070
							$eventData->arCallArgs = $arCallArgs;
2071 12
							$eventData->arCallFunction = $arCallFunction;
2072
							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...
2073 4
						}
2074
						return false;
2075 2
					} else {
2076 48
						debug("pobject: CheckConfig: no such file: ".$template["arTemplateId"].$template["arCallTemplate"]."","all");
2077
					}
2078
				} else {
2079 26
					debug("CheckConfig: no arCallTemplate ($arCallFunction from '$this->path')","object");
2080
				}
2081 56
2082
			}
2083
		}
2084
		return true;
2085
	}
2086
2087
	public function ClearCache($path="", $private=true, $recurse=false) {
2088
	global $AR;
2089
		$norealnode = false;
2090
		if (!$path) {
2091
			$path=$this->path;
2092
		} else {
2093
			$realpath = current($this->get($path, "system.get.path.phtml"));
2094
			if($realpath != false) {
2095
				$path = $realpath;
2096
			} else {
2097
				$norealnode = true;
2098
			}
2099
		}
2100
2101
		if($norealnode !== true) {
2102
			/*
2103
				we don't want to recurse to the currentsite, because the path
2104
				doesn't exists in the database, so it doesn't have a currentsite
2105
2106
				the privatecache should be emptied by delete, or by the cleanup
2107
				cronjob. The current path doesn't exists in the database, so a
2108
				object id which is needed to find the node in the cache, isn't
2109
				available
2110
			*/
2111
2112
			if ($private ) {
2113
				// now remove any private cache entries.
2114
				// 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...
2115
				//        only scalable solution is storage in a database
2116
				//        but it will need the original path info to
2117
				//        remove recursively fast enough.
2118
				//        this means a change in the filestore api. -> 2.5
2119
2120
				// Use chunks of max 5000 objects at a time to be more memory-efficient;
2121
				$pcache=$this->store->get_filestore("privatecache");
2122
				if ($recurse) {
2123
					$offset = 0;
2124
					$limit = 5000;
2125
					$ids=$this->store->info($this->store->find($path, "" , $limit, $offset));
2126
					while (is_array($ids) && count($ids)) {
2127
						foreach($ids as $value) {
2128
							$eventData = new object();
2129
							$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...
2130
							if ( !$eventData ) {
2131
								continue;
2132
							}
2133
2134
							$pcache->purge($value["id"]);
2135
							ar_events::fire( 'onclearprivatecache', $eventData, $value['type'], $value['path'] );
2136
						}
2137
2138
						$offset += $limit;
2139
						$ids = $this->store->info($this->store->find($path, "", $limit, $offset));
2140
					}
2141
				} else {
2142
					$eventData = new object();
2143
					$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...
2144
					if ( $eventData ) {
2145
						$pcache->purge($this->id);
2146
						ar_events::fire( 'onclearprivatecache', $eventData, $this->type, $this->path );
2147
					}
2148
				}
2149
			}
2150
2151
			// now clear all parents untill the current site
2152
			$site=$this->currentsite($path);
2153
			$project=$this->currentproject($path);
2154
			if ($path!=$site && $path != $project && $path!='/') {
2155
				$parent=$this->make_path($path.'../');
2156
				$this->ClearCache($parent, $private, false);
2157
			}
2158
		}
2159
		$recursed = array();
2160
2161
		// filesystem cache image filenames are always lower case, so
2162
		// use special path for that. Remember 'real' path name for
2163
		// recursion and stuff
2164
		$fs_path=strtolower($path);
2165
		$nlslist=$AR->nls->list;
2166
		$nlslist["."]="default";
2167
		$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...
2168
		$cache_types[] = "compressed";
2169
		$cache_types[] = "session";
2170
2171
		global $cache_config,$store_config;
2172
		$cachestore=new cache($cache_config);
2173
2174
2175
		$filestore = $this->store->get_config("files");
2176
		foreach($cache_types as $type){
2177
			foreach($nlslist as $nls => $language){
2178
				// break away if nls doesn't exists
2179
				// is dir is cached, so it should not cost more that it add's in speed
2180
				if(!is_dir($filestore."cache/$type/$nls")){
2181
					continue;
2182
				}
2183
2184
				$fpath=$filestore."cache/$type/$nls".$fs_path;
2185
				$hpath=$filestore."cacheheaders/$type/$nls".$fs_path;
2186
				if ($dir=@dir($fpath)) {
2187
					while (false !== ($entry = $dir->read())) {
2188
						if ($entry!="." && $entry!="..") {
2189
							if (is_file($fpath.$entry)) {
2190
								@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...
2191
								@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...
2192
								$cachestore->delete("/".$type."/".$nls.$fs_path.$entry);
2193
							} else if ( $recurse && !$recursed[$entry]) {
2194
								$this->ClearCache($path.$entry."/", false, true);
2195
								$recursed[$entry]=true;
2196
							}
2197
						}
2198
					}
2199
					$dir->close();
2200
					// remove empty directory entry's, hide errors about directory entry's with content
2201
					@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...
2202
					@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...
2203
				} else if (file_exists(substr($fpath,0,-1)."=")) {
2204
					@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...
2205
					@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...
2206
					$cachestore->delete("/".$type."/".$nls.substr($fs_path,0,-1)."=");
2207
				}
2208
			}
2209
		}
2210
	}
2211
2212
	public function getcache($name, $nls="") {
2213
		global $ARCurrent, $ARnls;
2214
		$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...
2215
		$this->error = '';
2216
		if ($name) {
2217
			$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...
2218
			if (!$nls) {
2219
				$nls=$this->nls;
2220
			}
2221
			$file=$nls.".".$name;
2222
2223
			$minfresh = time();
2224
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2225
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2226
			}
2227
2228
			$pcache=$this->store->get_filestore("privatecache");
2229
			if ( $pcache->exists($this->id, $file) &&
2230
			     ($pcache->mtime($this->id, $file) > ($minfresh) )  ) {
2231
2232
				$result = $pcache->read($this->id, $file);
2233
2234
				$contentType = $ARCurrent->ldHeaders['content-type'];
2235
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2236
					$contentType = $matches[1];
2237
				} else {
2238
					$contentType = '';
2239
				}
2240
2241 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2242
					require_once($this->store->get_config('code')."modules/mod_url.php");
2243
					$temp = explode('.', $file);
2244
					$imageNLS = $temp[0];
2245
					$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...
2246
				}
2247
			} else {
2248
				$result=false;
2249
				$ARCurrent->cache[]=$file;
2250
				ob_start();
2251
				/* output buffering is recursive, so this won't interfere with
2252
				   normal page caching, unless you forget to call savecache()...
2253
				   so normal pagecache needs to check $ARCurrent->cache, if it's
2254
				   not empty, issue a warning and don't cache the outputbuffer...
2255
				   savecache() must then pop the stack.
2256
				*/
2257
			}
2258
		} else {
2259
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2260
			$result = false;
2261
		}
2262
		return $result;
2263
	}
2264
2265
	public function cached($name, $nls="") {
2266
		if ($image=$this->getcache($name, $nls)) {
2267
			echo $image;
2268
			$result=true;
2269
		} else {
2270
			$result=false;
2271
		}
2272
		return $result;
2273
	}
2274
2275
	public function savecache($time="") {
2276
		global $ARCurrent, $ARnls, $DB;
2277
		$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...
2278
		$this->error = '';
2279
		if (!$time) {
2280
			$time=2; // 'freshness' in hours.
2281
		}
2282
		if ($file=array_pop($ARCurrent->cache)) {
2283
			$image=ob_get_contents();
2284
			if ($image !== false) {
2285
				$result = $image;
2286
2287
				$contentType = $ARCurrent->ldHeaders['content-type'];
2288
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2289
					$contentType = $matches[1];
2290
				} else {
2291
					$contentType = '';
2292
				}
2293
2294 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2295
					require_once($this->store->get_config('code')."modules/mod_url.php");
2296
					$temp = explode('.', $file);
2297
					$imageNLS = $temp[0];
2298
					$image = URL::RAWtoAR($image, $imageNLS);
2299
				}
2300
2301
				if( $time > 0  && $DB["wasUsed"] == 0) {
2302
					$pcache=$this->store->get_filestore("privatecache");
2303
					$pcache->write($image, $this->id, $file);
2304
					$time=time()+($time*3600);
2305 View Code Duplication
					if (!$pcache->touch($this->id, $file, $time)) {
2306
						$this->error = ar::error("savecache: ERROR: couldn't touch $file", 1113);
2307
						$result = false;
2308
					}
2309
				}
2310
				ob_end_clean();
2311
				echo $image;
2312
			} else {
2313
				debug("skipped saving cache - ob_get_contents returned false so output buffering was not active", "all");
2314
				$result = false;
2315
			}
2316
		} else {
2317
			$this->error = ar::error($ARnls["err:savecachenofile"], 1112);
2318
			$result = false;
2319
		}
2320
		return $result;
2321
	}
2322
2323
	public function getdatacache($name) {
2324
		global $ARCurrent, $ARnls;
2325
		$result=false;
2326
		$this->error = '';
2327
		if ($name) {
2328
2329
			$minfresh = time();
2330
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2331
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2332
			}
2333
2334
			$pcache=$this->store->get_filestore("privatecache");
2335
			if ( $pcache->exists($this->id, $name) &&
2336
			     ($pcache->mtime($this->id, $name) > $minfresh) ) {
2337
				$result = unserialize($pcache->read($this->id, $name));
2338
			} else {
2339
				debug("getdatacache: $name doesn't exists, returning false.","all");
2340
			}
2341
		} else {
2342
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2343
		}
2344
		return $result;
2345
	}
2346
2347
	public function savedatacache($name,$data,$time="") {
2348
		global $DB;
2349
		$this->error = '';
2350
		if (!$time) {
2351
			$time=2; // 'freshness' in hours.
2352
		}
2353
		$pcache=$this->store->get_filestore("privatecache");
2354
		if( $time > 0  && $DB["wasUsed"] == 0) {
2355
			$pcache->write(serialize($data), $this->id, $name);
2356
			$time=time()+($time*3600);
2357 View Code Duplication
			if (!$pcache->touch($this->id, $name, $time)) {
2358
				$this->error = ar::error('Could not touch '.$name, 1113);
2359
				return false;
2360
			}
2361
		}
2362 52
		return true;
2363
	}
2364
2365 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...
2366
	// function to retrieve variables from $this->data, with the correct
2367 52
	// language version.
2368 52
	global $ARCurrent;
2369 48
2370 48
		$result = false;
2371 48
		if ($nls!="none") {
2372 48 View Code Duplication
			if ($ARCurrent->arCallStack) {
2373 24
				$arCallArgs=end($ARCurrent->arCallStack);
2374
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2375
					extract($arCallArgs);
2376 24
				} else if (is_string($arCallArgs)) {
2377 48
					Parse_Str($arCallArgs);
2378 28
				}
2379 48
			}
2380
			if (isset(${$nls}[$varname])) {
2381 48
				$result=${$nls}[$varname];
2382
			} else if (isset($ARCurrent->$nls) && isset($ARCurrent->$nls->$varname)) {
2383 48
				$result=$ARCurrent->$nls->$varname;
2384
			} else if (($values=$_POST[$nls]) && isset($values[$varname])) {
2385 48
				$result=$values[$varname];
2386
			} else if (($values=$_GET[$nls]) && isset($values[$varname])) {
2387 48
				$result=$values[$varname];
2388
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2389
				$result=$arStoreVars[$nls][$varname];
2390 48
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2391 48
				$result=$arStoreVars[$nls][$varname];
2392 36
			}
2393 12
			if ($result===false) {
2394 24
				if (isset($this->data->${nls}) && isset($this->data->${nls}->${varname})) {
2395 24
					$result=$this->data->${nls}->${varname};
2396 52
				}
2397 52
			}
2398 52
		} else { // language independant variable.
2399 48 View Code Duplication
			if ($ARCurrent->arCallStack) {
2400 34
				$arCallArgs=end($ARCurrent->arCallStack);
2401
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2402
					extract($arCallArgs);
2403 26
				} else if (is_string($arCallArgs)) {
2404 52
					Parse_Str($arCallArgs);
2405 24
				}
2406 52
			}
2407
			if (isset($$varname)) {
2408 52
				$result=$$varname;
2409
			} else if (isset($ARCurrent->$varname)) {
2410 52
				$result=$ARCurrent->$varname;
2411 View Code Duplication
			} else if (isset($_POST[$varname])) {
2412 52
				$result=$_POST[$varname];
2413
			} else if (isset($_GET[$varname])) {
2414 52
				$result=$_GET[$varname];
2415
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$varname])) {
2416
				$result=$arStoreVars[$varname];
2417 52
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$varname])) {
2418 52
				$result=$arStoreVars[$varname];
2419 24
			}
2420 12
			if ($result===false) {
2421 26
				if (isset($this->data->$varname)) {
2422
					$result=$this->data->$varname;
2423 52
				}
2424 52
			}
2425 26
		}
2426 52
		if ( $result === false ) {
2427
			$result = $emptyResult;
2428
		}
2429
		return $result;
2430
	}
2431
2432
	public function showdata($varname, $nls="none", $emptyResult=false) {
2433
		echo htmlspecialchars($this->getdata($varname, $nls, $emptyResult), ENT_QUOTES, 'UTF-8');
2434
	}
2435
2436
	public function setnls($nls) {
2437
		ldSetNls($nls);
2438
	}
2439
2440
	public function getcharset() {
2441
		return "UTF-8";
2442
	}
2443
2444
	public function HTTPRequest($method, $url, $postdata = "", $port=80 ) {
2445
		$maxtries = 5;
2446
		$tries = 0;
2447
		$redirecting = true;
2448
2449
		if(isset($postdata) && is_array($postdata)) {
2450
			foreach($postdata as $key=>$val) {
2451
				if(!is_integer($key)) {
2452
					$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...
2453
				}
2454
			}
2455
		} else {
2456
			$data = $postdata;
2457
		}
2458
2459
		while ($redirecting && $tries < $maxtries) {
2460
			$tries++;
2461
			// get host name and URI from URL, URI not needed though
2462
			preg_match("/^([htps]*:\/\/)?([^\/]+)(.*)/i", $url, $matches);
2463
			$host = $matches[2];
2464
			$uri = $matches[3];
2465
			if (!$matches[1]) {
2466
				$url="http://".$url;
2467
			}
2468
			$connection = @fsockopen( $host, $port, $errno, $errstr, 120);
2469
			if( $connection ) {
2470
				if( strtoupper($method) == "GET" ) {
2471
					if ($data) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $data of type null|string is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

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

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

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

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
2472
						$uri .= "?" . $data;
2473
					}
2474
					fputs( $connection, "GET $uri HTTP/1.0\r\n");
2475
				} else if( strtoupper($method) == "POST" ) {
2476
					fputs( $connection, "POST $uri HTTP/1.0\r\n");
2477
				} else {
2478
					fputs( $connection, "$method $uri HTTP/1.0\r\n");
2479
				}
2480
2481
				fputs( $connection, "Host: $host\r\n");
2482
				fputs( $connection, "Accept: */*\r\n");
2483
				fputs( $connection, "Accept: image/gif\r\n");
2484
				fputs( $connection, "Accept: image/x-xbitmap\r\n");
2485
				fputs( $connection, "Accept: image/jpeg\r\n");
2486
2487
				if( strtoupper($method) == "POST" ) {
2488
					$strlength = strlen( $data);
2489
					fputs( $connection, "Content-type: application/x-www-form-urlencoded\r\n" );
2490
					fputs( $connection, "Content-length: ".$strlength."\r\n\r\n");
2491
					fputs( $connection, $data."\r\n");
2492
				}
2493
2494
				fputs( $connection, "\r\n" , 2);
2495
2496
				$headerContents = '';
2497
				$headerStart = 0;
2498
				$headerEnd = 0;
2499
				$redirecting = false;
2500
2501
				while (!feof($connection)) {
2502
					$currentLine = fgets ($connection, 1024);
2503
					if ($headerEnd && $redirecting) {
2504
						break;
2505
					} else if ($headerEnd && !$redirecting) {
2506
						//this is the html from the page
2507
						$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...
2508
					} else if ( preg_match("/^HTTP/", $currentLine) ) {
2509
						//came to the start of the header
2510
						$headerStart = 1;
2511
						$headerContents = $currentLine;
2512
					} else if ( $headerStart && preg_match('/^[\n\r\t ]*$/', $currentLine) ) {
2513
						//came to the end of the header
2514
						$headerEnd = 1;
2515
					} else {
2516
						//this is the header, if you want it...
2517
						if (preg_match("/^Location: (.+?)\n/is",$currentLine,$matches) ) {
2518
							$headerContents .= $currentLine;
2519
							//redirects are sometimes relative
2520
							$newurl = $matches[1];
2521
							if (!preg_match("/http:\/\//i", $newurl, $matches) ) {
2522
								$url .= $newurl;
2523
							} else {
2524
								$url = $newurl;
2525
							}
2526
							//extra \r's get picked up sometimes
2527
							//i think only with relative redirects
2528
							//this is a quick fix.
2529
							$url = preg_replace("/\r/s","",$url);
2530
							$redirecting = true;
2531
						} else {
2532
							$headerContents.=$currentLine;
2533
						}
2534
					}
2535
				}
2536
			} else {
2537
				$this->error="$errstr ($errno)";
2538
				$contents=false;
2539
				$url = "";
2540
			}
2541
			@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...
2542
		}
2543
		if (($method!="GET") && ($method!="POST")) {
2544
			$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...
2545
		}
2546
		return $contents;
2547
	}
2548
2549
	public function make_filesize( $size="" ,$precision=0) {
2550
		$suffixes = array('B','KB','MB','GB','TB','PB','EB','ZB','YB');
2551
2552
		if( $size === "" ) {
2553
			$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...
2554
		}
2555
		while ( (count($suffixes) > 1) && ($size > 1024) ){
2556
			$size = $size / 1024;
2557
			array_shift($suffixes);
2558
		}
2559
		$size = round($size,$precision);
2560
		if($precision==0){ // compatible with the old make_filesize
2561
			$size = intval($size);
2562
		}
2563
		$result = $size." ".array_shift($suffixes);
2564
		return $result;
2565
	}
2566
2567
	public function convertToUTF8($data, $charset = "CP1252") {
2568
2569
		include_once($this->store->get_config("code")."modules/mod_unicode.php");
2570
2571
		if (isset($data) && is_array($data)) {
2572
			foreach($data as $key => $val){
2573
				$data[$key] = $this->convertToUTF8($val, $charset);
2574
			}
2575
		} else
2576
		if (is_object($data)) {
2577
			foreach($data as $key => $val){
2578
				$data->$key = $this->convertToUTF8($val, $charset);
2579
			}
2580
		} else {
2581
			$data = unicode::convertToUTF8($charset, $data);
2582
		}
2583 28
		return $data;
2584 28
	}
2585 28
2586 28
	public function resetloopcheck() {
2587
		global $ARBeenHere;
2588
		$ARBeenHere=array();
2589
	}
2590
2591
/********************************************************************
2592
2593
  "safe" functions.
2594
2595
  The following functions are safe versions of existing functions
2596
  above.
2597
  - They don't change anything in the database.
2598
    This means that to save/delete something, a user will need to call
2599
    "system.save.data.phtml" or "system.delete.phtml" which check grants.
2600
  - All functions except _get and _exists don't take a path as
2601
    argument, they use the current objects path instead.
2602
2603
  These are meant to be used by 'pinp' versions of templates,
2604
  meaning user defined templates. 'pinp' rewrites call to functions
2605
  to the form '$this->_function'.
2606
2607
  All pinp files automatically first call CheckLogin('read').
2608
2609
********************************************************************/
2610
2611
	public function _call($function, $args="") {
2612
		// remove possible path information (greedy match)
2613
		if ( !( $function instanceof \Closure ) ) {
2614
			$function = basename( (string) $function );
2615
		}
2616
		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...
2617
	}
2618
2619
	public function _call_super($arCallArgs="") {
2620
	global $ARCurrent, $AR;
2621
		$context = $this->getContext();
2622
		if (!$arCallArgs) {
2623
			$arCallArgs = end($ARCurrent->arCallStack);
2624
		}
2625
		$arSuperContext = (array)$context['arSuperContext'];
2626
		$arLibrary		= $context['arLibrary'];
2627
		$arLibraryPath	= $context['arLibraryPath'];
2628
		$arCallType		= $context['arCallTemplateType'];
2629
		$arSuperPath	= $context['arCallTemplatePath'];
2630
		$arLibrariesSeen = $context['arLibrariesSeen'];
2631
		$arCallFunction = $arSuperFunction = $context['arCallFunction'];
2632
		if ($arLibrary) {
2633
			$arSuperFunction = str_replace($arLibrary.':', '', $arCallFunction);
2634
		}
2635
		if (strpos($arSuperFunction, "::") !== false) {
2636
			// template of a specific class defined via call("class::template");
2637
			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...
2638
		}
2639
		// remove current library path from the arLibrariesSeen array so that
2640
		// Ariadne will be able to re-enter the library and toggle the arSuperContext boolean there.
2641
		unset($arLibrariesSeen[$arLibraryPath]);
2642
		$arSuperContext[$arSuperPath.":".$arCallType.":".$arSuperFunction] = true;
2643
2644
		debug("call_super: searching for the template following (path: $arSuperPath; type: $arCallType; function: $arCallFunction) from $this->path");
2645
		// 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...
2646
		$redirects	= $ARCurrent->shortcut_redirect;
2647
		if (isset($redirects) && is_array($redirects)) {
2648
			$redirpath = $this->path;
2649
			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...
2650
						($redir = array_pop($redirects)) &&
2651
							$redir["keepurl"] &&
2652
								(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
2653
			) {
2654
				debug("call_super: following shortcut redirect: $redirpath; to ".$redir["dest"]);
2655
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"], false, $arLibrariesSeen, $arSuperContext);
2656
				$redirpath = $redir['src'];
2657
			}
2658 View Code Duplication
			if (!$template["arTemplateId"]) {
2659
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, '', false, $arLibrariesSeen, $arSuperContext);
2660
			}
2661
		}
2662 View Code Duplication
		if (!$template["arTemplateId"]) {
2663
			$template = $this->getPinpTemplate($arCallFunction, $this->path, '', false, $arLibrariesSeen, $arSuperContext);
2664
		}
2665
		if ($template["arCallTemplate"] && $template["arTemplateId"]) {
2666
			$arTemplates=$this->store->get_filestore("templates");
2667
			if ($arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")) {
2668
				debug("call_super: found template ".$template["arCallTemplate"]." on object with id ".$template["arTemplateId"]);
2669
				$arLibrary = $template['arLibrary'];
2670
				debug("call_super: found template on ".$template["arTemplateId"]);
2671
				if (is_int($arLibrary)) {
2672
					// set the library name for unnamed libraries to 'current'
2673
					// so that calls using getvar('arLibrary') will keep on working
2674
					$arLibrary = "current";
2675
				}
2676 View Code Duplication
				if (!is_string($arCallArgs)) {
2677
					$arCallArgs['arCallFunction'] = $arCallFunction;
2678
					$arCallArgs['arLibrary'] = $arLibrary;
2679
					$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
2680
				}
2681
				$ARCurrent->arCallStack[]=$arCallArgs;
2682
				$this->pushContext(
2683
					array(
2684
						"scope" => "pinp",
2685
						"arSuperContext" => $arSuperContext,
2686
						"arLibrary" => $arLibrary,
2687
						"arLibraryPath" => $template['arLibraryPath'],
2688
						"arCallFunction" => $arCallFunction,
2689
						"arCurrentObject" => $this,
2690
						"arCallType" => $template['arCallType'],
2691
						"arCallTemplateName" => $template['arCallTemplateName'],
2692
						"arCallTemplateNLS"  => $template['arCallTemplateNLS'],
2693
						"arCallTemplateType" => $template['arCallTemplateType'],
2694
						"arCallTemplatePath" => $template['arCallTemplatePath']
2695
					)
2696
				);
2697
				$continue = true;
2698
				$eventData = new object();
2699 View Code Duplication
				if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2700
					$AR->contextCallHandler = true;
2701
					$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...
2702
					$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...
2703
					$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...
2704
					$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...
2705
					$ARCurrent->arResult = $eventData->arResult;
2706
					$AR->contextCallHandler = false;
2707
					$continue = ($eventData!=false);
2708
				}
2709
				if ( $continue ) {
2710
					set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2711
					$arResult = $arTemplates->import($template["arTemplateId"], $template["arCallTemplate"], "", $this);
2712
					restore_error_handler();
2713
2714 View Code Duplication
					if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2715
						$AR->contextCallHandler = true;
2716
						$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2717
						$eventData->arResult = $arResult;
2718
						ar_events::fire('oncall', $eventData );
2719
						$ARCurrent->arResult = $temp; /* restore correct result */
2720
						$AR->contextCallHandler = false;
2721
					}
2722
				}
2723
				array_pop($ARCurrent->arCallStack);
2724
				$this->popContext();
2725
			}
2726
		}
2727
2728
		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...
2729
	}
2730
2731
	public function _get($path, $function="view.html", $args="") {
2732
		// remove possible path information (greedy match)
2733
		if ( !($function instanceof \Closure) ) {
2734
			$function = basename( (string) $function);
2735
		}
2736
		return $this->store->call($function, $args,
2737
			$this->store->get(
2738
				$this->make_path($path)));
2739
	}
2740
2741
	public function _call_object($object, $function, $args="") {
2742
		return $object->call($function, $args);
2743
	}
2744
2745 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...
2746
		// remove possible path information (greedy match)
2747
		if ( ! ( $function instanceof \Closure ) ) {
2748
			$function = basename( (string) $function );
2749
		}
2750
		return $this->store->call($function, $args,
2751
			$this->store->ls($this->path));
2752
	}
2753
2754 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...
2755
		// remove possible path information (greedy match)
2756
		if ( !($function instanceof \Closure ) ) {
2757
			$function = basename( (string) $function);
2758
		}
2759
		return $this->parents($this->path, $function, $args, $top);
2760
	}
2761
2762
	public function _find($criteria, $function="list.html", $args="", $limit=100, $offset=0) {
2763
		$this->error = '';
2764
		// remove possible path information (greedy match)
2765
		if ( !($function instanceof \Closure ) ) {
2766
			$function = basename( (string) $function);
2767
		}
2768
		$result = $this->store->call($function, $args,
2769
			$this->store->find($this->path, $criteria, $limit, $offset));
2770 View Code Duplication
		if ($this->store->error) {
2771
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error );
2772
		}
2773
		return $result;
2774
	}
2775
2776
	public function _exists($path) {
2777
		return $this->store->exists($this->make_path($path));
2778
	}
2779
2780
	public function _implements($implements) {
2781 52
		return $this->AR_implements($implements);
2782 52
	}
2783
2784 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...
2785 48
	global $ARCurrent, $ARConfig; // Warning: if you add other variables here, make sure you cannot get at it through $$var.
2786 48
2787 36 View Code Duplication
		if ($ARCurrent->arCallStack) {
2788 32
			$arCallArgs=end($ARCurrent->arCallStack);
2789
			if (isset($arCallArgs) && is_array($arCallArgs)) {
2790
				extract($arCallArgs);
2791 24
			} else if (is_string($arCallArgs)) {
2792 52
				Parse_Str($arCallArgs);
2793 16
			}
2794 52
		}
2795
		if (isset($$var) && ($var!='ARConfig')) {
2796 52
			$result=$$var;
2797
		} else if (isset($ARCurrent->$var)) {
2798 52
			$result=$ARCurrent->$var;
2799
		} else if (isset($ARConfig->pinpcache[$this->path][$var])) {
2800 52
			$result=$ARConfig->pinpcache[$this->path][$var];
2801 View Code Duplication
		} else if (isset($_POST[$var])) {
2802 52
			$result=$_POST[$var];
2803
		} else if (isset($_GET[$var])) {
2804 52
			$result=$_GET[$var];
2805
		} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$var])) {
2806
			$result=$arStoreVars[$var];
2807 52
		} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$var])) {
2808
			$result=$arStoreVars[$var];
2809
		}
2810
		return $result;
2811
	}
2812
2813
	public function _getvar($var) {
2814
		return $this->getvar($var);
2815
	}
2816
2817
	public function putvar($var, $value) {
2818
		global $ARCurrent;
2819
2820
		$ARCurrent->$var=$value;
2821
	}
2822
2823
	public function _putvar($var, $value) {
2824
		return $this->putvar($var, $value);
2825
	}
2826
2827
	public function _setnls($nls) {
2828
		$this->setnls($nls);
2829
	}
2830
2831
	// not exposed to pinp for obvious reasons
2832
	public function sgKey($grants) {
2833
		global $AR;
2834
		if( !$AR->sgSalt || !$this->CheckSilent("config") ) {
2835
			return false;
2836
		}
2837
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2838
		$this->_load("mod_grant.php");
2839
		$mg = new mod_grant();
2840
		$grantsarray = array();
2841
		$mg->compile($grants, $grantsarray);
2842
		$grants = serialize($grantsarray);
2843
		return sha1( $AR->sgSalt . $grants . $this->path);
2844
	}
2845
2846
	public function sgBegin($grants, $key = '', $path = '.') {
2847
		global $AR;
2848
		$result = false;
2849
		$context = $this->getContext();
2850
		$path    = $this->make_path($path);
2851
2852
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2853
		$this->_load("mod_grant.php");
2854
		$mg = new mod_grant();
2855
		$grantsarray = array();
2856
		$mg->compile($grants, $grantsarray);
2857
2858
		if ($context['scope'] == 'pinp') {
2859
			$checkgrants = serialize($grantsarray);
2860
			$check = ( $AR->sgSalt ? sha1( $AR->sgSalt . $checkgrants . $path) : false ); // not using suKey because that checks for config grant
2861
		} else {
2862
			$check = true;
2863
			$key = true;
2864
		}
2865
		if( $check !== false && $check === $key ) {
2866
			$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2867
			$grantsarray = (array)$AR->sgGrants[$path];
2868
			$mg->compile($grants, $grantsarray);
2869
			$AR->sgGrants[$path] = $grantsarray;
2870
			$result = true;
2871
		}
2872
		return $result;
2873
	}
2874
2875
	public function sgEnd($path = '.') {
2876
		global $AR;
2877
		$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2878
		$path = $this->make_path( $path );
2879
		unset($AR->sgGrants[$path]);
2880
		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...
2881
	}
2882
2883
	public function sgCall($grants, $key, $function="view.html", $args="") {
2884
		$result = false;
2885
		if( $this->sgBegin($grants, $key ) ) {
2886
			$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...
2887
			$this->sgEnd();
2888
		}
2889
		return $result;
2890
	}
2891
2892
	public function _sgBegin($grants, $key, $path = '.') {
2893
		return $this->sgBegin($grants, $key, $path);
2894
	}
2895
2896
	public function _sgEnd($path = '.') {
2897
		return $this->sgEnd($path);
2898
	}
2899
2900
	public function _sgCall($grants, $key, $function="view.html", $args="") {
2901
		return $this->sgCall($grants, $key, $function, $args);
2902
	}
2903
2904
	public function _widget($arWidgetName, $arWidgetTemplate, $arWidgetArgs="", $arWidgetType="lib") {
2905
	global $AR, $ARConfig, $ARCurrent, $ARnls;
2906
2907
		$arWidgetName=preg_replace("/[^a-zA-Z0-9\/]/","",$arWidgetName);
2908
		$arWidgetTemplate=preg_replace("/[^a-zA-Z0-9\.]/","",$arWidgetTemplate);
2909
		$wgResult=null;
2910
		if ($arWidgetType=="www") {
2911
			$coderoot=$AR->dir->root;
2912
		} else {
2913
			$coderoot=$this->store->get_config("code");
2914
		}
2915
		if (file_exists($coderoot."widgets/$arWidgetName")) {
2916
			if (file_exists($coderoot."widgets/$arWidgetName/$arWidgetTemplate")) {
2917
				if (isset($arWidgetArgs) && is_array($arWidgetArgs)) {
2918
					extract($arWidgetArgs);
2919
				} else if (is_string($arWidgetArgs)) {
2920
					Parse_str($arWidgetArgs);
2921
				}
2922
				include($coderoot."widgets/$arWidgetName/$arWidgetTemplate");
2923
			} else {
2924
				error("Template $arWidgetTemplate for widget $arWidgetName not found.");
2925
			}
2926
		} else {
2927
			error(sprintf($ARnls["err:widgetnotfound"],$arWidgetName));
2928
		}
2929
		if ($wgResult) {
2930
			return $wgResult;
2931
		}
2932
	}
2933
2934
	public function _getdata($varname, $nls="none", $emptyResult=false) {
2935
		return $this->getdata($varname, $nls, $emptyResult);
2936
	}
2937
2938
	public function _showdata($varname, $nls="none", $emptyResult=false) {
2939
		$this->showdata($varname, $nls, $emptyResult);
2940
	}
2941
2942
	public function _gettext($index=false) {
2943
	global $ARnls;
2944
		if (!$index) {
2945
			return $ARnls;
2946
		} else {
2947
			return $ARnls[$index];
2948
		}
2949
	}
2950
2951
	public function _loadtext($nls, $section="") {
2952
	global $ARnls, $ARCurrent;
2953
		if( is_object($ARnls) ) {
2954
			$ARnls->load($section, $nls);
2955
			$ARnls->setLanguage($nls);
2956
			$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...
2957
		} else { // older loaders and other shizzle
2958
2959
			$nls = preg_replace('/[^a-z]*/i','',$nls);
2960
			$section = preg_replace('/[^a-z0-9\._:-]*/i','',$section);
2961
			if (!$section) {
2962
				include($this->store->get_config("code")."nls/".$nls);
2963
				$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2964
			} else {
2965
				$nlsfile = $this->store->get_config("code")."nls/".$section.".".$nls;
2966
				if(strpos($nlsfile, ':') === false && file_exists($nlsfile)) {
2967
					include($nlsfile);
2968
					$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2969
				} else {
2970
					// current result;
2971
					$arResult = $ARCurrent->arResult;
2972
					$this->pushContext(array());
2973
						$oldnls = $this->reqnls;
2974
						$this->reqnls = $nls;
2975
						$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...
2976
						$this->reqnls = $oldnls;
2977
					$this->popContext();
2978
					// reset current result (CheckConfig may have changed it when it should not have).
2979
					$ARCurrent->arResult = $arResult;
2980
				}
2981
			}
2982
		}
2983
	}
2984
2985
	public function _startsession() {
2986
	global $ARCurrent;
2987
		ldStartSession(0);
2988
		return $ARCurrent->session->id;
2989
	}
2990
2991
	public function _putsessionvar($varname, $varvalue) {
2992
	global $ARCurrent;
2993
2994
		if ($ARCurrent->session) {
2995
			return $ARCurrent->session->put($varname, $varvalue);
2996
		} else {
2997
			return false;
2998
		}
2999
	}
3000
3001
	public function _getsessionvar($varname) {
3002
	global $ARCurrent;
3003
3004
		if ($ARCurrent->session) {
3005
			return $ARCurrent->session->get($varname);
3006
		} else {
3007
			return false;
3008
		}
3009
	}
3010
3011
	public function _setsessiontimeout($timeout = 0) {
3012
	global $ARCurrent;
3013
		if ($ARCurrent->session) {
3014
			return $ARCurrent->session->setTimeout($timeout);
3015
		} else {
3016
			return false;
3017
		}
3018
	}
3019
3020
	public function _killsession() {
3021
	global $ARCurrent;
3022
3023
		if ($ARCurrent->session) {
3024
			$ARCurrent->session->kill();
3025
			unset($ARCurrent->session);
3026
		}
3027
	}
3028
3029
	public function _sessionid() {
3030
	global $ARCurrent;
3031
		if ($ARCurrent->session) {
3032
			return $ARCurrent->session->id;
3033
		} else {
3034
			return 0;
3035
		}
3036
	}
3037
3038
	public function _resetloopcheck() {
3039
		return $this->resetloopcheck();
3040
	}
3041
3042
	public function _make_path($path="") {
3043
		return $this->make_path($path);
3044
	}
3045
3046
	public function _make_ariadne_url($path="") {
3047
		return $this->make_ariadne_url($path);
3048
	}
3049
3050
	public function _make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
3051
		return $this->make_url($path, $nls, $session, $https, $keephost);
3052
	}
3053
3054
	public function _make_local_url($path="", $nls=false, $session=true, $https=null) {
3055
		return $this->make_local_url($path, $nls, $session, $https);
3056
	}
3057
3058
	public function _getcache($name, $nls='') {
3059
		return $this->getcache($name, $nls);
3060
	}
3061
3062
	public function _cached($name, $nls='') {
3063
		return $this->cached($name, $nls);
3064
	}
3065
3066
	public function _savecache($time="") {
3067
		return $this->savecache($time);
3068
	}
3069
3070
	public function _getdatacache($name) {
3071
		return $this->getdatacache($name);
3072
	}
3073
3074
	public function _savedatacache($name,$data,$time="")
3075
	{
3076 56
		return $this->savedatacache($name,$data,$time);
3077 56
	}
3078 56
3079 48
	public function currentsite($path="", $skipRedirects = false) {
3080 24
		global $ARCurrent, $ARConfig;
3081 56
		if (!$path) {
3082 56
			$path=$this->path;
3083
		}
3084
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3085
		if (!$skipRedirects && @count($ARCurrent->shortcut_redirect)) {
3086
			$redir = end($ARCurrent->shortcut_redirect);
3087
			if ($redir["keepurl"] && substr($path, 0, strlen($redir["dest"])) == $redir["dest"]) {
3088
				if (substr($config->site, 0, strlen($redir["dest"]))!=$redir["dest"]) {
3089
					// search currentsite from the reference
3090
					$config = ($ARConfig->cache[$redir['src']]) ? $ARConfig->cache[$redir['src']] : $this->loadConfig($redir['src']);
3091 56
				}
3092
			}
3093
		}
3094
		return $config->site;
3095
	}
3096
3097
	public function parentsite($site) {
3098
	global $ARConfig;
3099
		$path=$this->store->make_path($site, "..");
3100
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3101 4
		return $config->site;
3102 4
	}
3103 4
3104 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...
3105 2
	global $ARConfig;
3106 4
		if (!$path) {
3107 4
			$path=$this->path;
3108
		}
3109
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3110
		return $config->section;
3111
	}
3112
3113 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...
3114
	global $ARConfig;
3115
		$path=$this->store->make_path($path, "..");
3116
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3117
		return $config->section;
3118
	}
3119
3120 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...
3121
	global $ARConfig;
3122
		if (!$path) {
3123
			$path=$this->path;
3124
		}
3125
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3126
		return $config->project;
3127
	}
3128
3129
	public function parentproject($path) {
3130
	global $ARConfig;
3131
		$path=$this->store->make_path($path, "..");
3132
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3133
		return $config->project;
3134
	}
3135
3136
	public function validateFormSecret() {
3137
		global $ARCurrent;
3138
		if (!$ARCurrent->session) {
3139
			return true;
3140
		}
3141
3142
		if ($ARCurrent->session && $ARCurrent->session->data && $ARCurrent->session->data->formSecret) {
3143
			$formSecret = $this->getvar("formSecret");
3144
			return ($formSecret === $ARCurrent->session->data->formSecret);
3145
		}
3146
		return false;
3147
	}
3148
3149
	public function _validateFormSecret() {
3150
		return $this->validateFormSecret();
3151
	}
3152
3153
	public function getValue($name, $nls=false) {
3154
	global $ARCurrent;
3155
		switch ($nls) {
3156
			case "none":
3157
				$result = $this->data->$name;
3158
			break;
3159
			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...
3160
				$nls = $ARCurrent->nls;
3161
				if (!isset($this->data->$nls) || !isset($this->data->$nls->$name)) {
3162
					$result = $this->data->$name;
3163
					break;
3164
				}
3165
			default:
3166
				$result = $this->data->$nls->$name;
3167
		}
3168
		return $result;
3169
	}
3170
3171
	public function setValue($name, $value, $nls=false) {
3172
3173
	global $AR, $ARConfig;
3174
		if ($value === null) {
3175
			if ($nls && $nls!="none") {
3176
				unset($this->data->$nls->$name);
3177
				if (!count(get_object_vars($this->data->$nls))) {
3178
					unset($this->data->$nls);
3179
					unset($this->data->nls->list[$nls]);
3180
					if (!count($this->data->nls->list)) {
3181
						unset($this->data->nls->list);
3182
						unset($this->data->nls);
3183
					} else {
3184
						if ($this->data->nls->default == $nls) {
3185
							if ($this->data->nls->list[$ARConfig->nls->default]) {
3186
								$this->data->nls->default = $ARConfig->nls->default;
3187
							} else {
3188
								list($this->data->nls->default) = each($this->data->nls->list);
3189
							}
3190
						}
3191
					}
3192
				}
3193
			} else {
3194
				unset($this->data->$name);
3195
			}
3196
		} else
3197
		if (!$nls) {
3198
			$this->data->$name = $value;
3199
		} else {
3200
			if (!$this->data->$nls) {
3201
				$this->data->$nls = new object;
3202
				if (!$this->data->nls) {
3203
					$this->data->nls = new object;
3204
					$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...
3205
				}
3206
				$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...
3207
			}
3208
			$this->data->$nls->$name = $value;
3209
		}
3210
	}
3211
3212
	public function showValue($name, $nls=false) {
3213
		$result = $this->getValue($name, $nls);
3214
		echo $result;
3215
		return $result;
3216
	}
3217
3218
	public function _getValue($name, $nls=false) {
3219
		return $this->getValue($name, $nls);
3220
	}
3221
3222
	public function _setValue($name, $value, $nls=false) {
3223
		return $this->setValue($name, $value, $nls);
3224
	}
3225
3226
	public function _showValue($name, $nls=false) {
3227
		return $this->showValue($name, $nls);
3228
	}
3229
3230
	public function _currentsite($path="", $skipRedirects = false) {
3231
		return $this->currentsite( $path, $skipRedirects );
3232
	}
3233
3234
	public function _parentsite($site) {
3235
		return $this->parentsite($site);
3236
	}
3237
3238
	public function _currentsection() {
3239
		return $this->currentsection();
3240
	}
3241
3242
	public function _parentsection($section) {
3243
		return $this->parentsection($section);
3244
	}
3245
3246
	public function _currentproject() {
3247
		return $this->currentproject();
3248
	}
3249
3250
	public function _parentproject($path) {
3251
		return $this->parentproject($path);
3252
	}
3253
3254
	public function _checkAdmin($user) {
3255
		return $this->CheckAdmin($user);
3256
	}
3257
3258
	public function _checkgrant($grant, $modifier=ARTHISTYPE, $path=".") {
3259
		// as this is called within a pinp template,
3260
		// all the grants are already loaded, so
3261
		// checksilent will fullfill our needs
3262
		$this->pushContext(array("scope" => "php"));
3263
			$result = $this->CheckSilent($grant, $modifier, $path);
3264
		$this->popContext();
3265
		return $result;
3266
	}
3267
3268
	public function _checkpublic($grant, $modifier=ARTHISTYPE) {
3269
3270
		return $this->CheckPublic($grant, $modifier);
3271
	}
3272
3273
	public function _getcharset() {
3274
		return $this->getcharset();
3275
	}
3276
3277
	public function _count_find($query='') {
3278
		return $this->count_find($this->path, $query);
3279
	}
3280
3281
	public function _count_ls() {
3282
		return $this->count_ls($this->path);
3283
	}
3284
3285
	public function _HTTPRequest($method, $url, $postdata = "", $port=80) {
3286
		return $this->HTTPRequest($method, $url, $postdata, $port);
3287
	}
3288
3289
	public function _make_filesize( $size="" ,$precision=0) {
3290
		return $this->make_filesize( $size ,$precision);
3291
	}
3292
3293
	public function _convertToUTF8($data, $charset = "CP1252") {
3294
		return $this->convertToUTF8($data,$charset);
3295
	}
3296
3297
	public function _getuser() {
3298
	global $AR;
3299
		if ($AR->pinp_user && $AR->pinp_user->data->login == $AR->user->data->login) {
3300
			$user = $AR->pinp_user;
3301
		} else {
3302
			$this->pushContext(array("scope" => "php"));
3303
				if ( $AR->user instanceof ariadne_object ) {
3304
					$user = current($AR->user->get(".", "system.get.phtml"));
3305
				} else {
3306
					$user = $AR->user;
3307
				}
3308
				$AR->pinp_user = $user;
3309
			$this->popContext();
3310
		}
3311
		return $user;
3312
	}
3313
3314
	public function ARinclude($file) {
3315 4
		include($file);
3316
	}
3317 4
3318 4
	public function _load($class) {
3319 4
		// only allow access to modules in the modules directory.
3320
		$class = preg_replace('/[^a-z0-9\._]/i','',$class);
3321
		include_once($this->store->get_config("code")."modules/".$class);
3322
	}
3323
3324
	public function _import($class) {
3325
		// deprecated
3326 16
		return $this->_load($class);
3327 16
	}
3328 16
3329
	public function html_to_text($text) {
3330 16
		$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
3331
		$cb  = function($matches) use ($trans) {
3332 16
			return strtr($matches[1],$trans);
3333 16
		};
3334
		//strip nonbreaking space, strip script and style blocks, strip html tags, convert html entites, strip extra white space
3335 16
		$search_clean = array("%&nbsp;%i", "%<(script|style)[^>]*>.*?<\/(script|style)[^>]*>%si", "%<[\/]*[^<>]*>%Usi", "%\s+%");
3336 16
		$replace_clean = array(" ", " ", " ", " ");
3337 2
3338
		$text = preg_replace_callback(
3339 2
			"%(\&[a-zA-Z0-9\#]+;)%s",
3340 16
			$cb,
3341 16
			$text
3342
		);
3343
		$text = preg_replace($search_clean, $replace_clean, $text);
3344
		return $text;
3345
	}
3346
3347
	public function _html_to_text($text) {
3348
		return $this->html_to_text($text);
3349
	}
3350
3351
	public function _newobject($filename, $type) {
3352
		$newpath=$this->make_path($filename);
3353
		$newparent=$this->store->make_path($newpath, "..");
3354
		$data=new object;
3355
		$object=$this->store->newobject($newpath, $newparent, $type, $data);
3356
		$object->arIsNewObject=true;
3357
		return $object;
3358
	}
3359
3360
	public function _save($properties="", $vtype="") {
3361
		if (isset($properties) && is_array($properties)) {
3362
			// isn't this double work, the save function doesn this again
3363
			foreach ($properties as $prop_name => $prop) {
3364
				foreach ($prop as $prop_index => $prop_record) {
3365
					$record = array();
3366 View Code Duplication
					foreach ($prop_record as $prop_field => $prop_value) {
3367
						switch (gettype($prop_value)) {
3368
							case "integer":
3369
							case "boolean":
3370
							case "double":
3371
								$value = $prop_value;
3372
							break;
3373
							default:
3374
								$value = $prop_value;
3375
								if (substr($prop_value, 0, 1) === "'" && substr($prop_value, -1) === "'"
3376
										&& "'".AddSlashes(StripSlashes(substr($prop_value, 1, -1)))."'" == $prop_value) {
3377
									$value = stripSlashes(substr($prop_value,1,-1));
3378
									// todo add deprecated warning
3379
								}
3380
						}
3381
						$record[$prop_field] = $value;
3382
					}
3383
					$properties[$prop_name][$prop_index] = $record;
3384
				}
3385
			}
3386
		}
3387
3388
		if ($this->arIsNewObject && $this->CheckSilent('add', $this->type)) {
3389
			unset($this->data->config);
3390
			$result = $this->save($properties, $vtype);
0 ignored issues
show
Bug introduced by
It seems like $properties can also be of type array or null; however, ariadne_object::save() does only seem to accept string, maybe add an additional type check?

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

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

    return array();
}

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

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

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

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

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

    return array();
}

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

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

Loading history...
3394
		}
3395
		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...
3396
	}
3397
3398
	public function _is_supported($feature) {
3399
		return $this->store->is_supported($feature);
3400
	}
3401
3402
	/*
3403
		since the preg_replace() function is able to execute normal php code
3404
		we have to intercept all preg_replace() calls and parse the
3405
		php code with the pinp parser.
3406
	*/
3407
3408
3409
	/*	this is a private function used by the _preg_replace wrapper */
3410
	// FIXME: remove this function when the minimal php version for ariadne is raised to php 7.0
0 ignored issues
show
Coding Style introduced by
Comment refers to a FIXME task "remove this function when the minimal php version for ariadne is raised to php 7.0"
Loading history...
3411
	protected function preg_replace_compile($pattern, $replacement) {
3412
	global $AR;
3413
		include_once($this->store->get_config("code")."modules/mod_pinp.phtml");
3414
		preg_match("/^\s*(.)/", $pattern, $regs);
3415
		$delim = $regs[1];
3416
		if (@eregi("\\${delim}[^$delim]*\\${delim}.*e.*".'$', $pattern)) {
3417
			$pinp = new pinp($AR->PINP_Functions, 'local->', '$AR_this->_');
3418
			return substr($pinp->compile("<pinp>$replacement</pinp>"), 5, -2);
3419
		} else {
3420
			return $replacement;
3421
		}
3422
	}
3423
3424
	public function _preg_replace($pattern, $replacement, $text, $limit = -1) {
3425
		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
3426
			if (isset($pattern) && is_array($pattern)) {
3427
				$newrepl = array();
3428
				reset($replacement);
3429
				foreach ($pattern as $i_pattern) {
3430
					list(, $i_replacement) = each($replacement);
3431
					$newrepl[] = $this->preg_replace_compile($i_pattern, $i_replacement);
3432
				}
3433
			} else {
3434
				$newrepl = $this->preg_replace_compile($pattern, $replacement);
3435
			}
3436
		} else {
3437
			// php7 is safe, no more eval
3438
			$newrepl = $replacement;
3439
		}
3440
		return preg_replace($pattern, $newrepl, $text, $limit);
3441
	}
3442
3443
	/* ob_start accepts a callback but we don't want that
3444
	 * this wrapper removes the arguments from the ob_start call
3445
	 */
3446
	public function _ob_start() {
3447
		return ob_start();
3448
	}
3449
3450
	public function _loadConfig($path='') {
3451
		return clone $this->loadConfig($path);
3452
	}
3453
3454
	public function _loadUserConfig($path='') {
3455
		return $this->loadUserConfig($path);
3456 4
	}
3457
3458
	public function _loadLibrary($name, $path) {
3459
		return $this->loadLibrary($name, $path);
3460
	}
3461
3462
	public function _resetConfig($path='') {
3463
		return $this->resetConfig($path);
3464
	}
3465
3466
	public function _getLibraries($path = '') {
3467
		return $this->getLibraries($path);
3468
	}
3469
3470
3471
	public function _getSetting($setting) {
3472
	global $AR;
3473
3474
		switch ($setting) {
3475
			case 'www':
3476
			case 'dir:www':
3477
				return $AR->dir->www;
3478
			case 'images':
3479
			case 'dir:images':
3480
				return $AR->dir->images;
3481
			case 'ARSessionKeyCheck':
3482
				$result = null;
3483
				if (function_exists('ldGenerateSessionKeyCheck')) {
3484
					$result = ldGenerateSessionKeyCheck();
3485
				}
3486
				return $result;
3487
			break;
3488
			case 'nls:list':
3489
				return $AR->nls->list;
3490
			break;
3491
			case 'nls:default':
3492
				return $AR->nls->default;
3493
			break;
3494
			case 'svn':
3495
				return $AR->SVN->enabled;
3496
			break;
3497
		}
3498
	}
3499
3500
	public function __call($name,$arguments) {
3501
		if ( $name[0] == '_' ) {
3502
			$fname = substr($name, 1);
3503
			if ( isset($this->{$fname}) && $this->{$fname} instanceof \Closure ) {
3504
				\Closure::bind( $this->{$fname}, $this );
3505
				return call_user_func_array( $this->{$fname}, $arguments);
3506
			}
3507
		}
3508
		switch($name) {
3509
			case "implements":
3510
				return $this->AR_implements($arguments[0]);
3511
			break;
3512
			default:
3513
				trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $name), E_USER_ERROR);
3514
				return false;
3515
			break;
3516
		}
3517 7
	}
3518 7
3519 7
	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...
3520
		global $nocache;
3521
		if (($errno & error_reporting()) == 0) {
3522
			return true;
3523
		}
3524
3525
		$nocache = true;
3526
		$context = pobject::getContext();
3527
		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...
3528
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." in library ".$context["arLibraryPath"] ."\n".$errstr."\n";
3529
		} else {
3530
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." on object ".$context['arCurrentObject']->path."\n".$errstr."\n";
3531
		}
3532
		$display = ini_get('display_errors');
3533
3534
		if($display) {
3535
			echo $msg;
3536
		}
3537
		error_log($msg);
3538
3539
		return false;
3540
	}
3541
3542
} // end of ariadne_object class definition
3543