ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
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(DB_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  global $ilLog;
117 
118  $ilLog->write(__METHOD__.': Cloning container sorting.');
119 
120  $target_obj_id = ilObject::_lookupObjId($a_target_id);
121 
122  include_once('./Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
123  $mappings = ilCopyWizardOptions::_getInstance($a_copy_id)->getMappings();
124 
125 
126  // copy blocks sorting
127  $set = $ilDB->queryF("SELECT * FROM container_sorting_bl ".
128  " WHERE obj_id = %s ",
129  array("integer"),
130  array($this->obj_id)
131  );
132  if ($rec = $ilDB->fetchAssoc($set))
133  {
134  if ($rec["block_ids"] != "")
135  {
136  $ilLog->debug("Got block sorting for obj_id = ".$this->obj_id.": ".$rec["block_ids"]);
137  $new_ids = implode(";", array_map(function ($block_id) use ($mappings) {
138  if (is_numeric($block_id))
139  {
140  $block_id = $mappings[$block_id];
141  }
142  return $block_id;
143  }, explode(";", $rec["block_ids"])));
144 
145  $ilDB->insert("container_sorting_bl", array(
146  "obj_id" => array("integer", $target_obj_id),
147  "block_ids" => array("text", $new_ids)
148  ));
149 
150  $ilLog->debug("Write block sorting for obj_id = ".$target_obj_id.": ".$new_ids);
151  }
152  }
153 
154 
155  $ilLog->debug("Read container_sorting for obj_id = ".$this->obj_id);
156 
157  $query = "SELECT * FROM container_sorting ".
158  "WHERE obj_id = ".$ilDB->quote($this->obj_id, 'integer');
159 
160  $res = $ilDB->query($query);
161 
162  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
163  {
164  if(!isset($mappings[$row->child_id]) or !$mappings[$row->child_id])
165  {
166  #$ilLog->write(__METHOD__.': No mapping found for:'.$row->child_id);
167  continue;
168  }
169 
170 
171  $new_parent_id = 0;
172  if($row->parent_id)
173  {
174  // see bug #20347
175  // at least in the case of sessions and item groups parent_ids in container sorting are object IDs but $mappings store references
176  if (in_array($row->parent_type, array("sess", "itgr")))
177  {
178  $par_refs = ilObject::_getAllReferences($row->parent_id);
179  $par_ref_id = current($par_refs); // should be only one
180  $ilLog->debug("Got ref id: ".$par_ref_id." for obj_id ".$row->parent_id." map ref id: ".$mappings[$par_ref_id].".");
181  if (isset($mappings[$par_ref_id]))
182  {
183  $new_parent_ref_id = $mappings[$par_ref_id];
184  $new_parent_id = ilObject::_lookupObjectId($new_parent_ref_id);
185  }
186  }
187  else // not sure if this is still used for other cases that expect ref ids
188  {
189  $new_parent_id = $mappings[$row->parent_id];
190  }
191  if ((int) $new_parent_id == 0)
192  {
193  $ilLog->debug("No mapping found for parent id:" . $row->parent_id . ", child_id: " . $row->child_id);
194  continue;
195  }
196  }
197 
198  $query = "DELETE FROM container_sorting ".
199  "WHERE obj_id = ".$ilDB->quote($target_obj_id,'integer')." ".
200  "AND child_id = ".$ilDB->quote($mappings[$row->child_id],'integer')." ".
201  "AND parent_type = ".$ilDB->quote($row->parent_type,'text').' '.
202  "AND parent_id = ".$ilDB->quote((int) $new_parent_id,'integer');
203  $ilLog->debug($query);
204  $ilDB->manipulate($query);
205 
206  // Add new value
207  $query = "INSERT INTO container_sorting (obj_id,child_id,position,parent_type,parent_id) ".
208  "VALUES( ".
209  $ilDB->quote($target_obj_id ,'integer').", ".
210  $ilDB->quote($mappings[$row->child_id] ,'integer').", ".
211  $ilDB->quote($row->position,'integer').", ".
212  $ilDB->quote($row->parent_type,'text').", ".
213  $ilDB->quote((int) $new_parent_id,'integer').
214  ")";
215  $ilDB->manipulate($query);
216  }
217  return true;
218  }
219 
220 
221 
229  public function sortItems($a_items)
230  {
231  $sorted = array();
232  if($this->getSortingSettings()->getSortMode() != ilContainer::SORT_MANUAL)
233  {
234  switch($this->getSortingSettings()->getSortMode())
235  {
237  foreach((array) $a_items as $type => $data)
238  {
239  // #16311 - sorting will remove keys (prev/next)
240  if($type == 'sess_link')
241  {
242  $sorted[$type] = $data;
243  continue;
244  }
245 
246  // this line used until #4389 has been fixed (3.10.6)
247  // reanimated with 4.4.0
248  $sorted[$type] = ilUtil::sortArray(
249  (array) $data,
250  'title',
251  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
252  FALSE
253  );
254 
255  // the next line tried to use db sorting and has replaced sortArray due to bug #4389
256  // but leads to bug #12165. PHP should be able to do a proper sorting, if the locale
257  // is set correctly, so we witch back to sortArray (with 4.4.0) and see what
258  // feedback we get
259  // (next line has been used from 3.10.6 to 4.3.x)
260 // $sorted[$type] = $data;
261  }
262  return $sorted ? $sorted : array();
263 
265  foreach((array) $a_items as $type => $data)
266  {
267  // #16311 - sorting will remove keys (prev/next)
268  if($type == 'sess_link')
269  {
270  $sorted[$type] = $data;
271  continue;
272  }
273 
274  $sorted[$type] = ilUtil::sortArray(
275  (array) $data,
276  'start',
277  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
278  TRUE
279  );
280 
281  }
282  return $sorted ? $sorted : array();
283 
284 
286  foreach((array) $a_items as $type => $data)
287  {
288  // #16311 - sorting will remove keys (prev/next)
289  if($type == 'sess_link')
290  {
291  $sorted[$type] = $data;
292  continue;
293  }
294 
295  $sorted[$type] = ilUtil::sortArray(
296  (array) $data,
297  'create_date',
298  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
299  TRUE
300  );
301  }
302  return $sorted ? $sorted : array();
303  }
304  return $a_items;
305  }
306  if(!count($a_items))
307  {
308  return $a_items;
309  }
310  $sorted = array();
311  foreach((array) $a_items as $type => $data)
312  {
313  if($type == 'sess_link')
314  {
315  $sorted[$type] = $data;
316  continue;
317  }
318 
319  // Add position
320  $items = array();
321  foreach((array) $data as $key => $item)
322  {
323  $items[$key] = $item;
324  if(is_array($this->sorting['all']) and isset($this->sorting['all'][$item['child']]))
325  {
326  $items[$key]['position'] = $this->sorting['all'][$item['child']];
327  }
328  else
329  {
330  $items[$key]['position'] = self::ORDER_DEFAULT;
331  }
332  }
333 
334  $items = $this->sortOrderDefault($items);
335 
336  switch($type)
337  {
338  case '_all':
339  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
340  break;
341 
342  case '_non_sess':
343  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
344  break;
345 
346  default:
347  $sorted[$type] = ilUtil::sortArray((array) $items,'position','asc',true);
348  break;
349  }
350  }
351  return $sorted ? $sorted : array();
352  }
353 
361  public function sortSubItems($a_parent_type,$a_parent_id,$a_items)
362  {
363  switch($this->getSortingSettings()->getSortMode())
364  {
366  $items = array();
367  foreach($a_items as $key => $item)
368  {
369  $items[$key] = $item;
370  $items[$key]['position'] = isset($this->sorting[$a_parent_type][$a_parent_id][$item['child']]) ?
371  $this->sorting[$a_parent_type][$a_parent_id][$item['child']] : self::ORDER_DEFAULT;
372  }
373 
374  $items = $this->sortOrderDefault($items);
375  return ilUtil::sortArray((array) $items,'position','asc',TRUE);
376 
377 
379  return ilUtil::sortArray(
380  (array) $a_items,
381  'start',
382  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
383  TRUE
384  );
385 
387  return ilUtil::sortArray(
388  (array) $a_items,
389  'create_date',
390  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
391  TRUE
392  );
393 
394  default:
396  return ilUtil::sortArray(
397  (array) $a_items,
398  'title',
399  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
400  FALSE
401  );
402  }
403 
404  }
405 
413  public function savePost($a_type_positions)
414  {
415  global $ilLog;
416 
417  if(!is_array($a_type_positions))
418  {
419  return false;
420  }
421  foreach($a_type_positions as $key => $position)
422  {
423  if($key == "blocks")
424  {
425  $this->saveBlockPositions($position);
426  }
427  else if(!is_array($position))
428  {
429  $items[$key] = $position * 100;
430  }
431  else
432  {
433  $ilLog->write(__METHOD__.': Deprecated call');
434  foreach($position as $parent_id => $sub_items)
435  {
436  $this->saveSubItems($key,$parent_id,$sub_items ? $sub_items : array());
437  }
438  }
439  }
440  $this->saveItems($items ? $items : array());
441  }
442 
443 
453  protected function saveItems($a_items)
454  {
455  global $ilDB;
456 
457  foreach($a_items as $child_id => $position)
458  {
459  $ilDB->replace(
460  'container_sorting',
461  array(
462  'obj_id' => array('integer',$this->obj_id),
463  'child_id' => array('integer',$child_id),
464  'parent_id' => array('integer',0)
465  ),
466  array(
467  'parent_type' => array('text',''),
468  'position' => array('integer',$position)
469  )
470  );
471  }
472  return true;
473  }
474 
482  protected function saveSubItems($a_parent_type,$a_parent_id,$a_items)
483  {
484  global $ilDB;
485 
486  foreach($a_items as $child_id => $position)
487  {
488  $ilDB->replace(
489  'container_sorting',
490  array(
491  'obj_id' => array('integer',$this->obj_id),
492  'child_id' => array('integer',$child_id),
493  'parent_id' => array('integer',$a_parent_id)
494  ),
495  array(
496  'parent_type' => array('text',$a_parent_type),
497  'position' => array('integer',$position)
498  )
499  );
500  }
501  return true;
502 
503  }
504 
510  protected function saveBlockPositions(array $a_values)
511  {
512  global $ilDB;
513 
514  asort($a_values);
515 
516  $ilDB->replace(
517  'container_sorting_bl',
518  array(
519  'obj_id' => array('integer',$this->obj_id)
520  ),
521  array(
522  'block_ids' => array('text', implode(";", array_keys($a_values)))
523  )
524  );
525  }
526 
532  public function getBlockPositions()
533  {
534  global $ilDB;
535 
536  $set = $ilDB->query("SELECT block_ids".
537  " FROM container_sorting_bl".
538  " WHERE obj_id = ".$ilDB->quote($this->obj_id, "integer"));
539  $row = $ilDB->fetchAssoc($set);
540  if($row["block_ids"])
541  {
542  return explode(";", $row["block_ids"]);
543  }
544  }
545 
546 
553  private function read()
554  {
555  global $tree;
556 
557  if(!$this->obj_id)
558  {
559  $this->sorting_settings = new ilContainerSortingSettings();
560  return true;
561  }
562 
564  $this->sorting_settings = $sorting_settings->loadEffectiveSettings();
565  $query = "SELECT * FROM container_sorting ".
566  "WHERE obj_id = ".$this->db->quote($this->obj_id ,'integer')." ORDER BY position";
567  $res = $this->db->query($query);
568  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
569  {
570  if($row->parent_id)
571  {
572  $this->sorting[$row->parent_type][$row->parent_id][$row->child_id] = $row->position;
573  }
574  else
575  {
576  $this->sorting['all'][$row->child_id] = $row->position;
577  }
578  }
579  return true;
580  }
581 
588  private function sortOrderDefault($items)
589  {
590  $no_position = array();
591 
592  foreach($items as $key => $item)
593  {
594  if($item["position"] == self::ORDER_DEFAULT)
595  {
596  $no_position[]= array("key" => $key, "title" => $item["title"], "create_date" => $item["create_date"],
597  "start" => $item["start"]);
598  }
599 
600  }
601 
602  if(!count($no_position))
603  {
604  return $items;
605  }
606 
607  switch($this->getSortingSettings()->getSortNewItemsOrder())
608  {
610  $no_position = ilUtil::sortArray( (array) $no_position,
611  'title',
612  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
613  TRUE);
614  break;
616  $no_position = ilUtil::sortArray((array) $no_position,
617  'create_date',
618  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
619  TRUE);
620  break;
622  $no_position = ilUtil::sortArray((array) $no_position,
623  'start',
624  ($this->getSortingSettings()->getSortDirection() == ilContainer::SORT_DIRECTION_ASC) ? 'asc' : 'desc',
625  TRUE);
626 
627  }
628  $count = $this->getSortingSettings()->getSortNewItemsPosition()
630 
631  foreach($no_position as $values)
632  {
633  $items[$values["key"]]["position"] = $count;
634  $count++;
635  }
636  return $items;
637  }
638 }
639 
640 
641 ?>
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
const DB_FETCHMODE_OBJECT
Definition: class.ilDB.php:11
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.
$data
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)
const SORT_NEW_ITEMS_ORDER_ACTIVATION
global $ilDB
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