ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilRepUtil.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("./classes/class.ilObjectFactory.php");
5 
13 class ilRepUtil
14 {
15 
22  static public function deleteObjects($a_cur_ref_id, $a_ids)
23  {
24  global $ilAppEventHandler, $rbacsystem, $rbacadmin, $log, $ilUser, $tree, $lng,
25  $ilSetting;
26 
27  include_once './payment/classes/class.ilPaymentObject.php';
28  include_once("./Services/Repository/exceptions/class.ilRepositoryException.php");
29 
30  // Remove duplicate ids from array
31  $a_ids = array_unique((array) $a_ids);
32 
33  // FOR ALL SELECTED OBJECTS
34  foreach ($a_ids as $id)
35  {
36  if ($tree->isDeleted($id))
37  {
38  $log->write(__METHOD__.': Object with ref_id: '.$id.' already deleted.');
39  throw new ilRepositoryException($lng->txt("msg_obj_already_deleted"));
40  }
41 
42  // GET COMPLETE NODE_DATA OF ALL SUBTREE NODES
43  $node_data = $tree->getNodeData($id);
44  $subtree_nodes = $tree->getSubTree($node_data);
45 
46  $all_node_data[] = $node_data;
47  $all_subtree_nodes[] = $subtree_nodes;
48 
49  // CHECK DELETE PERMISSION OF ALL OBJECTS
50  foreach ($subtree_nodes as $node)
51  {
52  if($node['type'] == 'rolf')
53  {
54  continue;
55  }
56  if (!$rbacsystem->checkAccess('delete',$node["child"]))
57  {
58  $not_deletable[] = $node["child"];
59  $perform_delete = false;
60  }
61  else if(ilPaymentObject::_isBuyable($node['child']))
62  {
63  $buyable[] = $node['child'];
64  $perform_delete = false;
65  }
66  }
67  }
68 
69  // IF THERE IS ANY OBJECT WITH NO PERMISSION TO DELETE
70  if (count($not_deletable))
71  {
72  $not_deletable = implode(',',$not_deletable);
73  session_unregister("saved_post");
74  throw new ilRepositoryException(
75  $lng->txt("msg_no_perm_delete")." ".$not_deletable."<br/>".$lng->txt("msg_cancel"));
76  }
77 
78  if(count($buyable))
79  {
80  foreach($buyable as $id)
81  {
82  $tmp_object = ilObjectFactory::getInstanceByRefId($id);
83 
84  $titles[] = $tmp_object->getTitle();
85  }
86  $title_str = implode(',',$titles);
87 
88  throw new ilRepositoryException(
89  $lng->txt('msg_obj_not_deletable_sold').' '.$title_str);
90  }
91 
92  // DELETE THEM
93  if (!$all_node_data[0]["type"])
94  {
95 // alex: this branch looks suspicious to me... I deactivate it for
96 // now. Objects that aren't in the tree should overwrite this method.
97 throw new ilRepositoryException($lng->txt("ilRepUtil::deleteObjects: Type information missing."));
98  // OBJECTS ARE NO 'TREE OBJECTS'
99  if ($rbacsystem->checkAccess('delete', $a_cur_ref_id))
100  {
101  foreach($a_ids as $id)
102  {
104  $obj->delete();
105 
106  // write log entry
107  $log->write("ilObjectGUI::confirmedDeleteObject(), deleted obj_id ".$obj->getId().
108  ", type: ".$obj->getType().", title: ".$obj->getTitle());
109  }
110  }
111  else
112  {
113  throw new ilRepositoryException(
114  $lng->txt("no_perm_delete")."<br/>".$lng->txt("msg_cancel"));
115  }
116  }
117  else
118  {
119  // SAVE SUBTREE AND DELETE SUBTREE FROM TREE
120  $affected_ids = array();
121  foreach ($a_ids as $id)
122  {
123  if($tree->isDeleted($id))
124  {
125  $log->write(__METHOD__.': Object with ref_id: '.$id.' already deleted.');
126  throw new ilRepositoryException($lng->txt("msg_obj_already_deleted"));
127  }
128 
129  // DELETE OLD PERMISSION ENTRIES
130  $subnodes = $tree->getSubtree($tree->getNodeData($id));
131 
132  foreach ($subnodes as $subnode)
133  {
134  $rbacadmin->revokePermission($subnode["child"]);
135  // remove item from all user desktops
136  $affected_users = ilUtil::removeItemFromDesktops($subnode["child"]);
137 
138  $affected_ids[$subnode["child"]] = $subnode["child"];
139 
140  // TODO: inform users by mail that object $id was deleted
141  //$mail->sendMail($id,$msg,$affected_users);
142  // should go to appevents at the end
143  }
144 
145  // TODO: needs other handling
146  // This class shouldn't have to know anything about ECS
147  include_once('./Services/WebServices/ECS/classes/class.ilECSContentWriter.php');
149 
150  if(!$tree->saveSubTree($id, true))
151  {
152  $log->write(__METHOD__.': Object with ref_id: '.$id.' already deleted.');
153  throw new ilRepositoryException($lng->txt("msg_obj_already_deleted"));
154  }
155 
156  // write log entry
157  $log->write("ilObjectGUI::confirmedDeleteObject(), moved ref_id ".$id.
158  " to trash");
159 
160  // remove item from all user desktops
161  $affected_users = ilUtil::removeItemFromDesktops($id);
162 
163  $affected_ids[$id] = $id;
164 
165  // TODO: inform users by mail that object $id was deleted
166  //$mail->sendMail($id,$msg,$affected_users);
167  }
168 
169  // send global events
170  foreach ($affected_ids as $aid)
171  {
172  $ilAppEventHandler->raise("Services/Object", "toTrash",
173  array("obj_id" => ilObject::_lookupObjId($aid),
174  "ref_id" => $aid));
175  }
176  // inform other objects in hierarchy about paste operation
177  //$this->object->notify("confirmedDelete", $_GET["ref_id"],$_GET["parent_non_rbac_id"],$_GET["ref_id"],$_SESSION["saved_post"]);
178  }
179 
180  if (!$ilSetting->get('enable_trash'))
181  {
183  }
184  }
185 
191  public function removeObjectsFromSystem($a_ref_ids, $a_from_recovery_folder = false)
192  {
193  global $rbacsystem, $log, $ilAppEventHandler, $tree;
194 
195  $affected_ids = array();
196 
197  // DELETE THEM
198  foreach ($a_ref_ids as $id)
199  {
200  // GET COMPLETE NODE_DATA OF ALL SUBTREE NODES
201  if (!$a_from_recovery_folder)
202  {
203  $saved_tree = new ilTree(-(int)$id);
204  $node_data = $saved_tree->getNodeData($id);
205  $subtree_nodes = $saved_tree->getSubTree($node_data);
206  }
207  else
208  {
209  $node_data = $tree->getNodeData($id);
210  $subtree_nodes = $tree->getSubTree($node_data);
211  }
212 
213  // BEGIN ChangeEvent: Record remove from system.
214  require_once('Services/Tracking/classes/class.ilChangeEvent.php');
216  {
217  // Record write event
218  global $ilUser, $tree;
219  $parent_data = $tree->getParentNodeData($node_data['ref_id']);
220  ilChangeEvent::_recordWriteEvent($node_data['obj_id'], $ilUser->getId(), 'purge',
221  $parent_data['obj_id']);
222  }
223  // END ChangeEvent: Record remove from system.
224 
225  // remember already checked deleted node_ids
226  if (!$a_from_recovery_folder)
227  {
228  $checked[] = -(int) $id;
229  }
230  else
231  {
232  $checked[] = $id;
233  }
234 
235  // dive in recursive manner in each already deleted subtrees and remove these objects too
236  ilRepUtil::removeDeletedNodes($id, $checked, true, $affected_ids);
237 
238  foreach ($subtree_nodes as $node)
239  {
240  if(!$node_obj =& ilObjectFactory::getInstanceByRefId($node["ref_id"],false))
241  {
242  continue;
243  }
244 
245  // write log entry
246  $log->write("ilObjectGUI::removeFromSystemObject(), delete obj_id: ".$node_obj->getId().
247  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
248  "title: ".$node_obj->getTitle());
249  $affected_ids[$node["ref_id"]] = array("ref_id" => $node["ref_id"],
250  "obj_id" => $node_obj->getId(), "type" => $node_obj->getType());
251 
252  // this is due to bug #1860 (even if this will not completely fix it)
253  // and the fact, that media pool folders may find their way into
254  // the recovery folder (what results in broken pools, if the are deleted)
255  // Alex, 2006-07-21
256  if (!$a_from_recovery_folder || $node_obj->getType() != "fold")
257  {
258  $node_obj->delete();
259  }
260  }
261 
262  // Use the saved tree object here (negative tree_id)
263  if (!$a_from_recovery_folder)
264  {
265  $saved_tree->deleteTree($node_data);
266  }
267  else
268  {
269  $tree->deleteTree($node_data);
270  }
271 
272  // write log entry
273  $log->write("ilObjectGUI::removeFromSystemObject(), deleted tree, tree_id: ".$node_data["tree"].
274  ", child: ".$node_data["child"]);
275 
276  }
277 
278  // send global events
279  foreach ($affected_ids as $aid)
280  {
281  $ilAppEventHandler->raise("Services/Object", "delete",
282  array("obj_id" => $aid["obj_id"],
283  "ref_id" => $aid["ref_id"],
284  "type" => $aid["type"]));
285  }
286  }
287 
291  private function removeDeletedNodes($a_node_id, $a_checked, $a_delete_objects,
292  &$a_affected_ids)
293  {
294  global $log, $ilDB, $tree;
295 
296  $q = "SELECT tree FROM tree WHERE parent= ".
297  $ilDB->quote($a_node_id, "integer")." AND tree < 0";
298 
299  $r = $ilDB->query($q);
300 
301  while($row = $ilDB->fetchObject($r))
302  {
303  // only continue recursion if fetched node wasn't touched already!
304  if (!in_array($row->tree,$a_checked))
305  {
306  $deleted_tree = new ilTree($row->tree);
307  $a_checked[] = $row->tree;
308 
309  $row->tree = $row->tree * (-1);
310  $del_node_data = $deleted_tree->getNodeData($row->tree);
311  $del_subtree_nodes = $deleted_tree->getSubTree($del_node_data);
312 
313  ilRepUtil::removeDeletedNodes($row->tree,$a_checked, $a_delete_objects, $a_affected_ids);
314 
315  if ($a_delete_objects)
316  {
317  foreach ($del_subtree_nodes as $node)
318  {
319  $node_obj =& ilObjectFactory::getInstanceByRefId($node["ref_id"]);
320 
321  // write log entry
322  $log->write("ilObjectGUI::removeDeletedNodes(), delete obj_id: ".$node_obj->getId().
323  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
324  "title: ".$node_obj->getTitle());
325  $a_affected_ids[$node["ref_id"]] = array("ref_id" => $node["ref_id"],
326  "obj_id" => $node_obj->getId(), "type" => $node_obj->getType());
327 
328  $node_obj->delete();
329 
330  }
331  }
332 
333  $tree->deleteTree($del_node_data);
334 
335  // write log entry
336  $log->write("ilObjectGUI::removeDeletedNodes(), deleted tree, tree_id: ".$del_node_data["tree"].
337  ", child: ".$del_node_data["child"]);
338  }
339  }
340 
341  return true;
342  }
343 
347  function restoreObjects($a_cur_ref_id, $a_ref_ids)
348  {
349  global $rbacsystem, $log, $ilAppEventHandler, $lng;
350 
351  $cur_obj_id = ilObject::_lookupObjId($a_cur_ref_id);
352 
353  foreach ($a_ref_ids as $id)
354  {
355  $obj_data = ilObjectFactory::getInstanceByRefId($id);
356 
357  if (!$rbacsystem->checkAccess('create', $a_cur_ref_id, $obj_data->getType()))
358  {
359  $no_create[] = ilObject::_lookupTitle(ilObject::_lookupObjId($id));
360  }
361  }
362 
363  if (count($no_create))
364  {
365  include_once("./Services/Repository/exceptions/class.ilRepositoryException.php");
366  throw new ilRepositoryException($lng->txt("msg_no_perm_paste")." ".implode(',',$no_create));
367  }
368 
369  $affected_ids = array();
370 
371  foreach ($a_ref_ids as $id)
372  {
373  $affected_ids[$id] = $id;
374 
375  // INSERT AND SET PERMISSIONS
376  ilRepUtil::insertSavedNodes($id, $a_cur_ref_id, -(int) $id, $affected_ids);
377 
378  // DELETE SAVED TREE
379  $saved_tree = new ilTree(-(int)$id);
380  $saved_tree->deleteTree($saved_tree->getNodeData($id));
381 
382  // BEGIN ChangeEvent: Record undelete.
383  require_once('Services/Tracking/classes/class.ilChangeEvent.php');
385  {
386  global $ilUser, $tree;
387 
388  $node_data = $saved_tree->getNodeData($id);
389  $saved_tree->deleteTree($node_data);
390 
391  // Record undelete event
392  $node_data = $tree->getNodeData($id);
393  $parent_data = $tree->getParentNodeData($node_data['ref_id']);
394  ilChangeEvent::_recordWriteEvent($node_data['obj_id'], $ilUser->getId(), 'undelete',
395  $parent_data['obj_id']);
396  ilChangeEvent::_catchupWriteEvents($cur_obj_id, $ilUser->getId());
397  }
398  // END PATCH ChangeEvent: Record undelete.
399 
400  }
401 
402  // send events
403  foreach ($affected_ids as $id)
404  {
405  // send global event
406  $ilAppEventHandler->raise("Services/Object", "undelete",
407  array("obj_id" => ilObject::_lookupObjId($id), "ref_id" => $id));
408  }
409  }
410 
414  private function insertSavedNodes($a_source_id, $a_dest_id, $a_tree_id, &$a_affected_ids)
415  {
416  global $rbacadmin, $rbacreview, $log, $tree;
417 
418  $tree->insertNode($a_source_id,$a_dest_id, IL_LAST_NODE, true);
419  $a_affected_ids[$a_source_id] = $a_source_id;
420 
421  // write log entry
422  $log->write("ilRepUtil::insertSavedNodes(), restored ref_id $a_source_id from trash");
423 
424  // SET PERMISSIONS
425  $parentRoles = $rbacreview->getParentRoleIds($a_dest_id);
426  $obj =& ilObjectFactory::getInstanceByRefId($a_source_id);
427 
428  foreach ($parentRoles as $parRol)
429  {
430  $ops = $rbacreview->getOperationsOfRole($parRol["obj_id"], $obj->getType(), $parRol["parent"]);
431  $rbacadmin->grantPermission($parRol["obj_id"],$ops,$a_source_id);
432  }
433 
434  $saved_tree = new ilTree($a_tree_id);
435  $childs = $saved_tree->getChilds($a_source_id);
436 
437  foreach ($childs as $child)
438  {
439  ilRepUtil::insertSavedNodes($child["child"],$a_source_id,$a_tree_id,$a_affected_ids);
440  }
441  }
442 
443 
444 }