1<?php 2 3/* Copyright (c) 2015 Richard Klees <richard.klees@concepts-and-training.de> Extended GPL, see docs/LICENSE */ 4/* Copyright (c) 2019 Stefan Hecken <stefan.hecken@concepts-and-training.de> Extended GPL, see docs/LICENSE */ 5 6declare(strict_types = 1); 7 8class ilStudyProgrammeSettingsDBRepository implements ilStudyProgrammeSettingsRepository 9{ 10 /** 11 * @var array 12 */ 13 protected static $cache = []; 14 15 /** 16 * @var ilDBInterface 17 */ 18 protected $db; 19 20 const TABLE = 'prg_settings'; 21 22 const FIELD_OBJ_ID = 'obj_id'; 23 const FIELD_SUBTYPE_ID = 'subtype_id'; 24 const FIELD_STATUS = 'status'; 25 const FIELD_LP_MODE = 'lp_mode'; 26 const FIELD_POINTS = 'points'; 27 const FIELD_LAST_CHANGED = 'last_change'; 28 const FIELD_DEADLINE_PERIOD = 'deadline_period'; 29 const FIELD_DEADLINE_DATE = 'deadline_date'; 30 const FIELD_VALIDITY_QUALIFICATION_DATE = 'vq_date'; 31 const FIELD_VALIDITY_QUALIFICATION_PERIOD = 'vq_period'; 32 const FIELD_VQ_RESTART_PERIOD = 'vq_restart_period'; 33 const FIELD_RM_NOT_RESTARTED_BY_USER_DAY = 'rm_nr_by_usr_days'; 34 const FIELD_PROC_ENDS_NOT_SUCCESSFUL = 'proc_end_no_success'; 35 const FIELD_SEND_RE_ASSIGNED_MAIL = "send_re_assigned_mail"; 36 const FIELD_SEND_INFO_TO_RE_ASSIGN_MAIL = "send_info_to_re_assign_mail"; 37 const FIELD_SEND_RISKY_TO_FAIL_MAIL = "send_risky_to_fail_mail"; 38 39 public function __construct(ilDBInterface $db) 40 { 41 $this->db = $db; 42 } 43 44 /** 45 * @inheritdoc 46 * @throws ilException 47 */ 48 public function createFor(int $obj_id) : ilStudyProgrammeSettings 49 { 50 $type_settings = new \ilStudyProgrammeTypeSettings( 51 ilStudyProgrammeSettings::DEFAULT_SUBTYPE 52 ); 53 $assessment_settings = new \ilStudyProgrammeAssessmentSettings( 54 ilStudyProgrammeSettings::DEFAULT_POINTS, 55 ilStudyProgrammeSettings::STATUS_DRAFT 56 ); 57 $deadline_settings = new \ilStudyProgrammeDeadlineSettings(null, null); 58 $validity_of_achieved_qualification_settings = 59 new \ilStudyProgrammeValidityOfAchievedQualificationSettings(null, null, null) 60 ; 61 $automail = new \ilStudyProgrammeAutoMailSettings(false, null, null); 62 63 $prg = new ilStudyProgrammeSettings( 64 $obj_id, 65 $type_settings, 66 $assessment_settings, 67 $deadline_settings, 68 $validity_of_achieved_qualification_settings, 69 $automail 70 ); 71 72 $this->insertDB( 73 $obj_id, 74 ilStudyProgrammeSettings::DEFAULT_SUBTYPE, 75 ilStudyProgrammeSettings::STATUS_DRAFT, 76 ilStudyProgrammeSettings::MODE_UNDEFINED, 77 ilStudyProgrammeSettings::DEFAULT_POINTS, 78 (new DateTime())->format(ilStudyProgrammeSettings::DATE_TIME_FORMAT), 79 0, 80 ilStudyProgrammeSettings::NO_VALIDITY_OF_QUALIFICATION_PERIOD, 81 ilStudyProgrammeSettings::NO_RESTART, 82 null, 83 null, 84 null, 85 null 86 ); 87 88 $prg = $prg->setLPMode(ilStudyProgrammeSettings::MODE_UNDEFINED); 89 self::$cache[$obj_id] = $prg; 90 return $prg; 91 } 92 93 /** 94 * @inheritdoc 95 * @throws ilException 96 */ 97 public function read(int $obj_id) : ilStudyProgrammeSettings 98 { 99 if (!array_key_exists($obj_id, self::$cache)) { 100 self::$cache[$obj_id] = $this->loadDB($obj_id); 101 } 102 return self::$cache[$obj_id]; 103 } 104 105 /** 106 * @inheritdoc 107 */ 108 public function update(ilStudyProgrammeSettings $settings) : void 109 { 110 $deadline_period = $settings->getDeadlineSettings()->getDeadlinePeriod(); 111 if (is_null($deadline_period)) { 112 $deadline_period = 0; 113 } 114 115 $deadline_date = $settings->getDeadlineSettings()->getDeadlineDate(); 116 if (!is_null($deadline_date)) { 117 $deadline_date = $deadline_date->format(ilStudyProgrammeSettings::DATE_TIME_FORMAT); 118 } 119 120 $vq_date = $settings->getValidityOfQualificationSettings()->getQualificationDate(); 121 if (!is_null($vq_date)) { 122 $vq_date = $vq_date->format(ilStudyProgrammeSettings::DATE_TIME_FORMAT); 123 } 124 125 $qp = $settings->getValidityOfQualificationSettings()->getQualificationPeriod(); 126 if (is_null($qp)) { 127 $qp = 0; 128 } 129 130 $rp = $settings->getValidityOfQualificationSettings()->getRestartPeriod(); 131 if (is_null($rp)) { 132 $rp = 0; 133 } 134 135 $this->updateDB( 136 $settings->getObjId(), 137 $settings->getTypeSettings()->getTypeId(), 138 $settings->getAssessmentSettings()->getStatus(), 139 $settings->getLPMode(), 140 $settings->getAssessmentSettings()->getPoints(), 141 $settings->getLastChange()->format(ilStudyProgrammeSettings::DATE_TIME_FORMAT), 142 $deadline_period, 143 $qp, 144 $rp, 145 $deadline_date, 146 $vq_date, 147 $settings->getAutoMailSettings()->getReminderNotRestartedByUserDays(), 148 $settings->getAutoMailSettings()->getProcessingEndsNotSuccessfulDays(), 149 $settings->getAutoMailSettings()->getSendReAssignedMail(), 150 false, 151 false 152 ); 153 self::$cache[$settings->getObjId()] = $settings; 154 } 155 156 /** 157 * @inheritdoc 158 */ 159 public function delete(ilStudyProgrammeSettings $settings) : void 160 { 161 unset(self::$cache[$settings->getObjId()]); 162 $this->deleteDB($settings->getObjId()); 163 } 164 165 /** 166 * @inheritdoc 167 * @throws ilException 168 */ 169 public function loadByType(int $type_id) : array 170 { 171 $q = 'SELECT ' . self::FIELD_SUBTYPE_ID 172 . ' ,' . self::FIELD_STATUS 173 . ' ,' . self::FIELD_POINTS 174 . ' ,' . self::FIELD_LP_MODE 175 . ' ,' . self::FIELD_LAST_CHANGED 176 . ' ,' . self::FIELD_OBJ_ID 177 . ' ,' . self::FIELD_DEADLINE_PERIOD 178 . ' ,' . self::FIELD_DEADLINE_DATE 179 . ' ,' . self::FIELD_VALIDITY_QUALIFICATION_PERIOD 180 . ' ,' . self::FIELD_VALIDITY_QUALIFICATION_DATE 181 . ' ,' . self::FIELD_VQ_RESTART_PERIOD 182 . ', ' . self::FIELD_SEND_RE_ASSIGNED_MAIL 183 . ', ' . self::FIELD_SEND_INFO_TO_RE_ASSIGN_MAIL 184 . ', ' . self::FIELD_SEND_RISKY_TO_FAIL_MAIL 185 . ' FROM ' . self::TABLE 186 . ' WHERE ' . self::FIELD_SUBTYPE_ID . ' = ' . $this->db->quote($type_id, 'integer'); 187 $res = $this->db->query($q); 188 $return = []; 189 while ($rec = $this->db->fetchAssoc($res)) { 190 $return[] = $this->createByRow($rec); 191 } 192 return $return; 193 } 194 195 196 public function loadIdsByType(int $type_id) : array 197 { 198 return []; 199 } 200 201 protected function insertDB( 202 int $obj_id, 203 int $subtype_id, 204 int $status, 205 int $lp_mode, 206 int $points, 207 string $last_change, 208 int $deadline_period, 209 int $vq_period, 210 int $vq_restart_period, 211 string $deadline_date = null, 212 string $vq_date = null, 213 int $rm_nr_by_usr_days = null, 214 int $proc_end_no_success = null, 215 bool $send_re_assigned_mail = false, 216 bool $send_info_to_re_assign_mail = false, 217 bool $send_risky_to_fail_mail = false 218 ) { 219 $this->db->insert( 220 self::TABLE, 221 [ 222 self::FIELD_OBJ_ID => ['integer', $obj_id], 223 self::FIELD_SUBTYPE_ID => ['integer', $subtype_id], 224 self::FIELD_STATUS => ['integer', $status], 225 self::FIELD_POINTS => ['integer', $points], 226 self::FIELD_LP_MODE => ['integer', $lp_mode], 227 self::FIELD_LAST_CHANGED => ['timestamp', $last_change], 228 self::FIELD_DEADLINE_PERIOD => ['integer', $deadline_period], 229 self::FIELD_DEADLINE_DATE => ['timestamp', $deadline_date], 230 self::FIELD_VALIDITY_QUALIFICATION_DATE => ['timestamp', $vq_date], 231 self::FIELD_VALIDITY_QUALIFICATION_PERIOD => ['integer', $vq_period], 232 self::FIELD_VQ_RESTART_PERIOD => ['integer', $vq_restart_period], 233 self::FIELD_RM_NOT_RESTARTED_BY_USER_DAY => ['integer', $rm_nr_by_usr_days], 234 self::FIELD_PROC_ENDS_NOT_SUCCESSFUL => ['integer', $proc_end_no_success], 235 self::FIELD_SEND_RE_ASSIGNED_MAIL => ['integer', $send_re_assigned_mail], 236 self::FIELD_SEND_INFO_TO_RE_ASSIGN_MAIL => ['integer', $send_info_to_re_assign_mail], 237 self::FIELD_SEND_RISKY_TO_FAIL_MAIL => ['integer', $send_risky_to_fail_mail] 238 ] 239 ); 240 } 241 242 /** 243 * @throws ilException 244 * @thorws LogicException 245 */ 246 protected function loadDB(int $obj_id) : ilStudyProgrammeSettings 247 { 248 $rec = $this->db->fetchAssoc( 249 $this->db->query( 250 'SELECT ' . self::FIELD_SUBTYPE_ID 251 . ', ' . self::FIELD_STATUS 252 . ', ' . self::FIELD_POINTS 253 . ', ' . self::FIELD_LP_MODE 254 . ', ' . self::FIELD_LAST_CHANGED 255 . ', ' . self::FIELD_OBJ_ID 256 . ', ' . self::FIELD_DEADLINE_PERIOD 257 . ', ' . self::FIELD_DEADLINE_DATE 258 . ', ' . self::FIELD_VALIDITY_QUALIFICATION_PERIOD 259 . ', ' . self::FIELD_VALIDITY_QUALIFICATION_DATE 260 . ', ' . self::FIELD_VQ_RESTART_PERIOD 261 . ', ' . self::FIELD_RM_NOT_RESTARTED_BY_USER_DAY 262 . ', ' . self::FIELD_PROC_ENDS_NOT_SUCCESSFUL 263 . ', ' . self::FIELD_SEND_RE_ASSIGNED_MAIL 264 . ', ' . self::FIELD_SEND_INFO_TO_RE_ASSIGN_MAIL 265 . ', ' . self::FIELD_SEND_RISKY_TO_FAIL_MAIL 266 . ' FROM ' . self::TABLE 267 . ' WHERE ' . self::FIELD_OBJ_ID . ' = ' . $this->db->quote($obj_id, 'integer') 268 ) 269 ); 270 if (!$rec) { 271 throw new LogicException('invaid obj_id to load: ' . $obj_id); 272 } 273 return $this->createByRow($rec); 274 } 275 276 /** 277 * @throws ilException 278 */ 279 protected function createByRow(array $row) : ilStudyProgrammeSettings 280 { 281 $type_settings = new \ilStudyProgrammeTypeSettings( 282 ilStudyProgrammeSettings::DEFAULT_SUBTYPE 283 ); 284 $assessment_settings = new \ilStudyProgrammeAssessmentSettings( 285 ilStudyProgrammeSettings::DEFAULT_POINTS, 286 ilStudyProgrammeSettings::STATUS_DRAFT 287 ); 288 $deadline_settings = new \ilStudyProgrammeDeadlineSettings(null, null); 289 $validity_of_achieved_qualification_settings = 290 new \ilStudyProgrammeValidityOfAchievedQualificationSettings(null, null, null) 291 ; 292 $automail = new \ilStudyProgrammeAutoMailSettings(false, null, null); 293 294 $prg = new ilStudyProgrammeSettings( 295 (int) $row[self::FIELD_OBJ_ID], 296 $type_settings, 297 $assessment_settings, 298 $deadline_settings, 299 $validity_of_achieved_qualification_settings, 300 $automail 301 ); 302 303 $return = $prg 304 ->setLPMode((int) $row[self::FIELD_LP_MODE]) 305 ->setLastChange(DateTime::createFromFormat( 306 ilStudyProgrammeSettings::DATE_TIME_FORMAT, 307 $row[self::FIELD_LAST_CHANGED] 308 )) 309 ; 310 311 $type = $return->getTypeSettings(); 312 $type = $type->withTypeId((int) $row['subtype_id']); 313 $return = $return->withTypeSettings($type); 314 315 $points = $return->getAssessmentSettings(); 316 $points = $points->withPoints((int) $row['points'])->withStatus((int) $row['status']); 317 $return = $return->withAssessmentSettings($points); 318 319 $deadline = $return->getDeadlineSettings(); 320 if ($row[self::FIELD_DEADLINE_DATE] !== null) { 321 $deadline = $deadline->withDeadlineDate(DateTime::createFromFormat( 322 ilStudyProgrammeSettings::DATE_TIME_FORMAT, 323 $row[self::FIELD_DEADLINE_DATE] 324 )) 325 ; 326 } else { 327 $deadline_period = (int) $row[self::FIELD_DEADLINE_PERIOD]; 328 if ($deadline_period == -1) { 329 $deadline_period = null; 330 } 331 $deadline = $deadline->withDeadlinePeriod($deadline_period); 332 } 333 $return = $return->withDeadlineSettings($deadline); 334 335 $vqs = $return->getValidityOfQualificationSettings(); 336 if ($row[self::FIELD_VALIDITY_QUALIFICATION_DATE] !== null) { 337 $vqs = $vqs->withQualificationDate( 338 DateTime::createFromFormat( 339 ilStudyProgrammeSettings::DATE_TIME_FORMAT, 340 $row[self::FIELD_VALIDITY_QUALIFICATION_DATE] 341 ) 342 ); 343 } else { 344 $qualification_period = (int) $row[self::FIELD_VALIDITY_QUALIFICATION_PERIOD]; 345 if ($qualification_period == -1) { 346 $qualification_period = null; 347 } 348 $vqs = $vqs->withQualificationPeriod($qualification_period); 349 } 350 $restart_period = (int) $row[self::FIELD_VQ_RESTART_PERIOD]; 351 if ($restart_period == -1) { 352 $restart_period = null; 353 } 354 $vqs = $vqs->withRestartPeriod($restart_period); 355 $return = $return->withValidityOfQualificationSettings($vqs); 356 357 $rm_nr_by_usr_days = $row[self::FIELD_RM_NOT_RESTARTED_BY_USER_DAY]; 358 if (!is_null($rm_nr_by_usr_days)) { 359 $rm_nr_by_usr_days = (int) $rm_nr_by_usr_days; 360 } 361 $proc_end_no_success = $row[self::FIELD_PROC_ENDS_NOT_SUCCESSFUL]; 362 if (!is_null($proc_end_no_success)) { 363 $proc_end_no_success = (int) $proc_end_no_success; 364 } 365 366 return $return->withAutoMailSettings( 367 new \ilStudyProgrammeAutoMailSettings( 368 (bool) $row[self::FIELD_SEND_RE_ASSIGNED_MAIL], 369 $rm_nr_by_usr_days, 370 $proc_end_no_success 371 ) 372 ); 373 } 374 375 /** 376 * @throws LogicException 377 */ 378 protected function deleteDB(int $obj_id) 379 { 380 if (!$this->checkExists($obj_id)) { 381 throw new LogicException('invaid obj_id to delete: ' . $obj_id); 382 } 383 $this->db->manipulate( 384 'DELETE FROM ' . self::TABLE 385 . ' WHERE ' . self::FIELD_OBJ_ID . ' = ' . $this->db->quote($obj_id, 'integer') 386 ); 387 } 388 389 /** 390 * @pthrows LogicException 391 */ 392 protected function updateDB( 393 int $obj_id, 394 int $subtype_id, 395 int $status, 396 int $lp_mode, 397 int $points, 398 string $last_change, 399 int $deadline_period, 400 int $vq_period, 401 int $vq_restart_period, 402 string $deadline_date = null, 403 string $vq_date = null, 404 int $rm_nr_by_usr_days = null, 405 int $proc_end_no_success = null, 406 bool $send_re_assigned_mail = false, 407 bool $send_info_to_re_assign_mail = false, 408 bool $send_risky_to_fail_mail = false 409 ) { 410 if (!$this->checkExists($obj_id)) { 411 throw new LogicException('invalid obj_id to update: ' . $obj_id); 412 } 413 $where = [ 414 self::FIELD_OBJ_ID => [ 415 'integer', 416 $obj_id 417 ] 418 ]; 419 420 $values = [ 421 self::FIELD_SUBTYPE_ID => [ 422 'integer', 423 $subtype_id 424 ], 425 self::FIELD_STATUS => [ 426 'integer', 427 $status 428 ], 429 self::FIELD_LP_MODE => [ 430 'integer', 431 $lp_mode 432 ], 433 self::FIELD_POINTS => [ 434 'integer', 435 $points 436 ], 437 self::FIELD_LAST_CHANGED => [ 438 'timestamp', 439 $last_change 440 ], 441 self::FIELD_DEADLINE_PERIOD => [ 442 'integer', 443 $deadline_period 444 ], 445 self::FIELD_DEADLINE_DATE => [ 446 'timestamp', 447 $deadline_date 448 ], 449 self::FIELD_VALIDITY_QUALIFICATION_PERIOD => [ 450 'integer', 451 $vq_period 452 ], 453 self::FIELD_VALIDITY_QUALIFICATION_DATE => [ 454 'timestamp', 455 $vq_date 456 ], 457 self::FIELD_VQ_RESTART_PERIOD => [ 458 'integer', 459 $vq_restart_period 460 ], 461 self::FIELD_RM_NOT_RESTARTED_BY_USER_DAY => [ 462 'integer', 463 $rm_nr_by_usr_days 464 ], 465 self::FIELD_PROC_ENDS_NOT_SUCCESSFUL => [ 466 'integer', 467 $proc_end_no_success 468 ], 469 self::FIELD_SEND_RE_ASSIGNED_MAIL => [ 470 'integer', 471 $send_re_assigned_mail 472 ], 473 self::FIELD_SEND_INFO_TO_RE_ASSIGN_MAIL => [ 474 'integer', 475 $send_info_to_re_assign_mail 476 ], 477 self::FIELD_SEND_RISKY_TO_FAIL_MAIL => [ 478 'integer', 479 $send_risky_to_fail_mail 480 ] 481 ]; 482 483 $this->db->update(self::TABLE, $values, $where); 484 } 485 486 protected function checkExists(int $obj_id) 487 { 488 $rec = $this->db->fetchAssoc( 489 $this->db->query( 490 'SELECT ' . self::FIELD_OBJ_ID 491 . ' FROM ' . self::TABLE 492 . ' WHERE ' . self::FIELD_OBJ_ID . ' = ' . $this->db->quote($obj_id, 'integer') 493 ) 494 ); 495 if ($rec) { 496 return true; 497 } 498 return false; 499 } 500 501 public static function clearCache() 502 { 503 self::$cache = []; 504 } 505} 506