ILIAS  release_8 Revision v8.19
All Data Structures Namespaces Files Functions Variables Modules Pages
class.ilTreeTrashQueries.php
Go to the documentation of this file.
1 <?php
2 
19 declare(strict_types=1);
20 
26 {
27  protected const QUERY_LIMIT = 10;
28 
29  private int $ref_id = 0;
30 
31  private ilTree $tree;
32 
33  private ilLogger $logger;
34 
35  private ilDBInterface $db;
36 
40  public function __construct()
41  {
42  global $DIC;
43 
44  $this->db = $DIC->database();
45  $this->logger = $DIC->logger()->tree();
46  $this->tree = $DIC->repositoryTree();
47  }
48 
53  public function isTrashedTrash(array $ref_ids): bool
54  {
55  $query = 'select tree,child,parent from tree ' .
56  'where ' . $this->db->in('child', $ref_ids, false, \ilDBConstants::T_INTEGER);
57  $res = $this->db->query($query);
58  $trashed_trash = false;
59  while ($row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
60  if ((int) $row->child != ((int) $row->tree * -1)) {
61  $trashed_trash = true;
62  }
63  if ($this->tree->isDeleted((int) $row->parent)) {
64  $trashed_trash = true;
65  }
66  }
67  return $trashed_trash;
68  }
69 
75  public function findRepositoryLocationForDeletedNode(int $deleted_node): int
76  {
77  $query = 'select parent from tree ' .
78  'where child = ' . $this->db->quote($deleted_node, \ilDBConstants::T_INTEGER) . ' ' .
79  'and tree = ' . $this->db->quote($deleted_node * -1, \ilDBConstants::T_INTEGER);
80  $this->logger->debug($query);
81  $res = $this->db->query($query);
82  while ($row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
83  return (int) $row->parent;
84  }
85  $this->logger->warning('Invalid node given for restoring to original location: deleted node id: ' . $deleted_node);
86  throw new \ilRepositoryException('Invalid node given for restoring to original location');
87  }
88 
93  public function getTrashedNodeTypesForContainer(int $ref_id): array
94  {
95  $subtreequery = $this->tree->getTrashSubTreeQuery($ref_id, ['child']);
96  $query = 'select distinct(type) obj_type from object_data obd ' .
97  'join object_reference obr on obd.obj_id = obr.obj_id ' .
98  'where ref_id in (' .
99  $subtreequery . ' ' .
100  ') ';
101 
102  $obj_types = [];
103  $res = $this->db->query($query);
104  while ($row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
105  $obj_types[] = (string) $row->obj_type;
106  }
107  return $obj_types;
108  }
109 
114  public function getNumberOfTrashedNodesForTrashedContainer(int $ref_id): int
115  {
116  $res = $this->db->query($this->tree->getTrashSubTreeQuery($ref_id, ['child']));
117  return $res->numRows();
118  }
119 
125  public function getTrashNodeForContainer(
126  int $ref_id,
127  array $filter,
128  int &$max_entries,
129  string $order_field,
130  string $order_direction,
131  int $limit = self::QUERY_LIMIT,
132  int $offset = 0
133  ): array {
134  $subtreequery = $this->tree->getTrashSubTreeQuery($ref_id, ['child']);
135 
136  $select = 'SELECT ref_id, obd.obj_id, type, title, description, deleted, deleted_by ';
137  $select_count = 'SELECT COUNT(ref_id) max_entries ';
138 
139  $from = 'FROM object_data obd ' .
140  'JOIN object_reference obr ON obd.obj_id = obr.obj_id ' .
141  'WHERE ref_id IN (' .
142  $subtreequery . ' ' .
143  ') ';
144 
145  $order = ' ';
146  if ($order_field) {
147  $order = 'ORDER BY ' . $order_field . ' ' . $order_direction;
148  }
149 
150  $query = $select . $from . $this->appendTrashNodeForContainerQueryFilter($filter) . $order;
151  $query_count = $select_count . $from . $this->appendTrashNodeForContainerQueryFilter($filter);
152 
156  $res_max_entries = $this->db->query($query_count);
157  while ($max_entries_row = $res_max_entries->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
158  $max_entries = (int) $max_entries_row->max_entries;
159  }
160 
161  $this->db->setLimit($limit, $offset);
162  $res = $this->db->query($query);
163 
164  $items = [];
165  while ($row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
166  $item = new \ilTreeTrashItem();
167  $item->setObjId((int) $row->obj_id);
168  $item->setRefId((int) $row->ref_id);
169  $item->setTitle((string) $row->title);
170  $item->setDescription((string) $row->description);
171  $item->setType((string) $row->type);
172  $item->setDeleted((string) $row->deleted);
173  $item->setDeletedBy((int) $row->deleted_by);
174  $items[] = $item;
175  }
176  return $items;
177  }
178 
186  public function getTrashedNodesForContainerUsingRecursion(int $ref_id): void
187  {
188  $query = 'WITH RECURSIVE trash (child,tree) AS ' .
189  '( SELECT child, tree FROM tree WHERE child = ' . $this->db->quote(
190  $ref_id,
192  ) . ' ' .
193  'UNION SELECT tc.child,tc.tree FROM tree tc JOIN tree tp ON tp.child = tc.parent ) ' .
194  'SELECT * FROM trash WHERE tree < 1 ';
195 
196  $trash_ids = [];
197  try {
198  $res = $this->db->query($query);
199  while ($row = $res->fetchRow(\ilDBConstants::FETCHMODE_OBJECT)) {
200  $trash_ids[] = (int) $row->child;
201  }
202  } catch (\ilDatabaseException $e) {
203  $this->logger->warning($query . ' is not supported');
204  throw $e;
205  }
206  }
207 
212  protected function appendTrashNodeForContainerQueryFilter(array $filter): string
213  {
214  $query = '';
215  if (isset($filter['type'])) {
216  $query .= 'and ' . $this->db->like(
217  'type',
219  $filter['type']
220  ) . ' ';
221  }
222  if (isset($filter['title'])) {
223  $query .= 'and ' . $this->db->like(
224  'title',
226  '%' . $filter['title'] . '%'
227  ) . ' ';
228  }
229 
230  // #33781 use an explizit date format to really include the 'to' date because it can be interpreted as 'xxxx-xx-xx 00:00:00'
231  if (
232  $filter['deleted']['from'] instanceof \ilDate &&
233  $filter['deleted']['to'] instanceof \ilDate) {
234  $query .= ('AND deleted BETWEEN ' .
235  $this->db->quote($filter['deleted']['from']->get(\IL_CAL_DATE), \ilDBConstants::T_TEXT) . ' AND ' .
236  $this->db->quote($filter['deleted']['to']->get(IL_CAL_DATE) . " 23:59:59", \ilDBConstants::T_TEXT) . ' ');
237  } elseif ($filter['deleted']['from'] instanceof \ilDate) {
238  $query .= 'AND deleted >= ' . $this->db->quote(
239  $filter['deleted']['from']->get(IL_CAL_DATE),
241  ) . ' ';
242  } elseif ($filter['deleted']['to'] instanceof \ilDate) {
243  $query .= 'AND deleted <= ' . $this->db->quote(
244  $filter['deleted']['to']->get(IL_CAL_DATE) . " 23:59:59",
246  ) . ' ';
247  }
248 
249  if (isset($filter['deleted_by']) && !empty($filter['deleted_by'])) {
250  $usr_id = \ilObjUser::_lookupId($filter['deleted_by']);
251  if ($usr_id > 0) {
252  $query .= 'AND deleted_by = ' . $this->db->quote($usr_id, \ilDBConstants::T_INTEGER) . ' ';
253  } else {
254  $query .= 'AND 1=2 ';
255  }
256  }
257 
258  return $query;
259  }
260 }
$res
Definition: ltiservices.php:69
getTrashNodeForContainer(int $ref_id, array $filter, int &$max_entries, string $order_field, string $order_direction, int $limit=self::QUERY_LIMIT, int $offset=0)
Get trashed nodes.
appendTrashNodeForContainerQueryFilter(array $filter)
getTrashedNodeTypesForContainer(int $ref_id)
getTrashedNodesForContainerUsingRecursion(int $ref_id)
Unfortunately not supported by mysql 5.
static _lookupId($a_user_str)
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
global $DIC
Definition: feed.php:28
__construct()
ilTreeTrash constructor.
findRepositoryLocationForDeletedNode(int $deleted_node)
getNumberOfTrashedNodesForTrashedContainer(int $ref_id)
$query
const IL_CAL_DATE