1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4require_once 'Modules/TestQuestionPool/interfaces/interface.ilQuestionChangeListener.php';
5
6/**
7 * Listener for question changes
8 *
9 * @author		Björn Heyser <bheyser@databay.de>
10 * @version		$Id$
11 *
12 * @package		Modules/Test
13 */
14class ilDynamicTestQuestionChangeListener implements ilQuestionChangeListener
15{
16    /**
17     * @var ilDBInterface
18     */
19    protected $db = null;
20
21    /**
22     * @param ilDBInterface $db
23     */
24    public function __construct(ilDBInterface $db)
25    {
26        $this->db = $db;
27    }
28
29    /**
30     * @var array[integer]
31     */
32    private $testObjIds = array();
33
34    /**
35     * @param integer $testObjId
36     */
37    public function addTestObjId($testObjId)
38    {
39        $this->testObjIds[] = $testObjId;
40    }
41
42    /**
43     * @return array[integer]
44     */
45    public function getTestObjIds()
46    {
47        return $this->testObjIds;
48    }
49
50    /**
51     * @param assQuestion $question
52     */
53    public function notifyQuestionCreated(assQuestion $question)
54    {
55        //mail('bheyser@databay.de', __METHOD__, __METHOD__);
56        // nothing to do
57    }
58
59    /**
60     * @param assQuestion $question
61     */
62    public function notifyQuestionEdited(assQuestion $question)
63    {
64        //mail('bheyser@databay.de', __METHOD__, __METHOD__);
65        $this->deleteTestsParticipantsQuestionData($question);
66    }
67
68    public function notifyQuestionDeleted(assQuestion $question)
69    {
70        //mail('bheyser@databay.de', __METHOD__, __METHOD__);
71        $this->deleteTestsParticipantsQuestionData($question);
72    }
73
74    /**
75     * @param assQuestion $question
76     */
77    private function deleteTestsParticipantsQuestionData(assQuestion $question)
78    {
79        $activeIds = $this->getActiveIds();
80
81        if (!is_array($activeIds) || 0 === count($activeIds)) {
82            return null;
83        }
84
85        $this->deleteTestsParticipantsResultsForQuestion($activeIds, $question->getId());
86        $this->deleteTestsParticipantsTrackingsForQuestion($activeIds, $question->getId());
87    }
88
89    private function deleteTestsParticipantsResultsForQuestion($activeIds, $questionId)
90    {
91        $inActiveIds = $this->db->in('active_fi', $activeIds, false, 'integer');
92
93        $this->db->manipulateF(
94            "DELETE FROM tst_solutions WHERE question_fi = %s AND $inActiveIds",
95            array('integer'),
96            array($questionId)
97        );
98
99        $this->db->manipulateF(
100            "DELETE FROM tst_qst_solved WHERE question_fi = %s AND $inActiveIds",
101            array('integer'),
102            array($questionId)
103        );
104
105        $this->db->manipulateF(
106            "DELETE FROM tst_test_result WHERE question_fi = %s AND $inActiveIds",
107            array('integer'),
108            array($questionId)
109        );
110
111        $this->db->manipulate("DELETE FROM tst_pass_result WHERE $inActiveIds");
112
113        $this->db->manipulate("DELETE FROM tst_result_cache WHERE $inActiveIds");
114    }
115
116    private function deleteTestsParticipantsTrackingsForQuestion($activeIds, $questionId)
117    {
118        $inActiveIds = $this->db->in('active_fi', $activeIds, false, 'integer');
119
120        $tables = array(
121            'tst_seq_qst_tracking', 'tst_seq_qst_answstatus', 'tst_seq_qst_postponed', 'tst_seq_qst_checked'
122        );
123
124        foreach ($tables as $table) {
125            $this->db->manipulateF(
126                "DELETE FROM $table WHERE question_fi = %s AND $inActiveIds",
127                array('integer'),
128                array($questionId)
129            );
130        }
131    }
132
133    private function getActiveIds()
134    {
135        if (!count($this->getTestObjIds())) {
136            return null;
137        }
138
139        $inTestObjIds = $this->db->in('obj_fi', $this->getTestObjIds(), false, 'integer');
140
141        $res = $this->db->query("
142			SELECT active_id
143			FROM tst_tests
144			INNER JOIN tst_active
145			ON test_fi = test_id
146			WHERE $inTestObjIds
147		");
148
149        $activeIds = array();
150
151        while ($row = $this->db->fetchAssoc($res)) {
152            $activeIds[] = $row['active_id'];
153        }
154
155        return $activeIds;
156    }
157}
158