Completed
Push — master ( c95774...6765cb )
by Auke
13:36
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 6
CRAP Score 168.873

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 48
ccs 6
cts 38
cp 0.1579
rs 4.9765
cc 16
eloc 28
nc 4
nop 2
crap 168.873

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 21
		}
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 9
		} 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 15
			$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 46
			"arCallFunction" => $arCallFunction
95 138
		) );
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 138
		}
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 138
		}
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 75
		} 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 138
		} else {
122
			// the requested language is not available, use default of the
123
			// current object instead.
124
			$this->nls=$this->data->nls->default;
125 3
			$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 99
		} 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 3
		}
138 184
		if (isset($this->data->custom['none'])) {
139 7
			$customdata=$this->data->custom['none'];
140 6
		}
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 6
				$arCallFunction = $libname.":".$arCallFunction;
154
			}
155 18
		} 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 3
				}
167
			}
168 3
		} else {
169 184
			if ($arCallFunction[0] === "#") {
170 15
				$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 35
				$arResult = $this;
178 24
			} 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 3
					}
190 24
					$arType=$arSuper;
191 18
				}
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 11
						break;
209 18
					} 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 11
							$arSuper=get_parent_class($arType);
218
219 26
							$AR->superClass[$arType]=$arSuper;
220 6
						}
221 184
						$arType=$arSuper;
222 3
					}
223 138
				}
224
			}
225 3
		}
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 15
		}
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 3
	public function ls($path="", $function="list.html", $args="") {
241 3
		$path=$this->store->make_path($this->path, $path);
242 3
		return $this->store->call($function, $args, $this->store->ls($path));
243 3
	}
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 3
	}
249
250 7
	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 7
			$top = $this->currentsection();
255 3
		} else {
256 7
			$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 3
		} 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 6
			}
274 3
		}
275 4
		$parents = array_reverse($parents);
276 4
		$result = array();
277 7
		foreach ($parents as $parent) {
278 4
			if ( $parent ) { // might not have read access to this object
279 4
				$result[] = $parent->call($function, $args);
280 3
			}
281 3
		}
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 3 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 3
		}
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 3
	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 3
							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 3
						}
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
			foreach($this->data->custom as $nls => $cdata) {
369
				foreach($cdata as $name => $value){
370
					// one index, this order (name, value, nls) ?
371
					if ($configcache->custom[$name]['containsHTML']) {
372
						$this->_load('mod_url.php');
373
						$value = URL::RAWtoAR($value, $nls);
374
						$this->data->custom[$nls][$name] = $value;
375
					}
376
					if ($configcache->custom[$name]['property']) {
377
						if (isset($value) && is_array($value)) {
378
							foreach($value as $valkey => $valvalue ) {
379
								$properties["custom"][] = [
380
									"name"  => $name,
381
									"value" => $valvalue,
382
									"nls"   => $nls,
383
								];
384
							}
385
						} else {
386
							$properties["custom"][] = [
387
								"name"  => $name,
388
								"value" => $value,
389
								"nls"   => $nls,
390
							];
391
392
						}
393
					}
394
				}
395
			}
396
		}
397 48
		return $properties;
398
	}
399
400 48
	public function save($properties="", $vtype="") {
401
	/***********************************************************************
402
	  save the current object.
403
	  if this is a new object ($this->arIsNewObject) the path is checked and
404
	  the object is saved under the new path.
405
	***********************************************************************/
406 48
	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 48
		$this->error = '';
414 48
		if ($this->arIsNewObject) { // save a new object
0 ignored issues
show
Bug introduced by
The property arIsNewObject does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
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 24
					if ($this->exists($arNewParent)) {
423 24
						if (!$config = $this->data->config) {
424 6
							$config=new object();
425
						}
426 18
					} else {
427 6
						$this->error = ar::error( sprintf($ARnls["err:noparent"],$arNewParent), 1102);
428
					}
429 18
				} else {
430 6
					$this->error = ar::error( sprintf($ARnls["err:alreadyexists"],$arNewFilename), 1103);
431
				}
432 18
			} else {
433 6
				$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$arNewFilename), 1104);
434
			}
435 18
		} else { // existing object
436 48
			debug("pobject: save: existing object","all");
437 48
			if ($this->exists($this->path)) { // prevent 'funny stuff'
438 48
				if (!$this->lock()) {
439
					$this->error = ar::error( $ARnls["err:objectalreadylocked"], 1105);
440
				} else {
441 48
					$needsUnlock = true;
442 48
					$config = $this->data->config;
443
				}
444 36
			} else {
445
				$this->error = ar::error($ARnls["err:corruptpathnosave"], 1106);
446
			}
447
		}
448
		// pre checks done
449
		// return now on error
450 48
		if ($this->error) {
451
			return $result;;
452
		}
453
454
455 48
		if ($ARCurrent->arCallStack) {
456 48
			$arCallArgs = end($ARCurrent->arCallStack);
457 36
		} else {
458 20
			$arCallArgs = array();
459
		}
460
461 48
		$context = $this->getContext();
462
463 48
		$wf_object = $this->store->newobject($this->path, $this->parent, $this->type, $this->data, $this->id, $this->lastchanged, $this->vtype, 0, $this->priority);
0 ignored issues
show
Bug introduced by
The property parent does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

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

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

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

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

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

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

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

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

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

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

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

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

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

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

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

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

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

Loading history...
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 48
		$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
491
		// the properties from the eventData are the new property list
