ILIAS  Release_4_4_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
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 
37 {
41  var $refId;
42 
46  var $obj;
47 
52  var $isDebug = false;
53 
59  function ilObjectDAV($refId, $obj = null)
60  {
61  if (is_object($obj))
62  {
63  $this->writelog('<constructor>('.$refId.','.get_class($obj).')');
64  }
65  $this->refId = $refId;
66  $this->obj =& $obj;
67  }
68 
69 
74  function getRefId()
75  {
76  return $this->refId;
77  }
82  function getObjectId()
83  {
84  return ($this->obj == null) ? null : $this->obj->getId();
85  }
86 
93  function getNodeId()
94  {
95  return 0;
96  }
97 
104  function initFromNull()
105  {
106  $this->obj->setPermissions($this->getRefId());
107  }
108 
109 
110 
111 
116  function read()
117  {
118  global $ilias;
119 
120  if (is_null($this->obj))
121  {
122  $this->obj =& $ilias->obj_factory->getInstanceByRefId($this->getRefId());
123  $this->obj->read();
124  }
125  }
130  function write()
131  {
132  $this->writelog('write() refid='.$this->refId);
133  $this->obj->update();
134  }
135 
136 
142  function getResourceName()
143  {
144  return $this->obj->getUntranslatedTitle();
145  }
151  function setResourceName($name)
152  {
153  $this->writelog('setResourceName('.$name.')');
154  return $this->obj->setTitle($name);
155  }
161  function getDisplayName()
162  {
163  return $this->obj->getTitle();
164  }
165 
172  {
173  return strtotime($this->obj->getCreateDate());
174  }
175 
182  {
183  return strtotime($this->obj->getLastUpdateDate());
184  }
185 
191  function getResourceType()
192  {
193  return "";
194  }
195 
201  function isCollection()
202  {
203  return $this->getResourceType() == 'collection';
204  }
210  function isFile()
211  {
212  return $this->getResourceType() == '';
213  }
218  function isNullResource()
219  {
220  return $this->getResourceType() == 'null';
221  }
222 
227  function getContentType()
228  {
229  return 'application/x-non-readable';//'application/octet-stream';
230  }
235  function setContentType($type)
236  {
237  // subclass responsibility
238  }
243  function setContentLength($length)
244  {
245  // subclass responsibility
246  }
251  function getContentLength()
252  {
253  return 0;
254  }
259  function getContentStream()
260  {
261  return null;
262  }
268  {
269  return null;
270  }
281  {
282  // subclass responsibility
283  }
289  function getContentData()
290  {
291  return null;
292  }
293 
297  function isOnline()
298  {
299  return true;
300  }
301 
312  function isPermitted($operations, $type = '')
313  {
314  // Mount instructions are always visible
315  if(isset($_GET['mount-instructions']))
316  {
317  return true;
318  }
319 
320  // The 'visible' operation is only permitted if the object is online,
321  // or if the user is also permitted the perform the 'write' operation.
322  if (false) // old implementation deactivated
323  {
324  $ops = explode(',',$operations);
325  if (in_array('visible',$ops) && ! in_array('write',$ops))
326  {
327  if (! $this->isOnline()) {
328  $operations .= ',write';
329  }
330  }
331 
332  global $rbacsystem;
333  return $rbacsystem->checkAccess($operations, $this->getRefId(), $type);
334  }
335  else // this one fixes bug #5367
336  {
337  $GLOBALS['ilLog']->write('Checking permission for ref_id: '.$this->getRefId());
338  $GLOBALS['ilLog']->write("Operations: ".print_r($operations,true));
339 
340  global $ilAccess;
341  $operations = explode(",",$operations."");
342  foreach ($operations as $operation)
343  {
344  if (!$ilAccess->checkAccess($operation, '', $this->getRefId(), $type))
345  {
346  $GLOBALS['ilLog']->write(__METHOD__.': Permission denied for user '.$GLOBALS['ilUser']->getId());
347  return false;
348  }
349  }
350  return true;
351  }
352  }
353 
357  function getILIASType()
358  {
359  if($this->obj instanceof ilObject)
360  {
361  return $this->obj->getType();
362  }
363  $GLOBALS['ilLog']->write(__METHOD__.': Invalid object given, class='.get_class($this->obj));
364  $GLOBALS['ilLog']->logStack();
365  }
370  {
371  return 'fold';
372  }
376  function getILIASFileType()
377  {
378  return 'file';
379  }
380 
385  function createNewVersion() {
386  }
387 
388 
395  function createCollection($name)
396  {
397  global $tree;
398 
399  // create and insert Folder in tree
400  require_once 'Modules/Folder/classes/class.ilObjFolder.php';
401  $newObj = new ilObjFolder(0);
402  $newObj->setType($this->getILIASCollectionType());
403  $newObj->setTitle($name);
404  //$newObj->setDescription('');
405  $newObj->create();
406  $newObj->createReference();
407  $newObj->setPermissions($this->getRefId());
408  $newObj->putInTree($this->getRefId());
409 
410  require_once 'class.ilObjFolderDAV.php';
411  return new ilObjFolderDAV($newObj->getRefId(), $newObj);
412  }
419  function createFile($name)
420  {
421  global $tree;
422 
423  // create and insert Folder in tree
424  require_once 'Modules/File/classes/class.ilObjFile.php';
425  $newObj = new ilObjFile(0);
426  $newObj->setType($this->getILIASFileType());
427  $newObj->setTitle($name);
428  $newObj->setFileName($name);
429  include_once("./Services/Utilities/classes/class.ilMimeTypeUtil.php");
430  $mime = ilMimeTypeUtil::getMimeType("", $name, 'application/octet-stream');
431  //$newObj->setFileType('application/octet-stream');
432  $newObj->setFileType($mime);
433  //$newObj->setDescription('');
434  $newObj->create();
435  $newObj->createReference();
436  $newObj->setPermissions($this->getRefId());
437  $newObj->putInTree($this->getRefId());
438  //$newObj->createDirectory();
439 
440  require_once 'class.ilObjFileDAV.php';
441  $objDAV = new ilObjFileDAV($newObj->getRefId(), $newObj);
442  /*
443  $fs = $objDAV->getContentOutputStream();
444  fwrite($fs,' ');
445  fclose($fs);
446  */
447  return $objDAV;
448  }
455  function createFileFromNull($name, &$nullDAV)
456  {
457  global $tree;
458 
459  // create and insert Folder in tree
460  require_once 'Modules/File/classes/class.ilObjFile.php';
461  $objDAV =& $nullDAV->convertToILIASType($this->getRefId(), $this->getILIASFileType());
462  $objDAV->initFromNull();
463  return $objDAV;
464  }
472  function createNull($name)
473  {
474  global $tree;
475 
476  // create and insert Folder in tree
477  require_once './Services/Object/classes/class.ilObject.php';
478  $newObj = new ilObject(0);
479  $newObj->setType('null');
480  $newObj->setTitle($name);
481  $newObj->create();
482  $newObj->createReference();
483  $newObj->setPermissions($this->getRefId());
484  $newObj->putInTree($this->getRefId());
485 
486  require_once 'class.ilObjNullDAV.php';
487  $objDAV = new ilObjNullDAV($newObj->getRefId(), $newObj);
488 
489  return $objDAV;
490  }
491 
492 
493 
499  function remove($objDAV)
500  {
501  global $tree, $rbacadmin;
502 
503  $subnodes = $tree->getSubTree($tree->getNodeData($objDAV->getRefId()));
504  foreach ($subnodes as $node)
505  {
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  function addCopy(&$objDAV, $newName = null)
521  {
522  $this->writelog("addCopy($objDAV,$newName) ....");
523  global $rbacadmin, $tree;
524  $revIdMapping = array();
525  $newRef = $this->cloneNodes($objDAV->getRefId(),$this->getRefId(),$revIdMapping, $newName);
526  //$rbacadmin->adjustMovedObjectPermissions($newRef, $tree->getParentId($objDAV->getRefId()));
527  return $this->createObject($newRef, $objDAV->getILIASType());
528  $this->writelog('... addCopy done.');
529  }
530 
541  function cloneNodes($srcRef,$dstRef,&$mapping, $newName=null)
542  {
543  $this->writelog("cloneNodes($srcRef,$dstRef,$mapping,$newName)");
544  global $tree;
545  global $ilias;
546 
547  // clone the source node
548  $srcObj =& $ilias->obj_factory->getInstanceByRefId($srcRef);
549  $this->writelog('cloneNodes cloning srcRef='.$srcRef.' dstRef='.$dstRef.'...');
550  $newObj = $srcObj->cloneObject($dstRef);
551  $newRef = $newObj->getRefId();
552 
553  // We must immediately apply a new name to the object, to
554  // prevent confusion of WebDAV clients about having two objects with identical
555  // name in the repository.
556  $this->writelog("cloneNodes newname not null? ".(! is_null($newName)));
557  if (! is_null($newName))
558  {
559  $newObjDAV = $this->createObject($newRef, $srcObj->getType());
560  $newObjDAV->setResourceName($newName);
561  $newObjDAV->write();
562  }
563  unset($srcObj);
564  $mapping[$newRef] = $srcRef;
565 
566  // clone all children of the source node
567  $children = $tree->getChilds($srcRef);
568  foreach ($tree->getChilds($srcRef) as $child)
569  {
570  // Don't clone role folders, because it does not make sense to clone local roles
571  // FIXME - Maybe it does make sense (?)
572  if ($child["type"] != 'rolf')
573  {
574  $this->cloneNodes($child["ref_id"],$newRef,$mapping,null);
575  }
576  else
577  {
578  if (count($rolf = $tree->getChildsByType($newRef,"rolf")))
579  {
580  $mapping[$rolf[0]["ref_id"]] = $child["ref_id"];
581  }
582  }
583  }
584  $this->writelog('cloneNodes ...cloned srcRef='.$srcRef.' dstRef='.$dstRef.' newRef='.$newRef);
585  return $newRef;
586  }
587 
595  function addMove(&$objDAV, $newName = null)
596  {
597  global $tree;
598  global $rbacadmin;
599  global $ilias;
600  global $log;
601 
602  $this->writelog('addMove('.$objDAV->getRefId().' to '.$this->getRefId().', newName='.$newName.')');
603 
604  // Step 0:Assign new name to moved object
605  if (! is_null($newName))
606  {
607  $objDAV->setResourceName($newName);
608  $objDAV->write();
609  }
610 
611  // Step 1: Store old parent
612  $old_parent = $tree->getParentId($objDAV->getRefId());
613 
614  // Step 2: Move the tree
615  $tree->moveTree($objDAV->getRefId(),$this->getRefId());
616 
617  // Step 3: Repair permissions
618  $rbacadmin->adjustMovedObjectPermissions($objDAV->getRefId(), $old_parent);
619 
620  /*
621  // STEP 1: Move subtree to trash
622  $this->writelog('addMove('.$objDAV->getRefId().' to '.$this->getRefId().') step 1: move subtree to trash');
623  $subnodes = $tree->getSubTree($tree->getNodeData($objDAV->getRefId()));
624  foreach ($subnodes as $node)
625  {
626  $rbacadmin->revokePermission($node["child"]);
627  $affectedUsers = ilUtil::removeItemFromDesktops($node["child"]);
628  }
629  $tree->saveSubTree($objDAV->getRefId());
630  $tree->deleteTree($tree->getNodeData($objDAV->getRefId()));
631 
632  // STEP 2: Move subtree to new location
633  // TODO: this whole put in place again stuff needs revision. Permission settings get lost.
634  $this->writelog('addMove() step 2: move subtree to new location');
635  // put top node to dest
636  $rbacadmin->revokePermission($subnodes[0]['child']);
637  $obj_data =& $ilias->obj_factory->getInstanceByRefId($subnodes[0]['child']);
638  $obj_data->putInTree($this->getRefId());
639  $obj_data->setPermissions($this->getRefId());
640  array_shift($subnodes);
641 
642  // put all sub nodes to their parent (of which we have moved top already to dest).
643  foreach ($subnodes as $node)
644  {
645  $rbacadmin->revokePermission($node['child']);
646  $obj_data =& $ilias->obj_factory->getInstanceByRefId($node['child']);
647  $obj_data->putInTree($node['parent']);
648  $obj_data->setPermissions($node['parent']);
649  }
650 
651  // STEP 3: Remove trashed objects from system
652  $this->writelog('addMove('.$objDAV->getRefID().') step 3: remove trashed objects from system');
653  require_once 'Services/Tree/classes/class.ilTree.php';
654  $trashTree = new ilTree(- (int) $objDAV->getRefId());
655  $node = $trashTree->getNodeData($objDAV->getRefId());
656  $subnodes = $trashTree->getSubTree($node);
657 
658  // remember already checked deleted node_ids
659  $checked[] = -(int) $objDAV->getRefId();
660 
661  // dive in recursive manner in each already deleted subtrees and remove these objects too
662  $this->removeDeletedNodes($objDAV->getRefId(), $checked, false);
663 
664  // delete trash tree
665  $tree->deleteTree($node);
666  $this->writelog('addMove('.$objDAV->getRefID().') all 3 steps done');
667  */
668  }
669 
678  function removeDeletedNodes($a_node_id, $a_checked, $a_delete_objects = true)
679  {
680  global $ilDB, $log, $ilias, $tree;
681 
682  $query = "SELECT tree FROM tree WHERE parent = ? AND tree < 0 ";
683  $sta = $ilDB->prepare($query,array('integer','integer'));
684  $res = $ilDB->execute($sta,array(
685  $a_node_id,
686  0));
687 
688 
689  while($row = $ilDB->fetchObject($res))
690  {
691  // only continue recursion if fetched node wasn't touched already!
692  if (!in_array($row->tree,$a_checked))
693  {
694  $deleted_tree = new ilTree($row->tree);
695  $a_checked[] = $row->tree;
696 
697  $row->tree = $row->tree * (-1);
698  $del_node_data = $deleted_tree->getNodeData($row->tree);
699  $del_subtree_nodes = $deleted_tree->getSubTree($del_node_data);
700 
701  $this->removeDeletedNodes($row->tree,$a_checked);
702 
703  if ($a_delete_objects)
704  {
705  foreach ($del_subtree_nodes as $node)
706  {
707  $node_obj =& $ilias->obj_factory->getInstanceByRefId($node["ref_id"]);
708 
709  // write log entry
710  /*$this->writelog("removeDeletedNodes(), delete obj_id: ".$node_obj->getId().
711  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
712  "title: ".$node_obj->getTitle());
713  */
714  $node_obj->delete();
715  }
716  }
717 
718  $tree->deleteTree($del_node_data);
719 
720  // write log entry
721  //$this->writelog("removeDeletedNodes(), deleted tree, tree_id: ".$del_node_data["tree"].", child: ".$del_node_data["child"]);
722  }
723  }
724 
725  return true;
726  }
733  function children()
734  {
735  // FIXME: Remove duplicate entries from this list, because of RFC2518, chapter 5.2
736  // If a duplicate is found, the older object must win. We use the object
737  // id to determine this. This is based on the assumption, that new objects
738  // have higher object id's then older objects.
739 
740  global $tree;
741 
742  $childrenDAV = array();
743  // Performance optimization. We sort the children using PHP instead of using the database.
744  //$childrenData =& $tree->getChilds($this->getRefId(),'title');
745  $childrenData =& $tree->getChilds($this->getRefId(),'');
746  foreach ($childrenData as $data)
747  {
748  $childDAV =& $this->createObject($data['ref_id'],$data['type']);
749  if (! is_null($childDAV))
750  {
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  }
757  return $childrenDAV;
758  }
768  function childrenWithPermission($operations, $type ='')
769  {
770  //$this->writelog('@'.$this->getRefId().'.childrenWithPermission('.$operations.','.$type.')');
771  $childrenDAV = $this->children();
772  $permittedChildrenDAV = array();
773  foreach ($childrenDAV as $childDAV)
774  {
775  if ($childDAV->isPermitted($operations, $type))
776  {
777  $permittedChildrenDAV[] = $childDAV;
778  }
779 
780  }
781  //$this->writelog('@'.$this->getRefId().'.childrenWithPermission():'.count($permittedChildrenDAV).' children');
782  return $permittedChildrenDAV;
783  }
784 
793  function createObject($refId, $type)
794  {
795  $newObj = null;
796  switch ($type)
797  {
798  case 'mountPoint' :
799  require_once 'class.ilObjMountPointDAV.php';
800  $newObj = new ilObjMountPointDAV($refId,null);
801  break;
802  case 'root' :
803  require_once 'class.ilObjRootDAV.php';
804  $newObj = new ilObjRootDAV($refId,null);
805  break;
806  case 'cat' :
807  require_once 'class.ilObjCategoryDAV.php';
808  $newObj = new ilObjCategoryDAV($refId,null);
809  break;
810  case 'fold' :
811  require_once 'class.ilObjFolderDAV.php';
812  $newObj = new ilObjFolderDAV($refId,null);
813  break;
814  case 'crs' :
815  require_once 'class.ilObjCourseDAV.php';
816  $newObj = new ilObjCourseDAV($refId,null);
817  break;
818  case 'grp' :
819  require_once 'class.ilObjGroupDAV.php';
820  $newObj = new ilObjGroupDAV($refId,null);
821  break;
822  case 'file' :
823  require_once 'class.ilObjFileDAV.php';
824  $newObj = new ilObjFileDAV($refId,null);
825  break;
826  case 'null' :
827  require_once 'class.ilObjNullDAV.php';
828  $newObj = new ilObjNullDAV($refId,null);
829  break;
830  default :
831  break;
832  }
833  if (! is_null($newObj))
834  {
835  $newObj->read();
836  }
837  return $newObj;
838  }
845  function writelog($message)
846  {
847  if ($this->isDebug)
848  {
849  global $log, $ilias;
850  $log->write(
851  $ilias->account->getLogin()
852  .' DAV .'.get_class($this).' '.str_replace("\n",";",$message)
853  );
854  /*
855  $fh = fopen('/opt/ilias/log/ilias.log', 'a');
856  fwrite($fh, date('Y-m-d h:i:s '));
857  fwrite($fh, str_replace("\n",";",$message));
858  fwrite($fh, "\n\n");
859  fclose($fh);
860  */
861  }
862  }
863 
868  function __toString() {
869  return get_class($this).'#'.$this->getObjectId();
870  }
871 }
872 // END WebDAV
873 ?>