Completed
Push — master ( 32b85c...2f7d3a )
by Auke
08:53
created

ariadne_object::_getcharset()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2
Metric Value
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
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 50
	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 50
			$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 1
				}
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
			$grants = $this->GetValidGrants();
1106
		} else {
1107 60
			$grants = $AR->user->grants[$this->path];
1108
		}
1109
1110 60
		if ($AR->user->data->login!="public") {
1111
			// Don't remove this or MSIE users won't get uptodate pages...
1112 60
			ldSetClientCache(false);
1113 45
		}
1114
1115 60
		if ( 	( !$grants[$grant]
1116 60
					|| ( $modifier && is_array($grants[$grant]) && !$grants[$grant][$modifier] )
1117 60
				) && !$isadmin ) {
1118
			// do login
1119
			$arLoginMessage = $ARnls["accessdenied"];
1120
			ldAccessDenied($this->path, $arLoginMessage);
1121
			$result=false;
1122
		} else {
1123 60
			$result=($grants || $isadmin);
1124
		}
1125
1126 60
		$ARCurrent->arLoginSilent=1;
1127 60
		return $result;
1128
	}
1129
1130
1131 4
	public function CheckPublic($grant, $modifier=ARTHISTYPE) {
1132 4
	global $AR;
1133
1134 4
		$result=false;
1135 4
		if (!$AR->public) {
1136 4
			$this->pushContext(array("scope" => "php"));
1137 4
				$AR->public=current($this->get("/system/users/public/", "system.get.phtml"));
1138 4
			$this->popContext();
1139 3
		}
1140 4
		if ($AR->public) {
1141 4
			$AR->private=$AR->user;
1142 4
			$AR->user=$AR->public;
1143 4
			$result=$this->CheckSilent($grant, $modifier);
1144 4
			$AR->user=$AR->private;
1145 3
		}
1146 4
		return $result;
1147
	}
1148
1149 44
	public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") {
1150 44
	global $AR, $ARConfig;
1151 44
		$path = $this->make_path($path);
1152 44
		if ($modifier==ARTHISTYPE) {
1153 44
			$modifier=$this->type;
1154 33
		}
1155
1156
		/* load config cache */
1157 44
		if (!$ARConfig->cache[$path]) {
1158 8
			$this->loadConfig($path);
1159 6
		}
1160 44
		if ($this->CheckAdmin($AR->user)) {
1161 40
			$result=1;
1162 34
		} else if ($grants=$AR->user->grants[$path]) {
1163
			$result=$grants[$grant];
1164
		} else {
1165 4
			$grants=$this->GetValidGrants();
1166 4
			$result=$grants[$grant];
1167
		}
1168 44
		if ($modifier && is_array($result)) {
1169
			$result=$result[$modifier];
1170
		}
1171 44
		return $result;
1172
	}
1173
1174
	public function CheckNewFile($newfilename) {
1175
	global $ARnls;
1176
	/**********************************************************************
1177
1178
	  This function performs all the necessary checks on a path to see
1179
	whether it's a valid path for a new object. This consists of:
1180
	1) checking for invalid characters, valid chars are "a-zA-Z0-9./_-"
1181
	2) checking whether the path starts and ends with a "/".
1182
	3) checking whether the path doesn't exist already.
1183
	4) checking whether the parent exists.
1184
1185
	if all this checks out, it returns 1. If not, $this->error is set to
1186
	the correct error message.
1187
1188
	**********************************************************************/
1189
1190
		$this->error="";
1191
		if (preg_match("|^/[a-z0-9\./_-]*/$|i",$newfilename)) {
1192
			if (!$this->store->exists($newfilename)) {
1193
				$parent=$this->store->make_path($newfilename, "..");
1194
				if ($this->store->exists($parent)) {
1195
					$result=1;
1196
				} else {
1197
					$this->error = ar::error( sprintf($ARnls["err:filenameinvalidnoparent"],$newfilename,$parent), 1102);
1198
				}
1199
			} else {
1200
				$this->error = ar::error( sprintf($ARnls["err:chooseotherfilename"],$newfilename), 1103);
1201
			}
1202
		} else {
1203
			$this->error = ar::error( sprintf($ARnls["err:fileillegalchars"],$newfilename)." ".$ARnls["err:startendslash"], 1104);
1204
		}
1205
		return $result;
0 ignored issues
show
Bug introduced by
The variable $result does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
1206
	}
1207
1208 View Code Duplication
	public function resetConfig($path='') {
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...
1209
	global $ARConfig;
1210
		$path = $this->make_path($path);
1211
		if ($ARConfig->cache[$path]) {
1212
			$path = preg_quote($path,'/');
1213
			$keys = preg_grep('/^'.$path.'/',array_keys($ARConfig->cache));
1214
			foreach ($keys as $cachepath) {
1215
				unset($ARConfig->cache[$cachepath]);
1216
				unset($ARConfig->pinpcache[$cachepath]);
1217
			}
1218
		}
1219
	}
1220
1221 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...
1222 36
	global $ARConfig;
1223 36
		$path = $this->make_path($path);
1224 36
		if ($ARConfig->cache[$path]) {
1225 36
			$path = preg_quote($path,'/');
1226 36
			$keys = preg_grep('/^'.$path.'./',array_keys($ARConfig->cache));
1227 36
			foreach($keys as $cachepath) {
1228 4
				unset($ARConfig->cache[$cachepath]);
1229 4
				unset($ARConfig->pinpcache[$cachepath]);
1230 4
				unset($ARConfig->libraries[$cachepath]);
1231 27
			}
1232 27
		}
1233 36
	}
1234
1235 36
	protected function getConfig() {
1236 36
	global $ARConfig, $ARCurrent, $ARConfigChecked;
1237
		// $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...
1238
		// 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...
1239
		// 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...
1240 36
		if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) {
1241 4
			$parent = current($this->get($this->parent, "system.get.phtml"));
1242 4
			if ($parent) {
1243 4
				$parent->getConfig();
1244 3
			}
1245 3
		}
1246
1247 36
		$this->getConfigData();
1248
1249 36
		$ARConfig->pinpcache[$this->path] = $ARConfig->pinpcache[$this->parent];
1250
		// backwards compatibility when calling templates from config.ini
1251 36
		$prevArConfig = $ARCurrent->arConfig;
1252 36
		$ARCurrent->arConfig = $ARConfig->pinpcache[$this->path];
1253
1254 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...
1255
1256
		/* calling config.ini directly for each system.get.config.phtml call */
1257 36
		$loginSilent = $ARCurrent->arLoginSilent;
1258 36
		$ARCurrent->arLoginSilent = true;
1259
		// 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...
1260
1261 36
		$initialNLS = $ARCurrent->nls;
1262 36
		$initialConfigChecked = $ARConfigChecked;
1263
1264 36
		$ARConfig->cache[$this->path]->inConfigIni = true;
1265 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...
1266
			//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...
1267
			// 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...
1268 4
			$arConfig = $ARCurrent->arResult;
1269 4
			if (!isset($arConfig)) {
1270
				$arConfig = $ARCurrent->arConfig;
1271
			}
1272 4
			unset($ARCurrent->arResult);
1273 4
			if (isset($arConfig['library']) && is_array($arConfig['library'])) {
1274
				if (!$ARConfig->libraries[$this->path]) {
1275
					$ARConfig->libraries[$this->path] = array();
1276
				}
1277
				foreach ($arConfig['library'] as $libName => $libPath) {
1278
					$this->loadLibrary($libName, $libPath);
1279
				}
1280
				unset($arConfig['library']);
1281
			}
1282 4
			$ARConfig->pinpcache[$this->path] = (array) $arConfig;
1283 3
		}
1284 36
		$ARConfig->cache[$this->path]->inConfigIni = false;
1285 36
		$this->clearChildConfigs( $this->path ); // remove any config data for child objects, since these are set before their parent config was set
1286 36
		$ARConfigChecked = $initialConfigChecked;
1287 36
		$ARCurrent->nls = $initialNLS;
1288
1289 36
		$arConfig = &$ARConfig->pinpcache[$this->path];
1290 36 View Code Duplication
		if (!is_array($arConfig['authentication']['userdirs'])) {
1291
			$arConfig['authentication']['userdirs'] = array('/system/users/');
1292
		} else {
1293 36
			if (reset($arConfig['authentication']['userdirs']) != '/system/users/') {
1294
				array_unshift($arConfig['authentication']['userdirs'], '/system/users/');
1295
			}
1296
		}
1297 36 View Code Duplication
		if (!is_array($arConfig['authentication']['groupdirs'])) {
1298
			$arConfig['authentication']['groupdirs'] = array('/system/groups/');
1299
		} else {
1300 36
			if (reset($arConfig['authentication']['groupdirs']) != '/system/groups/') {
1301
				array_unshift($arConfig['authentication']['groupdirs'], '/system/groups/');
1302
			}
1303
		}
1304
1305 36
		$ARCurrent->arLoginSilent = $loginSilent;
1306 36
		$ARCurrent->arConfig = $prevArConfig;
1307 36
	}
1308
1309 36
	protected function getConfigData() {
1310 36
	global $ARConfig, $AR;
1311 36
		$context = $this->getContext(0);
1312 36
		if (!$ARConfig->cache[$this->path] && $context["scope"] != "pinp") {
1313
			// first inherit parent configuration data
1314 36
			$configcache= clone $ARConfig->cache[$this->parent];
1315 36
			unset($configcache->localTemplates);
1316
			// cache default templates
1317 36
			if (isset($this->data->config->templates) && count($this->data->config->templates)) {
1318
				$configcache->templates=&$this->data->config->templates;
1319
			}
1320 36
			if (isset($this->data->config->privatetemplates) && count($this->data->config->privatetemplates)) {
1321
				$configcache->privatetemplates=&$this->data->config->privatetemplates;
1322
			}
1323
1324
			// Speedup check for config.ini
1325
1326 36
			if(isset($this->data->config->templates) && is_array($this->data->config->templates) ) {
1327 4
				$configcache->localTemplates = $this->data->config->templates;
1328 4
				if( !$configcache->hasDefaultConfigIni ) {
1329 4
					foreach($this->data->config->templates as $type => $templates ) {
1330
						if( isset($templates["config.ini"]) ) {
1331
							$configcache->hasDefaultConfigIni = true;
1332
							$configcache->hasConfigIni = true;
1333
							break;
1334
						}
1335 3
					}
1336 3
				}
1337 3
			}
1338
1339 36
			if( !$configcache->hasDefaultConfigIni ) {
1340 36
				$configcache->hasConfigIni = false;
1341 36
				if(isset($this->data->config->pinp) && is_array($this->data->config->pinp) ) {
1342 4
					foreach( $this->data->config->pinp as $type => $templates ) {
1343 4
						if( isset($templates["config.ini"]) ) {
1344 4
							$configcache->hasConfigIni = true;
1345 4
							break;
1346
						}
1347 3
					}
1348 3
				}
1349 27
			}
1350
1351 36
			$localcachesettings = $this->data->config->cacheSettings;
1352 36
			if (!is_array($localcachesettings) ){
1353 36
				$localcachesettings = array();
1354 27
			}
1355
1356 36
			if (!is_array($configcache->cacheSettings) ) {
1357
				$configcache->cacheSettings = array();
1358
			}
1359
1360 36
			if ($this->data->config->cacheconfig) { // When removing this part, also fix the setting below.
1361 4
				$configcache->cache=$this->data->config->cacheconfig;
1362 3
			}
1363
1364 36
			if (!isset($localcachesettings['serverCache']) && isset($this->data->config->cacheconfig)) {
1365 4
				$localcachesettings["serverCache"] = $this->data->config->cacheconfig;
1366 3
			}
1367
1368 36
			if ($localcachesettings['serverCache'] != 0 ) {
1369 4
				$localcachesettings['serverCacheDefault'] = $localcachesettings['serverCache'];
1370 3
			}
1371
1372 36
			$configcache->cacheSettings = $localcachesettings + $configcache->cacheSettings;
1373
1374
			// store the current object type
1375 36
			$configcache->type = $this->type;
1376
1377 36
			if ($this->data->config->typetree && ($this->data->config->typetree!="inherit")) {
1378
				$configcache->typetree=$this->data->config->typetree;
1379
			}
1380 36
			if (isset($this->data->config->nlsconfig->list)) {
1381 4
				$configcache->nls = clone $this->data->config->nlsconfig;
1382 3
			}
1383
1384 36
			if ($this->data->config->grants["pgroup"]["owner"]) {
1385
				$configcache->ownergrants = $this->data->config->grants["pgroup"]["owner"];
1386
			}
1387 36
			if (isset($configcache->ownergrants) && is_array($configcache->ownergrants)) {
1388
				if ($AR->user && $AR->user->data->login != 'public' && $AR->user->data->login === $this->data->config->owner) {
1389
					$ownergrants = $configcache->ownergrants;
1390
					if (isset($ownergrants) && is_array($ownergrants)) {
1391
						foreach( $ownergrants as $grant => $val ) {
1392
							$AR->user->ownergrants[$this->path][$grant] = $val;
1393
						}
1394
					}
1395
				}
1396
			}
1397
1398 36
			if (isset($this->data->config->customconfig) && is_array($this->data->config->customconfig)) {
1399
				$configcache->custom=array_merge(is_array($configcache->custom)?$configcache->custom:array(), $this->data->config->customconfig);
1400
			}
1401 36
			$ARConfig->cache[$this->path]=$configcache;
1402
1403 27
		}
1404 36
	}