492
		// no need to merge them with $properties, just manipulate the properties array directly
493
		// in the event data. unlike the user.workflow.pre.html template
494 48
		if (isset( $eventData->arProperties ) && is_array( $eventData->arProperties ) ) {
495 48
			$properties = $eventData->arProperties;
496 36
		} else {
497 44
			$properties = array();
498
		}
499
500
		// pass the current properties list to the workflow template
501
		// for backwards compatibility and workflow templates that just
502
		// returned only their own properties, merge them afterwards
503
		// don't do this for the eventData arProperties!
504 48
		$arCallArgs['properties'] = $properties;
505 48
		$wf_result = $wf_object->call("user.workflow.pre.html", $arCallArgs);
506
		/* merge workflow properties */
507 48
		if (isset($wf_result) && is_array($wf_result) ){
508
			$properties = $this->saveMergeWorkflowResult($properties,$wf_result);
509
		}
510
511 48
		$this->error = $wf_object->error;
512 48
		$this->priority = $wf_object->priority;
513 48
		$this->data = $wf_object->data;
514 48
		$this->data->config = $config;
0 ignored issues
show
Bug introduced by
The variable $config does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

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

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

Loading history...
577 48
			$this->unlock();
578 36
		}
579
580 48
		if ($this->data->nls->list[$this->nls]) {
581 48
			$mynlsdata=$this->data->{$this->nls};
582 36
		} else if ($this->data->nls->default) {
583
			$mynlsdata=$this->data->{$this->data->nls->default};
584
		} else {
585
			$mynlsdata=$this->data;
586
		}
587
588 48
		unset($this->nlsdata);
589 48
		$this->nlsdata=$mynlsdata;
590
591 48
		debug("pobject: save: end","all");
592 48
		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
		return $result;
628
	}
629
630 56
	public function exists($path) {
631 56
		$path=$this->make_path($path);
632 56
		return $this->store->exists($path);
633
	}
634
635 72
	public function make_path($path="") {
636
		switch($path){
637 72
			case '':
638 72
			case '.':
639 70
			case $this->path:
640 72
				return $this->path;
641
				break;
642 60
			case '..':
643 24
				return $this->parent;
644
				break;
645 45
			default:
646 60
				return $this->store->make_path($this->path, $path);
647 45
		}
648
	}
649
650
	public function make_ariadne_url($path="") {
651
		global $AR;
652
		$path = $this->make_path($path);
653
		return $AR->host . $AR->root . $this->store->get_config('rootoptions') . $path;
654
	}
655
656
657 52
	public function make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
658 52
		global $ARConfig, $AR, $ARCurrent;
659
660 52
		$rootoptions=$this->store->get_config('rootoptions');
661 52
		if (!$session || ($nls !== false)) {
662 52
			$rootoptions = "";
663 52
			if ($session && isset($ARCurrent->session->id) && !$AR->hideSessionIDfromURL) {
664
				$rootoptions .= "/-".$ARCurrent->session->id."-";
665
			}
666 52
			if ($nls) {
667 48
				$rootoptions_nonls = $rootoptions;
668 48
				$rootoptions .= '/'.$nls;
669 36
			}
670 39
		}
671 52
		$path=$this->make_path($path);
672
673
		// now run CheckConfig and get the parentsite of the path found
674 52
		if (!$temp_config=$ARConfig->cache[$path]) {
675 4
			$temp_path = $path;
676 4
			while (!($temp_site = $this->currentsite($temp_path)) && $temp_path!='/') {
677
				$temp_path = $this->make_path($temp_path.'../');
678
			}
679 4
			$temp_config=$ARConfig->cache[$temp_site];
680 3
		}
681
682 52
		if ( !isset($keephost) && (
683 52
			(!$nls && $this->compare_hosts($AR->host, $temp_config->root["value"])) ||
684 52
			($nls && ($this->compare_hosts($AR->host, $temp_config->root['list']['nls'][$nls])))
685 39
		)) {
686
			$keephost = false;
687
		}
688
689 52
		if (!$keephost) {
690 52
			if ($nls) {
691 48
				$url=$temp_config->root["list"]["nls"][$nls];
692 48
				if (isset($url) && is_array($url)) {
693
					$url = current( $url );
694
				}
695 48
				if ($url) {
696 View Code Duplication
					if (substr($url, -1)=='/') {
697
						$url=substr($url, 0, -1);
698
					}
699
					$url .= $rootoptions_nonls;
0 ignored issues
show
Bug introduced by
The variable $rootoptions_nonls does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

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

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

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

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

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

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
788
			}
789
		}
790
791
		do {
792 48 View Code Duplication
			if (!$config=$ARConfig->cache[$checkpath]) {
793
				$config=($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
794
			}
795 48
			if ($config) {
796 48
				$checkNLS = $nls;
797 48
				if (!$checkNLS) {
798
					$checkNLS = $this->nls;
799
				}
800 48
				$urlCheck = $config->root['list']['nls'][$checkNLS];
801 48
				if (!is_array($urlCheck)) {
802 48
					$urlCheck = $config->root["value"];
803 36
				}
804 48
				$requestedHost = ldGetRequestedHost();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $requestedHost is correct as ldGetRequestedHost() seems to always returns null.
Loading history...
805
806 48
				if ($this->compare_hosts($requestedHost, $urlCheck)) {
807
					$site=$config->site;
808
				}
809 36
			}
810 48
			$prevpath=$checkpath;
811 48
			$checkpath=$this->make_path($checkpath."../");
812 48
		} while ($prevpath!=$checkpath && !$site);
813 48
		if (!$site) {
814 48
			$site='/';
815 36
		}
816 48
		$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
		} else {
820 48
			$rest=substr($path, strlen($site));
821
		}
822 48
		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
		return $result;
838
	}
