ILIAS  release_5-2 Revision v5.2.25-18-g3f80b828510
class.ilContainerSorting.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 include_once './Services/Container/classes/class.ilContainer.php';
25 include_once('Services/Container/classes/class.ilContainerSortingSettings.php');
26 
36 {
37  protected static $instances = array();
38 
39  protected $obj_id;
40  protected $db;
41 
42  protected $sorting_settings = null;
43  const ORDER_DEFAULT = 999999;
44 
52  private function __construct($a_obj_id)
53  {
54  global $ilDB;
55 
56  $this->db = $ilDB;
57  $this->obj_id = $a_obj_id;
58 
59  $this->read();
60  }
61 
66  public function getSortingSettings()
67  {
69  }
70 
79  public static function _getInstance($a_obj_id)
80  {
81  if(isset(self::$instances[$a_obj_id]))
82  {
83  return self::$instances[$a_obj_id];
84  }
85  return self::$instances[$a_obj_id] = new ilContainerSorting($a_obj_id);
86  }
87 
93  public static function lookupPositions($a_obj_id)
94  {
95  global $ilDB;
96 
97  $query = "SELECT * FROM container_sorting WHERE ".
98  "obj_id = ".$ilDB->quote($a_obj_id,'integer');
99  $res = $ilDB->query($query);
100  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
101  {
102  $sorted[$row->child_id] = $row->position;
103  }
104  return $sorted ? $sorted : array();
105  }
106 
113  public function cloneSorting($a_target_id,$a_copy_id)
114  {
115  global $ilDB;
116 
118 
119  $ilLog->debug("Cloning container sorting.");
120 
121  $target_obj_id = ilObject::_lookupObjId($a_target_id);
122 
123  include_once('./Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
124  $mappings = ilCopyWizardOptions::_getInstance($a_copy_id)->getMappings();
125 
126 
127  // copy blocks sorting
128  $set = $ilDB->queryF("SELECT * FROM container_sorting_bl ".
129  " WHERE obj_id = %s ",
130  array("integer"),
131  array($this->obj_id)
132  );
133  if ($rec = $ilDB->fetchAssoc($set))
134  {
135  if ($rec["block_ids"] != "")
136  {
137  $ilLog->debug("Got block sorting for obj_id = ".$this->obj_id.": ".$rec["block_ids"]);
138  $new_ids = implode(";", array_map(function ($block_id) use ($mappings) {
139  if (is_numeric($block_id))
140  {
141  $block_id = $mappings[$block_id];
142  }
143  return $block_id;
144  }, explode(";", $rec["block_ids"])));
145 
146  $ilDB->insert("container_sorting_bl", array(
147  "obj_id" => array("integer", $target_obj_id),
148  "block_ids" => array("text", $new_ids)
149  ));
150 
151  $ilLog->debug("Write block sorting for obj_id = ".$target_obj_id.": ".$new_ids);
152  }
153  }
154 
155 
156  $ilLog->debug("Read container_sorting for obj_id = ".$this->obj_id);
157 
158  $query = "SELECT * FROM container_sorting ".
159  "WHERE obj_id = ".$ilDB->quote($this->obj_id, 'integer');
160 
161  $res = $ilDB->query($query);
162 
163  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
164  {
165  if(!isset($mappings[$row->child_id]) or !$mappings[$row->child_id])
166  {
167  $ilLog->debug("No mapping found for child id:".$row->child_id);
168  continue;
169  }
170 
171 
172  $new_parent_id = 0;
173  if($row->parent_id)
174  {
175  // see bug #20347
176  // at least in the case of sessions and item groups parent_ids in container sorting are object IDs but $mappings store references
177  if (in_array($row->parent_type, array("sess", "itgr")))
178  {
179  $par_refs = ilObject::_getAllReferences($row->parent_id);
180  $par_ref_id = current($par_refs); // should be only one
181  $ilLog->debug("Got ref id: ".$par_ref_id." for obj_id ".$row->parent_id." map ref id: ".$mappings[$par_ref_id].".");
182  if (isset($mappings[$par_ref_id]))
183  {
184  $new_parent_ref_id = $mappings[$par_ref_id];
185  $new_parent_id = ilObject::_lookupObjectId($new_parent_ref_id);
186  }
187  }
188  else // not sure if this is still used for other cases that expect ref ids
189  {
190  $new_parent_id = $mappings[$row->parent_id];
191  }
192  if ((int) $new_parent_id == 0)
193  {
194  $ilLog->debug("No mapping found for parent id:" . $row->parent_id . ", child_id: " . $row->child_id);
195  continue;
196  }
197  }
198 
199  $query = "DELETE FROM container_sorting ".
200  "WHERE obj_id = ".$ilDB->quote($target_obj_id,'integer')." ".
201  "AND child_id = ".$ilDB->quote($mappings[$row->child_id],'integer')." ".
202  "AND parent_type = ".$ilDB->quote($row->parent_type,'text').' '.
203  "AND parent_id = ".$ilDB->quote((int) $new_parent_id,'integer');
204  $ilLog->debug($query);
205  $ilDB->manipulate($query);
206 
207  // Add new value
208  $query = "INSERT INTO container_sorting (obj_id,child_id,position,parent_type,parent_id) ".
209  "VALUES( ".
210  $ilDB->quote($target_obj_id ,'integer').", ".
211  $ilDB->quote($mappings[$row->child_id] ,'integer').", ".
212  $ilDB->quote($row->position,'integer').", ".
213  $ilDB->quote($row->parent_type,'text').", ".
214  $ilDB->quote((int) $new_parent_id,'integer').
215  ")";
216  $ilLog->debug($query);
217  $ilDB->manipulate($query);
218  }
219  return true;
220  }
221 
222 
223 
231  public function sortItems($a_items)
232  {
233  $sorted = array();
234  if($this->getSortingSettings()->getSortMode() != ilContainer::SORT_MANUAL)
235  {
236  switch($this->getSortingSettings()->getSortMode())
237  {
239  foreach((array) $a_items as $type => $data)
240  {
241  // #16311 - sorting will remove keys (prev/next)
242  if($type == 'sess_link')
243  {
244  $sorted[$type] = $data;
245  continue;
246  }
247 
248  // this line used until #4389 has been fixed (3.10.6)
249  // reanimated with 4.4.0
250  $sorted[$type] = ilUtil::sortArray(
251  (array) $data,
252  'title',
253  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
254  FALSE
255  );
256 
257  // the next line tried to use db sorting and has replaced sortArray due to bug #4389
258  // but leads to bug #12165. PHP should be able to do a proper sorting, if the locale
259  // is set correctly, so we witch back to sortArray (with 4.4.0) and see what
260  // feedback we get
261  // (next line has been used from 3.10.6 to 4.3.x)
262 // $sorted[$type] = $data;
263  }
264  return $sorted ? $sorted : array();
265 
267  foreach((array) $a_items as $type => $data)
268  {
269  // #16311 - sorting will remove keys (prev/next)
270  if($type == 'sess_link')
271  {
272  $sorted[$type] = $data;
273  continue;
274  }
275 
276  $sorted[$type] = ilUtil::sortArray(
277  (array) $data,
278  'start',
279  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
280  TRUE
281  );
282 
283  }
284  return $sorted ? $sorted : array();
285 
286 
288  foreach((array) $a_items as $type => $data)
289  {
290  // #16311 - sorting will remove keys (prev/next)
291  if($type == 'sess_link')
292  {
293  $sorted[$type] = $data;
294  continue;
295  }
296 
297  $sorted[$type] = ilUtil::sortArray(
298  (array) $data,
299  'create_date',
300  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
301  TRUE
302  );
303  }
304  return $sorted ? $sorted : array();
305  }
306  return $a_items;
307  }
308  if(!count($a_items))
309  {
310  return $a_items;
311  }
312  $sorted = array();
313  foreach((array) $a_items as $type => $data)
314  {
315  if($type == 'sess_link')
316  {
317  $sorted[$type] = $data;
318  continue;
319  }
320 
321  // Add position
322  $items = array();
323  foreach((array) $data as $key => $item)
324  {
325  $items[$key] = $item;
326  if(is_array($this->sorting['all']) and isset($this->sorting['all'][$item['child']]))
327  {
328  $items[$key]['position'] = $this->sorting['all'][$item['child']];
329  }
330  else
331  {
332  $items[$key]['position'] = self::ORDER_DEFAULT;
333  }
334  }
335 
336  $items = $this->sortOrderDefault($items);
337 
338  switch($type)
339  {
340  case '_all':
341  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
342  break;
343 
344  case '_non_sess':
345  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
346  break;
347 
348  default:
349  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
350  break;
351  }
352  }
353  return $sorted ? $sorted : array();
354  }
355 
363  public function sortSubItems($a_parent_type,$a_parent_id,$a_items)
364  {
365  switch($this->getSortingSettings()->getSortMode())
366  {
368  $items = array();
369  foreach($a_items as $key => $item)
370  {
371  $items[$key] = $item;
372  $items[$key]['position'] = isset($this->sorting[$a_parent_type][$a_parent_id][$item['child']]) ?
373  $this->sorting[$a_parent_type][$a_parent_id][$item['child']] : self::ORDER_DEFAULT;
374  }
375 
376  $items = $this->sortOrderDefault($items);
377  return ilUtil::sortArray((array) $items,'position','asc',TRUE);
378 
379 
381  return ilUtil::sortArray(
382  (array) $a_items,
383  'start',
384  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
385  TRUE
386  );
387 
389  return ilUtil::sortArray(
390  (array) $a_items,
391  'create_date',
392  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
393  TRUE
394  );
395 
396  default:
398  return ilUtil::sortArray(
399  (array) $a_items,
400  'title',
401  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
402  FALSE
403  );
404  }
405 
406  }
407 
415  public function savePost($a_type_positions)
416  {
417  global $ilLog;
418 
419  if(!is_array($a_type_positions))
420  {
421  return false;
422  }
423  foreach($a_type_positions as $key => $position)
424  {
425  if($key == "blocks")
426  {
427  $this->saveBlockPositions($position);
428  }
429  else if(!is_array($position))
430  {
431  $items[$key] = $position * 100;
432  }
433  else
434  {
435  $ilLog->write(__METHOD__.': Deprecated call');
436  foreach($position as $parent_id => $sub_items)
437  {
438  $this->saveSubItems($key,$parent_id,$sub_items ? $sub_items : array());
439  }
440  }
441  }
442  $this->saveItems($items ? $items : array());
443  }
444 
445 
455  protected function saveItems($a_items)
456  {
457  global $ilDB;
458 
459  foreach($a_items as $child_id => $position)
460  {
461  $ilDB->replace(
462  'container_sorting',
463  array(
464  'obj_id' => array('integer',$this->obj_id),
465  'child_id' => array('integer',$child_id),
466  'parent_id' => array('integer',0)
467  ),
468  array(
469  'parent_type' => array('text',''),
470  'position' => array('integer',$position)
471  )
472  );
473  }
474  return true;
475  }
476 
484  protected function saveSubItems($a_parent_type,$a_parent_id,$a_items)
485  {
486  global $ilDB;
487 
488  foreach($a_items as $child_id => $position)
489  {
490  $ilDB->replace(
491  'container_sorting',
492  array(
493  'obj_id' => array('integer',$this->obj_id),
494  'child_id' => array('integer',$child_id),
495  'parent_id' => array('integer',$a_parent_id)
496  ),
497  array(
498  'parent_type' => array('text',$a_parent_type),
499  'position' => array('integer',$position)
500  )
501  );
502  }
503  return true;
504 
505  }
506 
512  protected function saveBlockPositions(array $a_values)
513  {
514  global $ilDB;
515 
516  asort($a_values);
517  $ilDB->replace(
518  'container_sorting_bl',
519  array(
520  'obj_id' => array('integer',$this->obj_id)
521  ),
522  array(
523  'block_ids' => array('text', implode(";", array_keys($a_values)))
524  )
525  );
526  }
527 
533  public function getBlockPositions()
534  {
535  global $ilDB;
536 
537  $set = $ilDB->query("SELECT block_ids".
538  " FROM container_sorting_bl".
539  " WHERE obj_id = ".$ilDB->quote($this->obj_id, "integer"));
540  $row = $ilDB->fetchAssoc($set);
541  if($row["block_ids"])
542  {
543  return explode(";", $row["block_ids"]);
544  }
545  }
546 
547 
554  private function read()
555  {
556  global $tree;
557 
558  if(!$this->obj_id)
559  {
560  $this->sorting_settings = new ilContainerSortingSettings();
561  return true;
562  }
563 
565  $this->sorting_settings = $sorting_settings->loadEffectiveSettings();
566  $query = "SELECT * FROM container_sorting ".
567  "WHERE obj_id = ".$this->db->quote($this->obj_id ,'integer')." ORDER BY position";
568  $res = $this->db->query($query);
569  while($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT))
570  {
571  if($row->parent_id)
572  {
573  $this->sorting[$row->parent_type][$row->parent_id][$row->child_id] = $row->position;
574  }
575  else
576  {
577  $this->sorting['all'][$row->child_id] = $row->position;
578  }
579  }
580  return true;
581  }
582 
589  private function sortOrderDefault($items)
590  {
591  $no_position = array();
592 
593  foreach($items as $key => $item)
594  {
595  if($item["position"] == self::ORDER_DEFAULT)
596  {
597  $no_position[]= array("key" => $key, "title" => $item["title"], "create_date" => $item["create_date"],
598  "start" => $item["start"]);
599  }
600 
601  }
602 
603  if(!count($no_position))
604  {
605  return $items;
606  }
607 
608  switch($this->getSortingSettings()->getSortNewItemsOrder())
609  {
611  $no_position = ilUtil::sortArray( (array) $no_position,
612  'title',
613  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
614  TRUE);
615  break;
617  $no_position = ilUtil::sortArray((array) $no_position,
618  'create_date',
619  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
620  TRUE);
621  break;
623  $no_position = ilUtil::sortArray((array) $no_position,
624  'start',
625  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
626  TRUE);
627 
628  }
629  $count = $this->getSortingSettings()->getSortNewItemsPosition()
631 
632  foreach($no_position as $values)
633  {
634  $items[$values["key"]]["position"] = $count;
635  $count++;
636  }
637  return $items;
638  }
639 }
640 
641 
642 ?>
saveItems($a_items)
save items
const SORT_NEW_ITEMS_POSITION_TOP
saveBlockPositions(array $a_values)
Save block custom positions (for current object id)
sortOrderDefault($items)
Position and order sort order for new object without position in manual sorting type.
savePost($a_type_positions)
Save post.
getBlockPositions()
Read block custom positions (for current object id)
sortSubItems($a_parent_type, $a_parent_id, $a_items)
sort subitems (items of sessions or learning objectives)
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
static _getAllReferences($a_id)
get all reference ids of object
static _lookupObjectId($a_ref_id)
lookup object id
getSortingSettings()
Get sorting settings.
sortItems($a_items)
sort subitems
__construct($a_obj_id)
Constructor.
static _getInstance($a_copy_id)
Get instance of copy wizard options.
saveSubItems($a_parent_type, $a_parent_id, $a_items)
Save subitem ordering (sessions, learning objectives)
const SORT_NEW_ITEMS_ORDER_CREATION
static _lookupObjId($a_id)
Create styles array
The data for the language used.
const SORT_NEW_ITEMS_ORDER_ACTIVATION
global $ilDB
static getLogger($a_component_id)
Get component logger.
static getInstanceByObjId($a_obj_id)
Get singleton instance.
static _getInstance($a_obj_id)
get instance by obj_id
const SORT_DIRECTION_ASC
static lookupPositions($a_obj_id)
Get positions of subitems.
const SORT_NEW_ITEMS_ORDER_TITLE
cloneSorting($a_target_id, $a_copy_id)
clone sorting