Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like ariadne_object often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use ariadne_object, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 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; |
||
| 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; |
|
| 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; |
|
| 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; |
|
| 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'); |
||
| 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'); |
||
| 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="") { |
|
| 244 | |||
| 245 | 56 | public function get($path, $function="view.html", $args="") { |
|
| 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+) */ |
||
| 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 ); |
||
| 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) { |
||
| 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)) { |
||
| 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); |
|
| 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 |
|
| 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); |
|
| 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; |
|
| 476 | 48 | $eventData->arCallFunction = $context['arCallFunction']; |
|
| 477 | 48 | $eventData->arIsNewObject = $arIsNewObject; |
|
| 478 | 48 | $eventData->arProperties = $properties; |
|
| 479 | 48 | $eventData = ar_events::fire( 'onbeforesave', $eventData ); |
|
| 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; |
|
| 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); |
||
| 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 ){ |
|
| 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) { |
||
| 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; |
||
| 612 | $eventData->arCallFunction = $context['arCallFunction']; |
||
| 613 | $eventData = ar_events::fire( 'onbeforedelete', $eventData ); |
||
| 614 | if ( !$eventData ) { |
||
| 615 | return false; |
||
| 616 | } |
||
| 617 | $this->call("user.workflow.delete.pre.html", $eventData->arCallArgs); |
||
| 618 | if (!$this->error) { |
||
| 619 | if ($this->store->delete($this->path)) { |
||
| 620 | $result = true; |
||
| 621 | $this->call("user.workflow.delete.post.html", $eventData->arCallArgs); |
||
| 622 | ar_events::fire( 'ondelete', $eventData ); |
||
| 623 | } else { |
||
| 624 | $this->error = ar::error( ''.$this->store->error, 1107, $this->store->error); |
||
| 625 | } |
||
| 626 | } |
||
| 627 | return $result; |
||
| 628 | } |
||
| 629 | |||
| 630 | 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; |
||
| 700 | } |
||
| 701 | 36 | } |
|
| 702 | 52 | if (!$url) { |
|
| 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(); |
|
| 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; |
||
| 740 | 48 | $url = $protocol . $requestedHost . $AR->root . $rootoptions . $path; |
|
| 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']; |
||
| 788 | } |
||
| 789 | } |
||
| 790 | |||
| 791 | do { |
||
| 792 | 48 | 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(); |
|
| 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)); |
||
| 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() { |
|
| 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) { |
| 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() { |
| 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) { |
||
| 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='') { |
||
| 898 | |||
| 899 | public function _load_properties($scope='') { |
||
| 902 | |||
| 903 | public function load_property($property, $scope='') { |
||
| 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; |
|
| 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"); |
|
| 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) { |
|
| 1148 | |||
| 1149 | 44 | public function CheckSilent($grant, $modifier=ARTHISTYPE, $path=".") { |
|
| 1173 | |||
| 1174 | public function CheckNewFile($newfilename) { |
||
| 1207 | |||
| 1208 | View Code Duplication | public function resetConfig($path='') { |
|
| 1220 | |||
| 1221 | 36 | View Code Duplication | public function clearChildConfigs($path='') { |
| 1234 | |||
| 1235 | 36 | protected function getConfig() { |
|
| 1236 | 36 | global $ARConfig, $ARCurrent, $ARConfigChecked; |
|
| 1237 | $this->pushContext(array('scope' => 'php', 'arCurrentObject' => $this)); |
||
| 1238 | // $context=$this->getContext(0); |
||
| 1239 | // debug("getConfig(".$this->path.") context: ".$context['scope'] ); |
||
| 1240 | 36 | // debug(print_r($ARConfig->nls, true)); |
|
| 1241 | 4 | if( !$ARConfig->cache[$this->parent] && $this->parent!=".." ) { |
|
| 1242 | 4 | $parent = current($this->get($this->parent, "system.get.phtml")); |
|
| 1243 | 4 | if ($parent) { |
|
| 1244 | 3 | $parent->getConfig(); |
|
| 1245 | 3 | } |
|
| 1246 | } |
||
| 1247 | 36 | ||
| 1310 | 36 | ||
| 1311 | 36 | protected function getConfigData() { |
|
| 1406 | 60 | ||
| 1407 | 60 | public function loadConfig($path='') { |
|
| 1454 | |||
| 1455 | |||
| 1456 | // TODO: look for a way to merge loadConfig and loadUserConfig into one function |
||
| 1457 | 12 | ||
| 1458 | 12 | public function loadUserConfig($path='') { |
|
| 1473 | 48 | ||
| 1474 | 48 | public function loadLibrary($name, $path) { |
|
| 1496 | |||
| 1497 | // returns a list of libraries loaded on $path |
||
| 1498 | public function getLibraries($path = '') { |
||
| 1503 | |||
| 1504 | public function mergeLibraryConfig( $defaultLibraryName, $defaults ) { |
||
| 1517 | |||
| 1518 | public function _mergeLibraryConfig( $defaultLibraryName, $defaults ) { |
||
| 1521 | |||
| 1522 | protected function findTemplateOnPath($path, $arCallFunction, $arType, $reqnls, &$arSuperContext){ |
||
| 1573 | 4 | ||
| 1574 | 4 | public function getPinpTemplate($arCallFunction='view.html', $path=".", $top="", $inLibrary = false, $librariesSeen = null, $arSuperContext=array()) { |
|
| 1714 | |||
| 1715 | public function CheckConfig($arCallFunction="", $arCallArgs="") { |
||
| 2016 | |||
| 2017 | public function ClearCache($path="", $private=true, $recurse=false) { |
||
| 2141 | |||
| 2142 | public function getcache($name, $nls="") { |
||
| 2194 | |||
| 2195 | public function cached($name, $nls="") { |
||
| 2204 | |||
| 2205 | public function savecache($time="") { |
||
| 2253 | |||
| 2254 | public function getdatacache($name) { |
||
| 2277 | |||
| 2278 | public function savedatacache($name,$data,$time="") { |
||
| 2295 | |||
| 2296 | public function getdata($varname, $nls="none", $emptyResult=false) { |
||
| 2362 | |||
| 2363 | public function showdata($varname, $nls="none", $emptyResult=false) { |
||
| 2366 | |||
| 2367 | public function setnls($nls) { |
||
| 2370 | |||
| 2371 | 52 | public function getcharset() { |
|
| 2374 | 52 | ||
| 2375 | public function HTTPRequest($method, $url, $postdata = "", $port=80 ) { |
||
| 2479 | |||
| 2480 | public function make_filesize( $size="" ,$precision=0) { |
||
| 2497 | |||
| 2498 | public function convertToUTF8($data, $charset = "CP1252") { |
||
| 2516 | |||
| 2517 | public function resetloopcheck() { |
||
| 2521 | |||
| 2522 | /******************************************************************** |
||
| 2523 | |||
| 2524 | "safe" functions. |
||
| 2525 | |||
| 2526 | The following functions are safe versions of existing functions |
||
| 2527 | above. |
||
| 2528 | - They don't change anything in the database. |
||
| 2529 | This means that to save/delete something, a user will need to call |
||
| 2530 | "system.save.data.phtml" or "system.delete.phtml" which check grants. |
||
| 2531 | - All functions except _get and _exists don't take a path as |
||
| 2532 | argument, they use the current objects path instead. |
||
| 2533 | |||
| 2534 | These are meant to be used by 'pinp' versions of templates, |
||
| 2535 | meaning user defined templates. 'pinp' rewrites call to functions |
||
| 2536 | to the form '$this->_function'. |
||
| 2537 | |||
| 2538 | All pinp files automatically first call CheckLogin('read'). |
||
| 2539 | |||
| 2540 | ********************************************************************/ |
||
| 2541 | |||
| 2542 | public function _call($function, $args="") { |
||
| 2549 | |||
| 2550 | public function _call_super($arCallArgs="") { |
||
| 2663 | |||
| 2664 | public function _get($path, $function="view.html", $args="") { |
||
| 2673 | |||
| 2674 | public function _call_object($object, $function, $args="") { |
||
| 2677 | |||
| 2678 | View Code Duplication | public function _ls($function="list.html", $args="") { |
|
| 2686 | |||
| 2687 | View Code Duplication | public function _parents($function="list.html", $args="", $top="") { |
|
| 2694 | |||
| 2695 | public function _find($criteria, $function="list.html", $args="", $limit=100, $offset=0) { |
||
| 2708 | |||
| 2709 | public function _exists($path) { |
||
| 2712 | |||
| 2713 | public function _implements($implements) { |
||
| 2716 | |||
| 2717 | public function getvar($var) { |
||
| 2745 | |||
| 2746 | public function _getvar($var) { |
||
| 2749 | |||
| 2750 | public function putvar($var, $value) { |
||
| 2755 | |||
| 2756 | public function _putvar($var, $value) { |
||
| 2759 | |||
| 2760 | public function _setnls($nls) { |
||
| 2763 | |||
| 2764 | // not exposed to pinp for obvious reasons |
||
| 2765 | public function sgKey($grants) { |
||
| 2778 | |||
| 2779 | public function sgBegin($grants, $key = '', $path = '.') { |
||
| 2807 | |||
| 2808 | 52 | public function sgEnd($path = '.') { |
|
| 2815 | |||
| 2816 | 52 | public function sgCall($grants, $key, $function="view.html", $args="") { |
|
| 2824 | |||
| 2825 | public function _sgBegin($grants, $key, $path = '.') { |
||
| 2828 | |||
| 2829 | public function _sgEnd($path = '.') { |
||
| 2832 | |||
| 2833 | public function _sgCall($grants, $key, $function="view.html", $args="") { |
||
| 2836 | |||
| 2837 | public function _widget($arWidgetName, $arWidgetTemplate, $arWidgetArgs="", $arWidgetType="lib") { |
||
| 2866 | |||
| 2867 | public function _getdata($varname, $nls="none", $emptyResult=false) { |
||
| 2870 | |||
| 2871 | public function _showdata($varname, $nls="none", $emptyResult=false) { |
||
| 2874 | |||
| 2875 | public function _gettext($index=false) { |
||
| 2883 | |||
| 2884 | public function _loadtext($nls, $section="") { |
||
| 2917 | |||
| 2918 | public function _startsession() { |
||
| 2923 | |||
| 2924 | public function _putsessionvar($varname, $varvalue) { |
||
| 2933 | |||
| 2934 | public function _getsessionvar($varname) { |
||
| 2943 | |||
| 2944 | public function _setsessiontimeout($timeout = 0) { |
||
| 2952 | |||
| 2953 | public function _killsession() { |
||
| 2961 | |||
| 2962 | public function _sessionid() { |
||
| 2970 | |||
| 2971 | public function _resetloopcheck() { |
||
| 2974 | |||
| 2975 | public function _make_path($path="") { |
||
| 2978 | |||
| 2979 | public function _make_ariadne_url($path="") { |
||
| 2982 | |||
| 2983 | public function _make_url($path="", $nls=false, $session=true, $https=null, $keephost=null) { |
||
| 2986 | |||
| 2987 | public function _make_local_url($path="", $nls=false, $session=true, $https=null) { |
||
| 2990 | |||
| 2991 | public function _getcache($name, $nls='') { |
||
| 2994 | |||
| 2995 | public function _cached($name, $nls='') { |
||
| 2998 | |||
| 2999 | public function _savecache($time="") { |
||
| 3002 | |||
| 3003 | public function _getdatacache($name) { |
||
| 3006 | |||
| 3007 | public function _savedatacache($name,$data,$time="") |
||
| 3011 | |||
| 3012 | public function currentsite($path="", $skipRedirects = false) { |
||
| 3029 | |||
| 3030 | public function parentsite($site) { |
||
| 3036 | |||
| 3037 | View Code Duplication | public function currentsection($path="") { |
|
| 3045 | |||
| 3046 | View Code Duplication | public function parentsection($path) { |
|
| 3052 | |||
| 3053 | View Code Duplication | public function currentproject($path="") { |
|
| 3061 | |||
| 3062 | public function parentproject($path) { |
||
| 3068 | |||
| 3069 | public function validateFormSecret() { |
||
| 3081 | |||
| 3082 | public function _validateFormSecret() { |
||
| 3085 | |||
| 3086 | public function getValue($name, $nls=false) { |
||
| 3103 | 56 | ||
| 3104 | public function setValue($name, $value, $nls=false) { |
||
| 3144 | |||
| 3145 | public function showValue($name, $nls=false) { |
||
| 3150 | |||
| 3151 | public function _getValue($name, $nls=false) { |
||
| 3154 | |||
| 3155 | public function _setValue($name, $value, $nls=false) { |
||
| 3158 | |||
| 3159 | public function _showValue($name, $nls=false) { |
||
| 3162 | |||
| 3163 | public function _currentsite($path="", $skipRedirects = false) { |
||
| 3166 | |||
| 3167 | public function _parentsite($site) { |
||
| 3170 | |||
| 3171 | public function _currentsection() { |
||
| 3174 | |||
| 3175 | public function _parentsection($section) { |
||
| 3178 | |||
| 3179 | public function _currentproject() { |
||
| 3182 | |||
| 3183 | public function _parentproject($path) { |
||
| 3186 | |||
| 3187 | public function _checkAdmin($user) { |
||
| 3190 | |||
| 3191 | public function _checkgrant($grant, $modifier=ARTHISTYPE, $path=".") { |
||
| 3200 | |||
| 3201 | public function _checkpublic($grant, $modifier=ARTHISTYPE) { |
||
| 3205 | |||
| 3206 | public function _getcharset() { |
||
| 3209 | |||
| 3210 | public function _count_find($query='') { |
||
| 3213 | |||
| 3214 | public function _count_ls() { |
||
| 3217 | |||
| 3218 | public function _HTTPRequest($method, $url, $postdata = "", $port=80) { |
||
| 3221 | |||
| 3222 | public function _make_filesize( $size="" ,$precision=0) { |
||
| 3225 | |||
| 3226 | public function _convertToUTF8($data, $charset = "CP1252") { |
||
| 3229 | |||
| 3230 | public function _getuser() { |
||
| 3246 | |||
| 3247 | public function ARinclude($file) { |
||
| 3250 | |||
| 3251 | public function _load($class) { |
||
| 3256 | |||
| 3257 | public function _import($class) { |
||
| 3261 | |||
| 3262 | public function html_to_text($text) { |
||
| 3279 | |||
| 3280 | public function _html_to_text($text) { |
||
| 3283 | |||
| 3284 | public function _newobject($filename, $type) { |
||
| 3292 | |||
| 3293 | public function _save($properties="", $vtype="") { |
||
| 3330 | 4 | ||
| 3331 | 4 | public function _is_supported($feature) { |
|
| 3334 | |||
| 3335 | /* |
||
| 3336 | since the preg_replace() function is able to execute normal php code |
||
| 3337 | we have to intercept all preg_replace() calls and parse the |
||
| 3338 | 52 | php code with the pinp parser. |
|
| 3339 | 52 | */ |
|
| 3340 | 52 | ||
| 3341 | |||
| 3342 | 52 | /* this is a private function used by the _preg_replace wrapper */ |
|
| 3343 | // FIXME: remove this function when the minimal php version for ariadne is raised to php 7.0 |
||
| 3344 | 52 | protected function preg_replace_compile($pattern, $replacement) { |
|
| 3356 | |||
| 3357 | public function _preg_replace($pattern, $replacement, $text, $limit = -1) { |
||
| 3375 | |||
| 3376 | /* ob_start accepts a callback but we don't want that |
||
| 3377 | * this wrapper removes the arguments from the ob_start call |
||
| 3378 | */ |
||
| 3379 | public function _ob_start() { |
||
| 3382 | |||
| 3383 | public function _loadConfig($path='') { |
||
| 3386 | |||
| 3387 | public function _loadUserConfig($path='') { |
||
| 3390 | |||
| 3391 | public function _loadLibrary($name, $path) { |
||
| 3394 | |||
| 3395 | public function _resetConfig($path='') { |
||
| 3398 | |||
| 3399 | public function _getLibraries($path = '') { |
||
| 3402 | |||
| 3403 | |||
| 3404 | public function _getSetting($setting) { |
||
| 3432 | |||
| 3433 | public function __call($name,$arguments) { |
||
| 3451 | |||
| 3452 | static public function pinpErrorHandler($errno, $errstr, $errfile, $errline, $errcontext) { |
||
| 3474 | |||
| 3475 | } // end of ariadne_object class definition |
||
| 3476 |
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.