839
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 48
	global $AR;
842 48
		if ($this->store->mod_lock) {
843 48
			$result=$this->store->mod_lock->lock($AR->user->data->login,$this->path,$mode,$time);
844 36
		} else {
845
			$result=true; // no lock module, so lock is 'set'
846
		}
847 48
		return $result;
848
	}
849
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 48
	global $AR;
852 48
		if ($this->store->mod_lock) {
853 48
			$result=$this->store->mod_lock->unlock($AR->user->data->login,$this->path);
854 36
		} else {
855
			$result=true;
856
		}
857 48
		return $result;
858
	}
859
860
	public function touch($id=0, $timestamp=-1) {
861
		if (!$id) {
862
			$id = $this->id;
863
		}
864
		$result = $this->store->touch($id, $timestamp);
865 View Code Duplication
		if ($this->store->error) {
866
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error);
867
		}
868
		return $result;
869
	}
870
871
	public function mogrify($id=0, $type, $vtype=null) {
0 ignored issues
show
Coding Style introduced by
Parameters which have default values should be placed at the end.

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

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

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

Let’s take a look at an example:

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

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

    // do something with $myArray
}

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

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

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

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1045 4
		return $grants;
1046
	}
1047
1048
1049 184
	public function pushContext($context) {
1050 184
	global $AR;
1051 184
		if(!empty($AR->context)) {
1052 72
			$context = array_merge(end($AR->context), $context);
1053 54
		}
1054 184
		array_push($AR->context, $context);
1055 184
	}
1056
1057
	public function setContext($context, $level=0) {
1058
	global $AR;
1059
		$AR->context[count($AR->context)-(1+$level)]=$context;
1060
	}
1061
1062 184
	public function popContext() {
1063 184
	global $AR;
1064 184
		return array_pop($AR->context);
1065
	}
1066
1067 184
	public static function getContext($level=0) {
1068 184
	global $AR;
1069 184
		return $AR->context[count($AR->context)-(1+$level)];
1070
	}
1071
1072 72
	public function CheckAdmin($user) {
1073 72
	if ($user->data->login == "admin") {
1074 68
			return true;
1075
		}
1076 4
		if ($user->data->groups['/system/groups/admin/']) {
1077
			return true;
1078
		}
1079 4
		return false;
1080
	}
1081
1082 60
	public function CheckLogin($grant, $modifier=ARTHISTYPE) {
1083 60
	global $AR,$ARnls,$ARConfig,$ARCurrent,$ARConfigChecked;
1084 60
		if (!$this->store->is_supported("grants")) {
1085
			debug("pobject: store doesn't support grants");
1086
			return true;
1087
		}
1088 60
		if ($modifier==ARTHISTYPE) {
1089 60
			$modifier=$this->type;
1090 45
		}
1091
1092
		/* load config cache */
1093 60
		if (!isset($ARConfig->cache[$this->path])) {
1094
			// since this is usually run before CheckConfig, make sure
1095
			// it doesn't set cache time
1096
			$realConfigChecked = $ARConfigChecked;
1097
			$ARConfigChecked = true;
1098
			$this->loadConfig();
1099
			$ARConfigChecked = $realConfigChecked;
1100
		}
1101
1102 60
		$isadmin = $this->CheckAdmin($AR->user);
1103
1104 60
		if (!$isadmin && !$AR->user->grants[$this->path]) {
1105
			$AR->user->grants[$this->path]=$this->GetValidGrants();
1106
		}
1107 60
		if ($AR->user->data->login!="public") {
1108
			// Don't remove this or MSIE users won't get uptodate pages...
1109 60
			ldSetClientCache(false);
1110 45
		}
1111
1112 60
		$grants=$AR->user->grants[$this->path];
1113 60
		if ( 	( !$grants[$grant]
1114 60
					|| ( $modifier && is_array($grants[$grant]) && !$grants[$grant][$modifier] )
1115 60
				) && !$isadmin ) {
1116
			// do login
1117
			$arLoginMessage = $ARnls["accessdenied"];
1118
			ldAccessDenied($this->path, $arLoginMessage);
1119
			$result=false;
1120
		} else {
1121 60
			$result=($grants || $isadmin);
1122
		}
1123
1124 60
		$ARCurrent->arLoginSilent=1;
1125 60
		return $result;
1126
	}
1127
1128
1129 4
	public function CheckPublic($grant, $modifier=ARTHISTYPE) {
1130 4
	global $AR;
1131
1132 4
		$result=false;
1133 4
		if (!$AR->public) {
1134 4
			$this->pushContext(array("scope" => "php"));
1135 4
				$AR->public=current($this->get("/system/users/public/", "system.get.phtml"));
1136 4
			$this->popContext();
1137 3
		}
1138 4
		if ($AR->public) {
1139 4
			$AR->private=$AR->user;
1140 4
			$AR->user=$AR->public;
1141 4
			$result=$this->CheckSilent($grant, $modifier);
1142 4
			$AR->user=$AR->private;
1143 3
		}
1144 4
		return $result;
1145
	}
1146
1147 44
	public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") {
1148 44
	global $AR, $ARConfig;
1149 44
		$path = $this->make_path($path);
