1<?php
2/* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4/**
5* Class ilLPObjSettings
6*
7* @author Stefan Meyer <meyer@leifos.com>
8*
9* @version $Id$
10*
11* @package ilias-tracking
12*
13*/
14class ilLPObjSettings
15{
16    public $db = null;
17
18    public $obj_id = null;
19    public $obj_type = null;
20    public $obj_mode = null;
21    public $visits = null;
22
23    public $is_stored = false;
24
25    const LP_MODE_DEACTIVATED = 0;
26    const LP_MODE_TLT = 1;
27    const LP_MODE_VISITS = 2;
28    const LP_MODE_MANUAL = 3;
29    const LP_MODE_OBJECTIVES = 4;
30    const LP_MODE_COLLECTION = 5;
31    const LP_MODE_SCORM = 6;
32    const LP_MODE_TEST_FINISHED = 7;
33    const LP_MODE_TEST_PASSED = 8;
34    const LP_MODE_EXERCISE_RETURNED = 9;
35    const LP_MODE_EVENT = 10;
36    const LP_MODE_MANUAL_BY_TUTOR = 11;
37    const LP_MODE_SCORM_PACKAGE = 12;
38    const LP_MODE_UNDEFINED = 13;
39    const LP_MODE_PLUGIN = 14;
40    const LP_MODE_COLLECTION_TLT = 15;
41    const LP_MODE_COLLECTION_MANUAL = 16;
42    const LP_MODE_QUESTIONS = 17;
43    const LP_MODE_SURVEY_FINISHED = 18;
44    const LP_MODE_VISITED_PAGES = 19;
45    const LP_MODE_CONTENT_VISITED = 20;
46    const LP_MODE_COLLECTION_MOBS = 21;
47    const LP_MODE_STUDY_PROGRAMME = 22;
48    const LP_MODE_INDIVIDUAL_ASSESSMENT = 23;
49    const LP_MODE_CMIX_COMPLETED = 24;
50    const LP_MODE_CMIX_COMPL_WITH_FAILED = 25;
51    const LP_MODE_CMIX_PASSED = 26;
52    const LP_MODE_CMIX_PASSED_WITH_FAILED = 27;
53    const LP_MODE_CMIX_COMPLETED_OR_PASSED = 28;
54    const LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED = 29;
55
56    const LP_DEFAULT_VISITS = 30; // ???
57
58    const LP_MODE_LTI_OUTCOME = 31;
59
60    const LP_MODE_COURSE_REFERENCE = 32;
61
62    protected static $map = array(
63
64        self::LP_MODE_DEACTIVATED => array('ilLPStatus',
65            'trac_mode_deactivated', 'trac_mode_deactivated_info_new')
66
67        ,self::LP_MODE_TLT => array('ilLPStatusTypicalLearningTime',
68            'trac_mode_tlt', 'trac_mode_tlt_info') // info has dynamic part!
69
70        ,self::LP_MODE_VISITS => array('ilLPStatusVisits',
71            'trac_mode_visits', 'trac_mode_visits_info')
72
73        ,self::LP_MODE_MANUAL => array('ilLPStatusManual',
74            'trac_mode_manual', 'trac_mode_manual_info')
75
76        ,self::LP_MODE_OBJECTIVES => array('ilLPStatusObjectives',
77            'trac_mode_objectives', 'trac_mode_objectives_info')
78
79        ,self::LP_MODE_COLLECTION => array('ilLPStatusCollection',
80            'trac_mode_collection', 'trac_mode_collection_info')
81
82        ,self::LP_MODE_SCORM => array('ilLPStatusSCORM',
83            'trac_mode_scorm', 'trac_mode_scorm_info')
84
85        ,self::LP_MODE_TEST_FINISHED => array('ilLPStatusTestFinished',
86            'trac_mode_test_finished', 'trac_mode_test_finished_info')
87
88        ,self::LP_MODE_TEST_PASSED => array('ilLPStatusTestPassed',
89            'trac_mode_test_passed', 'trac_mode_test_passed_info')
90
91        ,self::LP_MODE_EXERCISE_RETURNED => array('ilLPStatusExerciseReturned',
92            'trac_mode_exercise_returned', 'trac_mode_exercise_returned_info')
93
94        ,self::LP_MODE_EVENT => array('ilLPStatusEvent',
95            'trac_mode_event', 'trac_mode_event_info')
96
97        ,self::LP_MODE_MANUAL_BY_TUTOR => array('ilLPStatusManualByTutor',
98            'trac_mode_manual_by_tutor', 'trac_mode_manual_by_tutor_info')
99
100        ,self::LP_MODE_SCORM_PACKAGE => array('ilLPStatusSCORMPackage',
101            'trac_mode_scorm_package', 'trac_mode_scorm_package_info')
102
103        ,self::LP_MODE_UNDEFINED => null
104
105        ,self::LP_MODE_PLUGIN => array('ilLPStatusPlugin',
106            'trac_mode_plugin', '') // no settings screen, so no info needed
107
108        ,self::LP_MODE_COLLECTION_TLT => array('ilLPStatusCollectionTLT',
109            'trac_mode_collection_tlt', 'trac_mode_collection_tlt_info')
110
111        ,self::LP_MODE_COLLECTION_MANUAL => array('ilLPStatusCollectionManual',
112            'trac_mode_collection_manual', 'trac_mode_collection_manual_info')
113
114        ,self::LP_MODE_QUESTIONS => array('ilLPStatusQuestions',
115            'trac_mode_questions', 'trac_mode_questions_info')
116
117        ,self::LP_MODE_SURVEY_FINISHED => array('ilLPStatusSurveyFinished',
118            'trac_mode_survey_finished', 'trac_mode_survey_finished_info')
119
120        ,self::LP_MODE_VISITED_PAGES => array('ilLPStatusVisitedPages',
121            'trac_mode_visited_pages', 'trac_mode_visited_pages_info')
122
123        ,self::LP_MODE_CONTENT_VISITED => array('ilLPStatusContentVisited',
124            'trac_mode_content_visited', 'trac_mode_content_visited_info')
125
126        ,self::LP_MODE_COLLECTION_MOBS => array('ilLPStatusCollectionMobs',
127            'trac_mode_collection_mobs', 'trac_mode_collection_mobs_info')
128
129        ,self::LP_MODE_STUDY_PROGRAMME => array('ilLPStatusStudyProgramme',
130            'trac_mode_study_programme', '')
131
132        ,self::LP_MODE_INDIVIDUAL_ASSESSMENT => array('ilLPStatusIndividualAssessment',
133            'trac_mode_individual_assessment', 'trac_mode_individual_assessment_info')
134
135        ,self::LP_MODE_CMIX_COMPLETED => array(ilLPStatusCmiXapiCompleted::class,
136            'trac_mode_cmix_completed', 'trac_mode_cmix_completed_info')
137
138        ,self::LP_MODE_CMIX_COMPL_WITH_FAILED => array(ilLPStatusCmiXapiCompletedWithFailed::class,
139            'trac_mode_cmix_compl_with_failed', 'trac_mode_cmix_compl_with_failed_info')
140
141        ,self::LP_MODE_CMIX_PASSED => array(ilLPStatusCmiXapiPassed::class,
142            'trac_mode_cmix_passed', 'trac_mode_cmix_passed_info')
143
144        ,self::LP_MODE_CMIX_PASSED_WITH_FAILED => array(ilLPStatusCmiXapiPassedWithFailed::class,
145            'trac_mode_cmix_passed_with_failed', 'trac_mode_cmix_passed_with_failed_info')
146
147        ,self::LP_MODE_CMIX_COMPLETED_OR_PASSED => array(ilLPStatusCmiXapiCompletedOrPassed::class,
148            'trac_mode_cmix_completed_or_passed', 'trac_mode_cmix_completed_or_passed_info')
149
150        ,self::LP_MODE_CMIX_COMPL_OR_PASSED_WITH_FAILED => array(ilLPStatusCmiXapiCompletedOrPassedWithFailed::class,
151            'trac_mode_cmix_compl_or_passed_with_failed', 'trac_mode_cmix_compl_or_passed_with_failed_info')
152
153        ,self::LP_MODE_LTI_OUTCOME => array(ilLPStatusLtiOutcome::class,
154        'trac_mode_lti_outcome', 'trac_mode_lti_outcome_info')
155
156        ,self::LP_MODE_COURSE_REFERENCE => [
157            'ilLPStatusCourseReference',
158            'trac_mode_course_reference',
159            'trac_mode_course_reference_info'
160        ]
161    );
162
163    /**
164     * ilLPObjSettings constructor.
165     * @param int $a_obj_id
166     */
167    public function __construct($a_obj_id)
168    {
169        global $DIC;
170
171        $ilObjDataCache = $DIC['ilObjDataCache'];
172        $ilDB = $DIC['ilDB'];
173
174        $this->db = $ilDB;
175        $this->obj_id = $a_obj_id;
176
177        if (!$this->__read()) {
178            $this->obj_type = $ilObjDataCache->lookupType($this->obj_id);
179
180            include_once "Services/Object/classes/class.ilObjectLP.php";
181            $olp = ilObjectLP::getInstance($this->obj_id);
182            $this->obj_mode = $olp->getDefaultMode();
183        }
184    }
185
186    /**
187     * Clone settings
188     *
189     * @access public
190     * @param int new obj id
191     *
192     */
193    public function cloneSettings($a_new_obj_id)
194    {
195        global $DIC;
196
197        $ilDB = $DIC['ilDB'];
198
199        $query = "INSERT INTO ut_lp_settings (obj_id,obj_type,u_mode,visits) " .
200            "VALUES( " .
201            $this->db->quote($a_new_obj_id, 'integer') . ", " .
202            $this->db->quote($this->getObjType(), 'text') . ", " .
203            $this->db->quote($this->getMode(), 'integer') . ", " .
204            $this->db->quote($this->getVisits(), 'integer') .
205            ")";
206        $res = $ilDB->manipulate($query);
207        return true;
208    }
209
210    public function getVisits()
211    {
212        return (int) $this->visits ? $this->visits : self::LP_DEFAULT_VISITS;
213    }
214
215    public function setVisits($a_visits)
216    {
217        $this->visits = $a_visits;
218    }
219
220    public function setMode($a_mode)
221    {
222        $this->obj_mode = $a_mode;
223    }
224
225    public function getMode()
226    {
227        return $this->obj_mode;
228    }
229
230    public function getObjId()
231    {
232        return (int) $this->obj_id;
233    }
234
235    public function getObjType()
236    {
237        return $this->obj_type;
238    }
239
240    public function __read()
241    {
242        $res = $this->db->query("SELECT * FROM ut_lp_settings WHERE obj_id = " .
243            $this->db->quote($this->obj_id, 'integer'));
244        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
245            $this->is_stored = true;
246            $this->obj_type = $row->obj_type;
247            $this->obj_mode = $row->u_mode;
248            $this->visits = $row->visits;
249
250            return true;
251        }
252
253        return false;
254    }
255
256    public function update($a_refresh_lp = true)
257    {
258        global $DIC;
259
260        $ilDB = $DIC['ilDB'];
261
262        if (!$this->is_stored) {
263            return $this->insert();
264        }
265        $query = "UPDATE ut_lp_settings SET u_mode = " . $ilDB->quote($this->getMode(), 'integer') . ", " .
266            "visits = " . $ilDB->quote($this->getVisits(), 'integer') . " " .
267            "WHERE obj_id = " . $ilDB->quote($this->getObjId(), 'integer');
268        $res = $ilDB->manipulate($query);
269        $this->__read();
270
271        if ($a_refresh_lp) {
272            $this->doLPRefresh();
273        }
274
275        return true;
276    }
277
278    public function insert()
279    {
280        global $DIC;
281
282        $ilDB = $DIC['ilDB'];
283
284        $query = "INSERT INTO ut_lp_settings (obj_id,obj_type,u_mode,visits) " .
285            "VALUES(" .
286            $ilDB->quote($this->getObjId(), 'integer') . ", " .
287            $ilDB->quote($this->getObjType(), 'text') . ", " .
288            $ilDB->quote($this->getMode(), 'integer') . ", " .
289            $ilDB->quote($this->getVisits(), 'integer') .  // #12482
290            ")";
291        $res = $ilDB->manipulate($query);
292        $this->__read();
293
294        $this->doLPRefresh();
295
296        return true;
297    }
298
299    protected function doLPRefresh()
300    {
301        // refresh learning progress
302        include_once("./Services/Tracking/classes/class.ilLPStatusWrapper.php");
303        ilLPStatusWrapper::_refreshStatus($this->getObjId());
304    }
305
306    public static function _delete($a_obj_id)
307    {
308        global $DIC;
309
310        $ilDB = $DIC['ilDB'];
311
312        $query = "DELETE FROM ut_lp_settings WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer');
313        $res = $ilDB->manipulate($query);
314
315        return true;
316    }
317
318
319    // Static
320
321    public static function _lookupVisits($a_obj_id)
322    {
323        global $DIC;
324
325        $ilDB = $DIC['ilDB'];
326
327        $query = "SELECT visits FROM ut_lp_settings " .
328            "WHERE obj_id = " . $ilDB->quote($a_obj_id, 'integer');
329
330        $res = $ilDB->query($query);
331        while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
332            return $row->visits;
333        }
334        return self::LP_DEFAULT_VISITS;
335    }
336
337    public static function _lookupDBModeForObjects(array $a_obj_ids)
338    {
339        global $DIC;
340
341        $ilDB = $DIC['ilDB'];
342
343        // this does NOT handle default mode!
344
345        $res = array();
346
347        $query = "SELECT obj_id, u_mode FROM ut_lp_settings" .
348            " WHERE " . $ilDB->in("obj_id", $a_obj_ids, "", "integer");
349        $set = $ilDB->query($query);
350        while ($row = $set->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) {
351            $res[$row->obj_id] = $row->u_mode;
352        }
353
354        return $res;
355    }
356
357    public static function _lookupDBMode($a_obj_id)
358    {
359        global $DIC;
360
361        $ilDB = $DIC['ilDB'];
362
363        // this does NOT handle default mode!
364
365        $query = "SELECT u_mode FROM ut_lp_settings" .
366            " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer");
367        $set = $ilDB->query($query);
368        $row = $ilDB->fetchAssoc($set);
369        if (is_array($row)) {
370            return $row['u_mode'];
371        }
372    }
373
374    public static function _mode2Text($a_mode)
375    {
376        global $DIC;
377
378        $lng = $DIC['lng'];
379
380        if (array_key_exists($a_mode, self::$map) &&
381            is_array(self::$map[$a_mode])) {
382            return $lng->txt(self::$map[$a_mode][1]);
383        }
384    }
385
386    public static function _mode2InfoText($a_mode)
387    {
388        global $DIC;
389
390        $lng = $DIC['lng'];
391
392        if (array_key_exists($a_mode, self::$map) &&
393            is_array(self::$map[$a_mode])) {
394            $info = $lng->txt(self::$map[$a_mode][2]);
395
396            if ($a_mode == self::LP_MODE_TLT) {
397                // dynamic content
398                include_once 'Services/Tracking/classes/class.ilObjUserTracking.php';
399                $info = sprintf($info, ilObjUserTracking::_getValidTimeSpan());
400            }
401
402            return $info;
403        }
404    }
405
406    public static function getClassMap()
407    {
408        $res = array();
409        foreach (self::$map as $mode => $item) {
410            $res[$mode] = $item[0];
411        }
412        return $res;
413    }
414
415    public static function _deleteByObjId($a_obj_id)
416    {
417        global $DIC;
418
419        $ilDB = $DIC['ilDB'];
420
421        // we are only removing settings for now
422        // invalid ut_lp_collections-entries are filtered
423        // ut_lp_marks is deemed private user data
424
425        $ilDB->manipulate("DELETE FROM ut_lp_settings" .
426            " WHERE obj_id = " . $ilDB->quote($a_obj_id, "integer"));
427    }
428}
429