ILIAS  Release_5_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("./Services/Object/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 './Services/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  ilSession::clear("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.ilECSObjectSettings.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');
215  // Record write event
216  global $ilUser, $tree;
217  $parent_data = $tree->getParentNodeData($node_data['ref_id']);
218  ilChangeEvent::_recordWriteEvent($node_data['obj_id'], $ilUser->getId(), 'purge',
219  $parent_data['obj_id']);
220  // END ChangeEvent: Record remove from system.
221 
222  // remember already checked deleted node_ids
223  if (!$a_from_recovery_folder)
224  {
225  $checked[] = -(int) $id;
226  }
227  else
228  {
229  $checked[] = $id;
230  }
231 
232  // dive in recursive manner in each already deleted subtrees and remove these objects too
233  ilRepUtil::removeDeletedNodes($id, $checked, true, $affected_ids);
234 
235  foreach ($subtree_nodes as $node)
236  {
237  if(!$node_obj =& ilObjectFactory::getInstanceByRefId($node["ref_id"],false))
238  {
239  continue;
240  }
241 
242  // write log entry
243  $log->write("ilObjectGUI::removeFromSystemObject(), delete obj_id: ".$node_obj->getId().
244  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
245  "title: ".$node_obj->getTitle());
246  $affected_ids[$node["ref_id"]] = array("ref_id" => $node["ref_id"],
247  "obj_id" => $node_obj->getId(), "type" => $node_obj->getType());
248 
249  // this is due to bug #1860 (even if this will not completely fix it)
250  // and the fact, that media pool folders may find their way into
251  // the recovery folder (what results in broken pools, if the are deleted)
252  // Alex, 2006-07-21
253  if (!$a_from_recovery_folder || $node_obj->getType() != "fold")
254  {
255  $node_obj->delete();
256  }
257  }
258 
259  // Use the saved tree object here (negative tree_id)
260  if (!$a_from_recovery_folder)
261  {
262  $saved_tree->deleteTree($node_data);
263  }
264  else
265  {
266  $tree->deleteTree($node_data);
267  }
268 
269  // write log entry
270  $log->write("ilObjectGUI::removeFromSystemObject(), deleted tree, tree_id: ".$node_data["tree"].
271  ", child: ".$node_data["child"]);
272 
273  }
274 
275  // send global events
276  foreach ($affected_ids as $aid)
277  {
278  $ilAppEventHandler->raise("Services/Object", "delete",
279  array("obj_id" => $aid["obj_id"],
280  "ref_id" => $aid["ref_id"],
281  "type" => $aid["type"]));
282  }
283  }
284 
288  private function removeDeletedNodes($a_node_id, $a_checked, $a_delete_objects,
289  &$a_affected_ids)
290  {
291  global $log, $ilDB, $tree;
292 
293  $q = "SELECT tree FROM tree WHERE parent= ".
294  $ilDB->quote($a_node_id, "integer")." AND tree < 0";
295 
296  $r = $ilDB->query($q);
297 
298  while($row = $ilDB->fetchObject($r))
299  {
300  // only continue recursion if fetched node wasn't touched already!
301  if (!in_array($row->tree,$a_checked))
302  {
303  $deleted_tree = new ilTree($row->tree);
304  $a_checked[] = $row->tree;
305 
306  $row->tree = $row->tree * (-1);
307  $del_node_data = $deleted_tree->getNodeData($row->tree);
308  $del_subtree_nodes = $deleted_tree->getSubTree($del_node_data);
309 
310  ilRepUtil::removeDeletedNodes($row->tree,$a_checked, $a_delete_objects, $a_affected_ids);
311 
312  if ($a_delete_objects)
313  {
314  foreach ($del_subtree_nodes as $node)
315  {
316  $node_obj =& ilObjectFactory::getInstanceByRefId($node["ref_id"]);
317 
318  // write log entry
319  $log->write("ilObjectGUI::removeDeletedNodes(), delete obj_id: ".$node_obj->getId().
320  ", ref_id: ".$node_obj->getRefId().", type: ".$node_obj->getType().", ".
321  "title: ".$node_obj->getTitle());
322  $a_affected_ids[$node["ref_id"]] = array("ref_id" => $node["ref_id"],
323  "obj_id" => $node_obj->getId(), "type" => $node_obj->getType());
324 
325  $node_obj->delete();
326 
327  }
328  }
329 
330  $tree->deleteTree($del_node_data);
331 
332  // write log entry
333  $log->write("ilObjectGUI::removeDeletedNodes(), deleted tree, tree_id: ".$del_node_data["tree"].
334  ", child: ".$del_node_data["child"]);
335  }
336  }
337 
338  return true;
339  }
340 
344  function restoreObjects($a_cur_ref_id, $a_ref_ids)
345  {
346  global $rbacsystem, $log, $ilAppEventHandler, $lng, $tree;
347 
348  $cur_obj_id = ilObject::_lookupObjId($a_cur_ref_id);
349 
350  foreach ($a_ref_ids as $id)
351  {
352  $obj_data = ilObjectFactory::getInstanceByRefId($id);
353 
354  if (!$rbacsystem->checkAccess('create', $a_cur_ref_id, $obj_data->getType()))
355  {
356  $no_create[] = ilObject::_lookupTitle(ilObject::_lookupObjId($id));
357  }
358  }
359 
360  if (count($no_create))
361  {
362  include_once("./Services/Repository/exceptions/class.ilRepositoryException.php");
363  throw new ilRepositoryException($lng->txt("msg_no_perm_paste")." ".implode(',',$no_create));
364  }
365 
366  $affected_ids = array();
367 
368  foreach ($a_ref_ids as $id)
369  {
370  $affected_ids[$id] = $id;
371 
372  // INSERT AND SET PERMISSIONS
373  ilRepUtil::insertSavedNodes($id, $a_cur_ref_id, -(int) $id, $affected_ids);
374 
375  // DELETE SAVED TREE
376  $saved_tree = new ilTree(-(int)$id);
377  $saved_tree->deleteTree($saved_tree->getNodeData($id));
378 
379  include_once './Services/Object/classes/class.ilObjectFactory.php';
380  $factory = new ilObjectFactory();
381  $ref_obj = $factory->getInstanceByRefId($id,FALSE);
382  if($ref_obj instanceof ilObject)
383  {
384  $lroles = $GLOBALS['rbacreview']->getRolesOfRoleFolder($id,FALSE);
385  foreach($lroles as $role_id)
386  {
387  include_once './Services/AccessControl/classes/class.ilObjRole.php';
388  $role = new ilObjRole($role_id);
389  $role->setParent($id);
390  $role->delete();
391  }
392  $parent_ref = $GLOBALS['tree']->getParentId($id);
393  if($parent_ref)
394  {
395  $ref_obj->setPermissions($parent_ref);
396  }
397  }
398 
399  // BEGIN ChangeEvent: Record undelete.
400  require_once('Services/Tracking/classes/class.ilChangeEvent.php');
401  global $ilUser;
402 
403 
406  $ilUser->getId(),
407  'undelete',
408  ilObject::_lookupObjId($tree->getParentId($id))
409  );
411  $cur_obj_id,
412  $ilUser->getId());
413  // END PATCH ChangeEvent: Record undelete.
414 
415  }
416 
417  // send events
418  foreach ($affected_ids as $id)
419  {
420  // send global event
421  $ilAppEventHandler->raise("Services/Object", "undelete",
422  array("obj_id" => ilObject::_lookupObjId($id), "ref_id" => $id));
423  }
424  }
425 
429  private function insertSavedNodes($a_source_id, $a_dest_id, $a_tree_id, &$a_affected_ids)
430  {
431  global $rbacadmin, $rbacreview, $log, $tree;
432 
433  $tree->insertNode($a_source_id,$a_dest_id, IL_LAST_NODE, true);
434  $a_affected_ids[$a_source_id] = $a_source_id;
435 
436  // write log entry
437  $log->write("ilRepUtil::insertSavedNodes(), restored ref_id $a_source_id from trash");
438 
439  // SET PERMISSIONS
440  $parentRoles = $rbacreview->getParentRoleIds($a_dest_id);
441  $obj =& ilObjectFactory::getInstanceByRefId($a_source_id);
442 
443  foreach ($parentRoles as $parRol)
444  {
445  $ops = $rbacreview->getOperationsOfRole($parRol["obj_id"], $obj->getType(), $parRol["parent"]);
446  $rbacadmin->grantPermission($parRol["obj_id"],$ops,$a_source_id);
447  }
448 
449  $saved_tree = new ilTree($a_tree_id);
450  $childs = $saved_tree->getChilds($a_source_id);
451 
452  foreach ($childs as $child)
453  {
454  ilRepUtil::insertSavedNodes($child["child"],$a_source_id,$a_tree_id,$a_affected_ids);
455  }
456  }
457 
458 
459 }