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
24include_once './Services/Container/classes/class.ilContainer.php';
25include_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?>
An exception for terminatinating execution or to throw for unit testing.
static getInstanceByObjId($a_obj_id)
Get singleton instance.
cloneSorting($a_target_id, $a_copy_id)
clone sorting
sortItems($a_items)
sort subitems
getBlockPositions()
Read block custom positions (for current object id)
__construct($a_obj_id)
Constructor.
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.
saveItems($a_items)
save items
saveSubItems($a_parent_type, $a_parent_id, $a_items)
Save subitem ordering (sessions, learning objectives)
static lookupPositions($a_obj_id)
Get positions of subitems.
static _getInstance($a_obj_id)
get instance by obj_id
savePost($a_type_positions)
Save post.
sortSubItems($a_parent_type, $a_parent_id, $a_items)
sort subitems (items of sessions or learning objectives)
getSortingSettings()
Get sorting settings.
const SORT_NEW_ITEMS_ORDER_ACTIVATION
const SORT_NEW_ITEMS_ORDER_TITLE
const SORT_NEW_ITEMS_ORDER_CREATION
const SORT_NEW_ITEMS_POSITION_TOP
const SORT_DIRECTION_ASC
static _getInstance($a_copy_id)
Get instance of copy wizard options.
static getLogger($a_component_id)
Get component logger.
static _lookupObjId($a_id)
static _lookupObjectId($a_ref_id)
lookup object id
static _getAllReferences($a_id)
get all reference ids of object
static sortArray($array, $a_array_sortby, $a_array_sortorder=0, $a_numeric=false, $a_keep_keys=false)
sortArray
global $ilDB