1150 44
		if ($modifier==ARTHISTYPE) {
1151 44
			$modifier=$this->type;
1152 33
		}
1153
1154
		/* load config cache */
1155 44
		if (!$ARConfig->cache[$path]) {
1156 8
			$this->loadConfig($path);
1157 6
		}
1158 44
		if ($this->CheckAdmin($AR->user)) {
1159 40
			$result=1;
1160 34
		} else if ($grants=$AR->user->grants[$path]) {
1161
			$result=$grants[$grant];
1162
		} else {
1163 4
			$grants=$this->GetValidGrants();
1164 4
			$result=$grants[$grant];
1165
		}
1166 44
		if ($modifier && is_array($result)) {
1167
			$result=$result[$modifier];
1168
		}
1169 44
		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
		}
1217
	}
1218
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 36
			$path = preg_quote($path,'/');
1224 36
			$keys = preg_grep('/^'.$path.'./',array_keys($ARConfig->cache));
1225 36
			foreach($keys as $cachepath) {
1226 4
				unset($ARConfig->cache[$cachepath]);
1227 4
				unset($ARConfig->pinpcache[$cachepath]);
1228 4
				unset($ARConfig->libraries[$cachepath]);
1229 27
			}
1230 27
		}
1231 36
	}
1232
1233 36
	protected function getConfig() {
1234 36
	global $ARConfig, $ARCurrent, $ARConfigChecked;
1235
		// $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
		// 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
		// 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 36
		if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) {
1239 4
			$parent = current($this->get($this->parent, "system.get.phtml"));
1240 4
			if ($parent) {
1241 4
				$parent->getConfig();
1242 3
			}
1243 3
		}
1244
1245 36
		$this->getConfigData();
1246
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 36
		$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
1254
		/* calling config.ini directly for each system.get.config.phtml call */
1255 36
		$loginSilent = $ARCurrent->arLoginSilent;
1256 36
		$ARCurrent->arLoginSilent = true;
1257
		// 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 36
		$ARConfig->cache[$this->path]->inConfigIni = true;
1263 36
		if ($ARConfig->cache[$this->path]->hasConfigIni && !$this->CheckConfig('config.ini', $arCallArgs)) {
0 ignored issues
show
Documentation introduced by
$arCallArgs is of type array<string,?,{"arConfig":"?"}>, but the function expects a string.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug Best Practice introduced by
The expression $this->CheckConfig('config.ini', $arCallArgs) of type null|boolean is loosely compared to false; this is ambiguous if the boolean can be false. You might want to explicitly use !== null instead.

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

$a = canBeFalseAndNull();

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

// Better use one of the explicit versions:
if ($a !== null) { }
if ($a !== false) { }
if ($a !== null && $a !== false) { }
Loading history...
1264
			//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 4
			$arConfig = $ARCurrent->arResult;
1267 4
			if (!isset($arConfig)) {
1268
				$arConfig = $ARCurrent->arConfig;
1269
			}
1270 4
			unset($ARCurrent->arResult);
1271 4
			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
				}
1278
				unset($arConfig['library']);
1279
			}
1280 4
			$ARConfig->pinpcache[$this->path] = (array) $arConfig;
1281 3
		}
1282 36
		$ARConfig->cache[$this->path]->inConfigIni = false;
1283 36
		$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 36
		$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 36
			if (reset($arConfig['authentication']['userdirs']) != '/system/users/') {
1292
				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 36
			if (reset($arConfig['authentication']['groupdirs']) != '/system/groups/') {
1299
				array_unshift($arConfig['authentication']['groupdirs'], '/system/groups/');
1300
			}
1301
		}
1302
1303 36
		$ARCurrent->arLoginSilent = $loginSilent;
1304 36
		$ARCurrent->arConfig = $prevArConfig;
1305 36
	}
1306
1307 36
	protected function getConfigData() {
1308 36
	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 36
			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 36
			if (isset($this->data->config->privatetemplates) && count($this->data->config->privatetemplates)) {
1319
				$configcache->privatetemplates=&$this->data->config->privatetemplates;
1320
			}
1321
1322
			// Speedup check for config.ini
1323
1324 36
			if(isset($this->data->config->templates) && is_array($this->data->config->templates) ) {
1325 4
				$configcache->localTemplates = $this->data->config->templates;
1326 4
				if( !$configcache->hasDefaultConfigIni ) {
1327 4
					foreach($this->data->config->templates as $type => $templates ) {
1328
						if( isset($templates["config.ini"]) ) {
1329
							$configcache->hasDefaultConfigIni = true;
1330
							$configcache->hasConfigIni = true;
1331
							break;
1332
						}
1333 3
					}
1334 3
				}
1335 3
			}
1336
1337 36
			if( !$configcache->hasDefaultConfigIni ) {
1338 36
				$configcache->hasConfigIni = false;
1339 36
				if(isset($this->data->config->pinp) && is_array($this->data->config->pinp) ) {
1340 4
					foreach( $this->data->config->pinp as $type => $templates ) {
1341 4
						if( isset($templates["config.ini"]) ) {
1342 4
							$configcache->hasConfigIni = true;
1343 4
							break;
1344
						}
1345 3
					}
1346 3
				}
1347 27
			}
1348
1349 36
			$localcachesettings = $this->data->config->cacheSettings;
1350 36
			if (!is_array($localcachesettings) ){
1351 36
				$localcachesettings = array();
1352 27
			}
1353
1354 36
			if (!is_array($configcache->cacheSettings) ) {
1355
				$configcache->cacheSettings = array();
1356
			}
1357
1358 36
			if ($this->data->config->cacheconfig) { // When removing this part, also fix the setting below.
1359 4
				$configcache->cache=$this->data->config->cacheconfig;
1360 3
			}
1361
1362 36
			if (!isset($localcachesettings['serverCache']) && isset($this->data->config->cacheconfig)) {
1363 4
				$localcachesettings["serverCache"] = $this->data->config->cacheconfig;
1364 3
			}
1365
1366 36
			if ($localcachesettings['serverCache'] != 0 ) {
1367 4
				$localcachesettings['serverCacheDefault'] = $localcachesettings['serverCache'];
1368 3
			}
1369
1370 36
			$configcache->cacheSettings = $localcachesettings + $configcache->cacheSettings;
1371
1372
			// store the current object type
1373 36
			$configcache->type = $this->type;
1374
1375 36
			if ($this->data->config->typetree && ($this->data->config->typetree!="inherit")) {
1376
				$configcache->typetree=$this->data->config->typetree;
1377
			}
1378 36
			if (isset($this->data->config->nlsconfig->list)) {
1379 4
				$configcache->nls = clone $this->data->config->nlsconfig;
1380 3
			}
1381
1382 36
			if ($this->data->config->grants["pgroup"]["owner"]) {
1383
				$configcache->ownergrants = $this->data->config->grants["pgroup"]["owner"];
1384
			}
1385 36
			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
				}
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
			}