1405
1406 60
	public function loadConfig($path='') {
1407 60
	global $ARConfig, $ARConfigChecked, $ARCurrent;
1408 60
		$path=$this->make_path($path);
1409
		// 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...
1410 60
		if (!isset($ARConfig->cache[$path]) ) {
1411 36
			$allnls = $ARCurrent->allnls;
1412 36
			$ARCurrent->allnls = true;
1413 36
			$configChecked = $ARConfigChecked;
1414 36
			if (($this->path == $path && !$this->arIsNewObject) || $this->exists($path)) {
1415 36
				$this->pushContext(array("scope" => "php"));
1416 36
				if( $this->path == $path ) {
1417
					// 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...
1418 36
					$this->getConfig();
1419 27
				} else {
1420
					//debug("loadConfig: get path $path ");
1421 4
					$cur_obj = current($this->get($path, "system.get.phtml"));
1422 4
					$cur_obj->getConfig();
1423
				}
1424 36
				$this->popContext();
1425 36
				$result=$ARConfig->cache[$path];
1426 27
			} else if ($path === '/') {
1427
				// special case: / doesn't exists in the store
1428
				$result=$ARConfig->cache['..'];
1429
			} else {
1430
				$parent=$this->make_path($path.'../');
1431
				if (!$ARConfig->cache[$parent]) {
1432
					$this->pushContext(array("scope" => "php"));
1433
					// 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...
1434
					$cur_obj = current($this->get($parent, "system.get.phtml"));
1435
					if( $cur_obj ) {
1436
						$cur_obj->getConfig();
1437
					}
1438
					$this->popContext();
1439
				}
1440
				$result=$ARConfig->cache[$parent];
1441
				$ARConfig->cache[ $path ] = $result;
1442
				$ARConfig->pinpcache[ $path ] = $ARConfig->pinpcache[ $parent ];
1443
			}
1444
			// restore old ARConfigChecked state
1445 36
			$ARConfigChecked = $configChecked;
1446 36
			$ARCurrent->allnls = $allnls;
1447 27
		} else {
1448
			// 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...
1449 48
			$result=$ARConfig->cache[$path];
1450
		}
1451 60
		return $result;
1452
	}
1453
1454
1455
	// TODO: look for a way to merge loadConfig and loadUserConfig into one function
1456
1457 12
	public function loadUserConfig($path='') {
1458 12
	global $ARConfig;
1459 12
		$path = $this->make_path($path);
1460 12
		$parent = $this->make_path($path.'../');
1461
1462 12
		if (!$ARConfig->cache[$path]) {
1463
			$this->loadConfig($path);
1464
		}
1465 12
		if (!$ARConfig->pinpcache[$path]) {
1466
			$config = $ARConfig->pinpcache[$parent];
1467
		} else {
1468 12
			$config = $ARConfig->pinpcache[$path];
1469
		}
1470 12
		return (array)$config;
1471
	}
1472
1473 48
	protected function getTemplateFromCache($path, $type, $function, &$arSuperContext) {
1474 48
	global $AR, $ARConfig;
1475 48
		$templatesList = $ARConfig->libraryCache[$path][$function];
1476 48
		if (!is_array($templatesList)) {
1477 48
			return false;
1478
		}
1479
		foreach ($templatesList as $checkpath => $templates) {
1480
			$arType = $type;
1481
			while ($arType!='ariadne_object') {
1482
//				echo "checking $i::$arType<br>\n";
1483
				if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType][$this->reqnls])) {
1484
					$arCallTemplate=$arType.".".$function.".".$this->reqnls;
1485
					$arCallTemplateName = $function;
1486
					$arCallTemplateNLS = $this->reqnls;
1487
					break 2;
1488 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$function] && ($arTemplate=$templates[$arType]['any'])) {
1489
					$arCallTemplate=$arType.".".$function.".any";
1490
					$arCallTemplateName = $function;
1491
					$arCallTemplateNLS = "any";
1492
					break 2;
1493
				} else {
1494
1495
					if (!($arSuper=$AR->superClass[$arType])) {
1496
						// no template found, no default.phtml found, try superclass.
1497
						if ($subcpos = strpos($arType, '.')) {
1498
							$arSuper = substr($arType, 0, $subcpos);
1499
						} else {
1500
							if (!class_exists($arType, false)) {
1501
								// the given class was not yet loaded, so do that now
1502
								$arTemp=$this->store->newobject('','',$arType,new object);
1503
							} else {
1504
								$arTemp=new $arType();
1505
							}
1506
							$arSuper=get_parent_class($arTemp);
1507
						}
1508
						$AR->superClass[$arType]=$arSuper;
1509
					}
1510
					$arType=$arSuper;
1511
				}
1512
			}
1513
		}
1514
1515
		$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...
1516
		$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...
1517
1518
		return array(
1519
			"arTemplateId" => $arTemplate["arTemplateId"],
1520
			"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...
1521
			"arCallType" => $type,
1522
			"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...
1523
			"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...
1524
			"arCallTemplateType" => $arType,
1525
			"arCallTemplatePath" => $arTemplate["arLibraryLocalPath"],
1526
			"arLibrary" => "current",
1527
			"arLibraryPath" => $arTemplate["arLibraryPath"],
1528
			"arPrivateTemplate" => $arPrivateTemplate
1529
		);
1530
	}
1531
1532
	public function loadLibraryCache($base, $path, $arLibraryPath = "") {
1533
	global $ARConfig;
1534
		if (!$arLibraryPath) {
1535
			$arLibraryPath = $path;
1536
		}
1537
		$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1538
		$templates = $config->localTemplates;
1539
		if (isset($templates) && is_array($templates)) {
1540
			$list = array();
1541
			foreach ($templates as $type => $functions) {
1542
				foreach ($functions as $function => $template) {
1543
					foreach ($template as $nls => $templateId) {
1544
						$list[$function][$type][$nls] = array(
1545
								"arTemplateId" => $templateId,
1546
								"arLibraryPath" => $arLibraryPath,
1547
								"arLibraryLocalPath" => $path
1548
						);
1549
					}
1550
				}
1551
			}
1552
1553
			foreach ($list as $function => $types) {
1554
				if (!is_array($ARConfig->libraryCache[$base][$function])) {
1555
					$ARConfig->libraryCache[$base][$function] = array(
1556
						$path => $types
1557
					);
1558
				} else {
1559
					$ARConfig->libraryCache[$base][$function][$path] = $types;
1560
				}
1561
			}
1562
		}
1563
		list($basetype,) = explode('.', $config->type,2);
1564
		if ($path != '/' && $basetype != 'psection') {
1565
			$this->loadLibraryCache($base, $this->store->make_path($path, '../'), $arLibraryPath);
1566
		}
1567
	}
1568
1569 4
	public function loadLibrary($name, $path) {
1570 4
	global $ARConfig;
1571 4
		$path=$this->make_path($path);
1572 4
		debug("pobject::loadLibrary($name, $path);");
1573 4
		if ($name===ARUNNAMED) {
1574 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...
1575
				return ar::error('You cannot load an unnamed library from a child object.', 1109);
1576
			} else {
1577 4
				if (!$ARConfig->libraries[$this->path]) {
1578 4
					$ARConfig->libraries[$this->path]=array();
1579 3
				}
1580 4
				array_unshift($ARConfig->libraries[$this->path],$path);
1581 4 View Code Duplication
				if (!$ARConfig->cacheableLibraries[$this->path]) {
1582 4
					$ARConfig->cacheableLibraries[$this->path] = array($path);
1583 3
				} else {
1584 1
					array_unshift($ARConfig->cacheableLibraries[$this->path], $path);
1585
				}
1586
			}
1587 3
		} else if ($name && is_string($name)) {
1588
			if (!$ARConfig->cache[$this->path]) {
1589
debug("loadLibrary: loading cache for $this->path");
1590
				$this->loadConfig($this->path);
1591
			}
1592
			$ARConfig->libraries[$this->path][$name]=$path;
1593
			$ARConfig->cache[$this->path]->libraries[$name]=$path;
1594
			$ARConfig->pinpcache[$this->path]["library"][$name] = $path;
1595
		} else if (is_int($name)) {
1596
			if (!$ARConfig->cache[$this->path]) {
1597
				$this->loadConfig($this->path);
1598
			}
1599
			$ARConfig->libraries[$this->path][$name]=$path;
1600 View Code Duplication
			if (!$ARConfig->cacheableLibraries[$this->path]) {
1601
				$ARConfig->cacheableLibraries[$this->path] = array($name => $path);
1602
			} else {
1603
				$ARConfig->cacheableLibraries[$this->path][$name] = $path;
1604
			}
1605
			// make sure that unnamed libraries don't get added to the configcache
1606
			unset($ARConfig->cache[$this->path]->libraries[$name]);
1607
			unset($ARConfig->pinpcache[$this->path]["library"][$name]);
1608
		} else {
1609
			return ar::error('Illegal library name: '.$name, 1110);
1610
		}
1611 4
	}
1612
1613
	// returns a list of libraries loaded on $path
1614
	public function getLibraries($path = '') {
1615
	global $ARConfig;
1616
		$path = $this->make_path($path);
1617
		return (array)$ARConfig->libraries[$path];
1618
	}
1619
1620
	public function mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1621
		$libraryName = ar::getvar('arLibrary');
1622
		if ( is_numeric($libraryName) || $libraryName == 'current' ) { // library is loaded unnamed
1623
			$libraryName = $defaultLibraryName;
1624
		}
1625
		if ( $libraryName ) {
1626
			$userConfig = ar::acquire('defaults.'.$libraryName);
1627
			if (isset($userConfig) && is_array($userConfig) ) {
1628
				$defaults = array_merge( $defaults, $userConfig );
1629
			}
1630
		}
1631
		return array_merge( $defaults, $this->getvar('arCallArgs') );
1632
	}
1633
1634
	public function _mergeLibraryConfig( $defaultLibraryName, $defaults ) {
1635
		return $this->mergeLibraryConfig( $defaultLibraryName, $defaults );
1636
	}
