ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
class.ilObjectDAV.php
Go to the documentation of this file.
1 <?php
2 // BEGIN WebDAV
3 /*
4  +-----------------------------------------------------------------------------+
5  | ILIAS open source |
6  +-----------------------------------------------------------------------------+
7  | Copyright (c) 1998-2005 ILIAS open source, University of Cologne |
8  | |
9  | This program is free software; you can redistribute it and/or |
10  | modify it under the terms of the GNU General Public License |
11  | as published by the Free Software Foundation; either version 2 |
12  | of the License, or (at your option) any later version. |
13  | |
14  | This program is distributed in the hope that it will be useful, |
15  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17  | GNU General Public License for more details. |
18  | |
19  | You should have received a copy of the GNU General Public License |
20  | along with this program; if not, write to the Free Software |
21  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
22  +-----------------------------------------------------------------------------+
23 */
24 
38 {
42  public $refId;
43 
47  public $obj;
48 
53  public $isDebug = false;
54 
60  public function __construct($refId, $obj = null)
61  {
62  if (is_object($obj)) {
63  $this->writelog('<constructor>(' . $refId . ',' . get_class($obj) . ')');
64  }
65  $this->refId = $refId;
66  $this->obj =&$obj;
67  }
68 
69 
74  public function getRefId()
75  {
76  return $this->refId;
77  }
82  public function getObjectId()
83  {
84  return ($this->obj == null) ? null : $this->obj->getId();
85  }
86 
93  public function getNodeId()
94  {
95  return 0;
96  }
97 
104  public function initFromNull()
105  {
106  $this->obj->setPermissions($this->getRefId());
107  }
108 
109 
110 
111 
116  public function read()
117  {
118  global $DIC;
119  $ilias = $DIC['ilias'];
120 
121  if (is_null($this->obj)) {
122  $this->obj =&$ilias->obj_factory->getInstanceByRefId($this->getRefId());
123  $this->obj->read();
124  }
125  }
130  public function write()
131  {
132  $this->writelog('write() refid=' . $this->refId);
133  $this->obj->update();
134  }
135 
136 
142  public function getResourceName()
143  {
144  return $this->obj->getUntranslatedTitle();
145  }
151  public function setResourceName($name)
152  {
153  $this->writelog('setResourceName(' . $name . ')');
154  return $this->obj->setTitle($name);
155  }
161  public function getDisplayName()
162  {
163  return $this->obj->getTitle();
164  }
165 
171  public function getCreationTimestamp()
172  {
173  return strtotime($this->obj->getCreateDate());
174  }
175 
181  public function getModificationTimestamp()
182  {
183  return strtotime($this->obj->getLastUpdateDate());
184  }
185 
191  public function getResourceType()
192  {
193  return "";
194  }
195 
201  public function isCollection()
202  {
203  return $this->getResourceType() == 'collection';
204  }
210  public function isFile()
211  {
212  return $this->getResourceType() == '';
213  }
218  public function isNullResource()
219  {
220  return $this->getResourceType() == 'null';
221  }
222 
227  public function getContentType()
228  {
229  return 'application/x-non-readable';//'application/octet-stream';
230  }
235  public function setContentType($type)
236  {
237  // subclass responsibility
238  }
243  public function setContentLength($length)
244  {
245  // subclass responsibility
246  }
251  public function getContentLength()
252  {
253  return 0;
254  }
259  public function getContentStream()
260  {
261  return null;
262  }
267  public function getContentOutputStream()
268  {
269  return null;
270  }
281  {
282  // subclass responsibility
283  }
289  public function getContentData()
290  {
291  return null;
292  }
293 
297  public function isOnline()
298  {
299  return true;
300  }
301 
312  public function isPermitted($operations, $type = '')
313  {
314  // Mount instructions are always visible
315  if (isset($_GET['mount-instructions'])) {
316  return true;
317  }
318 
319  // The 'visible' operation is only permitted if the object is online,
320  // or if the user is also permitted the perform the 'write' operation.
321  if (false) { // old implementation deactivated
322  $ops = explode(',', $operations);
323  if (in_array('visible', $ops) && !in_array('write', $ops)) {
324  if (!$this->isOnline()) {
325  $operations .= ',write';
326  }
327  }
328 
329  global $DIC;
330  $rbacsystem = $DIC['rbacsystem'];
331  return $rbacsystem->checkAccess($operations, $this->getRefId(), $type);
332  } else { // this one fixes bug #5367
333  $GLOBALS['DIC']['ilLog']->write('Checking permission for ref_id: ' . $this->getRefId());
334  $GLOBALS['DIC']['ilLog']->write("Operations: " . print_r($operations, true));
335 
336  global $DIC;
337  $ilAccess = $DIC['ilAccess'];
338  $operations = explode(",", $operations . "");
339  foreach ($operations as $operation) {
340  if (!$ilAccess->checkAccess($operation, '', $this->getRefId(), $type)) {
341  $GLOBALS['DIC']['ilLog']->write(__METHOD__ . ': Permission denied for user ' . $GLOBALS['DIC']['ilUser']->getId());
342  return false;
343  }
344  }
345  return true;
346  }
347  }
348 
352  public function getILIASType()
353  {
354  if ($this->obj instanceof ilObject) {
355  return $this->obj->getType();
356  }
357  $GLOBALS['DIC']['ilLog']->write(__METHOD__ . ': Invalid object given, class=' . get_class($this->obj));
358  $GLOBALS['DIC']['ilLog']->logStack();
359  }
363  public function getILIASCollectionType()
364  {
365  return 'fold';
366  }
370  public function getILIASFileType()
371  {
372  return 'file';
373  }
374 
379  public function createNewVersion()
380  {
381  }
382 
383 
390  public function createCollection($name)
391  {
392  global $DIC;
393  $tree = $DIC['tree'];
394 
395  // create and insert Folder in tree
396  require_once 'Modules/Folder/classes/class.ilObjFolder.php';
397  $newObj = new ilObjFolder(0);
398  $newObj->setType($this->getILIASCollectionType());
399  $newObj->setTitle($name);
400  //$newObj->setDescription('');
401  $newObj->create();
402  $newObj->createReference();
403  $newObj->setPermissions($this->getRefId());
404  $newObj->putInTree($this->getRefId());
405 
406  require_once 'class.ilObjFolderDAV.php';
407  return new ilObjFolderDAV($newObj->getRefId(), $newObj);
408  }
415  public function createFile($name)
416  {
417  global $DIC;
418  $tree = $DIC['tree'];
419 
420  // create and insert Folder in tree
421  require_once 'Modules/File/classes/class.ilObjFile.php';
422  $newObj = new ilObjFile(0);
423  $newObj->setType($this->getILIASFileType());
424  $newObj->setTitle($name);
425  $newObj->setFileName($name);
426  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
427  $mime = ilMimeTypeUtil::getMimeType("", $name, 'application/octet-stream');
428  //$newObj->setFileType('application/octet-stream');
429  $newObj->setFileType($mime);
430  //$newObj->setDescription('');
431  $newObj->create();
432  $newObj->createReference();
433  $newObj->setPermissions($this->getRefId());
434  $newObj->putInTree($this->getRefId());
435  //$newObj->createDirectory();
436 
437  require_once 'class.ilObjFileDAV.php';
438  $objDAV = new ilObjFileDAV($newObj->getRefId(), $newObj);
439  /*
440  $fs = $objDAV->getContentOutputStream();
441  fwrite($fs,' ');
442  fclose($fs);
443  */
444  return $objDAV;
445  }
452  public function createFileFromNull($name, &$nullDAV)
453  {
454  global $DIC;
455  $tree = $DIC['tree'];
456 
457  // create and insert Folder in tree
458  require_once 'Modules/File/classes/class.ilObjFile.php';
459  $objDAV =&$nullDAV->convertToILIASType($this->getRefId(), $this->getILIASFileType());
460  $objDAV->initFromNull();
461  return $objDAV;
462  }
470  public function createNull($name)
471  {
472  global $DIC;
473  $tree = $DIC['tree'];
474 
475  // create and insert Folder in tree
476  require_once './Services/Object/classes/class.ilObject.php';
477  $newObj = new ilObject(0);
478  $newObj->setType('null');
479  $newObj->setTitle($name);
480  $newObj->create();
481  $newObj->createReference();
482  $newObj->setPermissions($this->getRefId());
483  $newObj->putInTree($this->getRefId());
484 
485  require_once 'class.ilObjNullDAV.php';
486  $objDAV = new ilObjNullDAV($newObj->getRefId(), $newObj);
487 
488  return $objDAV;
489  }
490 
491 
492 
498  public function remove($objDAV)
499  {
500  global $DIC;
501  $tree = $DIC['tree'];
502  $rbacadmin = $DIC['rbacadmin'];
503 
504  $subnodes = $tree->getSubTree($tree->getNodeData($objDAV->getRefId()));
505  foreach ($subnodes as $node) {
506  $rbacadmin->revokePermission($node["child"]);
507  $affectedUsers = ilUtil::removeItemFromDesktops($node["child"]);
508  }
509  $tree->saveSubTree($objDAV->getRefId());
510  $tree->deleteTree($tree->getNodeData($objDAV->getRefId()));
511  }
512 
520  public function addCopy(&$objDAV, $newName = null)
521  {
522  $this->writelog("addCopy($objDAV,$newName) ....");
523  global $DIC;
524  $rbacadmin = $DIC['rbacadmin'];
525  $tree = $DIC['tree'];
526  $revIdMapping = array();
527  $newRef = $this->cloneNodes($objDAV->getRefId(), $this->getRefId(), $revIdMapping, $newName);
528  //$rbacadmin->adjustMovedObjectPermissions($newRef, $tree->getParentId($objDAV->getRefId()));
529  return self::createObject($newRef, $objDAV->getILIASType());
530  $this->writelog('... addCopy done.');
531  }
532 
543  public function cloneNodes($srcRef, $dstRef, &$mapping, $newName=null)
544  {
545  $this->writelog("cloneNodes($srcRef,$dstRef,$mapping,$newName)");
546  global $DIC;
547  $tree = $DIC['tree'];
548  global $DIC;
549  $ilias = $DIC['ilias'];
550 
551  // clone the source node
552  $srcObj =&$ilias->obj_factory->getInstanceByRefId($srcRef);
553  $this->writelog('cloneNodes cloning srcRef=' . $srcRef . ' dstRef=' . $dstRef . '...');
554  $newObj = $srcObj->cloneObject($dstRef);
555  $newRef = $newObj->getRefId();
556 
557  // We must immediately apply a new name to the object, to
558  // prevent confusion of WebDAV clients about having two objects with identical
559  // name in the repository.
560  $this->writelog("cloneNodes newname not null? " . (!is_null($newName)));
561  if (!is_null($newName)) {
562  $newObjDAV = self::createObject($newRef, $srcObj->getType());
563  $newObjDAV->setResourceName($newName);
564  $newObjDAV->write();
565  }
566  unset($srcObj);
567  $mapping[$newRef] = $srcRef;
568 
569  // clone all children of the source node
570  $children = $tree->getChilds($srcRef);
571  foreach ($tree->getChilds($srcRef) as $child) {
572  // Don't clone role folders, because it does not make sense to clone local roles
573  // FIXME - Maybe it does make sense (?)
574  if ($child["type"] != 'rolf') {
575  $this->cloneNodes($child["ref_id"], $newRef, $mapping, null);
576  } else {
577  if (count($rolf = $tree->getChildsByType($newRef, "rolf"))) {
578  $mapping[$rolf[0]["ref_id"]] = $child["ref_id"];
579  }
580  }
581  }
582  $this->writelog('cloneNodes ...cloned srcRef=' . $srcRef . ' dstRef=' . $dstRef . ' newRef=' . $newRef);
583  return $newRef;
584  }
585 
593  public function addMove(&$objDAV, $newName = null)
594  {
595  global $DIC;
596  $tree = $DIC['tree'];
597  global $DIC;
598  $rbacadmin = $DIC['rbacadmin'];
599  global $DIC;
600  $ilias = $DIC['ilias'];
601  global $DIC;
602  $log = $DIC['log'];
603 
604  $this->writelog('addMove(' . $objDAV->getRefId() . ' to ' . $this->getRefId() . ', newName=' . $newName . ')');
605 
606  // Step 0:Assign new name to moved object
607  if (!is_null($newName)) {
608  $objDAV->setResourceName($newName);
609  $objDAV->write();
610  }
611 
612  // Step 1: Store old parent
613  $old_parent = $tree->getParentId($objDAV->getRefId());
614 
615  // Step 2: Move the tree
616  $tree->moveTree($objDAV->getRefId(), $this->getRefId());
617 
618  // Step 3: Repair permissions
619  $rbacadmin->adjustMovedObjectPermissions($objDAV->getRefId(), $old_parent);
620 
621  /*
622  // STEP 1: Move subtree to trash
623  $this->writelog('addMove('.$objDAV->getRefId().' to '.$this->getRefId().') step 1: move subtree to trash');
624  $subnodes = $tree->getSubTree($tree->getNodeData($objDAV->getRefId()));
625  foreach ($subnodes as $node)
626  {
627  $rbacadmin->revokePermission($node["child"]);
628  $affectedUsers = ilUtil::removeItemFromDesktops($node["child"]);
629  }
630  $tree->saveSubTree($objDAV->getRefId());
631  $tree->deleteTree($tree->getNodeData($objDAV->getRefId()));
632 
633  // STEP 2: Move subtree to new location
634  // TODO: this whole put in place again stuff needs revision. Permission settings get lost.
635  $this->writelog('addMove() step 2: move subtree to new location');
636  // put top node to dest
637  $rbacadmin->revokePermission($subnodes[0]['child']);
638  $obj_data =& $ilias->obj_factory->getInstanceByRefId($subnodes[0]['child']);
639  $obj_data->putInTree($this->getRefId());
640  $obj_data->setPermissions($this->getRefId());
641  array_shift($subnodes);
642 
643  // put all sub nodes to their parent (of which we have moved top already to dest).
644  foreach ($subnodes as $node)
645  {
646  $rbacadmin->revokePermission($node['child']);
647  $obj_data =& $ilias->obj_factory->getInstanceByRefId($node['child']);
648  $obj_data->putInTree($node['parent']);
649  $obj_data->setPermissions($node['parent']);
650  }
651 
652  // STEP 3: Remove trashed objects from system
653  $this->writelog('addMove('.$objDAV->getRefID().') step 3: remove trashed objects from system');
654  require_once 'Services/Tree/classes/class.ilTree.php';
655  $trashTree = new ilTree(- (int) $objDAV->getRefId());
656  $node = $trashTree->getNodeData($objDAV->getRefId());
657  $subnodes = $trashTree->getSubTree($node);
658 
659  // remember already checked deleted node_ids
660  $checked[] = -(int) $objDAV->getRefId();
661 
662  // dive in recursive manner in each already deleted subtrees and remove these objects too
663  $this->removeDeletedNodes($objDAV->getRefId(), $checked, false);
664 
665  // delete trash tree
666  $tree->deleteTree($node);
667  $this->writelog('addMove('.$objDAV->getRefID().') all 3 steps done');
668  */
669  }
670 
679  public function removeDeletedNodes($a_node_id, $a_checked, $a_delete_objects = true)
680  {
681  global $DIC;
682  $ilDB = $DIC['ilDB'];
683  $log = $DIC['log'];
684  $ilias = $DIC['ilias'];
685  $tree = $DIC['tree'];
686 
687  $query = "SELECT tree FROM tree WHERE parent = ? AND tree < 0 ";
688  $sta = $ilDB->prepare($query, array('integer','integer'));
689  $res = $ilDB->execute($sta, array(
690  $a_node_id,
691  0));
692 
693 
694  while ($row = $ilDB->fetchObject($res)) {
695  // only continue recursion if fetched node wasn't touched already!
696  if (!in_array($row->tree, $a_checked)) {
697  $deleted_tree = new ilTree($row->tree);
698  $a_checked[] = $row->tree;
699 
700  $row->tree = $row->tree * (-1);
701  $del_node_data = $deleted_tree->getNodeData($row->tree);
702  $del_subtree_nodes = $deleted_tree->getSubTree($del_node_data);
703 
704  $this->removeDeletedNodes($row->tree, $a_checked);
705 
706  if ($a_delete_objects) {
707  foreach ($del_subtree_nodes as $node) {
708  $node_obj =&$ilias->obj_factory->getInstanceByRefId($node["ref_id"]);
709 
710  // write log entry
711  /*$this->writelog("removeDeletedNodes(), delete obj_id: ".$node_obj->getId().
712  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
713  "title: ".$node_obj->getTitle());
714  */
715  $node_obj->delete();
716  }
717  }
718 
719  $tree->deleteTree($del_node_data);
720 
721  // write log entry
722  //$this->writelog("removeDeletedNodes(), deleted tree, tree_id: ".$del_node_data["tree"].", child: ".$del_node_data["child"]);
723  }
724  }
725 
726  return true;
727  }
734  public function children()
735  {
736  // FIXME: Remove duplicate entries from this list, because of RFC2518, chapter 5.2
737  // If a duplicate is found, the older object must win. We use the object
738  // id to determine this. This is based on the assumption, that new objects
739  // have higher object id's then older objects.
740 
741  global $DIC;
742  $tree = $DIC['tree'];
743 
744  $childrenDAV = array();
745  // Performance optimization. We sort the children using PHP instead of using the database.
746  //$childrenData =& $tree->getChilds($this->getRefId(),'title');
747  $childrenData =&$tree->getChilds($this->getRefId(), '');
748  foreach ($childrenData as $data) {
749  $childDAV =&self::createObject($data['ref_id'], $data['type']);
750  if (!is_null($childDAV)) {
751  // Note: We must not assign with =& here, because this will cause trouble
752  // when other functions attempt to work with the $childrenDAV array.
753  $childrenDAV[] = $childDAV;
754  }
755  }
756  return $childrenDAV;
757  }
767  public function childrenWithPermission($operations, $type ='')
768  {
769  //$this->writelog('@'.$this->getRefId().'.childrenWithPermission('.$operations.','.$type.')');
770  $childrenDAV = $this->children();
771  $permittedChildrenDAV = array();
772  foreach ($childrenDAV as $childDAV) {
773  if ($childDAV->isPermitted($operations, $type)) {
774  $permittedChildrenDAV[] = $childDAV;
775  }
776  }
777  //$this->writelog('@'.$this->getRefId().'.childrenWithPermission():'.count($permittedChildrenDAV).' children');
778  return $permittedChildrenDAV;
779  }
780 
789  public static function createObject($refId, $type)
790  {
791  $newObj = null;
792 
793  switch ($type) {
794  case 'mountPoint':
795  require_once 'class.ilObjMountPointDAV.php';
796  $newObj = new ilObjMountPointDAV($refId, null);
797  break;
798  case 'root':
799  require_once 'class.ilObjRootDAV.php';
800  $newObj = new ilObjRootDAV($refId, null);
801  break;
802  case 'cat':
803  require_once 'class.ilObjCategoryDAV.php';
804  $newObj = new ilObjCategoryDAV($refId, null);
805  break;
806  case 'fold':
807  require_once 'class.ilObjFolderDAV.php';
808  $newObj = new ilObjFolderDAV($refId, null);
809  break;
810  case 'crs':
811  require_once 'class.ilObjCourseDAV.php';
812  $newObj = new ilObjCourseDAV($refId, null);
813  break;
814  case 'grp':
815  require_once 'class.ilObjGroupDAV.php';
816  $newObj = new ilObjGroupDAV($refId, null);
817  break;
818  case 'file':
819  require_once 'class.ilObjFileDAV.php';
820  $newObj = new ilObjFileDAV($refId, null);
821  break;
822  case 'null':
823  require_once 'class.ilObjNullDAV.php';
824  $newObj = new ilObjNullDAV($refId, null);
825  break;
826  default:
827  break;
828  }
829  if (!is_null($newObj)) {
830  $newObj->read();
831  }
832  return $newObj;
833  }
840  public function writelog($message)
841  {
842  if ($this->isDebug) {
843  global $DIC;
844  $log = $DIC['log'];
845  $ilias = $DIC['ilias'];
846  $log->write(
847  $ilias->account->getLogin()
848  . ' DAV .' . get_class($this) . ' ' . str_replace("\n", ";", $message)
849  );
850  /*
851  $fh = fopen('/opt/ilias/log/ilias.log', 'a');
852  fwrite($fh, date('Y-m-d h:i:s '));
853  fwrite($fh, str_replace("\n",";",$message));
854  fwrite($fh, "\n\n");
855  fclose($fh);
856  */
857  }
858  }
859 
864  public function __toString()
865  {
866  return get_class($this) . '#' . $this->getObjectId();
867  }
868 }
869 // END WebDAV
getObjectId()
Returns the object id of this object.
children()
Returns the children of this object.
static createObject($refId, $type)
Static factory method to create a DAV object for a given refId and type.
getContentStream()
Returns the content of the object as a stream.
__toString()
This method is needed, because the object class in PHP 5.2 does not have a default implementation of ...
write()
Writes the object data.
static removeItemFromDesktops($a_id)
removes object from all user&#39;s desktops public
Class ilObjFolder.
createNewVersion()
Creates a new version of the object.
__construct($refId, $obj=null)
Constructor.
$type
global $DIC
Definition: saml.php:7
$_GET["client_id"]
getResourceType()
Returns the DAV resource type of this object.
childrenWithPermission($operations, $type='')
Returns the children of this object with the specified permissions.
createFile($name)
Creates a dav file as a child of this object.
cloneNodes($srcRef, $dstRef, &$mapping, $newName=null)
Recursively clones all nodes of the RBAC tree.
$GLOBALS['loaded']
Global hash that tracks already loaded includes.
createFileFromNull($name, &$nullDAV)
Creates a dav file as a child of this object.
isNullResource()
Returns true if this is a null resource.
getILIASFileType()
Returns the ilias type for files that can be created as children of this object.
createCollection($name)
Creates a dav collection as a child of this object.
getDisplayName()
Returns the display name of this object.
getContentType()
Returns the mime type of the content of this object.
setContentLength($length)
Sets the length (number of bytes) of the content of this object.
static getMimeType($a_file='', $a_filename='', $a_mime='')
if($format !==null) $name
Definition: metadata.php:146
catch(Exception $e) $message
foreach($_POST as $key=> $value) $res
getModificationTimestamp()
Returns the modification date of this object as a Unix timestamp.
getResourceName()
Returns the resource name of this object.
read()
Reads the object data.
getILIASCollectionType()
Returns the ilias type for collections that can be created as children of this object.
isFile()
Returns true if this object is a DAV file.
createNull($name)
Creates a dav null object as a child of this object.
isCollection()
Returns true if this object is a DAV collection.
addMove(&$objDAV, $newName=null)
Adds (moves) the specified object as a child to this object.
$query
getContentLength()
Returns the number of bytes of the content.
setContentType($type)
Sets the mime type of the content of this object.
Tree class data representation in hierachical trees using the Nested Set Model with Gaps by Joe Celco...
Create styles array
The data for the language used.
removeDeletedNodes($a_node_id, $a_checked, $a_delete_objects=true)
remove already deleted objects within the objects in trash recursive function
isPermitted($operations, $type='')
Returns whether a specific operation is permitted for the current user.
getContentOutputStream()
Returns an output stream to the content.
global $ilDB
$refId
Refid to the object.
setResourceName($name)
Sets the resource name of this object.
initFromNull()
Initializes the object after it has been converted from NULL.
$isDebug
The ObjectDAV prints lots of log messages to the ilias log, if this variable is set to true...
getNodeId()
Returns the node id of this object.
getContentOutputStreamLength()
Returns the length of the content output stream.
isOnline()
Returns true if the object is online.
getCreationTimestamp()
Returns the creation date of this object as a Unix timestamp.
getILIASType()
Returns the ilias type of the current object.
getContentData()
Returns the content of the object as a byte array.
writelog($message)
Writes a message to the logfile.,.
$obj
Application layer object.
addCopy(&$objDAV, $newName=null)
Adds a copy of the specified object as a child to this object.
getRefId()
Returns the ref id of this object.