1399 36
			$ARConfig->cache[$this->path]=$configcache;
1400
1401 27
		}
1402 36
	}
1403
1404 60
	public function loadConfig($path='') {
1405 60
	global $ARConfig, $ARConfigChecked, $ARCurrent;
1406 60
		$path=$this->make_path($path);
1407
		// 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 60
		if (!isset($ARConfig->cache[$path]) ) {
1409 36
			$allnls = $ARCurrent->allnls;
1410 36
			$ARCurrent->allnls = true;
1411 36
			$configChecked = $ARConfigChecked;
1412 36
			if (($this->path == $path && !$this->arIsNewObject) || $this->exists($path)) {
1413 36
				$this->pushContext(array("scope" => "php"));
1414 36
				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 36
					$this->getConfig();
1417 27
				} else {
1418
					//debug("loadConfig: get path $path ");
1419 4
					$cur_obj = current($this->get($path, "system.get.phtml"));
1420 4
					$cur_obj->getConfig();
1421
				}
1422 36
				$this->popContext();
1423 36
				$result=$ARConfig->cache[$path];
1424 27
			} 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
				$ARConfig->pinpcache[ $path ] = $ARConfig->pinpcache[ $parent ];
1441
			}
1442
			// restore old ARConfigChecked state
1443 36
			$ARConfigChecked = $configChecked;
1444 36
			$ARCurrent->allnls = $allnls;
1445 27
		} else {
1446
			// 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 48
			$result=$ARConfig->cache[$path];
1448
		}
1449 60
		return $result;
1450
	}
1451
1452
1453
	// TODO: look for a way to merge loadConfig and loadUserConfig into one function
1454
1455 12
	public function loadUserConfig($path='') {
1456 12
	global $ARConfig;
1457 12
		$path = $this->make_path($path);
1458 12
		$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
		} else {
1466 12
			$config = $ARConfig->pinpcache[$path];
1467
		}
1468 12
		return (array)$config;
1469
	}
1470
1471 48
	protected function getTemplateFromCache($path, $type, $function, &$arSuperContext) {
1472 48
	global $AR, $ARConfig;
1473 48
		$templatesList = $ARConfig->libraryCache[$path][$function];
1474 48
		if (!is_array($templatesList)) {
1475 48
			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
		}
1565
	}
1566
1567 4
	public function loadLibrary($name, $path) {
1568 4
	global $ARConfig;
1569 4
		$path=$this->make_path($path);
1570 4
		debug("pobject::loadLibrary($name, $path);");
1571 4
		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
				return ar::error('You cannot load an unnamed library from a child object.', 1109);
1574
			} else {
1575 4
				if (!$ARConfig->libraries[$this->path]) {
1576 4
					$ARConfig->libraries[$this->path]=array();
1577 3
				}
1578 4
				array_unshift($ARConfig->libraries[$this->path],$path);
1579 4 View Code Duplication
				if (!$ARConfig->cacheableLibraries[$this->path]) {
1580 4
					$ARConfig->cacheableLibraries[$this->path] = array($path);
1581 3
				} else {
1582 1
					array_unshift($ARConfig->cacheableLibraries[$this->path], $path);
1583
				}
1584
			}
1585 3
		} 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
		} else {
1607
			return ar::error('Illegal library name: '.$name, 1110);
1608
		}
1609 4
	}
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
		return $this->mergeLibraryConfig( $defaultLibraryName, $defaults );
1634
	}
1635
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 60
		$result = array();
1640 60
		if (!$top) {
1641 60
			$top = '/';
1642 45
		}
1643 60
		$path = $this->make_path($path);
1644 60
		if (!is_array($arSuperContext)) {
1645
			$arSuperContext = array();
1646
		}
1647
1648 60
		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
			}
1670
			$path = $this->make_path($path);
1671
		}
1672 60
		if (strpos($arCallFunction,"::")!==false) {
1673
			// template of a specific class defined via call("class::template");
1674
			list($arCallType, $arCallFunction)=explode("::",$arCallFunction);
1675
		} else {
1676 60
			$arCallType=$this->type;
1677
		}