1637
1638 60
	public function getPinpTemplate($arCallFunction='view.html', $path=".", $top="", $inLibrary = false, $librariesSeen = null, $arSuperContext=array()) {
1639 60
	global $ARCurrent, $ARConfig, $AR, $ARConfigChecked;
1640 60
		debug("getPinpTemplate: function: $arCallFunction; path: $path; top: $top; inLib: $inLibrary","class");
1641 60
		$result = array();
1642 60
		if (!$top) {
1643 60
			$top = '/';
1644 45
		}
1645 60
		$path = $this->make_path($path);
1646 60
		if (!is_array($arSuperContext)) {
1647
			$arSuperContext = array();
1648
		}
1649
1650 60
		if (($libpos=strpos($arCallFunction,":"))!==false && $libpos!==strpos($arCallFunction, "::")) {
1651
			// template of a specific library defined via call("library:template");
1652
			$arLibrary = substr($arCallFunction, 0, $libpos);
1653
			if ($arLibrary == 'current') {
1654
				// load the current arLibrary
1655
				$context = $this->getContext(1);
1656
				$arLibrary = $context['arLibrary'];
1657
				$arLibraryPath = $context['arLibraryPath'];
1658 View Code Duplication
			} else {
1659
				$config = (isset($ARConfig->cache[$path])) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1660
				$arLibraryPath = $config->libraries[$arLibrary];
1661
			}
1662
			$arCallFunction = substr($arCallFunction, $libpos+1);
1663
			if ($arLibraryPath) {
1664
				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...
1665
				$librariesSeen[$arLibraryPath] = true;
1666
				$inLibrary = true;
1667
				$path = $arLibraryPath;
1668
			} else {
1669
				debug("getPinpTemplate: Failed to find library $arLibrary");
1670
				return false;
1671
			}
1672
			$path = $this->make_path($path);
1673
		}
1674 60
		if (strpos($arCallFunction,"::")!==false) {
1675
			// template of a specific class defined via call("class::template");
1676
			list($arCallType, $arCallFunction)=explode("::",$arCallFunction);
1677
		} else {
1678 60
			$arCallType=$this->type;
1679
		}
1680
1681
		/* first check current templates */
1682 60
		if ($this->path == $path) {
1683 60
			$curr_templates = $this->data->config->pinp;
1684 45
		} else {
1685
			$config = ($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
1686
			$curr_templates = $config->templates;
1687
		}
1688
1689 60
		$checkpath=$path;
1690 60
		$lastcheckedpath="";
1691 60
		$arCallClassTemplate = $ARCurrent->arCallClassTemplate;
1692 60
		$arSetType = $arCallType;
1693 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...
1694 60
			$lastcheckedpath = $checkpath;
1695 60
			$arType = $arSetType;
1696 60
			while ($arType!='ariadne_object' && !$arCallTemplate) {
1697 60
				if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction][$this->reqnls])) {
1698
					$arCallTemplate=$arType.".".$arCallFunction.".".$this->reqnls;
1699
					$arCallTemplateName = $arCallFunction;
1700
					$arCallTemplateNLS = $this->reqnls;
1701 60 View Code Duplication
				} else if (!$arSuperContext[$checkpath.":".$arType.":".$arCallFunction] && ($arTemplateId=$curr_templates[$arType][$arCallFunction]['any'])) {
1702 12
					$arCallTemplate=$arType.".".$arCallFunction.".any";
1703 12
					$arCallTemplateName = $arCallFunction;
1704 12
					$arCallTemplateNLS = 'any';
1705 9
				} else {
1706
1707 48
					if (!($arSuper=$AR->superClass[$arType])) {
1708
						// no template found, no default.phtml found, try superclass.
1709
						if ($subcpos = strpos($arType, '.')) {
1710
							$arSuper = substr($arType, 0, $subcpos);
1711
						} else {
1712
							if (!class_exists($arType, false )) {
1713
								// the given class was not yet loaded, so do that now
1714
								$arTemp=$this->store->newobject('','',$arType,new object);
1715
							} else {
1716
								$arTemp=new $arType();
1717
							}
1718
							$arSuper=get_parent_class($arTemp);
1719
						}
1720
						$AR->superClass[$arType]=$arSuper;
1721
					}
1722 48
					$arType=$arSuper;
1723
				}
1724 45
			}
1725 60
			if ($inLibrary) {
1726
1727
				// faster matching on psection, prefix doesn't have to be a valid type
1728
				$prefix = substr($ARConfig->cache[$checkpath]->type,0,8);
1729
1730
				if ($prefix === 'psection') {
1731
					// 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...
1732
					// break search operation when we have found a
1733
					// psection object
1734
					break;
1735
				}
1736
			}
1737
1738 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...
1739 48
				if ($ARConfig->cacheableLibraries[$checkpath]) {
1740
					foreach ($ARConfig->cacheableLibraries[$checkpath] as $library => $path) {
1741
						if (is_int($library) && !$librariesSeen[$path]) {
1742
							$librariesSeen[$path] = true;
1743
							if ($ARConfigChecked) {
1744
								if (!$ARConfig->librariesCached[$checkpath][$path]) {
1745
									$this->loadLibraryCache($checkpath, $path);
1746
									unset($ARConfig->cacheableLibraries[$checkpath][$library]);
1747
								}
1748
							}
1749
						}
1750
					}
1751
				}
1752
1753 48
				if (isset($ARConfig->cacheableLibraries[$checkpath])) {
1754 48
					$template = $this->getTemplateFromCache($checkpath, $arCallType, $arCallFunction, $arSuperContext);
1755 48
					if ($template["arTemplateId"]) {
1756
						return $template;
1757
					}
1758 36
				}
1759 36
			}
1760 60
			if ($checkpath == $top) {
1761 48
				break;
1762
			}
1763
1764 60
			$checkpath=$this->store->make_path($checkpath, "..");
1765 60
			$config = ($ARConfig->cache[$checkpath]) ? $ARConfig->cache[$checkpath] : $this->loadConfig($checkpath);
1766 60
			$curr_templates = $config->templates;
1767 60
			$arSetType = $arCallType;
1768 45
		}
1769
1770 60
		$config = ($ARConfig->cache[$lastcheckedpath]) ? $ARConfig->cache[$lastcheckedpath] : $this->loadConfig($lastcheckedpath);
1771 60
		$arPrivateTemplate = $config->privatetemplates[$arCallType][$arCallFunction];
1772
1773
		//debug("getPinpTemplate END; $arTemplateId; $checkpath;");
1774 60
		$result["arTemplateId"] = $arTemplateId;
1775 60
		$result["arCallTemplate"] = $arCallTemplate;
1776 60
		$result["arCallType"] = $arCallType;
1777 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...
1778 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...
1779 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...
1780 60
		$result["arCallTemplatePath"] = $lastcheckedpath;
1781 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...
1782 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...
1783 60
		$result["arLibrariesSeen"] = $librariesSeen;
1784 60
		$result["arPrivateTemplate"] = $arPrivateTemplate;
1785
1786 60
		return $result;
1787
	}
1788
1789 64
	public function CheckConfig($arCallFunction="", $arCallArgs="") {
1790
	// returns true when cache isn't up to date and no other template is
1791
	// defined for $path/$function. Else it takes care of output to the
1792
	// browser.
1793
	// All these templates must exist under a fixed directory, $AR->dir->templates
1794 64
	global $nocache, $AR, $ARConfig, $ARCurrent, $ARBeenHere, $ARnls, $ARConfigChecked;
1795 64
		$MAX_LOOP_COUNT=10;
1796
1797
1798
		// system templates (.phtml) have $arCallFunction=='', so the first check in the next line is to
1799
		// make sure that loopcounts don't apply to those templates.
1800 64
		if (0 && $arCallFunction && $ARBeenHere[$this->path][$arCallFunction]>$MAX_LOOP_COUNT) { // protect against infinite loops
1801
			error(sprintf($ARnls["err:maxloopexceed"],$this->path,$arCallFunction,$arCallArgs));
1802
			$this->store->close();
1803
			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...
1804
		} else {
1805 64
			$ARBeenHere[$this->path][$arCallFunction]+=1;
1806
1807
			// this will prevent the parents from setting the cache time
1808 64
			$initialConfigChecked = $ARConfigChecked;
1809 64
			$ARConfigChecked = true;
1810 64
			$config = ($ARConfig->cache[$this->path]) ? $ARConfig->cache[$this->path] : $this->loadConfig();
1811 64
			$ARConfigChecked = $initialConfigChecked;
1812 64
			$ARConfig->nls=$config->nls;
1813
1814
1815
			// if a default language is entered in a parent and no language is
1816
			// explicitly selected in the url, use that default.
1817
			// The root starts with the system default (ariadne.phtml config file)
1818 64
			if ( !$ARCurrent->nls ) {
1819 64
				if ( $config->root['nls'] ) {
1820
					$this->reqnls = $config->root['nls'];
1821
					if ( !$ARConfigChecked ) {
1822
						$ARCurrent->nls = $this->reqnls;
1823
					}
1824 64
				} else if ( $config->nls->default ) {
1825 64
					$this->reqnls = $config->nls->default;
1826 64
					$this->nls = $this->reqnls;
1827 64
					if ( !$ARConfigChecked ) {
1828 16
						$ARCurrent->nls = $this->nls;
1829
					}
1830 48
				}
1831 48
			} else {
1832
				$this->reqnls = $ARCurrent->nls;
1833
			}
1834 64
			$nls = &$this->nls;
1835 64
			$reqnls = &$this->reqnls;
1836
1837 64
			if (!$ARConfigChecked && is_object($ARnls)) {
1838
				$ARnls->setLanguage($ARCurrent->nls);
1839
			}
1840
1841
1842 64
			if (!$ARCurrent->arContentTypeSent) {
1843
				ldHeader("Content-Type: text/html; charset=UTF-8");
1844
				$ARCurrent->arContentTypeSent = true;
1845
			}
1846
1847
/*			// 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...
1848
1849
			if ($ARCurrent->acceptlang && !$ARCurrent->nls) {
1850
				if ($ARCurrent->acceptlang && is_array($this->data->nls->list)) {
1851
					$validlangs = array_intersect(array_keys($ARCurrent->acceptlang), array_keys($this->data->nls->list));
1852
				}
1853
				if ($validlangs) {
1854
					$reqnls=array_shift($validlangs);
1855
					$ARCurrent->nls = $reqnls;
1856
				}
1857
			}
1858
*/
1859 64 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom['none']) {
1860 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...
1861 3
			}
1862 64 View Code Duplication
			if (isset($this->data->custom) && is_array($this->data->custom) && $this->data->custom[$nls]) {
1863
				$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...
1864
			}
1865
1866 64
			if (!$ARConfigChecked) {
1867
				// this template is the first template called in this request.
1868
				$eventData = new object();
1869
				$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...
1870
				$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...
1871
1872
				$ARConfigChecked = true;
1873
				$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...
1874
				$ARConfigChecked = $initialConfigChecked;
1875
				if ( !$result ) { //prevent default action: view
1876
					return false;
1877
				}
1878
			}
1879
1880 64
			if (!$ARConfigChecked) {
1881
				// if this object isn't available in the requested language, show
1882
				// a language select dialog with all available languages for this object.
1883
				if (isset($this->data->nls) && !$this->data->name) {
1884
					if (!$ARCurrent->forcenls && (!isset($this->data->nls->list[$reqnls]) || !$config->nls->list[$reqnls])) {
1885
						if (!$ARCurrent->nolangcheck && $arCallFunction != 'config.ini') {
1886
							$ARCurrent->nolangcheck=1;
1887
							$eventData = new object();
1888
							$eventData->arCallFunction = $arCallFunction;
1889
							$eventData->arCallArgs = $arCallArgs;
1890
							$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...
1891
							$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...
1892
							if ( $result ) { // continue with default action: langaugeselect
1893
								$result->arCallArgs["arOriginalFunction"] = $result->arCallFunction;
1894
								$this->call("user.languageselect.html", $result->arCallArgs);
1895
								return false;
1896
							}
1897
						} else {
1898
							$this->nlsdata=$this->data->$nls;
1899
						}
1900
					} else {
1901
						$this->nlsdata=$this->data->$reqnls;
1902
					}
1903
				}
1904
				$ARCurrent->nolangcheck=1;
1905
			}
1906
1907
			/*
1908
				Set ARConfigChecked to true to indicate that we have been here
1909
				earlier.
1910
			*/
1911 64
			$ARConfigChecked = true;
1912 64
			if ($arCallFunction) { // don't search for templates named ''
1913
				// 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...
1914 60
				$redirects	= $ARCurrent->shortcut_redirect;
1915 60
				if (isset($redirects) && is_array($redirects)) {
1916
					$redirpath = $this->path;
1917
					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...
1918
								($redir = array_pop($redirects)) &&
1919
									$redir["keepurl"] &&
1920
										(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
1921
					) {
1922
						$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"]);
1923
						$redirpath = $redir['src'];
1924
					}
1925
1926
					if (!$template["arTemplateId"] && $redirpath) {
1927
						$template = $this->getPinpTemplate($arCallFunction, $redirpath);
1928
					}
1929
				}
1930 60
				if (!$template["arTemplateId"]) {
1931 60
					$template = $this->getPinpTemplate($arCallFunction);
1932 45
				}
1933
1934 60
				if ($template["arCallTemplate"] && $template["arTemplateId"]) {
1935 12
					if (!isset($ARCurrent->cacheTemplateChain)) {
1936
						$ARCurrent->cacheTemplateChain = array();
1937
					}
1938 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]])) {
1939 8
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]] = array();
1940 6
					}
