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
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(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?>
const DB_FETCHMODE_OBJECT
Definition: class.ilDB.php:11
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 _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
$data
global $ilDB