1678
1679
		/* first check current templates */
1680 60
		if ($this->path == $path) {
1681 60
			$curr_templates = $this->data->config->pinp;
1682 45
		} else {
1683
			$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1684
			$curr_templates = $config->templates;
1685
		}
1686
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 60
			$arType = $arSetType;
1694 60
			while ($arType!='ariadne_object' && !$arCallTemplate) {
1695 60
				if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction][$this->reqnls])) {
1696
					$arCallTemplate=$arType.".".$arCallFunction.".".$this->reqnls;
1697
					$arCallTemplateName = $arCallFunction;
1698
					$arCallTemplateNLS = $this->reqnls;
1699 60 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction]['any'])) {
1700 12
					$arCallTemplate=$arType.".".$arCallFunction.".any";
1701 12
					$arCallTemplateName = $arCallFunction;
1702 12
					$arCallTemplateNLS = 'any';
1703 9
				} else {
1704
1705 48
					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
						}
1718
						$AR->superClass[$arType]=$arSuper;
1719
					}
1720 48
					$arType=$arSuper;
1721
				}
1722 45
			}
1723 60
			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
				}
1734
			}
1735
1736 60
			if (!$arTemplateId && $ARConfigChecked) {
0 ignored issues
show
Bug introduced by
The variable $arTemplateId does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1737 48
				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
					}
1749
				}
1750
1751 48
				if (isset($ARConfig->cacheableLibraries[$checkpath])) {
1752 48
					$template = $this->getTemplateFromCache($checkpath, $arCallType, $arCallFunction, $arSuperContext);
1753 48
					if ($template["arTemplateId"]) {
1754
						return $template;
1755
					}
1756 36
				}
1757 36
			}
1758 60
			if ($checkpath == $top) {
1759 48
				break;
1760
			}
1761
1762 60
			$checkpath=$this->store->make_path($checkpath, "..");
1763 60
			$config = ($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
1764 60
			$curr_templates = $config->templates;
1765 60
			$arSetType = $arCallType;
1766 45
		}
1767
1768 60
		$config = ($ARConfig->cache[$lastcheckedpath]) ? $ARConfig->cache[$lastcheckedpath] : $this->loadConfig($lastcheckedpath);
1769 60
		$arPrivateTemplate = $config->privatetemplates[$arCallType][$arCallFunction];
1770
1771
		//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 60
		$result["arLibraryPath"] = $arLibraryPath;
0 ignored issues
show
Bug introduced by
The variable $arLibraryPath does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1781 60
		$result["arLibrariesSeen"] = $librariesSeen;
1782 60
		$result["arPrivateTemplate"] = $arPrivateTemplate;
1783
1784 60
		return $result;
1785
	}
1786
1787 64
	public function CheckConfig($arCallFunction="", $arCallArgs="") {
1788
	// returns true when cache isn't up to date and no other template is
1789
	// defined for $path/$function. Else it takes care of output to the
1790
	// browser.
1791
	// All these templates must exist under a fixed directory, $AR->dir->templates
1792 64
	global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked;
1793 64
		$MAX_LOOP_COUNT=10;
1794
1795
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 64
		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
			$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
1805
			// this will prevent the parents from setting the cache time
1806 64
			$initialConfigChecked = $ARConfigChecked;
1807 64
			$ARConfigChecked = true;
1808 64
			$config = ($ARConfig->cache[$this->path]) ? $ARConfig->cache[$this->path] : $this->loadConfig();
1809 64
			$ARConfigChecked = $initialConfigChecked;
1810 64
			$ARConfig->nls=$config->nls;
1811
1812
1813
			// if a default language is entered in a parent and no language is
1814
			// explicitly selected in the url, use that default.
1815
			// The root starts with the system default (ariadne.phtml config file)
1816 64
			if ( !$ARCurrent->nls ) {
1817 64
				if ( $config->root['nls'] ) {
1818
					$this->reqnls = $config->root['nls'];
1819
					if ( !$ARConfigChecked ) {
1820
						$ARCurrent->nls = $this->reqnls;
1821
					}
1822 64
				} else if ( $config->nls->default ) {
1823 64
					$this->reqnls = $config->nls->default;
1824 64
					$this->nls = $this->reqnls;
1825 64
					if ( !$ARConfigChecked ) {
1826 16
						$ARCurrent->nls = $this->nls;
1827
					}
1828 48
				}
1829 48
			} else {
1830
				$this->reqnls = $ARCurrent->nls;
1831
			}
1832 64
			$nls = &$this->nls;
1833 64
			$reqnls = &$this->reqnls;
1834
1835 64
			if (!$ARConfigChecked && is_object($ARnls)) {
1836
				$ARnls->setLanguage($ARCurrent->nls);
1837
			}
1838
1839
1840 64
			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
				}
1855
			}
1856
*/
1857 64 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom['none']) {
1858 4
				$this->customdata=$this->data->custom['none'];
0 ignored issues
show
Bug introduced by
The property customdata does not exist. Did you maybe forget to declare it?

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

class MyClass { }

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

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

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
1859 3
			}
1860 64 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom[$nls]) {
1861
				$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 64
			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
				}
1876
			}
1877
1878 64
			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
				Set ARConfigChecked to true to indicate that we have been here
1907
				earlier.
1908
			*/
1909 64
			$ARConfigChecked = true;