1941 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']])) {
1942 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']] = array();
1943 9
					}
1944 12
					if (!isset($ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']])) {
1945 12
						$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']] = 0;
1946 9
					}
1947 12
					$ARCurrent->cacheTemplateChain[$template["arTemplateId"]][$template['arCallTemplate']][$template['arCallTemplateType']]++;
1948
1949
1950 12
					debug("CheckConfig: arCallTemplate=".$template["arCallTemplate"].", arTemplateId=".$template["arTemplateId"],"object");
1951
					// $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...
1952
					// check if template exists, if it doesn't exist, then continue the original template that called CheckConfig
1953 12
					$arTemplates=$this->store->get_filestore("templates");
1954
					if (
1955 12
						$arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")
1956 9
					) {
1957
						// check if the requested language exists, if not do not display anything,
1958
						// unless otherwise indicated by $ARCurrent->allnls
1959
						// This triggers only for pinp templates called by other templates,
1960
						// as the first template (in the url) will first trigger the language
1961
						// choice dialogue instead.
1962 12
						$arLibrary = $template['arLibrary'];
1963 12
						if (is_int($arLibrary)) {
1964
							// set the library name for unnamed libraries to 'current'
1965
							// so that calls using getvar('arLibrary') will keep on working
1966
							$arLibrary = "current";
1967
						}
1968
1969 12 View Code Duplication
						if (!is_string($arCallArgs)) {
1970 12
							$arCallArgs['arCallFunction'] = $arCallFunction;
1971 12
							$arCallArgs['arLibrary'] = $arLibrary;
1972 12
							$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
1973 9
						}
1974
1975 12
						$ARCurrent->arCallStack[]=$arCallArgs;
1976
						// start running a pinp template
1977
1978 12
						$this->pushContext(
1979
							array(
1980 12
								"scope" => "pinp",
1981 12
								"arLibrary" => $arLibrary,
1982 12
								"arLibraryPath" => $template['arLibraryPath'],
1983 12
								"arCallFunction" => $arCallFunction,
1984 12
								"arCurrentObject" => $this,
1985 12
								"arCallType" => $template['arCallType'],
1986 12
								"arCallTemplateName" => $template['arCallTemplateName'],
1987 12
								"arCallTemplateNLS" => $template['arCallTemplateNLS'],
1988 12
								"arCallTemplateType" => $template['arCallTemplateType'],
1989 12
								"arCallTemplatePath" => $template['arCallTemplatePath'],
1990 12
								"arLibrariesSeen" => $template['arLibrariesSeen']
1991 9
							)
1992 9
						);
1993
1994
						// 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...
1995 12
						if (count($ARCurrent->arCallStack) == 2 && $template['arPrivateTemplate']) {
1996
							// Do not allow private templates to be called first in the stack.
1997
							// echo "Bad request";
1998
1999
							// 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...
2000
							// Return true zorgt er voor dat de default 404 handler het oppikt alsof het template niet bestaat.
2001
							$this->popContext();
2002
							array_pop($ARCurrent->arCallStack);
2003
							return true;
2004 12
						} else if ($ARCurrent->forcenls || isset($this->data->nls->list[$reqnls])) {
2005
							// the requested language is available.
2006 12
							$this->nlsdata=$this->data->$reqnls;
2007 12
							$this->nls=$reqnls;
2008 12
							$continue=true;
2009 9
						} else if (!isset($this->data->nls)) {
2010
							// the object has no language support
2011
							$this->nlsdata=$this->data;
2012
							$continue=true;
2013
						} else if (($ARCurrent->allnls) || (!$initialConfigChecked && $ARCurrent->nolangcheck)) {
2014
							// all objects must be displayed
2015
							// $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...
2016
							$this->nls = isset($this->data->nls->default) ? $this->data->nls->default : $this->reqnls;
2017
							$this->nlsdata = $this->data->$nls ?: $this->data->{$this->nls} ?: $this->data;
2018
							$continue=true;
2019
						} else {
2020
							debug("CheckConfig: requested language not available, allnls not set","object");
2021
							// -> skip this object (do not run template but do return false)
2022
							$continue=false;
2023
						}
2024 12
						if ($continue) {
2025 12
							$eventData = new object();
2026 12 View Code Duplication
							if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2027 12
								$AR->contextCallHandler = true;
2028 12
								$eventData->arCallArgs = $arCallArgs;
2029 12
								$eventData->arCallFunction = $arCallFunction;
2030 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...
2031 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...
2032 12
								$ARCurrent->arResult = $eventData->arResult;
2033 12
								$AR->contextCallHandler = false;
2034 12
								$continue = ($eventData!=false);
2035 9
							}
2036 12
							if ( $continue ) {
2037 12
								if (!isset($ARCurrent->cacheCallChainSettings)) {
2038
									$ARCurrent->cacheCallChainSettings = array();
2039
								}
2040 12
								if ($ARConfig->cache[$this->path]->inConfigIni == false) {
2041 8
									$ARCurrent->cacheCallChainSettings[$this->id] = $config->cacheSettings;
2042 6
								}
2043
2044 12
								if ($ARCurrent->ARShowTemplateBorders) {
2045
									echo "<!-- arTemplateStart\nData: ".$this->type." ".$this->path." \nTemplate: ".$template["arCallTemplatePath"]." ".$template["arCallTemplate"]." \nLibrary:".$template["arLibrary"]." -->";
2046
								}
2047 12
								set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2048 12
								$func = $arTemplates->import($template["arTemplateId"], $template["arCallTemplate"]);
2049 12
								if(is_callable($func)){
2050 12
									$arResult = $func($this);
2051 9
								}
2052 12
								restore_error_handler();
2053 12
								if (isset($arResult)) {
2054 12
									$ARCurrent->arResult=$arResult;
2055 9
								}
2056 12
								if ($ARCurrent->ARShowTemplateBorders) {
2057
									echo "<!-- arTemplateEnd -->";
2058
								}
2059 12 View Code Duplication
								if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2060 12
									$AR->contextCallHandler = true;
2061 12
									$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2062 12
									$eventData->arResult = $temp;
2063 12
									ar_events::fire('oncall', $eventData );
2064 12
									$ARCurrent->arResult = $temp; /* restore correct result */
2065 12
									$AR->contextCallHandler = false;
2066 9
								}
2067 9
							}
2068 9
						}
2069 12
						array_pop($ARCurrent->arCallStack);
2070 12
						$this->popContext();
2071
2072 12
						if ( !$initialConfigChecked && $arCallFunction != 'config.ini' ) {
2073
							// this template was the first template called in this request.
2074
							$eventData = new object();
2075
							$eventData->arCallArgs = $arCallArgs;
2076
							$eventData->arCallFunction = $arCallFunction;
2077
							ar_events::fire( 'onview', $eventData ); // no default action to prevent, so ignore return value.
0 ignored issues
show
Documentation introduced by
$eventData is of type object<object>, but the function expects a array.

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

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

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

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

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

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

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

function acceptsInteger($int) { }

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

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
2149 24
					if ( $eventData ) {
2150 24
						$pcache->purge($this->id);
2151 24
						ar_events::fire( 'onclearprivatecache', $eventData, $this->type, $this->path );
2152 18
					}
2153
				}
2154 18
			}
2155
2156
			// now clear all parents untill the current site
2157 24
			$site=$this->currentsite($path);
2158 24
			$project=$this->currentproject($path);
2159 24
			if ($path!=$site && $path != $project && $path!='/') {
2160 24
				$parent=$this->make_path($path.'../');
2161 24
				$this->ClearCache($parent, $private, false);
2162 18
			}
2163 18
		}
2164 24
		$recursed = array();
2165
2166
		// filesystem cache image filenames are always lower case, so
2167
		// use special path for that. Remember 'real' path name for
2168
		// recursion and stuff
2169 24
		$fs_path=strtolower($path);
2170 24
		$nlslist=$AR->nls->list;
2171 24
		$nlslist["."]="default";
2172 24
		$cache_types[] = "normal";
0 ignored issues
show
Coding Style Comprehensibility introduced by
$cache_types was never initialized. Although not strictly required by PHP, it is generally a good practice to add $cache_types = array(); before regardless.

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

Let’s take a look at an example:

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

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

    // do something with $myArray
}

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

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

Loading history...
2173 24
		$cache_types[] = "compressed";
2174 24
		$cache_types[] = "session";
2175
2176 24
		global $cache_config,$store_config;
2177 24
		$cachestore=new cache($cache_config);
2178
2179
2180 24
		$filestore = $this->store->get_config("files");
2181 24
		foreach($cache_types as $type){
2182 24
			foreach($nlslist as $nls => $language){
2183
				// break away if nls doesn't exists
2184
				// is dir is cached, so it should not cost more that it add's in speed
2185 24
				if(!is_dir($filestore."cache/$type/$nls")){
2186 24
					continue;
2187
				}
2188
2189
				$fpath=$filestore."cache/$type/$nls".$fs_path;
2190
				$hpath=$filestore."cacheheaders/$type/$nls".$fs_path;
2191
				if ($dir=@dir($fpath)) {
2192
					while (false !== ($entry = $dir->read())) {
2193
						if ($entry!="." && $entry!="..") {
2194
							if (is_file($fpath.$entry)) {
2195
								@unlink($fpath.$entry);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
2211 6
					$cachestore->delete("/".$type."/".$nls.substr($fs_path,0,-1)."=");
2212
				}
2213 18
			}
2214 18
		}
2215 24
	}
2216
2217
	public function getcache($name, $nls="") {
2218
		global $ARCurrent, $ARnls;
2219
		$result=false;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

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

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

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

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

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

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

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

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

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

Loading history...
2223
			if (!$nls) {
2224
				$nls=$this->nls;
2225
			}
2226
			$file=$nls.".".$name;
2227
2228
			$minfresh = time();
2229
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2230
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2231
			}
2232
2233
			$pcache=$this->store->get_filestore("privatecache");
2234
			if ( $pcache->exists($this->id, $file) &&
2235
			     ($pcache->mtime($this->id, $file) > ($minfresh) )  ) {
2236
2237
				$result = $pcache->read($this->id, $file);
2238
2239
				$contentType = $ARCurrent->ldHeaders['content-type'];
2240
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2241
					$contentType = $matches[1];
2242
				} else {
2243
					$contentType = '';
2244
				}
2245
2246 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2247
					require_once($this->store->get_config('code')."modules/mod_url.php");
2248
					$temp = explode('.', $file);
2249
					$imageNLS = $temp[0];
2250
					$result = URL::ARtoRAW($result, $imageNLS);
0 ignored issues
show
Unused Code introduced by
The call to URL::ARtoRAW() has too many arguments starting with $imageNLS.

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

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

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

Loading history...
2251
				}
2252
			} else {
2253
				$result=false;
2254
				$ARCurrent->cache[]=$file;
2255
				ob_start();
2256
				/* output buffering is recursive, so this won't interfere with
2257
				   normal page caching, unless you forget to call savecache()...
2258
				   so normal pagecache needs to check $ARCurrent->cache, if it's
2259
				   not empty, issue a warning and don't cache the outputbuffer...
2260
				   savecache() must then pop the stack.
2261
				*/
2262
			}
2263
		} else {
2264
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2265
			$result = false;
2266
		}
2267
		return $result;
2268
	}
2269
2270
	public function cached($name, $nls="") {
2271
		if ($image=$this->getcache($name, $nls)) {
2272
			echo $image;
2273
			$result=true;
2274
		} else {
2275
			$result=false;
2276
		}
2277
		return $result;
2278
	}
