ILIAS  release_4-3 Revision
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilObject2GUI.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3 
4 include_once("./Services/Object/classes/class.ilObjectGUI.php");
5 
28 abstract class ilObject2GUI extends ilObjectGUI
29 {
30  protected $object_id;
31  protected $node_id;
32  protected $creation_forms = array();
33  protected $id_type = array();
34  protected $parent_id;
35  public $tree;
36  protected $access_handler;
37 
38  const OBJECT_ID = 0;
39  const REPOSITORY_NODE_ID = 1;
40  const WORKSPACE_NODE_ID = 2;
43 
51  function __construct($a_id = 0, $a_id_type = self::REPOSITORY_NODE_ID, $a_parent_node_id = 0)
52  {
53  global $objDefinition, $tpl, $ilCtrl, $ilErr, $lng, $ilTabs, $tree, $ilAccess;
54 
55  if (!isset($ilErr))
56  {
57  $ilErr = new ilErrorHandling();
58  $ilErr->setErrorHandling(PEAR_ERROR_CALLBACK,array($ilErr,'errorHandler'));
59  }
60  else
61  {
62  $this->ilErr =& $ilErr;
63  }
64 
65  $this->id_type = $a_id_type;
66  $this->parent_id = $a_parent_node_id;
67  $this->type = $this->getType();
68  $this->html = "";
69 
70  // use globals instead?
71  $this->tabs_gui = $ilTabs;
72  $this->objDefinition = $objDefinition;
73  $this->tpl = $tpl;
74  $this->ctrl = $ilCtrl;
75  $this->lng = $lng;
76 
77  $params = array();
78  switch($this->id_type)
79  {
80  case self::REPOSITORY_NODE_ID:
81  $this->node_id = $a_id;
82  $this->object_id = ilObject::_lookupObjectId($this->node_id);
83  $this->tree = $tree;
84  $this->access_handler = $ilAccess;
85  $this->call_by_reference = true; // needed for prepareOutput()
86  $params[] = "ref_id";
87  break;
88 
89  case self::REPOSITORY_OBJECT_ID:
90  $this->object_id = $a_id;
91  $this->tree = $tree;
92  $this->access_handler = $ilAccess;
93  $params[] = "obj_id"; // ???
94  break;
95 
96  case self::WORKSPACE_NODE_ID:
97  global $ilUser;
98  $this->node_id = $a_id;
99  include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
100  $this->tree = new ilWorkspaceTree($ilUser->getId());
101  $this->object_id = $this->tree->lookupObjectId($this->node_id);
102  include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php";
103  $this->access_handler = new ilWorkspaceAccessHandler($this->tree);
104  $params[] = "wsp_id";
105  break;
106 
107  case self::WORKSPACE_OBJECT_ID:
108  global $ilUser;
109  $this->object_id = $a_id;
110  include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceTree.php";
111  $this->tree = new ilWorkspaceTree($ilUser->getId());
112  include_once "Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php";
113  $this->access_handler = new ilWorkspaceAccessHandler($this->tree);
114  $params[] = "obj_id"; // ???
115  break;
116 
117  case self::OBJECT_ID:
118  $this->object_id = $a_id;
119  include_once "Services/Object/classes/class.ilDummyAccessHandler.php";
120  $this->access_handler = new ilDummyAccessHandler();
121  $params[] = "obj_id";
122  break;
123  }
124  $this->ctrl->saveParameter($this, $params);
125 
126 
127 
128  // old stuff for legacy code (obsolete?)
129  if(!$this->object_id)
130  {
131  $this->creation_mode = true;
132  }
133  if($this->node_id)
134  {
135  // add parent node id if missing
136  if(!$this->parent_id && $this->tree)
137  {
138  $this->parent_id = $this->tree->getParentId($this->node_id);
139  }
140  }
141  $this->ref_id = $this->node_id;
142  $this->obj_id = $this->object_id;
143 
144 
145 
146  $this->assignObject();
147 
148  // set context
149  if (is_object($this->object))
150  {
151  $this->ctrl->setContext($this->object->getId(), $this->object->getType());
152  }
153 
154  $this->afterConstructor();
155  }
156 
160  protected function afterConstructor()
161  {
162  }
163 
167  function &executeCommand()
168  {
169  global $rbacsystem;
170 
171  $next_class = $this->ctrl->getNextClass($this);
172  $cmd = $this->ctrl->getCmd();
173 
174  $this->prepareOutput();
175 
176  switch($next_class)
177  {
178  case "ilworkspaceaccessgui";
179  if($this->node_id)
180  {
181  $this->tabs_gui->activateTab("id_permissions");
182 
183  include_once('./Services/PersonalWorkspace/classes/class.ilWorkspaceAccessGUI.php');
184  $wspacc = new ilWorkspaceAccessGUI($this->node_id, $this->getAccessHandler());
185  $this->ctrl->forwardCommand($wspacc);
186  break;
187  }
188 
189  default:
190  if(!$cmd)
191  {
192  $cmd = "render";
193  }
194  return $this->$cmd();
195  }
196 
197  return true;
198  }
199 
203  final protected function assignObject()
204  {
205  if ($this->object_id != 0)
206  {
207  switch($this->id_type)
208  {
209  case self::OBJECT_ID:
210  case self::REPOSITORY_OBJECT_ID:
211  case self::WORKSPACE_OBJECT_ID:
212  $this->object = ilObjectFactory::getInstanceByObjId($this->object_id);
213  break;
214 
215  case self::REPOSITORY_NODE_ID:
216  $this->object = ilObjectFactory::getInstanceByRefId($this->node_id);
217  break;
218 
219  case self::WORKSPACE_NODE_ID:
220  // to be discussed
221  $this->object = ilObjectFactory::getInstanceByObjId($this->object_id);
222  break;
223  }
224  }
225  }
226 
232  protected function getAccessHandler()
233  {
234  return $this->access_handler;
235  }
236 
240  final protected function setLocator()
241  {
242  global $ilLocator, $tpl;
243 
244  if ($this->omit_locator)
245  {
246  return;
247  }
248 
249  switch($this->id_type)
250  {
251  case self::REPOSITORY_NODE_ID:
252  $ref_id = $this->node_id
253  ? $this->node_id
255  $ilLocator->addRepositoryItems($ref_id);
256 
257  // not so nice workaround: todo: handle $ilLocator as tabs in ilTemplate
258  if ($_GET["admin_mode"] == "" &&
259  strtolower($this->ctrl->getCmdClass()) == "ilobjrolegui")
260  {
261  $this->ctrl->setParameterByClass("ilobjrolegui",
262  "rolf_ref_id", $_GET["rolf_ref_id"]);
263  $this->ctrl->setParameterByClass("ilobjrolegui",
264  "obj_id", $_GET["obj_id"]);
265  $ilLocator->addItem($this->lng->txt("role"),
266  $this->ctrl->getLinkTargetByClass(array("ilpermissiongui",
267  "ilobjrolegui"), "perm"));
268  }
269 
270  // in workspace this is done in ilPersonalWorkspaceGUI
271  if($this->object_id)
272  {
273  $this->addLocatorItems();
274  }
275  $tpl->setLocator();
276 
277  break;
278 
279  case self::WORKSPACE_NODE_ID:
280  // :TODO:
281  break;
282  }
283 
284 
285  }
286 
290  public function delete()
291  {
292  switch($this->id_type)
293  {
294  case self::REPOSITORY_NODE_ID:
295  case self::REPOSITORY_OBJECT_ID:
296  return parent::deleteObject();
297 
298  case self::WORKSPACE_NODE_ID:
299  case self::WORKSPACE_OBJECT_ID:
300  return $this->deleteConfirmation();
301 
302  case self::OBJECT_ID:
303  // :TODO: should this ever occur?
304  break;
305  }
306  }
307 
313  protected function deleteConfirmation()
314  {
315  global $lng, $tpl, $objDefinition;
316 
317  $node_id = (int)$_REQUEST["item_ref_id"];
318  if (!$node_id)
319  {
320  ilUtil::sendFailure($lng->txt("no_checkbox"), true);
321  $this->ctrl->redirect($this, "");
322  }
323 
324  // on cancel or fail we return to parent node
325  $parent_node = $this->tree->getParentId($node_id);
326  $this->ctrl->setParameter($this, "wsp_id", $parent_node);
327 
328  include_once("./Services/Utilities/classes/class.ilConfirmationGUI.php");
329  $cgui = new ilConfirmationGUI();
330  $cgui->setHeaderText($lng->txt("info_delete_sure")."<br/>".
331  $lng->txt("info_delete_warning_no_trash"));
332 
333  $cgui->setFormAction($this->ctrl->getFormAction($this));
334  $cgui->setCancel($lng->txt("cancel"), "cancelDelete");
335  $cgui->setConfirm($lng->txt("confirm"), "confirmedDelete");
336 
337  $a_ids = array($node_id);
338  foreach ($a_ids as $node_id)
339  {
340  $children = $this->tree->getSubTree($this->tree->getNodeData($node_id));
341  foreach($children as $child)
342  {
343  $node_id = $child["wsp_id"];
344  $obj_id = $this->tree->lookupObjectId($node_id);
346  $title = call_user_func(array(ilObjectFactory::getClassByType($type),'_lookupTitle'), $obj_id);
347 
348  // if anything fails, abort the whole process
349  if(!$this->checkPermissionBool("delete", "", "", $node_id))
350  {
351  ilUtil::sendFailure($lng->txt("msg_no_perm_delete")." ".$title, true);
352  $this->ctrl->redirect($this);
353  }
354 
355  $cgui->addItem("id[]", $node_id, $title,
356  ilObject::_getIcon($obj_id, "small", $type),
357  $lng->txt("icon")." ".$lng->txt("obj_".$type));
358  }
359  }
360 
361  $tpl->setContent($cgui->getHTML());
362  }
363 
367  public function confirmedDelete()
368  {
369  switch($this->id_type)
370  {
371  case self::REPOSITORY_NODE_ID:
372  case self::REPOSITORY_OBJECT_ID:
374 
375  case self::WORKSPACE_NODE_ID:
376  case self::WORKSPACE_OBJECT_ID:
377  return $this->deleteConfirmedObjects();
378 
379  case self::OBJECT_ID:
380  // :TODO: should this ever occur?
381  break;
382  }
383  }
384 
390  protected function deleteConfirmedObjects()
391  {
392  global $lng, $objDefinition;
393 
394  if(sizeof($_POST["id"]))
395  {
396  foreach($_POST["id"] as $node_id)
397  {
398  $node = $this->tree->getNodeData($node_id);
399 
400  // tree/reference
401  $this->tree->deleteReference($node_id);
402  $this->tree->deleteTree($node);
403 
404  // permission
405  $this->getAccessHandler()->removePermission($node_id);
406 
407  // object
408  $object = ilObjectFactory::getInstanceByObjId($node["obj_id"], false);
409  if($object)
410  {
411  $object->delete();
412  }
413  }
414 
415  ilUtil::sendSuccess($lng->txt("msg_removed"), true);
416  }
417  else
418  {
419  ilUtil::sendFailure($lng->txt("no_checkbox"), true);
420  }
421 
422  $this->ctrl->redirect($this, "");
423  }
424 
425  public function getHTML() { return parent::getHTML(); }
426 
430  final public function withReferences() { return parent::withReferences(); }
431  final public function setCreationMode($a_mode = true) { return parent::setCreationMode($a_mode); }
432  final public function getCreationMode() { return parent::getCreationMode(); }
433  final protected function prepareOutput() { return parent::prepareOutput(); }
434  protected function setTitleAndDescription() { return parent::setTitleAndDescription(); }
435  final protected function showUpperIcon() { return parent::showUpperIcon(); }
436 // final private function showMountWebfolderIcon() { return parent::showMountWebfolderIcon(); }
437  final protected function omitLocator($a_omit = true) { return parent::omitLocator($a_omit); }
438  final protected function getTargetFrame($a_cmd, $a_target_frame = "") { return parent::getTargetFrame($a_cmd, $a_target_frame); }
439  final protected function setTargetFrame($a_cmd, $a_target_frame) { return parent::setTargetFrame($a_cmd, $a_target_frame); }
440  final public function isVisible() { return parent::isVisible(); }
441  final protected function getCenterColumnHTML() { return parent::getCenterColumnHTML(); }
442  final protected function getRightColumnHTML() { return parent::getRightColumnHTML(); }
443  final protected function setColumnSettings($column_gui) { return parent::setColumnSettings($column_gui); }
444  final protected function checkPermission($a_perm, $a_cmd = "") { return parent::checkPermission($a_perm, $a_cmd); }
445 
446  // -> ilContainerGUI
447  final protected function showPossibleSubObjects() { return parent::showPossibleSubObjects(); }
448  // -> ilRepUtilGUI
449  final public function trash() { return parent::trashObject(); } // done
450  // -> ilRepUtil
451  final public function undelete() { return parent::undeleteObject(); } // done
452  final public function cancelDelete() { return parent::cancelDeleteObject(); } // ok
453  final public function removeFromSystem() { return parent::removeFromSystemObject(); } // done
454  final protected function redirectToRefId() { return parent::redirectToRefId(); } // ok
455 
456  // -> stefan
457  final protected function fillCloneTemplate($a_tpl_varname,$a_type) { return parent::fillCloneTemplate($a_tpl_varname,$a_type); }
458  final protected function fillCloneSearchTemplate($a_tpl_varname,$a_type) { return parent::fillCloneSearchTemplate($a_tpl_varname,$a_type); }
459  final protected function searchCloneSource() { return parent::searchCloneSourceObject(); }
460  final public function cloneAll() { return parent::cloneAllObject(); }
461  final protected function buildCloneSelect($existing_objs) { return parent::buildCloneSelect($existing_objs); }
462 
463  // -> ilAdministration
464  final private function displayList() { return parent::displayList(); }
465 // final private function setAdminTabs() { return parent::setAdminTabs(); }
466 // final public function getAdminTabs($a) { return parent::getAdminTabs($a); }
467  final protected function addAdminLocatorItems() { return parent::addAdminLocatorItems(); }
468 
472  public function view()
473  {
474  switch($this->id_type)
475  {
476  case self::REPOSITORY_NODE_ID:
477  case self::REPOSITORY_OBJECT_ID:
478  return parent::viewObject();
479 
480  case self::WORKSPACE_NODE_ID:
481  case self::WORKSPACE_OBJECT_ID:
482  return $this->render();
483 
484  case self::OBJECT_ID:
485  // :TODO: should this ever occur? do nothing or edit() ?!
486  break;
487  }
488  }
489 
495  protected function setTabs()
496  {
497  global $ilTabs, $lng;
498 
499  switch($this->id_type)
500  {
501  case self::REPOSITORY_NODE_ID:
502  case self::REPOSITORY_OBJECT_ID:
503  if ($this->checkPermissionBool("edit_permission"))
504  {
505  $ilTabs->addTab("id_permissions",
506  $lng->txt("perm_settings"),
507  $this->ctrl->getLinkTargetByClass(array(get_class($this), "ilpermissiongui"), "perm"));
508  }
509  break;
510 
511  case self::WORKSPACE_NODE_ID:
512  case self::WORKSPACE_OBJECT_ID:
513  // only files and blogs can be shared for now
514  if ($this->checkPermissionBool("edit_permission") && in_array($this->type, array("file", "blog")) && $this->node_id)
515  {
516  $ilTabs->addTab("id_permissions",
517  $lng->txt("wsp_permissions"),
518  $this->ctrl->getLinkTargetByClass(array(get_class($this), "ilworkspaceaccessgui"), "share"));
519  }
520  break;
521  }
522  }
523 
527 // final private function setSubObjects() { die("ilObject2GUI::setSubObjects() is deprecated."); }
528 // final public function getFormAction() { die("ilObject2GUI::getFormAction() is deprecated."); }
529 // final protected function setFormAction() { die("ilObject2GUI::setFormAction() is deprecated."); }
530  final protected function getReturnLocation() { die("ilObject2GUI::getReturnLocation() is deprecated."); }
531  final protected function setReturnLocation() { die("ilObject2GUI::setReturnLocation() is deprecated."); }
532  final protected function showActions() { die("ilObject2GUI::showActions() is deprecated."); }
533  final protected function getTitlesByRefId() { die("ilObject2GUI::getTitlesByRefId() is deprecated."); }
534  final protected function getTabs() {nj(); die("ilObject2GUI::getTabs() is deprecated."); }
535  final protected function __showButton() { die("ilObject2GUI::__showButton() is deprecated."); }
536  final protected function hitsperpageObject() { die("ilObject2GUI::hitsperpageObject() is deprecated."); }
537  final protected function __initTableGUI() { die("ilObject2GUI::__initTableGUI() is deprecated."); }
538  final protected function __setTableGUIBasicData() { die("ilObject2GUI::__setTableGUIBasicData() is deprecated."); }
539  final protected function __showClipboardTable() { die("ilObject2GUI::__showClipboardTable() is deprecated."); }
540 
544  protected function addLocatorItems() {}
545 
549  abstract function getType();
550 
554 // final private function permObject() { parent::permObject(); }
555 // final private function permSaveObject() { parent::permSaveObject(); }
556 // final private function infoObject() { parent::infoObject(); }
557 // final private function __buildRoleFilterSelect() { parent::__buildRoleFilterSelect(); }
558 // final private function __filterRoles() { parent::__filterRoles(); }
559 // final private function ownerObject() { parent::ownerObject(); }
560 // final private function changeOwnerObject() { parent::changeOwnerObject(); }
561 // final private function addRoleObject() { parent::addRoleObject(); }
562 // final private function setActions() { die("ilObject2GUI::setActions() is deprecated."); }
563 // final protected function getActions() { die("ilObject2GUI::getActions() is deprecated."); }
564 
568  public function create() { parent::createObject(); }
569  public function save() { parent::saveObject(); }
570  public function edit() { parent::editObject(); }
571  public function update() { parent::updateObject(); }
572  public function cancel() { parent::cancelObject(); }
573 
582  protected function initCreationForms($a_new_type)
583  {
584  $forms = parent::initCreationForms($a_new_type);
585 
586  // cloning doesn't work in workspace yet
587  if($this->id_type == self::WORKSPACE_NODE_ID)
588  {
589  unset($forms[self::CFORM_CLONE]);
590  }
591 
592  return $forms;
593  }
594 
600  function importFile()
601  {
602  parent::importFileObject($this->parent_id);
603  }
604 
611  protected function putObjectInTree(ilObject $a_obj, $a_parent_node_id = null)
612  {
613  global $rbacreview, $ilUser, $objDefinition;
614 
615  $this->object_id = $a_obj->getId();
616 
617  if(!$a_parent_node_id)
618  {
619  $a_parent_node_id = $this->parent_id;
620  }
621 
622  // add new object to custom parent container
623  if((int)$_REQUEST["crtptrefid"])
624  {
625  $a_parent_node_id = (int)$_REQUEST["crtptrefid"];
626  }
627 
628  switch($this->id_type)
629  {
630  case self::REPOSITORY_NODE_ID:
631  case self::REPOSITORY_OBJECT_ID:
632  if(!$this->node_id)
633  {
634  $a_obj->createReference();
635  $this->node_id = $a_obj->getRefId();
636  }
637  $a_obj->putInTree($a_parent_node_id);
638  $a_obj->setPermissions($a_parent_node_id);
639 
640  // rbac log
641  include_once "Services/AccessControl/classes/class.ilRbacLog.php";
642  $rbac_log_roles = $rbacreview->getParentRoleIds($this->node_id, false);
643  $rbac_log = ilRbacLog::gatherFaPa($this->node_id, array_keys($rbac_log_roles), true);
644  ilRbacLog::add(ilRbacLog::CREATE_OBJECT, $this->node_id, $rbac_log);
645 
646  $this->ctrl->setParameter($this, "ref_id", $this->node_id);
647  break;
648 
649  case self::WORKSPACE_NODE_ID:
650  case self::WORKSPACE_OBJECT_ID:
651  if(!$this->node_id)
652  {
653  $this->node_id = $this->tree->insertObject($a_parent_node_id, $this->object_id);
654  }
655  $this->getAccessHandler()->setPermissions($a_parent_node_id, $this->node_id);
656 
657  $this->ctrl->setParameter($this, "wsp_id", $this->node_id);
658  break;
659 
660  case self::OBJECT_ID:
661  // do nothing
662  break;
663  }
664 
665  // BEGIN ChangeEvent: Record save object.
666  require_once('Services/Tracking/classes/class.ilChangeEvent.php');
667  ilChangeEvent::_recordWriteEvent($this->object_id, $ilUser->getId(), 'create');
668  // END ChangeEvent: Record save object.
669 
670  // use forced callback after object creation
671  if($_REQUEST["crtcb"])
672  {
673  $callback_type = ilObject::_lookupType((int)$_REQUEST["crtcb"], true);
674  $class_name = "ilObj".$objDefinition->getClassName($callback_type)."GUI";
675  $location = $objDefinition->getLocation($callback_type);
676  include_once($location."/class.".$class_name.".php");
677  if (in_array(strtolower($class_name), array("ilobjitemgroupgui")))
678  {
679  $callback_obj = new $class_name((int)$_REQUEST["crtcb"]);
680  }
681  else
682  {
683  $callback_obj = new $class_name(null, (int)$_REQUEST["crtcb"], true, false);
684  }
685  $callback_obj->afterSaveCallback($a_obj);
686  }
687  }
688 
698  protected function checkPermissionBool($a_perm, $a_cmd = "", $a_type = "", $a_node_id = null)
699  {
700  global $ilUser;
701 
702  if($a_perm == "create")
703  {
704  if(!$a_node_id)
705  {
706  $a_node_id = $this->parent_id;
707  }
708  if($a_node_id)
709  {
710  return $this->getAccessHandler()->checkAccess($a_perm."_".$a_type, $a_cmd, $a_node_id);
711  }
712  }
713  else
714  {
715 
716  if (!$a_node_id)
717  {
718  $a_node_id = $this->node_id;
719  }
720  if($a_node_id)
721  {
722  return $this->getAccessHandler()->checkAccess($a_perm, $a_cmd, $a_node_id);
723  }
724  }
725 
726  // if we do not have a node id, check if current user is owner
727  if($this->obj_id && $this->object->getOwner() == $ilUser->getId())
728  {
729  return true;
730  }
731  return false;
732  }
733 
741  protected function initHeaderAction($a_sub_type = null, $a_sub_id = null)
742  {
743  global $ilAccess;
744 
745  if($this->id_type == self::WORKSPACE_NODE_ID)
746  {
747  if(!$this->creation_mode && $this->object_id)
748  {
749  include_once "Services/Object/classes/class.ilCommonActionDispatcherGUI.php";
751  $this->getAccessHandler(), $this->getType(), $this->node_id, $this->object_id);
752 
753  $dispatcher->setSubObject($a_sub_type, $a_sub_id);
754 
755  include_once "Services/Object/classes/class.ilObjectListGUI.php";
756  ilObjectListGUI::prepareJSLinks($this->ctrl->getLinkTarget($this, "redrawHeaderAction", "", true),
757  $this->ctrl->getLinkTargetByClass(array("ilcommonactiondispatchergui", "ilnotegui"), "", "", true, false),
758  $this->ctrl->getLinkTargetByClass(array("ilcommonactiondispatchergui", "iltagginggui"), "", "", true, false));
759 
760  $lg = $dispatcher->initHeaderAction();
761 
762  if(is_object($lg))
763  {
764  // to enable add to desktop / remove from desktop
765  if($this instanceof ilDesktopItemHandling)
766  {
767  $lg->setContainerObject($this);
768  }
769 
770  // for activation checks see ilObjectGUI
771  // $lg->enableComments(true);
772  $lg->enableNotes(true);
773  // $lg->enableTags(true);
774  }
775 
776  return $lg;
777  }
778  }
779  else
780  {
781  return parent::initHeaderAction();
782  }
783  }
784 
788  protected function redrawHeaderAction()
789  {
791  }
792 
793  protected function getPermanentLinkWidget($a_append = null, $a_center = false)
794  {
795  if($this->id_type == self::WORKSPACE_NODE_ID)
796  {
797  $a_append .= "_wsp";
798  }
799 
800  include_once('Services/PermanentLink/classes/class.ilPermanentLinkGUI.php');
801  $plink = new ilPermanentLinkGUI($this->getType(), $this->node_id , $a_append);
802  $plink->setIncludePermanentLinkText(false);
803  $plink->setAlignCenter($a_center);
804  return $plink->getHTML();
805  }
806 }
807 
808 ?>