1910 64
			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 60
				$redirects	= $ARCurrent->shortcut_redirect;
1913 60
				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
						$template = $this->getPinpTemplate($arCallFunction, $redirpath);
1926
					}
1927
				}
1928 60
				if (!$template["arTemplateId"]) {
1929 60
					$template = $this->getPinpTemplate($arCallFunction);
1930 45
				}
1931
1932 60
				if ($template["arCallTemplate"] && $template["arTemplateId"]) {
1933 12
					if (!isset($ARCurrent->cacheTemplateChain)) {
1934
						$ARCurrent->cacheTemplateChain = array();
1935
					}
1936 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) {
1937 8
						$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 9
					}
1942 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']])) {
1943 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0;
1944 9
					}
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
					// check if template exists, if it doesn't exist, then continue the original template that called CheckConfig
1951 12
					$arTemplates=$this->store->get_filestore("templates");
1952
					if (
1953 12
						$arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")
1954 9
					) {
1955
						// check if the requested language exists, if not do not display anything,
1956
						// unless otherwise indicated by $ARCurrent->allnls
1957
						// This triggers only for pinp templates called by other templates,
1958
						// as the first template (in the url) will first trigger the language
1959
						// choice dialogue instead.
1960 12
						$arLibrary = $template['arLibrary'];
1961 12
						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
							$arLibrary = "current";
1965
						}
1966
1967 12 View Code Duplication
						if (!is_string($arCallArgs)) {
1968 12
							$arCallArgs['arCallFunction'] = $arCallFunction;
1969 12
							$arCallArgs['arLibrary'] = $arLibrary;
1970 12
							$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
1971 9
						}
1972
1973 12
						$ARCurrent->arCallStack[]=$arCallArgs;
1974
						// start running a pinp template
1975
1976 12
						$this->pushContext(
1977
							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 12
								"arCallTemplateType" => $template['arCallTemplateType'],
1987 12
								"arCallTemplatePath" => $template['arCallTemplatePath'],
1988 12
								"arLibrariesSeen" => $template['arLibrariesSeen']
1989 9
							)
1990 9
						);
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 12
						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
							$this->popContext();
2000
							array_pop($ARCurrent->arCallStack);
2001
							return true;
2002 12
						} else if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) {
2003
							// the requested language is available.
2004 12
							$this->nlsdata=$this->data->$reqnls;
2005 12
							$this->nls=$reqnls;
2006 12
							$continue=true;
2007 9
						} 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
							// -> skip this object (do not run template but do return false)
2020
							$continue=false;
2021
						}
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 12
								$ARCurrent->arResult = $eventData->arResult;
2031 12
								$AR->contextCallHandler = false;
2032 12
								$continue = ($eventData!=false);
2033 9
							}
2034 12
							if ( $continue ) {
2035 12
								if (!isset($ARCurrent->cacheCallChainSettings)) {
2036
									$ARCurrent->cacheCallChainSettings = array();
2037
								}
2038 12
								if ($ARConfig->cache[$this->path]->inConfigIni == false) {
2039 8
									$ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings;
2040 6
								}
2041
2042 12
								if ($ARCurrent->ARShowTemplateBorders) {
2043
									echo "<!-- arTemplateStart\nData: ".$this->type." ".$this->path." \nTemplate: ".$template["arCallTemplatePath"]." ".$template["arCallTemplate"]." \nLibrary:".$template["arLibrary"]." -->";
2044
								}
2045 12
								set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2046 12
								$arResult=$arTemplates->import($template["arTemplateId"], $template["arCallTemplate"], "", $this);
2047 12
								restore_error_handler();
2048 12
								if (isset($arResult)) {
2049 12
									$ARCurrent->arResult=$arResult;
2050 9
								}
2051 12
								if ($ARCurrent->ARShowTemplateBorders) {
2052
									echo "<!-- arTemplateEnd -->";
2053
								}
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 12
									ar_events::fire('oncall', $eventData );
2059 12
									$ARCurrent->arResult = $temp; /* restore correct result */
2060 12
									$AR->contextCallHandler = false;
2061 9
								}
2062 9
							}
2063 9
						}
2064 12
						array_pop($ARCurrent->arCallStack);
2065 12
						$this->popContext();
2066
2067 12
						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
							$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
						}
2074 12
						return false;
2075
					} else {
2076 4
						debug("pobject: CheckConfig: no such file: ".$template["arTemplateId"].$template["arCallTemplate"]."","all");
2077
					}
2078 3
				} else {
2079 48
					debug("CheckConfig: no arCallTemplate ($arCallFunction from '$this->path')","object");
2080
				}
2081
2082 39
			}
2083
		}
2084 56
		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
		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
	// language version.
2368 52
	global $ARCurrent;
2369
2370 52
		$result = false;
2371 52
		if ($nls!="none") {
2372 48 View Code Duplication
			if ($ARCurrent->arCallStack) {
2373 48
				$arCallArgs=end($ARCurrent->arCallStack);
2374 48
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2375 48
					extract($arCallArgs);
2376 36
				} else if (is_string($arCallArgs)) {
2377
					Parse_Str($arCallArgs);
2378
				}
2379 36
			}
2380 48
			if (isset(${$nls}[$varname])) {
2381 28
				$result=${$nls}[$varname];
2382 48
			} else if (isset($ARCurrent->$nls) && isset($ARCurrent->$nls->$varname)) {
2383
				$result=$ARCurrent->$nls->$varname;
2384 48
			} else if (($values=$_POST[$nls]) && isset($values[$varname])) {
2385
				$result=$values[$varname];
2386 48
			} else if (($values=$_GET[$nls]) && isset($values[$varname])) {
2387
				$result=$values[$varname];
2388 48
			} 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
				$result=$arStoreVars[$nls][$varname];