2279
2280
	public function savecache($time="") {
2281
		global $ARCurrent, $ARnls, $DB;
2282
		$result = false;
0 ignored issues
show
Unused Code introduced by
$result is not used, you could remove the assignment.

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

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

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

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

Loading history...
2283
		$this->error = '';
2284
		if (!$time) {
2285
			$time=2; // 'freshness' in hours.
2286
		}
2287
		if ($file=array_pop($ARCurrent->cache)) {
2288
			$image=ob_get_contents();
2289
			if ($image !== false) {
2290
				$result = true;
2291
				$origimage = $image;
2292
2293
				$contentType = $ARCurrent->ldHeaders['content-type'];
2294
				if (preg_match('|^content-type:[ ]*([^ /]+)/|i', $contentType, $matches)) {
2295
					$contentType = $matches[1];
2296
				} else {
2297
					$contentType = '';
2298
				}
2299
2300 View Code Duplication
				if (!$contentType || strtolower($contentType) == 'text') {
2301
					require_once($this->store->get_config('code')."modules/mod_url.php");
2302
					$temp = explode('.', $file);
2303
					$imageNLS = $temp[0];
2304
					$image = URL::RAWtoAR($image, $imageNLS);
2305
				}
2306
2307
				if( $time > 0  && $DB["wasUsed"] == 0) {
2308
					$pcache=$this->store->get_filestore("privatecache");
2309
					$pcache->write($image, $this->id, $file);
2310
					$time=time()+($time*3600);
2311 View Code Duplication
					if (!$pcache->touch($this->id, $file, $time)) {
2312
						$this->error = ar::error("savecache: ERROR: couldn't touch $file", 1113);
2313
						$result = false;
2314
					}
2315
				}
2316
				ob_end_clean();
2317
				echo $origimage;
2318
			} else {
2319
				debug("skipped saving cache - ob_get_contents returned false so output buffering was not active", "all");
2320
				$result = false;
2321
			}
2322
		} else {
2323
			$this->error = ar::error($ARnls["err:savecachenofile"], 1112);
2324
			$result = false;
2325
		}
2326
		return $result;
2327
	}
2328
2329
	public function getdatacache($name) {
2330
		global $ARCurrent, $ARnls;
2331
		$result=false;
2332
		$this->error = '';
2333
		if ($name) {
2334
2335
			$minfresh = time();
2336
			if (isset($ARCurrent->RequestCacheControl["min-fresh"])) {
2337
				$minfresh += $ARCurrent->RequestCacheControl["min-fresh"];
2338
			}
2339
2340
			$pcache=$this->store->get_filestore("privatecache");
2341
			if ( $pcache->exists($this->id, $name) &&
2342
			     ($pcache->mtime($this->id, $name) > $minfresh) ) {
2343
				$result = unserialize($pcache->read($this->id, $name));
2344
			} else {
2345
				debug("getdatacache: $name doesn't exists, returning false.","all");
2346
			}
2347
		} else {
2348
			$this->error = ar::error($ARnls["err:nonamecache"], 1111);
2349
		}
2350
		return $result;
2351
	}
2352
2353
	public function savedatacache($name,$data,$time="") {
2354
		global $DB;
2355
		$this->error = '';
2356
		if (!$time) {
2357
			$time=2; // 'freshness' in hours.
2358
		}
2359
		$pcache=$this->store->get_filestore("privatecache");
2360
		if( $time > 0  && $DB["wasUsed"] == 0) {
2361
			$pcache->write(serialize($data), $this->id, $name);
2362
			$time=time()+($time*3600);
2363 View Code Duplication
			if (!$pcache->touch($this->id, $name, $time)) {
2364
				$this->error = ar::error('Could not touch '.$name, 1113);
2365
				return false;
2366
			}
2367
		}
2368
		return true;
2369
	}
2370
2371 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...
2372
	// function to retrieve variables from $this->data, with the correct
2373
	// language version.
2374 52
	global $ARCurrent;
2375
2376 52
		$result = false;
2377 52
		if ($nls!="none") {
2378 48 View Code Duplication
			if ($ARCurrent->arCallStack) {
2379 48
				$arCallArgs=end($ARCurrent->arCallStack);
2380 48
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2381 48
					extract($arCallArgs);
2382 36
				} else if (is_string($arCallArgs)) {
2383
					Parse_Str($arCallArgs);
2384
				}
2385 36
			}
2386 48
			if (isset(${$nls}[$varname])) {
2387 28
				$result=${$nls}[$varname];
2388 48
			} else if (isset($ARCurrent->$nls) && isset($ARCurrent->$nls->$varname)) {
2389
				$result=$ARCurrent->$nls->$varname;
2390 48
			} else if (($values=$_POST[$nls]) && isset($values[$varname])) {
2391
				$result=$values[$varname];
2392 48
			} else if (($values=$_GET[$nls]) && isset($values[$varname])) {
2393
				$result=$values[$varname];
2394 48
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2395
				$result=$arStoreVars[$nls][$varname];
2396 48
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$nls][$varname])) {
2397
				$result=$arStoreVars[$nls][$varname];
2398
			}
2399 48
			if ($result===false) {
2400 48
				if (isset($this->data->${nls}) && isset($this->data->${nls}->${varname})) {
2401 30
					$result=$this->data->${nls}->${varname};
2402 18
				}
2403 36
			}
2404 36
		} else { // language independant variable.
2405 52 View Code Duplication
			if ($ARCurrent->arCallStack) {
2406 52
				$arCallArgs=end($ARCurrent->arCallStack);
2407 52
				if (isset($arCallArgs) && is_array($arCallArgs)) {
2408 48
					extract($arCallArgs);
2409 43
				} else if (is_string($arCallArgs)) {
2410
					Parse_Str($arCallArgs);
2411
				}
2412 39
			}
2413 52
			if (isset($$varname)) {
2414 24
				$result=$$varname;
2415 52
			} else if (isset($ARCurrent->$varname)) {
2416
				$result=$ARCurrent->$varname;
2417 52 View Code Duplication
			} else if (isset($_POST[$varname])) {
2418
				$result=$_POST[$varname];
2419 52
			} else if (isset($_GET[$varname])) {
2420
				$result=$_GET[$varname];
2421 52
			} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$varname])) {
2422
				$result=$arStoreVars[$varname];
2423 52
			} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$varname])) {
2424
				$result=$arStoreVars[$varname];
2425
			}
2426 52
			if ($result===false) {
2427 52
				if (isset($this->data->$varname)) {
2428 24
					$result=$this->data->$varname;
2429 18
				}
2430 39
			}
2431
		}
2432 52
		if ( $result === false ) {
2433 52
			$result = $emptyResult;
2434 39
		}
2435 52
		return $result;
2436
	}
2437
2438
	public function showdata($varname, $nls="none", $emptyResult=false) {
2439
		echo htmlspecialchars($this->getdata($varname, $nls, $emptyResult), ENT_QUOTES, 'UTF-8');
2440
	}
2441
2442
	public function setnls($nls) {
2443
		ldSetNls($nls);
2444
	}
2445
2446
	public function getcharset() {
2447
		return "UTF-8";
2448
	}
2449
2450
	public function HTTPRequest($method, $url, $postdata = "", $port=80 ) {
2451
		$maxtries = 5;
2452
		$tries = 0;
2453
		$redirecting = true;
2454
2455
		if(isset($postdata) && is_array($postdata)) {
2456
			foreach($postdata as $key=>$val) {
2457
				if(!is_integer($key)) {
2458
					$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...
2459
				}
2460
			}
2461
		} else {
2462
			$data = $postdata;
2463
		}
2464
2465
		while ($redirecting && $tries < $maxtries) {
2466
			$tries++;
2467
			// get host name and URI from URL, URI not needed though
2468
			preg_match("/^([htps]*:\/\/)?([^\/]+)(.*)/i", $url, $matches);
2469
			$host = $matches[2];
2470
			$uri = $matches[3];
2471
			if (!$matches[1]) {
2472
				$url="http://".$url;
2473
			}
2474
			$connection = @fsockopen( $host, $port, $errno, $errstr, 120);
2475
			if( $connection ) {
2476
				if( strtoupper($method) == "GET" ) {
2477
					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...
2478
						$uri .= "?" . $data;
2479
					}
2480
					fputs( $connection, "GET $uri HTTP/1.0\r\n");
2481
				} else if( strtoupper($method) == "POST" ) {
2482
					fputs( $connection, "POST $uri HTTP/1.0\r\n");
2483
				} else {
2484
					fputs( $connection, "$method $uri HTTP/1.0\r\n");
2485
				}
2486
2487
				fputs( $connection, "Host: $host\r\n");
2488
				fputs( $connection, "Accept: */*\r\n");
2489
				fputs( $connection, "Accept: image/gif\r\n");
2490
				fputs( $connection, "Accept: image/x-xbitmap\r\n");
2491
				fputs( $connection, "Accept: image/jpeg\r\n");
2492
2493
				if( strtoupper($method) == "POST" ) {
2494
					$strlength = strlen( $data);
2495
					fputs( $connection, "Content-type: application/x-www-form-urlencoded\r\n" );
2496
					fputs( $connection, "Content-length: ".$strlength."\r\n\r\n");
2497
					fputs( $connection, $data."\r\n");
2498
				}
2499
2500
				fputs( $connection, "\r\n" , 2);
2501
2502
				$headerContents = '';
2503
				$headerStart = 0;
2504
				$headerEnd = 0;
2505
				$redirecting = false;
2506
2507
				while (!feof($connection)) {
2508
					$currentLine = fgets ($connection, 1024);
2509
					if ($headerEnd && $redirecting) {
2510
						break;
2511
					} else if ($headerEnd && !$redirecting) {
2512
						//this is the html from the page
2513
						$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...
2514
					} else if ( preg_match("/^HTTP/", $currentLine) ) {
2515
						//came to the start of the header
2516
						$headerStart = 1;
2517
						$headerContents = $currentLine;
2518
					} else if ( $headerStart && preg_match('/^[\n\r\t ]*$/', $currentLine) ) {
2519
						//came to the end of the header
2520
						$headerEnd = 1;
2521
					} else {
2522
						//this is the header, if you want it...
2523
						if (preg_match("/^Location: (.+?)\n/is",$currentLine,$matches) ) {
2524
							$headerContents .= $currentLine;
2525
							//redirects are sometimes relative
2526
							$newurl = $matches[1];
2527
							if (!preg_match("/http:\/\//i", $newurl, $matches) ) {
2528
								$url .= $newurl;
2529
							} else {
2530
								$url = $newurl;
2531
							}
2532
							//extra \r's get picked up sometimes
2533
							//i think only with relative redirects
2534
							//this is a quick fix.
2535
							$url = preg_replace("/\r/s","",$url);
2536
							$redirecting = true;
2537
						} else {
2538
							$headerContents.=$currentLine;
2539
						}
2540
					}
2541
				}
2542
			} else {
2543
				$this->error="$errstr ($errno)";
2544
				$contents=false;
2545
				$url = "";
2546
			}
2547
			@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...
2548
		}
2549
		if (($method!="GET") && ($method!="POST")) {
2550
			$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...
2551
		}
2552
		return $contents;
2553
	}
2554
2555
	public function make_filesize( $size="" ,$precision=0) {
2556
		$suffixes = array('B','KB','MB','GB','TB','PB','EB','ZB','YB');
2557
2558
		if( $size === "" ) {
2559
			$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...
2560
		}
2561
		while ( (count($suffixes) > 1) && ($size > 1024) ){
2562
			$size = $size / 1024;
2563
			array_shift($suffixes);
2564
		}
2565
		$size = round($size,$precision);
2566
		if($precision==0){ // compatible with the old make_filesize
2567
			$size = intval($size);
2568
		}
2569
		$result = $size." ".array_shift($suffixes);
2570
		return $result;
2571
	}
2572
2573
	public function convertToUTF8($data, $charset = "CP1252") {
2574
2575
		include_once($this->store->get_config("code")."modules/mod_unicode.php");
2576
2577
		if (isset($data) && is_array($data)) {
2578
			foreach($data as $key => $val){
2579
				$data[$key] = $this->convertToUTF8($val, $charset);
2580
			}
2581
		} else
2582
		if (is_object($data)) {
2583
			foreach($data as $key => $val){
2584
				$data->$key = $this->convertToUTF8($val, $charset);
2585
			}
2586
		} else {
2587
			$data = unicode::convertToUTF8($charset, $data);
2588
		}
2589
		return $data;
2590
	}
