ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
class.ilCronFinishUnfinishedTestPasses.php
Go to the documentation of this file.
1 <?php
2 require_once 'Services/Cron/classes/class.ilCronJob.php';
3 require_once 'Services/Cron/classes/class.ilCronJobResult.php';
4 require_once 'Modules/Test/classes/class.ilObjTest.php';
5 require_once 'Modules/Test/classes/class.ilTestPassFinishTasks.php';
6 require_once 'Services/Logging/classes/public/class.ilLoggerFactory.php';
7 
8 /* Copyright (c) 1998-2016 ILIAS open source, Extended GPL, see docs/LICENSE */
9 
15 {
16 
20  protected $log;
21 
25  protected $lng;
26 
30  protected $db;
31 
35  protected $obj_data_cache;
36 
40  protected $now;
41 
42  protected $unfinished_passes;
43 
44  protected $test_ids;
45 
46  protected $test_ending_times;
47 
52 
56  public function __construct()
57  {
63  global $DIC;
64  $ilObjDataCache = $DIC['ilObjDataCache'];
65  $lng = $DIC['lng'];
66  $ilDB = $DIC['ilDB'];
67 
68  global $DIC; /* @var ILIAS\DI\Container $DIC */
69 
70  $this->log = ilLoggerFactory::getLogger('tst');
71  $this->lng = $lng;
72  $this->lng->loadLanguageModule('assessment');
73  $this->db = $ilDB;
74  $this->obj_data_cache = $ilObjDataCache;
75  $this->now = time();
76  $this->unfinished_passes = array();
77  $this->test_ids = array();
78  $this->test_ending_times = array();
79 
80  require_once 'Modules/Test/classes/class.ilTestProcessLockerFactory.php';
81  $this->processLockerFactory = new ilTestProcessLockerFactory(
82  new ilSetting('assessment'),
83  $DIC->database()
84  );
85  }
86 
87  public function getId()
88  {
89  return 'finish_unfinished_passes';
90  }
91 
92  public function getTitle()
93  {
94  global $DIC;
95  $lng = $DIC['lng'];
96 
97  return $lng->txt("finish_unfinished_passes");
98  }
99 
100  public function getDescription()
101  {
102  global $DIC;
103  $lng = $DIC['lng'];
104 
105  return $lng->txt("finish_unfinished_passes_desc");
106  }
107 
108  public function getDefaultScheduleType()
109  {
110  return self::SCHEDULE_TYPE_DAILY;
111  }
112 
113  public function getDefaultScheduleValue()
114  {
115  return;
116  }
117 
118  public function hasAutoActivation()
119  {
120  return false;
121  }
122 
123  public function hasFlexibleSchedule()
124  {
125  return true;
126  }
127 
128  public function hasCustomSettings()
129  {
130  return true;
131  }
132 
133  public function run()
134  {
135  $this->log->info('start inf cronjob...');
136 
137  $result = new ilCronJobResult();
138 
140  if (count($this->unfinished_passes) > 0) {
141  $this->log->info('found ' . count($this->unfinished_passes) . ' unfinished passes starting analyses.');
143  $this->processPasses();
144  } else {
145  $this->log->info('No unfinished passes found.');
146  }
147 
149 
150  $this->log->info(' ...finishing cronjob.');
151 
152  return $result;
153  }
154 
155  protected function gatherUsersWithUnfinishedPasses()
156  {
157  $query = "SELECT tst_active.active_id,
158  tst_active.tries,
159  tst_active.user_fi usr_id,
160  tst_active.test_fi test_fi,
161  usr_data.login,
162  usr_data.lastname,
163  usr_data.firstname,
164  tst_active.submitted test_finished,
165  usr_data.matriculation,
166  usr_data.active,
167  tst_active.lastindex,
168  tst_active.last_started_pass last_started
169  FROM tst_active
170  LEFT JOIN usr_data
171  ON tst_active.user_fi = usr_data.usr_id
172  WHERE IFNULL(tst_active.last_finished_pass, -1) <> tst_active.last_started_pass
173  ";
174  $result = $this->db->query($query);
175  while ($row = $this->db->fetchAssoc($result)) {
176  $this->unfinished_passes[] = $row;
177  $this->test_ids[] = $row['test_fi'];
178  }
179  }
180 
181  protected function getTestsFinishAndProcessingTime()
182  {
183  $query = 'SELECT test_id, obj_fi, ending_time, ending_time_enabled, processing_time, enable_processing_time FROM tst_tests WHERE ' .
184  $this->db->in('test_id', $this->test_ids, false, 'integer');
185  $result = $this->db->query($query);
186  while ($row = $this->db->fetchAssoc($result)) {
187  $this->test_ending_times[$row['test_id']] = $row;
188  }
189  $this->log->info('Gathered data for ' . count($this->test_ids) . ' test id(s) => (' . implode(',', $this->test_ids) . ')');
190  }
191 
192  protected function processPasses()
193  {
194  $now = time();
195  foreach ($this->unfinished_passes as $key => $data) {
196  $test_id = $data['test_fi'];
197  $can_not_be_finished = true;
198  if (array_key_exists($test_id, $this->test_ending_times)) {
199  if ($this->test_ending_times[$test_id]['ending_time_enabled'] == 1) {
200  $this->log->info('Test (' . $test_id . ') has ending time (' . $this->test_ending_times[$test_id]['ending_time'] . ')');
201  $ending_time = $this->test_ending_times[$test_id]['ending_time'];
202  if ($ending_time < $now) {
203  $this->finishPassForUser($data['active_id'], $this->test_ending_times[$test_id]['obj_fi']);
204  $can_not_be_finished = false;
205  } else {
206  $this->log->info('Test (' . $test_id . ') ending time (' . $this->test_ending_times[$test_id]['ending_time'] . ') > now (' . $now . ') is not reached.');
207  }
208  } else {
209  $this->log->info('Test (' . $test_id . ') has no ending time.');
210  }
211  if ($this->test_ending_times[$test_id]['enable_processing_time'] == 1) {
212  $this->log->info('Test (' . $test_id . ') has processing time (' . $this->test_ending_times[$test_id]['processing_time'] . ')');
213  $obj_id = $this->test_ending_times[$test_id]['obj_fi'];
214  $test_obj = new ilObjTest($obj_id, false);
215  $startingTime = $test_obj->getStartingTimeOfUser($data['active_id'], $data['last_started_pass']);
216  $max_processing_time = $test_obj->isMaxProcessingTimeReached($startingTime, $data['active_id']);
217  if ($max_processing_time) {
218  $this->log->info('Max Processing time reached for user id (' . $data['usr_id'] . ') so test with active id (' . $data['active_id'] . ') will be finished.');
219  $this->finishPassForUser($data['active_id'], $this->test_ending_times[$test_id]['obj_fi']);
220  $can_not_be_finished = false;
221  }
222  } else {
223  $this->log->info('Test (' . $test_id . ') has no processing time.');
224  }
225 
226  if ($can_not_be_finished) {
227  $this->log->info('Test session with active id (' . $data['active_id'] . ') can not be finished by this cron job.');
228  }
229  }
230  }
231  }
232 
233  protected function finishPassForUser($active_id, $obj_id)
234  {
235  $this->processLockerFactory->setActiveId($active_id);
236  $processLocker = $this->processLockerFactory->getLocker();
237 
238  $pass_finisher = new ilTestPassFinishTasks($active_id, $obj_id);
239  $pass_finisher->performFinishTasks($processLocker);
240 
241  $this->log->info('Test session with active id (' . $active_id . ') and obj_id (' . $obj_id . ') is now finished.');
242  }
243 }
Class ilTestPassFinishTasks.
$result
global $DIC
Definition: saml.php:7
Cron job application base class.
Class ilCronFinishUnfinishedTestPasses.
$query
$row
global $ilDB
static getLogger($a_component_id)
Get component logger.
Cron job result data container.
$key
Definition: croninfo.php:18
$data
Definition: bench.php:6