2392
			}
2393 48
			if ($result===false) {
2394 48
				if (isset($this->data->${nls}) && isset($this->data->${nls}->${varname})) {
2395 30
					$result=$this->data->${nls}->${varname};
2396 18
				}
2397 36
			}
2398 36
		} else { // language independant variable.
2399 52 View Code Duplication
			if ($ARCurrent->arCallStack) {
2400 52
				$arCallArgs=end($ARCurrent->arCallStack);
2401 52
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2402 48
					extract($arCallArgs);
2403 43
				} else if (is_string($arCallArgs)) {
2404
					Parse_Str($arCallArgs);
2405
				}
2406 39
			}
2407 52
			if (isset($$varname)) {
2408 24
				$result=$$varname;
2409 52
			} else if (isset($ARCurrent->$varname)) {
2410
				$result=$ARCurrent->$varname;
2411 52 View Code Duplication
			} else if (isset($_POST[$varname])) {
2412
				$result=$_POST[$varname];
2413 52
			} else if (isset($_GET[$varname])) {
2414
				$result=$_GET[$varname];
2415 52
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$varname])) {
2416
				$result=$arStoreVars[$varname];
2417 52
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$varname])) {
2418
				$result=$arStoreVars[$varname];
2419
			}
2420 52
			if ($result===false) {
2421 52
				if (isset($this->data->$varname)) {
2422 24
					$result=$this->data->$varname;
2423 18
				}
2424 39
			}
2425
		}
2426 52
		if ( $result === false ) {
2427 52
			$result = $emptyResult;
2428 39
		}
2429 52
		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
		return $data;
2584
	}
2585
2586 28
	public function resetloopcheck() {
2587 28
		global $ARBeenHere;
2588 28
		$ARBeenHere=array();
2589 28
	}
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
		return $this->AR_implements($implements);
2782
	}
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 52
	global $ARCurrent, $ARConfig; // Warning: if you add other variables here, make sure you cannot get at it through $$var.
2786
2787 52 View Code Duplication
		if ($ARCurrent->arCallStack) {
2788 48
			$arCallArgs=end($ARCurrent->arCallStack);
2789 48
			if (isset($arCallArgs) && is_array($arCallArgs)) {
2790 36
				extract($arCallArgs);
2791 40
			} else if (is_string($arCallArgs)) {
2792
				Parse_Str($arCallArgs);
2793
			}
2794 36
		}
2795 52
		if (isset($$var) && ($var!='ARConfig')) {
2796 16
			$result=$$var;
2797 52
		} else if (isset($ARCurrent->$var)) {
2798
			$result=$ARCurrent->$var;
2799 52
		} else if (isset($ARConfig->pinpcache[$this->path][$var])) {
2800
			$result=$ARConfig->pinpcache[$this->path][$var];
2801 52 View Code Duplication
		} else if (isset($_POST[$var])) {
2802
			$result=$_POST[$var];
2803 52
		} else if (isset($_GET[$var])) {
2804
			$result=$_GET[$var];
2805 52
		} 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 52
		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
		return $this->savedatacache($name,$data,$time);
3077
	}
3078
3079 56
	public function currentsite($path="", $skipRedirects = false) {
3080 56
		global $ARCurrent, $ARConfig;
3081 56
		if (!$path) {
3082 48
			$path=$this->path;
3083 36
		}
3084 56
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3085 56
		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
				}
3092
			}
3093
		}
3094 56
		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
		return $config->site;
3102
	}
3103
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 4
	global $ARConfig;
3106 4
		if (!$path) {
3107 4
			$path=$this->path;
3108 3
		}
3109 4
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3110 4
		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
		include($file);
3316
	}
3317
3318 4
	public function _load($class) {
3319
		// only allow access to modules in the modules directory.
3320 4
		$class = preg_replace('/[^a-z0-9\._]/i','',$class);
3321 4
		include_once($this->store->get_config("code")."modules/".$class);
3322 4
	}
3323
3324
	public function _import($class) {
3325
		// deprecated
3326
		return $this->_load($class);
3327
	}
3328
3329 52
	public function html_to_text($text) {
3330 52
		$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
3331 52
		$cb  = function($matches) use ($trans) {
3332
			return strtr($matches[1],$trans);
3333 52
		};
3334
		//strip nonbreaking space, strip script and style blocks, strip html tags, convert html entites, strip extra white space
3335 52
		$search_clean = array("%&nbsp;%i", "%<(script|style)[^>]*>.*?<\/(script|style)[^>]*>%si", "%<[\/]*[^<>]*>%Usi", "%\s+%");
3336 52
		$replace_clean = array(" ", " ", " ", " ");
3337
3338 52
		$text = preg_replace_callback(
3339 52
			"%(\&[a-zA-Z0-9\#]+;)%s",
3340 39
			$cb,
3341
			$text
3342 39
		);
3343 52
		$text = preg_replace($search_clean, $replace_clean, $text);
3344 52
		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
	}
3457
3458
	public function _loadLibrary($name, $path) {
3459 4
		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
	}
3518
3519
	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 4
		global $nocache;
3521 4
		if (($errno & error_reporting()) == 0) {
3522 4
			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