2591
2592 28
	public function resetloopcheck() {
2593 28
		global $ARBeenHere;
2594 28
		$ARBeenHere=array();
2595 28
	}
2596
2597
/********************************************************************
2598
2599
  "safe" functions.
2600
2601
  The following functions are safe versions of existing functions
2602
  above.
2603
  - They don't change anything in the database.
2604
    This means that to save/delete something, a user will need to call
2605
    "system.save.data.phtml" or "system.delete.phtml" which check grants.
2606
  - All functions except _get and _exists don't take a path as
2607
    argument, they use the current objects path instead.
2608
2609
  These are meant to be used by 'pinp' versions of templates,
2610
  meaning user defined templates. 'pinp' rewrites call to functions
2611
  to the form '$this->_function'.
2612
2613
  All pinp files automatically first call CheckLogin('read').
2614
2615
********************************************************************/
2616
2617
	public function _call($function, $args="") {
2618
		// remove possible path information (greedy match)
2619
		if ( !( $function instanceof \Closure ) ) {
2620
			$function = basename( (string) $function );
2621
		}
2622
		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...
2623
	}
2624
2625
	public function _call_super($arCallArgs="") {
2626
	global $ARCurrent, $AR;
2627
		$context = $this->getContext();
2628
		if (!$arCallArgs) {
2629
			$arCallArgs = end($ARCurrent->arCallStack);
2630
		}
2631
		$arSuperContext = (array)$context['arSuperContext'];
2632
		$arLibrary		= $context['arLibrary'];
2633
		$arLibraryPath	= $context['arLibraryPath'];
2634
		$arCallType		= $context['arCallTemplateType'];
2635
		$arSuperPath	= $context['arCallTemplatePath'];
2636
		$arLibrariesSeen = $context['arLibrariesSeen'];
2637
		$arCallFunction = $arSuperFunction = $context['arCallFunction'];
2638
		if ($arLibrary) {
2639
			$arSuperFunction = str_replace($arLibrary.':', '', $arCallFunction);
2640
		}
2641
		if (strpos($arSuperFunction, "::") !== false) {
2642
			// template of a specific class defined via call("class::template");
2643
			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...
2644
		}
2645
		// remove current library path from the arLibrariesSeen array so that
2646
		// Ariadne will be able to re-enter the library and toggle the arSuperContext boolean there.
2647
		unset($arLibrariesSeen[$arLibraryPath]);
2648
		$arSuperContext[$arSuperPath.":".$arCallType.":".$arSuperFunction] = true;
2649
2650
		debug("call_super: searching for the template following (path: $arSuperPath; type: $arCallType; function: $arCallFunction) from $this->path");
2651
		// 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...
2652
		$redirects	= $ARCurrent->shortcut_redirect;
2653
		if (isset($redirects) && is_array($redirects)) {
2654
			$redirpath = $this->path;
2655
			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...
2656
						($redir = array_pop($redirects)) &&
2657
							$redir["keepurl"] &&
2658
								(substr($redirpath, 0, strlen($redir["dest"])) == $redir["dest"])
2659
			) {
2660
				debug("call_super: following shortcut redirect: $redirpath; to ".$redir["dest"]);
2661
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, $redir["dest"], false, $arLibrariesSeen, $arSuperContext);
2662
				$redirpath = $redir['src'];
2663
			}
2664 View Code Duplication
			if (!$template["arTemplateId"]) {
2665
				$template = $this->getPinpTemplate($arCallFunction, $redirpath, '', false, $arLibrariesSeen, $arSuperContext);
2666
			}
2667
		}
2668 View Code Duplication
		if (!$template["arTemplateId"]) {
2669
			$template = $this->getPinpTemplate($arCallFunction, $this->path, '', false, $arLibrariesSeen, $arSuperContext);
2670
		}
2671
		if ($template["arCallTemplate"] && $template["arTemplateId"]) {
2672
			$arTemplates=$this->store->get_filestore("templates");
2673
			if ($arTemplates->exists($template["arTemplateId"], $template["arCallTemplate"].".inc")) {
2674
				debug("call_super: found template ".$template["arCallTemplate"]." on object with id ".$template["arTemplateId"]);
2675
				$arLibrary = $template['arLibrary'];
2676
				debug("call_super: found template on ".$template["arTemplateId"]);
2677
				if (is_int($arLibrary)) {
2678
					// set the library name for unnamed libraries to 'current'
2679
					// so that calls using getvar('arLibrary') will keep on working
2680
					$arLibrary = "current";
2681
				}
2682 View Code Duplication
				if (!is_string($arCallArgs)) {
2683
					$arCallArgs['arCallFunction'] = $arCallFunction;
2684
					$arCallArgs['arLibrary'] = $arLibrary;
2685
					$arCallArgs['arLibraryPath'] = $template["arLibraryPath"];
2686
				}
2687
				$ARCurrent->arCallStack[]=$arCallArgs;
2688
				$this->pushContext(
2689
					array(
2690
						"scope" => "pinp",
2691
						"arSuperContext" => $arSuperContext,
2692
						"arLibrary" => $arLibrary,
2693
						"arLibraryPath" => $template['arLibraryPath'],
2694
						"arCallFunction" => $arCallFunction,
2695
						"arCurrentObject" => $this,
2696
						"arCallType" => $template['arCallType'],
2697
						"arCallTemplateName" => $template['arCallTemplateName'],
2698
						"arCallTemplateNLS"  => $template['arCallTemplateNLS'],
2699
						"arCallTemplateType" => $template['arCallTemplateType'],
2700
						"arCallTemplatePath" => $template['arCallTemplatePath']
2701
					)
2702
				);
2703
				$continue = true;
2704
				$eventData = new object();
2705 View Code Duplication
				if ( !$AR->contextCallHandler ) { /* prevent onbeforecall from re-entering here */
2706
					$AR->contextCallHandler = true;
2707
					$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...
2708
					$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...
2709
					$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...
2710
					$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...
2711
					$ARCurrent->arResult = $eventData->arResult;
2712
					$AR->contextCallHandler = false;
2713
					$continue = ($eventData!=false);
2714
				}
2715
				if ( $continue ) {
2716
					set_error_handler(array('pobject','pinpErrorHandler'),error_reporting());
2717
					$func = $arTemplates->import($template["arTemplateId"], $template["arCallTemplate"]);
2718
					if(is_callable($func)){
2719
						$arResult = $func($this);
2720
					}
2721
					restore_error_handler();
2722
2723 View Code Duplication
					if ( !$AR->contextCallHandler ) { /* prevent oncall from re-entering here */
2724
						$AR->contextCallHandler = true;
2725
						$temp = $ARCurrent->arResult; /* event listeners will change ARCurrent->arResult */
2726
						$eventData->arResult = $arResult;
0 ignored issues
show
Bug introduced by
The variable $arResult does not seem to be defined for all execution paths leading up to this point.

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

Let’s take a look at an example:

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

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

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

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

Available Fixes

  1. Check for existence of the variable explicitly:

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

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

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
2727
						ar_events::fire('oncall', $eventData );
2728
						$ARCurrent->arResult = $temp; /* restore correct result */
2729
						$AR->contextCallHandler = false;
2730
					}
2731
				}
2732
				array_pop($ARCurrent->arCallStack);
2733
				$this->popContext();
2734
			}
2735
		}
2736
2737
		return $arResult;
2738
	}
2739
2740
	public function _get($path, $function="view.html", $args="") {
2741
		// remove possible path information (greedy match)
2742
		if ( !($function instanceof \Closure) ) {
2743
			$function = basename( (string) $function);
2744
		}
2745
		return $this->store->call($function, $args,
2746
			$this->store->get(
2747
				$this->make_path($path)));
2748
	}
2749
2750
	public function _call_object($object, $function, $args="") {
2751
		return $object->call($function, $args);
2752
	}
2753
2754 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...
2755
		// remove possible path information (greedy match)
2756
		if ( ! ( $function instanceof \Closure ) ) {
2757
			$function = basename( (string) $function );
2758
		}
2759
		return $this->store->call($function, $args,
2760
			$this->store->ls($this->path));
2761
	}
2762
2763 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...
2764
		// remove possible path information (greedy match)
2765
		if ( !($function instanceof \Closure ) ) {
2766
			$function = basename( (string) $function);
2767
		}
2768
		return $this->parents($this->path, $function, $args, $top);
2769
	}
2770
2771
	public function _find($criteria, $function="list.html", $args="", $limit=100, $offset=0) {
2772
		$this->error = '';
2773
		// remove possible path information (greedy match)
2774
		if ( !($function instanceof \Closure ) ) {
2775
			$function = basename( (string) $function);
2776
		}
2777
		$result = $this->store->call($function, $args,
2778
			$this->store->find($this->path, $criteria, $limit, $offset));
2779 View Code Duplication
		if ($this->store->error) {
2780
			$this->error = ar::error( ''.$this->store->error, 1107, $this->store->error );
2781
		}
2782
		return $result;
2783
	}
2784
2785
	public function _exists($path) {
2786
		return $this->store->exists($this->make_path($path));
2787
	}
2788
2789
	public function _implements($implements) {
2790
		return $this->AR_implements($implements);
2791
	}
2792
2793 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...
2794 52
	global $ARCurrent, $ARConfig; // Warning: if you add other variables here, make sure you cannot get at it through $$var.
2795
2796 52 View Code Duplication
		if ($ARCurrent->arCallStack) {
2797 48
			$arCallArgs=end($ARCurrent->arCallStack);
2798 48
			if (isset($arCallArgs) && is_array($arCallArgs)) {
2799 36
				extract($arCallArgs);
2800 40
			} else if (is_string($arCallArgs)) {
2801
				Parse_Str($arCallArgs);
2802
			}
2803 36
		}
2804 52
		if (isset($$var) && ($var!='ARConfig')) {
2805 16
			$result=$$var;
2806 52
		} else if (isset($ARCurrent->$var)) {
2807
			$result=$ARCurrent->$var;
2808 52
		} else if (isset($ARConfig->pinpcache[$this->path][$var])) {
2809
			$result=$ARConfig->pinpcache[$this->path][$var];
2810 52 View Code Duplication
		} else if (isset($_POST[$var])) {
2811
			$result=$_POST[$var];
2812 52
		} else if (isset($_GET[$var])) {
2813
			$result=$_GET[$var];
2814 52
		} else if (($arStoreVars=$_POST["arStoreVars"]) && isset($arStoreVars[$var])) {
2815
			$result=$arStoreVars[$var];
2816 52
		} else if (($arStoreVars=$_GET["arStoreVars"]) && isset($arStoreVars[$var])) {
2817
			$result=$arStoreVars[$var];
2818
		}
2819 52
		return $result;
2820
	}
2821
2822
	public function _getvar($var) {
2823
		return $this->getvar($var);
2824
	}
2825
2826
	public function putvar($var, $value) {
2827
		global $ARCurrent;
2828
2829
		$ARCurrent->$var=$value;
2830
	}
2831
2832
	public function _putvar($var, $value) {
2833
		return $this->putvar($var, $value);
2834
	}
2835
2836
	public function _setnls($nls) {
2837
		$this->setnls($nls);
2838
	}
2839
2840
	// not exposed to pinp for obvious reasons
2841
	public function sgKey($grants) {
2842
		global $AR;
2843
		if( !$AR->sgSalt || !$this->CheckSilent("config") ) {
2844
			return false;
2845
		}
2846
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2847
		$this->_load("mod_grant.php");
2848
		$mg = new mod_grant();
2849
		$grantsarray = array();
2850
		$mg->compile($grants, $grantsarray);
2851
		$grants = serialize($grantsarray);
2852
		return sha1( $AR->sgSalt . $grants . $this->path);
2853
	}
