1<?php
2/* Copyright (c) 1998-2013 ILIAS open source, Extended GPL, see docs/LICENSE */
3
4
5/**
6 * @author		Björn Heyser <bheyser@databay.de>
7 * @version		$Id$
8 *
9 * @package     Modules/Test
10 */
11class ilTestParticipantData
12{
13    /**
14     * @var ilDBInterface
15     */
16    protected $db;
17
18    /**
19     * @var ilLanguage
20     */
21    protected $lng;
22
23    /**
24     * @var array
25     */
26    private $activeIdsFilter;
27
28    /**
29     * @var array
30     */
31    private $userIdsFilter;
32
33    /**
34     * @var array
35     */
36    private $anonymousIdsFilter;
37
38    /**
39     * @var array
40     */
41    private $byActiveId;
42
43    /**
44     * @var array
45     */
46    private $byUserId;
47
48    /**
49     * @var array
50     */
51    private $byAnonymousId;
52
53    /**
54     * @var callable
55     */
56    protected $participantAccessFilter;
57
58    /**
59     * @var bool
60     */
61    protected $scoredParticipantsFilterEnabled;
62
63    public function __construct(ilDBInterface $db, ilLanguage $lng)
64    {
65        $this->db = $db;
66        $this->lng = $lng;
67
68        $this->activeIdsFilter = array();
69        $this->userIdsFilter = array();
70        $this->anonymousIdsFilter = array();
71
72        $this->byActiveId = array();
73        $this->byUserId = array();
74        $this->byAnonymousId = array();
75
76        $this->scoredParticipantsFilterEnabled = false;
77    }
78
79    /**
80     * @return callable
81     */
82    public function getParticipantAccessFilter()
83    {
84        return $this->participantAccessFilter;
85    }
86
87    /**
88     * @param callable $participantAccessFilter
89     */
90    public function setParticipantAccessFilter($participantAccessFilter)
91    {
92        $this->participantAccessFilter = $participantAccessFilter;
93    }
94
95    /**
96     * @return bool
97     */
98    public function isScoredParticipantsFilterEnabled()
99    {
100        return $this->scoredParticipantsFilterEnabled;
101    }
102
103    /**
104     * @param bool $scoredParticipantsFilterEnabled
105     */
106    public function setScoredParticipantsFilterEnabled($scoredParticipantsFilterEnabled)
107    {
108        $this->scoredParticipantsFilterEnabled = $scoredParticipantsFilterEnabled;
109    }
110
111    public function load($testId)
112    {
113        $this->byActiveId = array();
114        $this->byUserId = array();
115
116        $query = "
117			SELECT		ta.active_id,
118						ta.user_fi user_id,
119						ta.anonymous_id,
120						ud.firstname,
121						ud.lastname,
122						ud.login,
123						ud.matriculation
124			FROM		tst_active ta
125			LEFT JOIN	usr_data ud
126			ON 			ud.usr_id = ta.user_fi
127			WHERE		test_fi = %s
128			AND			{$this->getConditionalExpression()}
129			AND 		{$this->getScoredParticipantsFilterExpression()}
130		";
131
132        $res = $this->db->queryF($query, array('integer'), array($testId));
133
134        $rows = array();
135        $accessFilteredUsrIds = array();
136
137        while ($row = $this->db->fetchAssoc($res)) {
138            $accessFilteredUsrIds[] = $row['user_id'];
139            $rows[] = $row;
140        }
141
142        if (is_callable($this->getParticipantAccessFilter(), true)) {
143            $accessFilteredUsrIds = call_user_func_array($this->getParticipantAccessFilter(), [$accessFilteredUsrIds]);
144        }
145
146        foreach ($rows as $row) {
147            if (!in_array($row['user_id'], $accessFilteredUsrIds)) {
148                continue;
149            }
150
151            $this->byActiveId[ $row['active_id'] ] = $row;
152
153            if ($row['user_id'] == ANONYMOUS_USER_ID) {
154                $this->byAnonymousId[ $row['anonymous_id'] ] = $row;
155            } else {
156                $this->byUserId[ $row['user_id'] ] = $row;
157            }
158        }
159    }
160
161    public function getScoredParticipantsFilterExpression()
162    {
163        if ($this->isScoredParticipantsFilterEnabled()) {
164            return "ta.last_finished_pass = ta.last_started_pass";
165        }
166
167        return '1 = 1';
168    }
169
170    public function getConditionalExpression()
171    {
172        $conditions = array();
173
174        if (count($this->getActiveIdsFilter())) {
175            $conditions[] = $this->db->in('active_id', $this->getActiveIdsFilter(), false, 'integer');
176        }
177
178        if (count($this->getUserIdsFilter())) {
179            $conditions[] = $this->db->in('user_fi', $this->getUserIdsFilter(), false, 'integer');
180        }
181
182        if (count($this->getAnonymousIdsFilter())) {
183            $conditions[] = $this->db->in('anonymous_id', $this->getAnonymousIdsFilter(), false, 'integer');
184        }
185
186        if (count($conditions)) {
187            return '(' . implode(' OR ', $conditions) . ')';
188        }
189
190        return '1 = 1';
191    }
192
193    public function setActiveIdsFilter($activeIdsFilter)
194    {
195        $this->activeIdsFilter = $activeIdsFilter;
196    }
197
198    public function getActiveIdsFilter()
199    {
200        return $this->activeIdsFilter;
201    }
202
203    public function setUserIdsFilter($userIdsFilter)
204    {
205        $this->userIdsFilter = $userIdsFilter;
206    }
207
208    public function getUserIdsFilter()
209    {
210        return $this->userIdsFilter;
211    }
212
213    public function setAnonymousIdsFilter($anonymousIdsFilter)
214    {
215        $this->anonymousIdsFilter = $anonymousIdsFilter;
216    }
217
218    public function getAnonymousIdsFilter()
219    {
220        return $this->anonymousIdsFilter;
221    }
222
223    public function getActiveIds()
224    {
225        return array_keys($this->byActiveId);
226    }
227
228    public function getUserIds()
229    {
230        return array_keys($this->byUserId);
231    }
232
233    public function getAnonymousIds()
234    {
235        return array_keys($this->byAnonymousId);
236    }
237
238    public function getUserIdByActiveId($activeId)
239    {
240        return $this->byActiveId[$activeId]['user_id'];
241    }
242
243    public function getActiveIdByUserId($userId)
244    {
245        return $this->byUserId[$userId]['active_id'];
246    }
247
248    public function getConcatedFullnameByActiveId($activeId)
249    {
250        return "{$this->byActiveId[$activeId]['firstname']} {$this->byActiveId[$activeId]['lastname']}";
251    }
252
253    public function getFormatedFullnameByActiveId($activeId)
254    {
255        return $this->buildFormatedFullname($this->byActiveId[$activeId]);
256    }
257
258    public function getFileSystemCompliantFullnameByActiveId($activeId)
259    {
260        $fullname = str_replace(' ', '', $this->byActiveId[$activeId]['lastname']);
261        $fullname .= '_' . str_replace(' ', '', $this->byActiveId[$activeId]['firstname']);
262        $fullname .= '_' . $this->byActiveId[$activeId]['login'];
263
264        return ilUtil::getASCIIFilename($fullname);
265    }
266
267    public function getOptionArray()
268    {
269        $options = array();
270
271        foreach ($this->byActiveId as $activeId => $usrData) {
272            $options[$activeId] = $this->buildFormatedFullname($usrData);
273        }
274
275        asort($options);
276
277        return $options;
278    }
279
280    private function buildFormatedFullname($usrData)
281    {
282        return sprintf(
283            $this->lng->txt('tst_participant_fullname_pattern'),
284            $usrData['firstname'],
285            $usrData['lastname']
286        );
287    }
288
289    public function getAnonymousActiveIds()
290    {
291        $anonymousActiveIds = array();
292
293        foreach ($this->byActiveId as $activeId => $active) {
294            if ($active['user_id'] == ANONYMOUS_USER_ID) {
295                $anonymousActiveIds[] = $activeId;
296            }
297        }
298
299        return $anonymousActiveIds;
300    }
301
302    public function getUserDataByActiveId($activeId)
303    {
304        if (isset($this->byActiveId[$activeId])) {
305            return $this->byActiveId[$activeId];
306        }
307
308        return null;
309    }
310}
311