ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilObjRoleTemplateGUI.php
Go to the documentation of this file.
1<?php
2
3/* Copyright (c) 1998-2010 ILIAS open source, Extended GPL, see docs/LICENSE */
4
5require_once "./Services/Object/classes/class.ilObjectGUI.php";
6require_once('./Services/Repository/classes/class.ilObjectPlugin.php');
7
19{
20
21 const FORM_MODE_EDIT = 1;
23
29 var $type;
30
42 function __construct($a_data,$a_id,$a_call_by_reference)
43 {
44 global $lng;
45
46 $lng->loadLanguageModule('rbac');
47
48 $this->type = "rolt";
49 parent::__construct($a_data,$a_id,$a_call_by_reference,false);
50 $this->rolf_ref_id =& $this->ref_id;
51 $this->ctrl->saveParameter($this, "obj_id");
52 }
53
54 function executeCommand()
55 {
56 global $rbacsystem;
57
58 $this->prepareOutput();
59
60 $next_class = $this->ctrl->getNextClass($this);
61 $cmd = $this->ctrl->getCmd();
62
63 switch($next_class)
64 {
65 default:
66 if(!$cmd)
67 {
68 $cmd = "perm";
69 }
70 $cmd .= "Object";
71 $this->$cmd();
72
73 break;
74 }
75
76 return true;
77 }
78
84 protected function initFormRoleTemplate($a_mode = self::FORM_MODE_CREATE)
85 {
86 include_once './Services/Form/classes/class.ilPropertyFormGUI.php';
87 $form = new ilPropertyFormGUI();
88
89 if($this->creation_mode)
90 {
91 $this->ctrl->setParameter($this, "new_type", 'rolt');
92 }
93
94 $form->setFormAction($this->ctrl->getFormAction($this));
95
96 if($a_mode == self::FORM_MODE_CREATE)
97 {
98 $form->setTitle($this->lng->txt('rolt_new'));
99 $form->addCommandButton('save', $this->lng->txt('rolt_new'));
100 }
101 else
102 {
103 $form->setTitle($this->lng->txt('rolt_edit'));
104 $form->addCommandButton('update', $this->lng->txt('save'));
105
106 }
107 $form->addCommandButton('cancel', $this->lng->txt('cancel'));
108
109 $title = new ilTextInputGUI($this->lng->txt('title'),'title');
110 if($a_mode != self::FORM_MODE_CREATE)
111 {
112 if($this->object->isInternalTemplate())
113 {
114 $title->setDisabled(true);
115 }
116 $title->setValue($this->object->getTitle());
117 }
118 $title->setSize(40);
119 $title->setMaxLength(70);
120 $title->setRequired(true);
121 $form->addItem($title);
122
123 $desc = new ilTextAreaInputGUI($this->lng->txt('description'),'desc');
124
125 if($a_mode != self::FORM_MODE_CREATE)
126 {
127 $desc->setValue($this->object->getDescription());
128 }
129 $desc->setCols(40);
130 $desc->setRows(3);
131 $form->addItem($desc);
132
133 if($a_mode != self::FORM_MODE_CREATE)
134 {
135 $ilias_id = new ilNonEditableValueGUI($this->lng->txt("ilias_id"), "ilias_id");
136 $ilias_id->setValue('il_'.IL_INST_ID.'_'.ilObject::_lookupType($this->object->getId()).'_'.$this->object->getId());
137 $form->addItem($ilias_id);
138 }
139
140 $pro = new ilCheckboxInputGUI($this->lng->txt('role_protect_permissions'),'protected');
141 $pro->setChecked($GLOBALS['rbacreview']->isProtected(
142 $this->rolf_ref_id,
143 $this->object->getId()
144 ));
145 $pro->setValue(1);
146 $form->addItem($pro);
147
148 return $form;
149 }
150
151
157 function createObject(ilPropertyFormGUI $form = null)
158 {
159 global $rbacsystem;
160
161 if (!$rbacsystem->checkAccess("create_rolt", $this->rolf_ref_id))
162 {
163 $this->ilias->raiseError($this->lng->txt("permission_denied"),$this->ilias->error_obj->MESSAGE);
164 }
165 if(!$form)
166 {
167 $form = $this->initFormRoleTemplate(self::FORM_MODE_CREATE);
168 }
169 $this->tpl->setContent($form->getHTML());
170 return true;
171 }
172
176 public function editObject(ilPropertyFormGUI $form = null)
177 {
178 global $rbacsystem;
179
180 if (!$rbacsystem->checkAccess("write", $this->rolf_ref_id))
181 {
182 $this->ilias->raiseError($this->lng->txt("msg_no_perm_write"),$this->ilias->error_obj->MESSAGE);
183 }
184
185 if(!$form)
186 {
187 $form = $this->initFormRoleTemplate(self::FORM_MODE_EDIT);
188 }
189 $GLOBALS['tpl']->setContent($form->getHTML());
190 }
191
197 public function updateObject()
198 {
199 global $rbacsystem, $rbacadmin, $rbacreview;
200
201 // check write access
202 if (!$rbacsystem->checkAccess("write", $this->rolf_ref_id))
203 {
204 $this->ilias->raiseError($this->lng->txt("msg_no_perm_modify_rolt"),$this->ilias->error_obj->WARNING);
205 }
206
207 $form = $this->initFormRoleTemplate(self::FORM_MODE_EDIT);
208 if($form->checkInput())
209 {
210 $this->object->setTitle($form->getInput('title'));
211 $this->object->setDescription($form->getInput('desc'));
212 $rbacadmin->setProtected(
213 $this->rolf_ref_id,
214 $this->object->getId(),
215 $form->getInput('protected') ? 'y' : 'n'
216 );
217 $this->object->update();
218 ilUtil::sendSuccess($this->lng->txt("saved_successfully"),true);
219 $this->ctrl->returnToParent($this);
220 }
221
222 $form->setValuesByPost();
223 $this->editObject($form);
224 }
225
226
227
233 public function saveObject()
234 {
235 global $rbacsystem,$rbacadmin, $rbacreview;
236
237 if (!$rbacsystem->checkAccess("create_rolt",$this->rolf_ref_id))
238 {
239 $this->ilias->raiseError($this->lng->txt("msg_no_perm_create_rolt"),$this->ilias->error_obj->WARNING);
240 }
241 $form = $this->initFormRoleTemplate();
242 if($form->checkInput())
243 {
244 include_once("./Services/AccessControl/classes/class.ilObjRoleTemplate.php");
245 $roltObj = new ilObjRoleTemplate();
246 $roltObj->setTitle($form->getInput('title'));
247 $roltObj->setDescription($form->getInput('desc'));
248 $roltObj->create();
249 $rbacadmin->assignRoleToFolder($roltObj->getId(), $this->rolf_ref_id,'n');
250 $rbacadmin->setProtected(
251 $this->rolf_ref_id,
252 $roltObj->getId(),
253 $form->getInput('protected') ? 'y' : 'n'
254 );
255
256 ilUtil::sendSuccess($this->lng->txt("rolt_added"),true);
257 // redirect to permission screen
258 $this->ctrl->setParameter($this,'obj_id',$roltObj->getId());
259 $this->ctrl->redirect($this,'perm');
260 }
261 $form->setValuesByPost();
262 $this->createObject($form);
263 }
264
270 function permObject()
271 {
272 global $rbacadmin, $rbacreview, $rbacsystem,$objDefinition,$ilSetting;
273
274 if (!$rbacsystem->checkAccess('write',$this->rolf_ref_id))
275 {
276 $this->ilias->raiseError($this->lng->txt("msg_no_perm_perm"),$this->ilias->error_obj->WARNING);
277 exit();
278 }
279
280 $to_filter = $objDefinition->getSubobjectsToFilter();
281
282 $tpl_filter = array();
283 $internal_tpl = false;
284
285 if (($internal_tpl = $this->object->isInternalTemplate()))
286 {
287 $tpl_filter = $this->object->getFilterOfInternalTemplate();
288 }
289 $op_order = array();
290
291 foreach(ilRbacReview::_getOperationList() as $op)
292 {
293 $op_order[$op["ops_id"]] = $op["order"];
294 }
295
296 $operation_info = $rbacreview->getOperationAssignment();
297
298 foreach($operation_info as $info)
299 {
300 if($objDefinition->getDevMode($info['type']))
301 {
302 continue;
303 }
304 // FILTER SUBOJECTS OF adm OBJECT
305 if(in_array($info['type'],$to_filter))
306 {
307 continue;
308 }
309 if ($internal_tpl and $tpl_filter and !in_array($info['type'],$tpl_filter))
310 {
311 continue;
312 }
313 $rbac_objects[$info['typ_id']] = array("obj_id" => $info['typ_id'],
314 "type" => $info['type']);
315
316 $txt = $objDefinition->isPlugin($info['type'])
317 ? ilObjectPlugin::lookupTxtById($info['type'], $info['type']."_".$info['operation'])
318 : $this->lng->txt($info['type']."_".$info['operation']);
319 if (substr($info['operation'], 0, 7) == "create_" &&
320 $objDefinition->isPlugin(substr($info['operation'], 7)))
321 {
322 $txt = ilObjectPlugin::lookupTxtById(substr($info['operation'], 7), $info['type']."_".$info['operation']);
323 }
324 elseif(substr($info['operation'],0,6) == 'create')
325 {
326 $txt = $this->lng->txt('rbac_'.$info['operation']);
327 }
328
329 $order = $op_order[$info['ops_id']];
330 if(substr($info['operation'],0,6) == 'create')
331 {
332 $order = $objDefinition->getPositionByType($info['type']);
333 }
334
335 $rbac_operations[$info['typ_id']][$info['ops_id']] = array(
336 "ops_id" => $info['ops_id'],
337 "title" => $info['operation'],
338 "name" => $txt,
339 "order" => $order);
340 }
341
342 foreach ($rbac_objects as $key => $obj_data)
343 {
344 if ($objDefinition->isPlugin($obj_data["type"]))
345 {
346 $rbac_objects[$key]["name"] = ilObjectPlugin::lookupTxtById($obj_data["type"],
347 "obj_".$obj_data["type"]);
348 }
349 else
350 {
351 $rbac_objects[$key]["name"] = $this->lng->txt("obj_".$obj_data["type"]);
352 }
353
354 $rbac_objects[$key]["ops"] = $rbac_operations[$key];
355 }
356
357 sort($rbac_objects);
358
359 foreach ($rbac_objects as $key => $obj_data)
360 {
361 sort($rbac_objects[$key]["ops"]);
362 }
363
364 // sort by (translated) name of object type
365 $rbac_objects = ilUtil::sortArray($rbac_objects,"name","asc");
366
367 // BEGIN CHECK_PERM
368 foreach ($rbac_objects as $key => $obj_data)
369 {
370 $arr_selected = $rbacreview->getOperationsOfRole($this->object->getId(), $obj_data["type"], $this->rolf_ref_id);
371 $arr_checked = array_intersect($arr_selected,array_keys($rbac_operations[$obj_data["obj_id"]]));
372
373 foreach ($rbac_operations[$obj_data["obj_id"]] as $operation)
374 {
375 $checked = in_array($operation["ops_id"],$arr_checked);
376 $disabled = false;
377
378 // Es wird eine 2-dim Post Variable �bergeben: perm[rol_id][ops_id]
379 $box = ilUtil::formCheckBox($checked,"template_perm[".$obj_data["type"]."][]",$operation["ops_id"],$disabled);
380 $output["perm"][$obj_data["obj_id"]][$operation["ops_id"]] = $box;
381 }
382 }
383 // END CHECK_PERM
384
385 $output["col_anz"] = count($rbac_objects);
386 $output["txt_save"] = $this->lng->txt("save");
387 $output["check_protected"] = ilUtil::formCheckBox($rbacreview->isProtected($this->rolf_ref_id,$this->object->getId()),"protected",1);
388 $output["text_protected"] = $this->lng->txt("role_protect_permissions");
389
390/************************************/
391/* adopt permissions form */
392/************************************/
393
394 $output["message_middle"] = $this->lng->txt("adopt_perm_from_template");
395
396 // send message for system role
397 if ($this->object->getId() == SYSTEM_ROLE_ID)
398 {
399 $output["adopt"] = array();
400 ilUtil::sendFailure($this->lng->txt("msg_sysrole_not_editable"));
401 }
402 else
403 {
404 // BEGIN ADOPT_PERMISSIONS
405 $parent_role_ids = $rbacreview->getParentRoleIds($this->rolf_ref_id,true);
406
407 // sort output for correct color changing
408 ksort($parent_role_ids);
409
410 foreach ($parent_role_ids as $key => $par)
411 {
412 if ($par["obj_id"] != SYSTEM_ROLE_ID)
413 {
414 $radio = ilUtil::formRadioButton(0,"adopt",$par["obj_id"]);
415 $output["adopt"][$key]["css_row_adopt"] = ilUtil::switchColor($key, "tblrow1", "tblrow2");
416 $output["adopt"][$key]["check_adopt"] = $radio;
417 $output["adopt"][$key]["type"] = ($par["type"] == 'role' ? 'Role' : 'Template');
418 $output["adopt"][$key]["role_name"] = $par["title"];
419 }
420 }
421
422 $output["formaction_adopt"] = $this->ctrl->getFormAction($this);
423 // END ADOPT_PERMISSIONS
424 }
425
426 $output["formaction"] =
427 $this->ctrl->getFormAction($this);
428
429 $this->data = $output;
430
431
432/************************************/
433/* generate output */
434/************************************/
435
436 $this->tpl->addBlockFile("ADM_CONTENT", "adm_content", "tpl.adm_perm_role.html",
437 "Services/AccessControl");
438
439 foreach ($rbac_objects as $obj_data)
440 {
441 // BEGIN object_operations
442 $this->tpl->setCurrentBlock("object_operations");
443
444 $obj_data["ops"] = ilUtil::sortArray($obj_data["ops"], 'order','asc',true,true);
445
446 foreach ($obj_data["ops"] as $operation)
447 {
448 $ops_ids[] = $operation["ops_id"];
449
450 $css_row = ilUtil::switchColor($key, "tblrow1", "tblrow2");
451 $this->tpl->setVariable("CSS_ROW",$css_row);
452 $this->tpl->setVariable("PERMISSION",$operation["name"]);
453 $this->tpl->setVariable("CHECK_PERMISSION",$this->data["perm"][$obj_data["obj_id"]][$operation["ops_id"]]);
454 $this->tpl->parseCurrentBlock();
455 } // END object_operations
456
457 // BEGIN object_type
458 $this->tpl->setCurrentBlock("object_type");
459 $this->tpl->setVariable("TXT_OBJ_TYPE",$obj_data["name"]);
460
461// TODO: move this if in a function and query all objects that may be disabled or inactive
462 if ($this->objDefinition->getDevMode($obj_data["type"]))
463 {
464 $this->tpl->setVariable("TXT_NOT_IMPL", "(".$this->lng->txt("not_implemented_yet").")");
465 }
466
467 // js checkbox toggles
468 $this->tpl->setVariable("JS_VARNAME","template_perm_".$obj_data["type"]);
469 $this->tpl->setVariable("JS_ONCLICK",ilUtil::array_php2js($ops_ids));
470 $this->tpl->setVariable("TXT_CHECKALL", $this->lng->txt("check_all"));
471 $this->tpl->setVariable("TXT_UNCHECKALL", $this->lng->txt("uncheck_all"));
472
473
474 $this->tpl->parseCurrentBlock();
475 // END object_type
476 }
477
478 /*
479 // BEGIN ADOPT PERMISSIONS
480 foreach ($this->data["adopt"] as $key => $value)
481 {
482 $this->tpl->setCurrentBlock("ADOPT_PERM_ROW");
483 $this->tpl->setVariable("CSS_ROW_ADOPT",$value["css_row_adopt"]);
484 $this->tpl->setVariable("CHECK_ADOPT",$value["check_adopt"]);
485 $this->tpl->setVariable("TYPE",$value["type"]);
486 $this->tpl->setVariable("ROLE_NAME",$value["role_name"]);
487 $this->tpl->parseCurrentBlock();
488 }
489
490 $this->tpl->setCurrentBlock("ADOPT_PERM_FORM");
491 $this->tpl->setVariable("MESSAGE_MIDDLE",$this->data["message_middle"]);
492 $this->tpl->setVariable("FORMACTION_ADOPT",$this->data["formaction_adopt"]);
493 $this->tpl->setVariable("ADOPT",$this->lng->txt('copy'));
494 $this->tpl->parseCurrentBlock();
495 // END ADOPT PERMISSIONS
496 */
497
498 $this->tpl->setCurrentBlock("tblfooter_protected");
499 $this->tpl->setVariable("COL_ANZ",3);
500 $this->tpl->setVariable("CHECK_BOTTOM",$this->data["check_protected"]);
501 $this->tpl->setVariable("MESSAGE_TABLE",$this->data["text_protected"]);
502 $this->tpl->parseCurrentBlock();
503
504 $this->tpl->setVariable("COL_ANZ_PLUS",4);
505 $this->tpl->setVariable("TXT_SAVE",$this->data["txt_save"]);
506 $this->tpl->setCurrentBlock("adm_content");
507 $this->tpl->setVariable("TBL_TITLE_IMG",ilUtil::getImagePath("icon_".$this->object->getType().".svg"));
508 $this->tpl->setVariable("TBL_TITLE_IMG_ALT",$this->lng->txt($this->object->getType()));
509
510 // compute additional information in title
511 if (substr($this->object->getTitle(),0,3) == "il_")
512 {
513 $desc = $this->lng->txt("predefined_template");//$this->lng->txt("obj_".$parent_node['type'])." (".$parent_node['obj_id'].") : ".$parent_node['title'];
514 }
515
516 $description = "<br/>&nbsp;<span class=\"small\">".$desc."</span>";
517
518 // translation for autogenerated roles
519 if (substr($this->object->getTitle(),0,3) == "il_")
520 {
521 include_once('./Services/AccessControl/classes/class.ilObjRole.php');
522
523 $title = ilObjRole::_getTranslation($this->object->getTitle())." (".$this->object->getTitle().")";
524 }
525 else
526 {
527 $title = $this->object->getTitle();
528 }
529
530 $this->tpl->setVariable("TBL_TITLE",$title.$description);
531
532 $this->tpl->setVariable("TXT_PERMISSION",$this->data["txt_permission"]);
533 $this->tpl->setVariable("FORMACTION",$this->data["formaction"]);
534 $this->tpl->parseCurrentBlock();
535 }
536
537
543 function permSaveObject()
544 {
545 global $rbacadmin, $rbacsystem, $rbacreview,$objDefinition;
546
547 if (!$rbacsystem->checkAccess('write',$this->rolf_ref_id))
548 {
549 $this->ilias->raiseError($this->lng->txt("msg_no_perm_perm"),$this->ilias->error_obj->WARNING);
550 }
551 else
552 {
553 // Alle Template Eintraege loeschen
554 $rbacadmin->deleteRolePermission($this->object->getId(), $this->rolf_ref_id);
555
556 foreach ($_POST["template_perm"] as $key => $ops_array)
557 {
558 // Setzen der neuen template permissions
559 $rbacadmin->setRolePermission($this->object->getId(), $key,$ops_array,$this->rolf_ref_id);
560 }
561 }
562
563 // update object data entry (to update last modification date)
564 $this->object->update();
565
566 // set protected flag
567 // not applicable for role templates
568 #$rbacadmin->setProtected($this->rolf_ref_id,$this->object->getId(),ilUtil::tf2yn($_POST['protected']));
569
570 ilUtil::sendSuccess($this->lng->txt("saved_successfully"),true);
571
572 $this->ctrl->redirect($this, "perm");
573 }
574
581 {
582 global $rbacadmin, $rbacsystem, $rbacreview;
583
584 if (!$rbacsystem->checkAccess('write',$this->rolf_ref_id))
585 {
586 $this->ilias->raiseError($this->lng->txt("msg_no_perm_perm"),$this->ilias->error_obj->WARNING);
587 }
588 elseif ($this->obj_id == $_POST["adopt"])
589 {
590 ilUtil::sendFailure($this->lng->txt("msg_perm_adopted_from_itself"),true);
591 }
592 else
593 {
594 $rbacadmin->deleteRolePermission($this->obj_id, $this->rolf_ref_id);
595 $parentRoles = $rbacreview->getParentRoleIds($this->rolf_ref_id,true);
596 $rbacadmin->copyRoleTemplatePermissions($_POST["adopt"],$parentRoles[$_POST["adopt"]]["parent"],
597 $this->rolf_ref_id,$this->obj_id);
598 // update object data entry (to update last modification date)
599 $this->object->update();
600
601 // send info
602 $obj_data =& $this->ilias->obj_factory->getInstanceByObjId($_POST["adopt"]);
603 ilUtil::sendSuccess($this->lng->txt("msg_perm_adopted_from1")." '".$obj_data->getTitle()."'.<br/>".$this->lng->txt("msg_perm_adopted_from2"),true);
604 }
605
606 $this->ctrl->redirect($this, "perm");
607 }
608
612 function getAdminTabs()
613 {
614 $this->getTabs();
615 }
616
617 function getTabs()
618 {
619 global $rbacsystem;
620
621 if ($rbacsystem->checkAccess('write',$this->rolf_ref_id))
622 {
623 $this->tabs_gui->addTarget("settings",
624 $this->ctrl->getLinkTarget($this, "edit"),
625 array("edit","update"), get_class($this));
626
627 $this->tabs_gui->addTarget("default_perm_settings",
628 $this->ctrl->getLinkTarget($this, "perm"),
629 array("perm"), get_class($this));
630 }
631 }
632
633
638 function cancelObject()
639 {
640 $this->ctrl->redirectByClass("ilobjrolefoldergui","view");
641 }
642
643
644
645
650 function addAdminLocatorItems($a_do_not_add_object = false)
651 {
652 global $ilLocator;
653
654 parent::addAdminLocatorItems(true);
655
656 $ilLocator->addItem(ilObject::_lookupTitle(
657 ilObject::_lookupObjId($_GET["ref_id"])),
658 $this->ctrl->getLinkTargetByClass("ilobjrolefoldergui", "view"));
659 }
660
661} // END class.ilObjRoleTemplateGUI
662?>
$_GET["client_id"]
$_POST["username"]
An exception for terminatinating execution or to throw for unit testing.
This class represents a checkbox property in a property form.
This class represents a non editable value in a property form.
Class ilObjRoleTemplateGUI.
createObject(ilPropertyFormGUI $form=null)
create new role definition template
adoptPermSaveObject()
adopting permission setting from other roles/role templates
cancelObject()
cancelObject is called when an operation is canceled, method links back @access public
getAdminTabs()
admin and normal tabs are equal for roles
__construct($a_data, $a_id, $a_call_by_reference)
Constructor.
addAdminLocatorItems($a_do_not_add_object=false)
should be overwritten to add object specific items (repository items are preloaded)
saveObject()
save a new role template object
permSaveObject()
save permission templates of role
updateObject()
update role template object
editObject(ilPropertyFormGUI $form=null)
Create new object.
getTabs()
get tabs abstract method.
initFormRoleTemplate($a_mode=self::FORM_MODE_CREATE)
Init create form.
Class ilObjRoleTemplate.
static _getTranslation($a_role_title)
Class ilObjectGUI Basic methods of all Output classes.
prepareOutput($a_show_subobjects=true)
prepare output
editObject()
edit object
createObject()
create new object form
static lookupTxtById($plugin_id, $lang_var)
static _lookupObjId($a_id)
static _lookupTitle($a_id)
lookup object title
static _lookupType($a_id, $a_reference=false)
lookup object type
This class represents a property form user interface.
static _getOperationList($a_type=null)
get operation list by object type @access public @access static
This class represents a text area property in a property form.
This class represents a text property in a property form.
static formRadioButton($checked, $varname, $value, $onclick=null, $disabled=false)
??? @access public
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static sendSuccess($a_info="", $a_keep=false)
Send Success Message to Screen.
static sendFailure($a_info="", $a_keep=false)
Send Failure Message to Screen.
static switchColor($a_num, $a_css1, $a_css2)
switches style sheets for each even $a_num (used for changing colors of different result rows)
static array_php2js($data)
convert php arrays to javascript arrays
static getImagePath($img, $module_path="", $mode="output", $offline=false)
get image path (for images located in a template directory)
$txt
Definition: error.php:12
$info
Definition: example_052.php:80
if(!is_dir( $entity_dir)) exit("Fatal Error ([A-Za-z0-9]+)\s+" &#(? foreach( $entity_files as $file) $output
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
redirection script todo: (a better solution should control the processing via a xml file)
global $ilSetting
Definition: privfeed.php:17
$cmd
Definition: sahs_server.php:35