2854
2855
	public function sgBegin($grants, $key = '', $path = '.') {
2856
		global $AR;
2857
		$result = false;
2858
		$context = $this->getContext();
2859
		$path    = $this->make_path($path);
2860
2861
		// serialize the grants so the order does not matter, mod_grant takes care of the sorting for us
2862
		$this->_load("mod_grant.php");
2863
		$mg = new mod_grant();
2864
		$grantsarray = array();
2865
		$mg->compile($grants, $grantsarray);
2866
2867
		if ($context['scope'] == 'pinp') {
2868
			$checkgrants = serialize($grantsarray);
2869
			$check = ( $AR->sgSalt ? sha1( $AR->sgSalt . $checkgrants . $path) : false ); // not using suKey because that checks for config grant
2870
		} else {
2871
			$check = true;
2872
			$key = true;
2873
		}
2874
		if( $check !== false && $check === $key ) {
2875
			$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2876
			$grantsarray = (array)$AR->sgGrants[$path];
2877
			$mg->compile($grants, $grantsarray);
2878
			$AR->sgGrants[$path] = $grantsarray;
2879
			$result = true;
2880
		}
2881
		return $result;
2882
	}
2883
2884
	public function sgEnd($path = '.') {
2885
		global $AR;
2886
		$AR->user->grants = array(); // unset all grants for the current user, this makes sure GetValidGrants gets called again for this path and all childs
2887
		$path = $this->make_path( $path );
2888
		unset($AR->sgGrants[$path]);
2889
		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...
2890
	}
2891
2892
	public function sgCall($grants, $key, $function="view.html", $args="") {
2893
		$result = false;
2894
		if( $this->sgBegin($grants, $key ) ) {
2895
			$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...
2896
			$this->sgEnd();
2897
		}
2898
		return $result;
2899
	}
2900
2901
	public function _sgBegin($grants, $key, $path = '.') {
2902
		return $this->sgBegin($grants, $key, $path);
2903
	}
2904
2905
	public function _sgEnd($path = '.') {
2906
		return $this->sgEnd($path);
2907
	}
2908
2909
	public function _sgCall($grants, $key, $function="view.html", $args="") {
2910
		return $this->sgCall($grants, $key, $function, $args);
2911
	}
2912
2913
	public function _widget($arWidgetName, $arWidgetTemplate, $arWidgetArgs="", $arWidgetType="lib") {
2914
	global $AR, $ARConfig, $ARCurrent, $ARnls;
2915
2916
		$arWidgetName=preg_replace("/[^a-zA-Z0-9\/]/","",$arWidgetName);
2917
		$arWidgetTemplate=preg_replace("/[^a-zA-Z0-9\.]/","",$arWidgetTemplate);
2918
		$wgResult=null;
2919
		if ($arWidgetType=="www") {
2920
			$coderoot=$AR->dir->root;
2921
		} else {
2922
			$coderoot=$this->store->get_config("code");
2923
		}
2924
		if (file_exists($coderoot."widgets/$arWidgetName")) {
2925
			if (file_exists($coderoot."widgets/$arWidgetName/$arWidgetTemplate")) {
2926
				if (isset($arWidgetArgs) && is_array($arWidgetArgs)) {
2927
					extract($arWidgetArgs);
2928
				} else if (is_string($arWidgetArgs)) {
2929
					Parse_str($arWidgetArgs);
2930
				}
2931
				include($coderoot."widgets/$arWidgetName/$arWidgetTemplate");
2932
			} else {
2933
				error("Template $arWidgetTemplate for widget $arWidgetName not found.");
2934
			}
2935
		} else {
2936
			error(sprintf($ARnls["err:widgetnotfound"],$arWidgetName));
2937
		}
2938
		if ($wgResult) {
2939
			return $wgResult;
2940
		}
2941
	}
2942
2943
	public function _getdata($varname, $nls="none", $emptyResult=false) {
2944
		return $this->getdata($varname, $nls, $emptyResult);
2945
	}
2946
2947
	public function _showdata($varname, $nls="none", $emptyResult=false) {
2948
		$this->showdata($varname, $nls, $emptyResult);
2949
	}
2950
2951
	public function _gettext($index=false) {
2952
	global $ARnls;
2953
		if (!$index) {
2954
			return $ARnls;
2955
		} else {
2956
			return $ARnls[$index];
2957
		}
2958
	}
2959
2960
	public function _loadtext($nls, $section="") {
2961
	global $ARnls, $ARCurrent;
2962
		if( is_object($ARnls) ) {
2963
			$ARnls->load($section, $nls);
2964
			$ARnls->setLanguage($nls);
2965
			$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...
2966
		} else { // older loaders and other shizzle
2967
2968
			$nls = preg_replace('/[^a-z]*/i','',$nls);
2969
			$section = preg_replace('/[^a-z0-9\._:-]*/i','',$section);
2970
			if (!$section) {
2971
				include($this->store->get_config("code")."nls/".$nls);
2972
				$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2973
			} else {
2974
				$nlsfile = $this->store->get_config("code")."nls/".$section.".".$nls;
2975
				if(strpos($nlsfile, ':') === false && file_exists($nlsfile)) {
2976
					include($nlsfile);
2977
					$this->ARnls = array_merge((array)$this->ARnls, $ARnls);
2978
				} else {
2979
					// current result;
2980
					$arResult = $ARCurrent->arResult;
2981
					$this->pushContext(array());
2982
						$oldnls = $this->reqnls;
2983
						$this->reqnls = $nls;
2984
						$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...
2985
						$this->reqnls = $oldnls;
2986
					$this->popContext();
2987
					// reset current result (CheckConfig may have changed it when it should not have).
2988
					$ARCurrent->arResult = $arResult;
2989
				}
2990
			}
2991
		}
2992
	}
2993
2994
	public function _startsession() {
2995
	global $ARCurrent;
2996
		ldStartSession(0);
2997
		return $ARCurrent->session->id;
2998
	}
2999
3000
	public function _putsessionvar($varname, $varvalue) {
3001
	global $ARCurrent;
3002
3003
		if ($ARCurrent->session) {
3004
			return $ARCurrent->session->put($varname, $varvalue);
3005
		} else {
3006
			return false;
3007
		}
3008
	}
3009
3010
	public function _getsessionvar($varname) {
3011
	global $ARCurrent;
3012
3013
		if ($ARCurrent->session) {
3014
			return $ARCurrent->session->get($varname);
3015
		} else {
3016
			return false;
3017
		}
3018
	}
3019
3020
	public function _setsessiontimeout($timeout = 0) {
3021
	global $ARCurrent;
3022
		if ($ARCurrent->session) {
3023
			return $ARCurrent->session->setTimeout($timeout);
3024
		} else {
3025
			return false;
3026
		}
3027
	}
3028
3029
	public function _killsession() {
3030
	global $ARCurrent;
3031
3032
		if ($ARCurrent->session) {
3033
			$ARCurrent->session->kill();
3034
			unset($ARCurrent->session);
3035
		}
3036
	}
3037
3038
	public function _sessionid() {
3039
	global $ARCurrent;
3040
		if ($ARCurrent->session) {
3041
			return $ARCurrent->session->id;
3042
		} else {
3043
			return 0;
3044
		}
3045
	}
3046
3047
	public function _resetloopcheck() {
3048
		return $this->resetloopcheck();
3049
	}
3050
3051
	public function _make_path($path="") {
3052
		return $this->make_path($path);
3053
	}
3054
3055
	public function _make_ariadne_url($path="") {
3056
		return $this->make_ariadne_url($path);
3057
	}
3058
3059
	public function _make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) {
3060
		return $this->make_url($path, $nls, $session, $https, $keephost);
3061
	}
3062
3063
	public function _make_local_url($path="", $nls=false, $session=true, $https=null) {
3064
		return $this->make_local_url($path, $nls, $session, $https);
3065
	}
3066
3067
	public function _getcache($name, $nls='') {
3068
		return $this->getcache($name, $nls);
3069
	}
3070
3071
	public function _cached($name, $nls='') {
3072
		return $this->cached($name, $nls);
3073
	}
3074
3075
	public function _savecache($time="") {
3076
		return $this->savecache($time);
3077
	}
3078
3079
	public function _getdatacache($name) {
3080
		return $this->getdatacache($name);
3081
	}
3082
3083
	public function _savedatacache($name,$data,$time="")
3084
	{
3085
		return $this->savedatacache($name,$data,$time);
3086
	}
3087
3088 56
	public function currentsite($path="", $skipRedirects = false) {
3089 56
		global $ARCurrent, $ARConfig;
3090 56
		if (!$path) {
3091 48
			$path=$this->path;
3092 36
		}
3093 56
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3094 56
		if (!$skipRedirects && @count($ARCurrent->shortcut_redirect)) {
3095
			$redir = end($ARCurrent->shortcut_redirect);
3096
			if ($redir["keepurl"] && substr($path, 0, strlen($redir["dest"])) == $redir["dest"]) {
3097
				if (substr($config->site, 0, strlen($redir["dest"]))!=$redir["dest"]) {
3098
					// search currentsite from the reference
3099
					$config = ($ARConfig->cache[$redir['src']]) ? $ARConfig->cache[$redir['src']] : $this->loadConfig($redir['src']);
3100
				}
3101
			}
3102
		}
3103 56
		return $config->site;
3104
	}
3105
3106
	public function parentsite($site) {
3107
	global $ARConfig;
3108
		$path=$this->store->make_path($site, "..");
3109
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3110
		return $config->site;
3111
	}
3112
3113 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...
3114 4
	global $ARConfig;
3115 4
		if (!$path) {
3116 4
			$path=$this->path;
3117 3
		}
3118 4
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3119 4
		return $config->section;
3120
	}
3121
3122 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...
3123
	global $ARConfig;
3124
		$path=$this->store->make_path($path, "..");
3125
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3126
		return $config->section;
3127
	}
3128
3129 24 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...
3130 24
	global $ARConfig;
3131 24
		if (!$path) {
3132
			$path=$this->path;
3133
		}
3134 24
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3135 24
		return $config->project;
3136
	}
3137
3138
	public function parentproject($path) {
3139
	global $ARConfig;
3140
		$path=$this->store->make_path($path, "..");
3141
		$config=($ARConfig->cache[$path]) ? $ARConfig->cache[$path] : $this->loadConfig($path);
3142
		return $config->project;
3143
	}
3144
3145
	public function validateFormSecret() {
3146
		global $ARCurrent;
3147
		if (!$ARCurrent->session) {
3148
			return true;
3149
		}
3150
3151
		if ($ARCurrent->session && $ARCurrent->session->data && $ARCurrent->session->data->formSecret) {
3152
			$formSecret = $this->getvar("formSecret");
3153
			return ($formSecret === $ARCurrent->session->data->formSecret);
3154
		}
3155
		return false;
3156
	}
3157
3158
	public function _validateFormSecret() {
3159
		return $this->validateFormSecret();
3160
	}
3161
3162
	public function getValue($name, $nls=false) {
3163
	global $ARCurrent;
3164
		switch ($nls) {
3165
			case "none":
3166
				$result = $this->data->$name;
3167
			break;
3168
			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...
3169
				$nls = $ARCurrent->nls;
3170
				if (!isset($this->data->$nls) || !isset($this->data->$nls->$name)) {
3171
					$result = $this->data->$name;
3172
					break;
3173
				}
3174
			default:
3175
				$result = $this->data->$nls->$name;
3176
		}
3177
		return $result;
3178
	}
3179
3180
	public function setValue($name, $value, $nls=false) {
3181
3182
	global $AR, $ARConfig;
3183
		if ($value === null) {
3184
			if ($nls && $nls!="none") {
3185
				unset($this->data->$nls->$name);
3186
				if (!count(get_object_vars($this->data->$nls))) {
3187
					unset($this->data->$nls);
3188
					unset($this->data->nls->list[$nls]);
3189
					if (!count($this->data->nls->list)) {
3190
						unset($this->data->nls->list);
3191
						unset($this->data->nls);
3192
					} else {
3193
						if ($this->data->nls->default == $nls) {
3194
							if ($this->data->nls->list[$ARConfig->nls->default]) {
3195
								$this->data->nls->default = $ARConfig->nls->default;
3196
							} else {
3197
								list($this->data->nls->default) = each($this->data->nls->list);
3198
							}
3199
						}
3200
					}
3201
				}
3202
			} else {
3203
				unset($this->data->$name);
3204
			}
3205
		} else
3206
		if (!$nls) {
3207
			$this->data->$name = $value;
3208
		} else {
3209
			if (!$this->data->$nls) {
3210
				$this->data->$nls = new object;
3211
				if (!$this->data->nls) {
3212
					$this->data->nls = new object;
3213
					$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...
3214
				}
3215
				$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...
3216
			}
3217
			$this->data->$nls->$name = $value;
3218
		}
3219
	}
