ILIAS  Release_4_2_x_branch Revision 61807
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilCourseItems.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2001 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 
34 define('IL_CRS_TIMINGS_ACTIVATION',0);
35 define('IL_CRS_TIMINGS_DEACTIVATED',1);
36 define('IL_CRS_TIMINGS_PRESETTING',2);
37 define('IL_CRS_TIMINGS_FIXED',3);
38 
40 {
41  private $course_ref_id;
42 
43  var $ilErr;
44  var $ilDB;
45  var $tree;
46  var $lng;
47 
48  var $items;
49  var $parent; // ID OF PARENT CONTAINER e.g course_id, folder_id, group_id
50 
54 
55 
56  function ilCourseItems($a_course_ref_id,$a_parent = 0,$user_id = 0)
57  {
58  global $ilErr,$ilDB,$lng,$tree;
59 
60  $this->ilErr =& $ilErr;
61  $this->ilDB =& $ilDB;
62  $this->lng =& $lng;
63  $this->tree =& $tree;
64 
65  $this->course_ref_id = $a_course_ref_id;
66  $this->user_id = $user_id;
67 
68 
69  $this->setParentId($a_parent); // this implicitly calls __read
70  //$this->__read();
71  }
72 
81  public function cloneDependencies($a_target_id,$a_copy_id)
82  {
83  global $ilObjDataCache,$ilLog;
84 
85  $ilLog->write(__METHOD__.': Begin course items...');
86 
87  $target_obj_id = $ilObjDataCache->lookupObjId($a_target_id);
88 
89  include_once('Services/CopyWizard/classes/class.ilCopyWizardOptions.php');
90  $cp_options = ilCopyWizardOptions::_getInstance($a_copy_id);
91  $mappings = $cp_options->getMappings();
92 
93  $query = "SELECT * FROM crs_items WHERE ".
94  "parent_id = ".$this->ilDB->quote($this->getParentId(),'integer')." ";
95  $res = $this->ilDB->query($query);
96 
97  if(!$res->numRows())
98  {
99  $ilLog->write(__METHOD__.': No course items found.');
100  return true;
101  }
102 
103  // new course item object
104  if(!is_object($new_container = ilObjectFactory::getInstanceByRefId($a_target_id,false)))
105  {
106  $ilLog->write(__METHOD__.': Cannot create target object.');
107  return false;
108  }
109  $new_items = new ilCourseItems($this->course_ref_id,$a_target_id);
110  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
111  {
112  if(!isset($mappings[$row->parent_id]) or !$mappings[$row->parent_id])
113  {
114  $ilLog->write(__METHOD__.': No mapping for parent nr. '.$row->parent_id);
115  continue;
116  }
117  if(!isset($mappings[$row->obj_id]) or !$mappings[$row->obj_id])
118  {
119  $ilLog->write(__METHOD__.': No mapping for item nr. '.$row->obj_id);
120  continue;
121  }
122  $new_item_id = $mappings[$row->obj_id];
123  $new_parent = $mappings[$row->parent_id];
124 
125  $new_items->setItemId($new_item_id);
126  $new_items->setParentId($new_parent);
127  $new_items->setTimingType($row->timing_type);
128  $new_items->setTimingStart($row->timing_start);
129  $new_items->setTimingEnd($row->timing_end);
130  $new_items->setSuggestionStart($row->suggestion_start);
131  $new_items->setSuggestionEnd($row->suggestion_end);
132  $new_items->toggleChangeable($row->changeable);
133  $new_items->setEarliestStart($row->earliest_start);
134  $new_items->setLatestEnd($row->latest_end);
135  $new_items->toggleVisible($row->visible);
136  $new_items->update($new_item_id);
137  $ilLog->write(__METHOD__.': Added new entry for item nr. '.$row->obj_id);
138  }
139  $ilLog->write(__METHOD__.': Finished course items.');
140  }
141 
142  public function setItemId($a_item_id)
143  {
144  $this->item_id = $a_item_id;
145  }
146 
147  public function getItemId()
148  {
149  return $this->item_id;
150  }
151  function getUserId()
152  {
153  global $ilUser;
154 
155  return $this->user_id ? $this->user_id : $ilUser->getId();
156  }
157 
158  function _hasCollectionTimings($a_ref_id)
159  {
160  global $tree,$ilDB,$ilObjDataCache;
161 
162  // get all collections
163  include_once 'Services/Tracking/classes/class.ilLPObjSettings.php';
164 
165  $obj_id = $ilObjDataCache->lookupObjId($a_ref_id);
166  switch(ilLPObjSettings::_lookupMode($obj_id))
167  {
169  case LP_MODE_COLLECTION:
170  include_once 'Services/Tracking/classes/class.ilLPCollectionCache.php';
171  $ids = ilLPCollectionCache::_getItems($obj_id);
172  break;
173  default:
174  $ids = array($a_ref_id);
175  break;
176  }
177  if(!$ids)
178  {
179  return false;
180  }
181 
182  $query = "SELECT * FROM crs_items ".
183  "WHERE timing_type = ".$ilDB->quote(IL_CRS_TIMINGS_PRESETTING,'integer')." ".
184  "AND ".$ilDB->in('obj_id',$ids,false,'integer');
185 
186  $res = $ilDB->query($query);
187  return $res->numRows() ? true :false;
188  }
189 
197  public function _hasTimings($a_ref_id)
198  {
199  global $tree,$ilDB;
200 
201  $subtree = $tree->getSubTree($tree->getNodeData($a_ref_id));
202 
203  foreach($subtree as $node)
204  {
205  $ref_ids[] = $node['ref_id'];
206  }
207 
208  $query = "SELECT * FROM crs_items ".
209  "WHERE timing_type = ".$ilDB->quote(IL_CRS_TIMINGS_PRESETTING,'integer')." ".
210  "AND ".$ilDB->in('obj_id',$ref_ids,false,'integer')." ".
211  "AND ".$ilDB->in('parent_id',$ref_ids,false,'integer')." ";
212 
213  $res = $ilDB->query($query);
214  return $res->numRows() ? true :false;
215  }
216 
217  function _hasChangeableTimings($a_ref_id)
218  {
219  global $tree,$ilDB;
220 
221  $subtree = $tree->getSubTree($tree->getNodeData($a_ref_id));
222 
223  foreach($subtree as $node)
224  {
225  $ref_ids[] = $node['ref_id'];
226  }
227 
228  $query = "SELECT * FROM crs_items ".
229  "WHERE timing_type = ".$ilDB->quote(IL_CRS_TIMINGS_PRESETTING,'integer')." ".
230  "AND changeable = ".$ilDB->quote(1,'integer')." ".
231  "AND ".$ilDB->in('obj_id',$ref_ids,false,'integer')." ".
232  "AND ".$ilDB->in('parent_id',$ref_ids,false,'integer')." ";
233 
234  $res = $ilDB->query($query);
235  return $res->numRows() ? true :false;
236  }
237 
238  function setParentId($a_parent = 0)
239  {
240  $this->parent = $a_parent ? $a_parent : $this->course_ref_id;
241  $this->__read();
242 
243  return true;
244  }
245  function getParentId()
246  {
247  return $this->parent;
248  }
249 
250  function setTimingType($a_type)
251  {
252  $this->timing_type = $a_type;
253  }
254  function getTimingType()
255  {
256  return $this->timing_type;
257  }
258 
259  function setTimingStart($a_start)
260  {
261  $this->timing_start = $a_start;
262  }
263  function getTimingStart()
264  {
265  return $this->timing_start;
266  }
267  function setTimingEnd($a_end)
268  {
269  $this->timing_end = $a_end;
270  }
271  function getTimingEnd()
272  {
273  return $this->timing_end;
274  }
275  function setSuggestionStart($a_start)
276  {
277  $this->suggestion_start = $a_start;
278  }
280  {
281  return $this->suggestion_start ? $this->suggestion_start : mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
282  }
283  function setSuggestionEnd($a_end)
284  {
285  $this->suggestion_end = $a_end;
286  }
287  function getSuggestionEnd()
288  {
289  return $this->suggestion_end ? $this->suggestion_end : mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
290  }
291  function setEarliestStart($a_start)
292  {
293  $this->earliest_start = $a_start;
294  }
295  function getEarliestStart()
296  {
297  return $this->earliest_start ? $this->earliest_start : mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
298  }
299  function setLatestEnd($a_end)
300  {
301  $this->latest_end = $a_end;
302  }
303  function getLatestEnd()
304  {
305  return $this->latest_end ? $this->latest_end : mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
306  }
307  function toggleVisible($a_status)
308  {
309  $this->visible = (int) $a_status;
310  }
311  function enabledVisible()
312  {
313  return (bool) $this->visible;
314  }
315  function toggleChangeable($a_status)
316  {
317  $this->changeable = (int) $a_status;
318  }
319  function enabledChangeable()
320  {
321  return (bool) $this->changeable;
322  }
323 
324  function setPosition($a_pos)
325  {
326  $this->position = $a_pos;
327  }
328 
329  function getAllItems()
330  {
331  return $this->items ? $this->items : array();
332  }
333 
337  function getFilteredItems($a_container_ref_id)
338  {
339  global $objDefinition;
340 
341  include_once 'Modules/Session/classes/class.ilEventItems.php';
342 
343  $event_items = ilEventItems::_getItemsOfContainer($a_container_ref_id);
344  foreach($this->items as $item)
345  {
346  if(!in_array($item['ref_id'],$event_items) &&
347  !$objDefinition->isSideBlock($item['type']))
348  {
349  $filtered[] = $item;
350  }
351  }
352  return $filtered ? $filtered : array();
353  }
354 
355  function getItemsByEvent($a_event_id)
356  {
357  include_once 'Modules/Session/classes/class.ilEventItems.php';
358 
359  $event_items_obj = new ilEventItems($a_event_id);
360  $event_items = $event_items_obj->getItems();
361  foreach($event_items as $item)
362  {
363  if($this->tree->isDeleted($item))
364  {
365  continue;
366  }
367  // #7571: when node is removed from system, e.g. inactive trashcan, an empty array is returned
368  $node = $this->tree->getNodeData($item);
369  if($node["ref_id"] == $item)
370  {
371  $items[] = $this->__getItemData($node);
372  }
373  }
374  return $items ? $items : array();
375  }
376 
377  function getItemsByObjective($a_objective_id)
378  {
379  include_once('./Modules/Course/classes/class.ilCourseObjectiveMaterials.php');
380 
382  {
383  if($this->tree->isDeleted($ref_id))
384  {
385  continue;
386  }
387  // #7571: when node is removed from system, e.g. inactive trashcan, an empty array is returned
388  $node = $this->tree->getNodeData($ref_id);
389  if($node["ref_id"] == $ref_id)
390  {
391  $items[] = $this->__getItemData($node);
392  }
393  }
394  return $items ? $items : array();
395  }
396 
397 
398  function getItems()
399  {
400  global $rbacsystem;
401 
402  foreach($this->items as $item)
403  {
404  if($item["type"] != "rolf" and
405  ($item["timing_type"] or
406  ($item["timing_start"] <= time() and $item["timing_end"] >= time())))
407  {
408  if($rbacsystem->checkAccess('visible',$item['ref_id']))
409  {
410  $filtered[] = $item;
411  }
412  }
413  }
414  return $filtered ? $filtered : array();
415  }
416  function getItem($a_item_id)
417  {
418  foreach($this->items as $item)
419  {
420  if($item["child"] == $a_item_id)
421  {
422  return $item;
423  }
424  }
425  return array();
426  }
427 
429  {
430  global $ilErr;
431 
432  $ilErr->setMessage('');
433 
435  {
436  if($this->getTimingStart() > $this->getTimingEnd())
437  {
438  $ilErr->appendMessage($this->lng->txt("crs_activation_start_invalid"));
439  }
440  }
442  {
443  if($this->getSuggestionStart() > $this->getSuggestionEnd())
444  {
445  $ilErr->appendMessage($this->lng->txt('crs_latest_end_not_valid'));
446  }
447  }
448  // Disabled
449  #if($this->getTimingType() == IL_CRS_TIMINGS_PRESETTING and
450  # $this->enabledChangeable())
451  #{
452  # if($this->getSuggestionStart() < $this->getEarliestStart() or
453  # $this->getSuggestionEnd() > $this->getLatestEnd() or
454  # $this->getSuggestionStart() > $this->getLatestEnd() or
455  # $this->getSuggestionEnd() < $this->getEarliestStart())
456  # {
457  # $ilErr->appendMessage($this->lng->txt("crs_suggestion_not_within_activation"));
458  # }
459  #}
460 
461  if($ilErr->getMessage())
462  {
463  return false;
464  }
465  return true;
466  }
467 
474  public function save()
475  {
476  global $ilLog,$ilDB;
477 
478  $query = "INSERT INTO crs_items (timing_type,timing_start,timing_end,".
479  "suggestion_start,suggestion_end, ".
480  "changeable,earliest_start,latest_end,visible,parent_id,obj_id) ".
481  "VALUES( ".
482  $ilDB->quote($this->getTimingType(),'integer').", ".
483  $ilDB->quote($this->getTimingStart(),'integer').", ".
484  $ilDB->quote($this->getTimingEnd(),'integer').", ".
485  $ilDB->quote($this->getSuggestionStart(),'integer').", ".
486  $ilDB->quote($this->getSuggestionEnd(),'integer').", ".
487  $ilDB->quote($this->enabledChangeable(),'integer').", ".
488  $ilDB->quote($this->getEarliestStart(),'integer').", ".
489  $ilDB->quote($this->getLatestEnd(),'integer').", ".
490  $ilDB->quote($this->enabledVisible(),'integer').", ".
491  $ilDB->quote($this->getParentId(),'integer').", ".
492  $ilDB->quote($this->getItemId(),'integer')." ".
493  ")";
494  $res = $ilDB->manipulate($query);
495  }
496 
497 
498  function update($a_item_id)
499  {
500  global $ilDB;
501 
502  $query = "UPDATE crs_items SET ".
503  "timing_type = ".$ilDB->quote($this->getTimingType(),'integer').", ".
504  "timing_start = ".$ilDB->quote($this->getTimingStart(),'integer').", ".
505  "timing_end = ".$ilDB->quote($this->getTimingEnd(),'integer').", ".
506  "suggestion_start = ".$ilDB->quote($this->getSuggestionStart(),'integer').", ".
507  "suggestion_end = ".$ilDB->quote($this->getSuggestionEnd(),'integer').", ".
508  "changeable = ".$ilDB->quote($this->enabledChangeable(),'integer').", ".
509  "earliest_start = ".$ilDB->quote($this->getEarliestStart(),'integer').", ".
510  "latest_end = ".$ilDB->quote($this->getLatestEnd(),'integer').", ".
511  "visible = ".$ilDB->quote($this->enabledVisible(),'integer')." ".
512  "WHERE parent_id = ".$ilDB->quote($this->getParentId(),'integer')." ".
513  "AND obj_id = ".$ilDB->quote($a_item_id,'integer')."";
514  $res = $ilDB->manipulate($query);
515  $this->__read();
516 
517  return true;
518  }
519 
520 
521  function moveUp($item_id)
522  {
523  $this->__read();
524 
525  return true;
526  }
527  function moveDown($item_id)
528  {
529  $this->__read();
530 
531  return true;
532  }
533 
534  function deleteAllEntries()
535  {
536  global $ilDB;
537 
538  $all_items = $this->tree->getChilds($this->parent);
539 
540  foreach($all_items as $item)
541  {
542  $query = "DELETE FROM crs_items ".
543  "WHERE parent_id = ".$ilDB->quote($item["child"],'integer')."";
544  $res = $ilDB->manipulate($query);
545  }
546  $query = "DELETE FROM crs_items ".
547  "WHERE parent_id = ".$ilDB->quote($this->course_ref_id,'integer')." ";
548  $res = $ilDB->manipulate($query);
549 
550  return true;
551  }
552 
553  // PRIVATE
554  function __read()
555  {
556  global $ilBench, $test;
557 
558  $this->items = array();
559 
560  $ilBench->start("Course", "ilCouseItems_read - getChilds");
561  $all_items = $this->tree->getChilds($this->parent);
562  $ilBench->stop("Course", "ilCouseItems_read - getChilds");
563 
564  foreach($all_items as $item)
565  {
566  if($item["type"] != 'rolf')
567  {
568  $this->items[] = $item;
569  }
570  }
571  $ilBench->start("Course", "ilCouseItems_read - getItemData");
572  for($i = 0;$i < count($this->items); ++$i)
573  {
574  if($this->items[$i]["type"] == 'rolf')
575  {
576  unset($this->items[$i]);
577  continue;
578  }
579  $this->items[$i] = $this->__getItemData($this->items[$i]);
580  }
581  $ilBench->stop("Course", "ilCouseItems_read - getItemData");
582 
583  $ilBench->start("Course", "ilCouseItems_read - purge and sort");
584  $this->__purgeDeleted();
585  $this->__sort();
586  $ilBench->stop("Course", "ilCouseItems_read - purge and sort");
587 
588  // one array for items per child id
589  $this->items_per_child = array();
590  foreach($this->items as $item)
591  {
592  $this->items_per_child[$item["child"]] = $item;
593  }
594 
595  return true;
596  }
597 
598  function __purgeDeleted()
599  {
600  global $tree,$ilDB;
601 
602  $all = array();
603 
604  $query = "SELECT obj_id FROM crs_items ".
605  "WHERE parent_id = ".$ilDB->quote($this->getParentId(),'integer')." ";
606 
607  $res = $this->ilDB->query($query);
608  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
609  {
610  if($tree->getParentId($row->obj_id) != $this->getParentId())
611  {
612  $this->__delete($row->obj_id);
613  }
614  }
615  }
616 
617  function __delete($a_obj_id)
618  {
619  global $ilDB;
620 
621  // DELETE ENTRY
622  $query = "DELETE FROM crs_items ".
623  "WHERE parent_id = ".$ilDB->quote($this->getParentId(),'integer')." ".
624  "AND obj_id = ".$ilDB->quote($a_obj_id,'integer')." ";
625  $res = $ilDB->manipulate($query);
626 
627  return true;
628  }
629 
630  function __getItemData($a_item)
631  {
632  global $ilDB,$ilUser,$ilObjDataCache, $ilBench;
633 
634  $ilBench->start("Course", "ilCourseItems_getItemData - 1");
635  $query = "SELECT * FROM crs_items ".
636  "WHERE obj_id = ".$ilDB->quote($a_item['child'],'integer')." ".
637  "AND parent_id = ".$ilDB->quote($a_item['parent'],'integer')." ";
638  $res = $this->ilDB->query($query);
639  $ilBench->stop("Course", "ilCourseItems_getItemData - 1");
640  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
641  {
642  $ilBench->start("Course", "ilCourseItems_getItemData - 2");
643  $a_item["timing_type"] = $row->timing_type;
644  $a_item["timing_start"] = $row->timing_start;
645  $a_item["timing_end"] = $row->timing_end;
646  $a_item["suggestion_start"] = $row->suggestion_start ? $row->suggestion_start :
647  mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
648  $a_item["suggestion_end"] = $row->suggestion_end ? $row->suggestion_end :
649  mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
650  $a_item['changeable'] = $row->changeable;
651  $a_item['earliest_start'] = $row->earliest_start ? $row->earliest_start :
652  mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
653  $a_item['latest_end'] = $row->latest_end ? $row->latest_end :
654  mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
655  $a_item['visible'] = $row->visible;
656 
657  include_once 'Modules/Course/classes/Timings/class.ilTimingPlaned.php';
658  $data = ilTimingPlaned::_getPlanedTimings($this->getUserId(),$a_item['child']);
659  $ilBench->stop("Course", "ilCourseItems_getItemData - 2");
660 
661  $ilBench->start("Course", "ilCourseItems_getItemData - 3");
662 
663  // changed for performance reasons
664  $obj_id = ($a_item['obj_id'] > 0)
665  ? $a_item['obj_id']
666  : $ilObjDataCache->lookupObjId($row->obj_id);
667  $obj_type = ($a_item['type'] != "")
668  ? $a_item['type']
669  : $ilObjDataCache->lookupType($obj_id);
670 
671 
672  $ilBench->stop("Course", "ilCourseItems_getItemData - 3");
673 
674  //if($ilObjDataCache->lookupType($obj_id = $ilObjDataCache->lookupObjId($row->obj_id)) == 'sess')
675 
676  // Check for user entry
677  $ilBench->start("Course", "ilCourseItems_getItemData - 4");
678  if($a_item['changeable'] and
679  $a_item['timing_type'] == IL_CRS_TIMINGS_PRESETTING)
680  {
681  if($data['planed_start'])
682  {
683  $a_item['start'] = $data['planed_start'];
684  $a_item['end'] = $data['planed_end'];
685  $a_item['activation_info'] = 'crs_timings_planed_info';
686  }
687  else
688  {
689  $a_item['start'] = $row->suggestion_start;
690  $a_item['end'] = $row->suggestion_end;
691  $a_item['activation_info'] = 'crs_timings_suggested_info';
692  }
693  }
694  elseif($a_item['timing_type'] == IL_CRS_TIMINGS_PRESETTING)
695  {
696  $a_item['start'] = $row->suggestion_start;
697  $a_item['end'] = $row->suggestion_end;
698  $a_item['activation_info'] = 'crs_timings_suggested_info';
699  }
700  elseif($a_item['timing_type'] == IL_CRS_TIMINGS_ACTIVATION)
701  {
702  $a_item['start'] = $row->timing_start;
703  $a_item['end'] = $row->timing_end;
704  $a_item['activation_info'] = 'activation';
705  }
706  elseif($obj_type == 'sess')
707  {
708  include_once('./Modules/Session/classes/class.ilSessionAppointment.php');
709 
710  $ilBench->start("Course", "ilCourseItems_getItemData - lookupAppointment");
712  $ilBench->stop("Course", "ilCourseItems_getItemData - lookupAppointment");
713 
714  $a_item['timing_type'] = IL_CRS_TIMINGS_FIXED;
715  $a_item['start'] = $info['start'];
716  $a_item['end'] = $info['end'];
717  $a_item['fullday'] = $info['fullday'];
718  $a_item['activation_info'] = 'crs_timings_suggested_info';
719  }
720  else
721  {
722  $a_item['start'] = 999999999;
723  }
724  $ilBench->stop("Course", "ilCourseItems_getItemData - 4");
725  }
726 
727  $ilBench->start("Course", "ilCourseItems_getItemData - 5");
728  if(!isset($a_item["timing_start"]))
729  {
730  $a_item = $this->createDefaultEntry($a_item);
731  }
732  $ilBench->stop("Course", "ilCourseItems_getItemData - 5");
733 
734  return $a_item;
735  }
736 
737  function createDefaultEntry($a_item)
738  {
739  global $ilDB, $objDefinition;
740 
741  $a_item["timing_type"] = IL_CRS_TIMINGS_DEACTIVATED;
742  $a_item["timing_start"] = time();
743  $a_item["timing_end"] = time();
744  $a_item["suggestion_start"] = time();
745  $a_item["suggestion_end"] = time();
746  $a_item['visible'] = 0;
747  $a_item['changeable'] = 0;
748  $a_item['earliest_start'] = time();
749  $a_item['latest_end'] = mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
750  $a_item['visible'] = 0;
751  $a_item['changeable'] = 0;
752 
753 
754  $query = "INSERT INTO crs_items (parent_id,obj_id,timing_type,timing_start,timing_end," .
755  "suggestion_start,suggestion_end, ".
756  "changeable,earliest_start,latest_end,visible,position) ".
757  "VALUES( ".
758  $ilDB->quote($a_item['parent'],'integer').",".
759  $ilDB->quote($a_item["child"],'integer').",".
760  $ilDB->quote($a_item["timing_type"],'integer').",".
761  $ilDB->quote($a_item["timing_start"],'integer').",".
762  $ilDB->quote($a_item["timing_end"],'integer').",".
763  $ilDB->quote($a_item["suggestion_start"],'integer').",".
764  $ilDB->quote($a_item["suggestion_end"],'integer').",".
765  $ilDB->quote($a_item["changeable"],'integer').",".
766  $ilDB->quote($a_item['earliest_start'],'integer').", ".
767  $ilDB->quote($a_item['latest_end'],'integer').", ".
768  $ilDB->quote($a_item["visible"],'integer').", ".
769  $ilDB->quote(0,'integer').")";
770  $res = $ilDB->manipulate($query);
771 
772  return $a_item;
773  }
774 
775  // methods for manual sortation
776  function __getLastPosition()
777  {
778  global $ilDB;
779 
780  $query = "SELECT MAX(position) last_position FROM crs_items ".
781  "WHERE parent_id = ".$ilDB->quote($this->getParentId(),'integer')." ";
782 
783  $res = $this->ilDB->query($query);
784  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
785  {
786  $max = $row->last_position;
787  }
788  return $max ? $max : 0;
789  }
790 
791 
792 
793  function __isMovable($a_ref_id)
794  {
795  include_once 'Modules/Session/classes/class.ilEventItems.php';
796 
797  global $ilObjDataCache;
798 
799  if($ilObjDataCache->lookupType($ilObjDataCache->lookupObjId($a_ref_id)) != 'crs')
800  {
801  return true;
802  }
803  if(ilEventItems::_isAssigned($a_ref_id))
804  {
805  return false;
806  }
807  return true;
808  }
809 
810  function __switchNodes($node_a,$node_b)
811  {
812  global $ilDB;
813 
814  if(!$node_b["obj_id"])
815  {
816  return false;
817  }
818 
819  $query = "UPDATE crs_items SET ".
820  "position = ".$ilDB->quote($node_a["position"],'integer')." ".
821  "WHERE obj_id = ".$ilDB->quote($node_b["obj_id"],'integer')." ".
822  "AND parent_id = ".$ilDB->quote($this->getParentId(),'integer')."";
823  $res = $ilDB->manipulate($query);
824 
825  $query = "UPDATE crs_items SET ".
826  "position = ".$ilDB->quote($node_b["position"],'integer')." ".
827  "WHERE obj_id = ".$ilDB->quote($node_a["obj_id"],'integer')." ".
828  "AND parent_id = ".$ilDB->quote($this->getParentId(),'integer')."";
829  $res = $ilDB->manipulate($query);
830 
831  return true;
832  }
833 
842  public static function _sort($a_sort_mode,$a_items)
843  {
844  switch($a_sort_mode)
845  {
847  // Sort by starting time. If mode is IL_CRS_TIMINGS_DEACTIVATED then sort these items by title and append
848  // them to the array.
849  $inactive = $active = array();
850  foreach($a_items as $item)
851  {
852  if($item['timing_type'] == IL_CRS_TIMINGS_DEACTIVATED)
853  {
854  $inactive[] = $item;
855  }
856  else
857  {
858  $active[] = $item;
859  }
860  }
861  $sorted_active = ilUtil::sortArray($active,"start","asc");
862  $sorted_inactive = ilUtil::sortArray($inactive,'title','asc');
863 
864  return array_merge($sorted_active,$sorted_inactive);
865  break;
866 
867  default:
868  return $a_items;
869  }
870  return true;
871 
872  }
873 
874 
875  function __sort()
876  {
877  include_once './Services/Container/classes/class.ilContainerSortingSettings.php';
879  switch($sort)
880  {
882  // Sort by starting time. If mode is IL_CRS_TIMINGS_DEACTIVATED then sort these items by title and append
883  // them to the array.
884  list($active,$inactive) = $this->__splitByActivation();
885 
886  $sorted_active = ilUtil::sortArray($active,"start","asc");
887  $sorted_inactive = ilUtil::sortArray($inactive,'title','asc');
888 
889  $this->items = array_merge($sorted_active,$sorted_inactive);
890  break;
891 
892  default:
893  return true;
894  }
895  return true;
896  }
897 
899  {
900  $inactive = $active = array();
901  foreach($this->items as $item)
902  {
903  if($item['timing_type'] == IL_CRS_TIMINGS_DEACTIVATED)
904  {
905  $inactive[] = $item;
906  }
907  else
908  {
909  $active[] = $item;
910  }
911  }
912  return array($active,$inactive);
913  }
914  // STATIC
919  public static function _getItem($a_item_id)
920  {
921  include_once 'Modules/Course/classes/class.ilObjCourse.php';
922 
923  global $ilDB,$ilUser;
924 
925  $query = "SELECT * FROM crs_items ".
926  "WHERE obj_id = ".$ilDB->quote($a_item_id,'integer');
927  $res = $ilDB->query($query);
928  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
929  {
930  $data['parent_id'] = $row->parent_id;
931  $data['obj_id'] = $row->obj_id;
932  $data['ref_id'] = $row->obj_id;
933  $data['child'] = $row->obj_id;
934  $data['timing_type'] = $row->timing_type;
935  $data['timing_start'] = $row->timing_start;
936  $data['timing_end'] = $row->timing_end;
937  $data["suggestion_start"] = $row->suggestion_start ? $row->suggestion_start :
938  mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
939  $data["suggestion_end"] = $row->suggestion_end ? $row->suggestion_end :
940  mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
941  $data['changeable'] = $row->changeable;
942  $data['earliest_start'] = $row->earliest_start ? $row->earliest_start :
943  mktime(0,0,1,date('n',time()),date('j',time()),date('Y',time()));
944  $data['latest_end'] = $row->latest_end ? $row->latest_end :
945  mktime(23,55,00,date('n',time()),date('j',time()),date('Y',time()));
946  $data['visible'] = $row->visible;
947 
948  include_once 'Modules/Course/classes/Timings/class.ilTimingPlaned.php';
949  $user_data = ilTimingPlaned::_getPlanedTimings($ilUser->getId(),$data['child']);
950 
951  // #7359 - session sorting should always base on appointment date
952  if(ilObject::_lookupType($a_item_id) == 'sess')
953  {
954  include_once('./Modules/Session/classes/class.ilSessionAppointment.php');
955  $info = ilSessionAppointment::_lookupAppointment($a_item_id);
956 
957  $data['start'] = $info['start'];
958  $data['end'] = $info['end'];
959  $data['activation_info'] = 'crs_timings_suggested_info';
960  }
961  // Check for user entry
962  else if($data['changeable'] and
963  $data['timing_type'] == IL_CRS_TIMINGS_PRESETTING)
964  {
965  if($user_data['planed_start'])
966  {
967  $data['start'] = $user_data['planed_start'];
968  $data['end'] = $user_data['planed_end'];
969  $data['activation_info'] = 'crs_timings_planed_info';
970  }
971  else
972  {
973  $data['start'] = $row->suggestion_start;
974  $data['end'] = $row->suggestion_end;
975  $data['activation_info'] = 'crs_timings_suggested_info';
976  }
977  }
978  elseif($data['timing_type'] == IL_CRS_TIMINGS_PRESETTING)
979  {
980  $data['start'] = $row->suggestion_start;
981  $data['end'] = $row->suggestion_end;
982  $data['activation_info'] = 'crs_timings_suggested_info';
983  }
984  elseif($data['timing_type'] == IL_CRS_TIMINGS_ACTIVATION)
985  {
986  $data['start'] = $row->timing_start;
987  $data['end'] = $row->timing_end;
988  $data['activation_info'] = 'activation';
989  }
990  else
991  {
992  $data['start'] = 999999999;
993  }
994  }
995  return $data ? $data : array();
996  }
997 
998  function _isActivated($a_item_id)
999  {
1000  global $ilDB;
1001 
1002  $query = "SELECT * FROM crs_items ".
1003  "WHERE obj_id = ".$ilDB->quote($a_item_id,'integer')." ";
1004 
1005  $res = $ilDB->query($query);
1006  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1007  {
1008  if($row->activation_unlimited)
1009  {
1010  return true;
1011  }
1012  if(time() > $row->activation_start and time() < $row->activation_end)
1013  {
1014  return true;
1015  }
1016  }
1017  return true;
1018  }
1019 
1027  public static function _readActivationTimes($a_ref_ids)
1028  {
1029  global $ilDB;
1030 
1031  if(!is_array($a_ref_ids) or !$a_ref_ids)
1032  {
1033  return array();
1034  }
1035 
1036  $query = "SELECT obj_id,timing_type,timing_start,timing_end,visible FROM crs_items ".
1037  "WHERE ".$ilDB->in('obj_id',$a_ref_ids,false,'integer');
1038 
1039  $res = $ilDB->query($query);
1040  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
1041  {
1042  $ac_times[(string) $row->obj_id]['obj_id'] = $row->obj_id;
1043  $ac_times[(string) $row->obj_id]['timing_type'] = $row->timing_type;
1044  $ac_times[(string) $row->obj_id]['timing_start'] = $row->timing_start;
1045  $ac_times[(string) $row->obj_id]['timing_end'] = $row->timing_end;
1046  $ac_times[(string) $row->obj_id]['visible'] = $row->visible;
1047  }
1048 
1049  return $ac_times ? $ac_times : array();
1050  }
1051 
1056  {
1057  if (is_array($this->items_per_child[$a_item["child"]]))
1058  {
1059  $a_item = array_merge($a_item, $this->items_per_child[$a_item["child"]]);
1060  }
1061  }
1062 }
1063 ?>