3220
3221
	public function showValue($name, $nls=false) {
3222
		$result = $this->getValue($name, $nls);
3223
		echo $result;
3224
		return $result;
3225
	}
3226
3227
	public function _getValue($name, $nls=false) {
3228
		return $this->getValue($name, $nls);
3229
	}
3230
3231
	public function _setValue($name, $value, $nls=false) {
3232
		return $this->setValue($name, $value, $nls);
3233
	}
3234
3235
	public function _showValue($name, $nls=false) {
3236
		return $this->showValue($name, $nls);
3237
	}
3238
3239
	public function _currentsite($path="", $skipRedirects = false) {
3240
		return $this->currentsite( $path, $skipRedirects );
3241
	}
3242
3243
	public function _parentsite($site) {
3244
		return $this->parentsite($site);
3245
	}
3246
3247
	public function _currentsection() {
3248
		return $this->currentsection();
3249
	}
3250
3251
	public function _parentsection($section) {
3252
		return $this->parentsection($section);
3253
	}
3254
3255
	public function _currentproject() {
3256
		return $this->currentproject();
3257
	}
3258
3259
	public function _parentproject($path) {
3260
		return $this->parentproject($path);
3261
	}
3262
3263
	public function _checkAdmin($user) {
3264
		return $this->CheckAdmin($user);
3265
	}
3266
3267
	public function _checkgrant($grant, $modifier=ARTHISTYPE, $path=".") {
3268
		// as this is called within a pinp template,
3269
		// all the grants are already loaded, so
3270
		// checksilent will fullfill our needs
3271
		$this->pushContext(array("scope" => "php"));
3272
			$result = $this->CheckSilent($grant, $modifier, $path);
3273
		$this->popContext();
3274
		return $result;
3275
	}
3276
3277
	public function _checkpublic($grant, $modifier=ARTHISTYPE) {
3278
3279
		return $this->CheckPublic($grant, $modifier);
3280
	}
3281
3282
	public function _getcharset() {
3283
		return $this->getcharset();
3284
	}
3285
3286
	public function _count_find($query='') {
3287
		return $this->count_find($this->path, $query);
3288
	}
3289
3290
	public function _count_ls() {
3291
		return $this->count_ls($this->path);
3292
	}
3293
3294
	public function _HTTPRequest($method, $url, $postdata = "", $port=80) {
3295
		return $this->HTTPRequest($method, $url, $postdata, $port);
3296
	}
3297
3298
	public function _make_filesize( $size="" ,$precision=0) {
3299
		return $this->make_filesize( $size ,$precision);
3300
	}
3301
3302
	public function _convertToUTF8($data, $charset = "CP1252") {
3303
		return $this->convertToUTF8($data,$charset);
3304
	}
3305
3306
	public function _getuser() {
3307
	global $AR;
3308
		if ($AR->pinp_user && $AR->pinp_user->data->login == $AR->user->data->login) {
3309
			$user = $AR->pinp_user;
3310
		} else {
3311
			$this->pushContext(array("scope" => "php"));
3312
				if ( $AR->user instanceof ariadne_object ) {
3313
					$user = current($AR->user->get(".", "system.get.phtml"));
3314
				} else {
3315
					$user = $AR->user;
3316
				}
3317
				$AR->pinp_user = $user;
3318
			$this->popContext();
3319
		}
3320
		return $user;
3321
	}
3322
3323
	public function ARinclude($file) {
3324
		include($file);
3325
	}
3326
3327 4
	public function _load($class) {
3328
		// only allow access to modules in the modules directory.
3329 4
		$class = preg_replace('/[^a-z0-9\._]/i','',$class);
3330 4
		include_once($this->store->get_config("code")."modules/".$class);
3331 4
	}
3332
3333
	public function _import($class) {
3334
		// deprecated
3335
		return $this->_load($class);
3336
	}
3337
3338 52
	public function html_to_text($text) {
3339 52
		$trans = array_flip(get_html_translation_table(HTML_ENTITIES));
3340 52
		$cb  = function($matches) use ($trans) {
3341
			return strtr($matches[1],$trans);
3342 52
		};
3343
		//strip nonbreaking space, strip script and style blocks, strip html tags, convert html entites, strip extra white space
3344 52
		$search_clean = array("%&nbsp;%i", "%<(script|style)[^>]*>.*?<\/(script|style)[^>]*>%si", "%<[\/]*[^<>]*>%Usi", "%\s+%");
3345 52
		$replace_clean = array(" ", " ", " ", " ");
3346
3347 52
		$text = preg_replace_callback(
3348 52
			"%(\&[a-zA-Z0-9\#]+;)%s",
3349 39
			$cb,
3350
			$text
3351 39
		);
3352 52
		$text = preg_replace($search_clean, $replace_clean, $text);
3353 52
		return $text;
3354
	}
3355
3356
	public function _html_to_text($text) {
3357
		return $this->html_to_text($text);
3358
	}
3359
3360
	public function _newobject($filename, $type) {
3361
		$newpath=$this->make_path($filename);
3362
		$newparent=$this->store->make_path($newpath, "..");
3363
		$data=new object;
3364
		$object=$this->store->newobject($newpath, $newparent, $type, $data);
3365
		$object->arIsNewObject=true;
3366
		return $object;
3367
	}
3368
3369
	public function _save($properties="", $vtype="") {
3370
		if (isset($properties) && is_array($properties)) {
3371
			// isn't this double work, the save function doesn this again
3372
			foreach ($properties as $prop_name => $prop) {
3373
				foreach ($prop as $prop_index => $prop_record) {
3374
					$record = array();
3375 View Code Duplication
					foreach ($prop_record as $prop_field => $prop_value) {
3376
						switch (gettype($prop_value)) {
3377
							case "integer":
3378
							case "boolean":
3379
							case "double":
3380
								$value = $prop_value;
3381
							break;
3382
							default:
3383
								$value = $prop_value;
3384
								if (substr($prop_value, 0, 1) === "'" && substr($prop_value, -1) === "'"
3385
										&& "'".AddSlashes(StripSlashes(substr($prop_value, 1, -1)))."'" == $prop_value) {
3386
									$value = stripSlashes(substr($prop_value,1,-1));
3387
									// todo add deprecated warning
3388
								}
3389
						}
3390
						$record[$prop_field] = $value;
3391
					}
3392
					$properties[$prop_name][$prop_index] = $record;
3393
				}
3394
			}
3395
		}
3396
3397
		if ($this->arIsNewObject && $this->CheckSilent('add', $this->type)) {
3398
			unset($this->data->config);
3399
			$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...
3400
		} else if (!$this->arIsNewObject && $this->CheckSilent('edit', $this->type)) {
3401
			$this->data->config = current($this->get('.', 'system.get.data.config.phtml'));
3402
			$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...
3403
		}
3404
		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...
3405
	}
3406
3407
	public function _is_supported($feature) {
3408
		return $this->store->is_supported($feature);
3409
	}
3410
3411
	/*
3412
		since the preg_replace() function is able to execute normal php code
3413
		we have to intercept all preg_replace() calls and parse the
3414
		php code with the pinp parser.
3415
	*/
3416
3417
3418
	/*	this is a private function used by the _preg_replace wrapper */
3419
	// 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...
3420
	protected function preg_replace_compile($pattern, $replacement) {
3421
	global $AR;
3422
		include_once($this->store->get_config("code")."modules/mod_pinp.phtml");
3423
		preg_match("/^\s*(.)/", $pattern, $regs);
3424
		$delim = $regs[1];
3425
		if (@eregi("\\${delim}[^$delim]*\\${delim}.*e.*".'$', $pattern)) {
3426
			$pinp = new pinp($AR->PINP_Functions, 'local->', '$AR_this->_');
3427
			return substr($pinp->compile("<pinp>$replacement</pinp>"), 5, -2);
3428
		} else {
3429
			return $replacement;
3430
		}
3431
	}
3432
3433
	public function _preg_replace($pattern, $replacement, $text, $limit = -1) {
3434
		if (version_compare(PHP_VERSION, '7.0.0', '<')) {
3435
			if (isset($pattern) && is_array($pattern)) {
3436
				$newrepl = array();
3437
				reset($replacement);
3438
				foreach ($pattern as $i_pattern) {
3439
					list(, $i_replacement) = each($replacement);
3440
					$newrepl[] = $this->preg_replace_compile($i_pattern, $i_replacement);
3441
				}
3442
			} else {
3443
				$newrepl = $this->preg_replace_compile($pattern, $replacement);
3444
			}
3445
		} else {
3446
			// php7 is safe, no more eval
3447
			$newrepl = $replacement;
3448
		}
3449
		return preg_replace($pattern, $newrepl, $text, $limit);
3450
	}
3451
3452
	/* ob_start accepts a callback but we don't want that
3453
	 * this wrapper removes the arguments from the ob_start call
3454
	 */
3455
	public function _ob_start() {
3456
		return ob_start();
3457
	}
3458
3459
	public function _loadConfig($path='') {
3460
		return clone $this->loadConfig($path);
3461
	}
3462
3463
	public function _loadUserConfig($path='') {
3464
		return $this->loadUserConfig($path);
3465
	}
3466
3467
	public function _loadLibrary($name, $path) {
3468 4
		return $this->loadLibrary($name, $path);
3469
	}
3470
3471
	public function _resetConfig($path='') {
3472
		return $this->resetConfig($path);
3473
	}
3474
3475
	public function _getLibraries($path = '') {
3476
		return $this->getLibraries($path);
3477
	}
3478
3479
3480
	public function _getSetting($setting) {
3481
	global $AR;
3482
3483
		switch ($setting) {
3484
			case 'www':
3485
			case 'dir:www':
3486
				return $AR->dir->www;
3487
			case 'images':
3488
			case 'dir:images':
3489
				return $AR->dir->images;
3490
			case 'ARSessionKeyCheck':
3491
				$result = null;
3492
				if (function_exists('ldGenerateSessionKeyCheck')) {
3493
					$result = ldGenerateSessionKeyCheck();
3494
				}
3495
				return $result;
3496
			break;
3497
			case 'nls:list':
3498
				return $AR->nls->list;
3499
			break;
3500
			case 'nls:default':
3501
				return $AR->nls->default;
3502
			break;
3503
			case 'svn':
3504
				return $AR->SVN->enabled;
3505
			break;
3506
		}
3507
	}
3508
3509
	public function __call($name,$arguments) {
3510
		if ( $name[0] == '_' ) {
3511
			$fname = substr($name, 1);
3512
			if ( isset($this->{$fname}) && $this->{$fname} instanceof \Closure ) {
3513
				\Closure::bind( $this->{$fname}, $this );
3514
				return call_user_func_array( $this->{$fname}, $arguments);
3515
			}
3516
		}
3517
		switch($name) {
3518
			case "implements":
3519
				return $this->AR_implements($arguments[0]);
3520
			break;
3521
			default:
3522
				trigger_error(sprintf('Call to undefined function: %s::%s().', get_class($this), $name), E_USER_ERROR);
3523
				return false;
3524
			break;
3525
		}
3526
	}
3527
3528
	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...
3529 4
		global $nocache;
3530 4
		if (($errno & error_reporting()) == 0) {
3531 4
			return true;
3532
		}
3533
3534
		$nocache = true;
3535
		$context = pobject::getContext();
3536
		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...
3537
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." in library ".$context["arLibraryPath"] ."\n".$errstr."\n";
3538
		} else {
3539
			$msg = "Error on line $errline in ".$context['arCallTemplateType'].'::'.$context['arCallFunction'] ." on object ".$context['arCurrentObject']->path."\n".$errstr."\n";
3540
		}
3541
		$display = ini_get('display_errors');
3542
3543
		if($display) {
3544
			echo $msg;
3545
		}
3546
		error_log($msg);
3547
3548
		return false;
3549
	}
3550
3551
} // end of ariadne_object class definition
3552