1<?php 2/* Copyright (c) 1998-2018 ILIAS open source, Extended GPL, see docs/LICENSE */ 3 4use ILIAS\UI\Factory; 5use ILIAS\UI\Renderer; 6 7/** 8 * @ingroup ServicesCertificate 9 * @author Niels Theen <ntheen@databay.de> 10 * @ilCtrl_IsCalledBy ilUserCertificateGUI: ilAchievementsGUI 11 */ 12class ilUserCertificateGUI 13{ 14 /** @var ilTemplate */ 15 private $template; 16 17 /** @var ilCtrl */ 18 private $controller; 19 20 /** @var ilLanguage */ 21 private $language; 22 23 /** @var ilUserCertificateRepository|null */ 24 private $userCertificateRepository; 25 26 /** @var ilObjUser|null */ 27 private $user; 28 29 /** @var \GuzzleHttp\Psr7\Request|null|\Psr\Http\Message\ServerRequestInterface */ 30 private $request; 31 32 /** @var ilLogger */ 33 private $certificateLogger; 34 35 /** @var ilSetting */ 36 protected $certificateSettings; 37 38 /** @var Factory */ 39 protected $uiFactory; 40 41 /** @var Renderer */ 42 protected $uiRenderer; 43 44 /** @var ilAccessHandler */ 45 protected $access; 46 47 const SORTATION_SESSION_KEY = 'my_certificates_sorting'; 48 49 /** 50 * @var array 51 */ 52 protected $sortationOptions = [ 53 'title_ASC' => 'cert_sortable_by_title_asc', 54 'title_DESC' => 'cert_sortable_by_title_desc', 55 'date_ASC' => 'cert_sortable_by_issue_date_asc', 56 'date_DESC' => 'cert_sortable_by_issue_date_desc', 57 ]; 58 59 /** @var string */ 60 protected $defaultSorting = 'date_DESC'; 61 62 /** @var \ILIAS\Filesystem\Filesystem */ 63 private $filesystem; 64 65 /** 66 * @var ilCertificateMigrationValidator|null 67 */ 68 private $migrationVisibleValidator; 69 70 /** 71 * @param ilTemplate|null $template 72 * @param ilCtrl|null $controller 73 * @param ilLanguage|null $language 74 * @param ilObjUser $user 75 * @param ilUserCertificateRepository|null $userCertificateRepository 76 * @param \GuzzleHttp\Psr7\Request|null $request 77 * @param ilLogger $certificateLogger 78 * @param ilSetting|null $certificateSettings 79 * @param Factory|null $uiFactory 80 * @param Renderer|null $uiRenderer 81 * @param \ilAccessHandler|null $access 82 * @param \ILIAS\Filesystem\Filesystem|null $filesystem 83 * @param ilCertificateMigrationValidator|null $migrationVisibleValidator 84 */ 85 public function __construct( 86 ilTemplate $template = null, 87 ilCtrl $controller = null, 88 ilLanguage $language = null, 89 ilObjUser $user = null, 90 ilUserCertificateRepository $userCertificateRepository = null, 91 GuzzleHttp\Psr7\Request $request = null, 92 ilLogger $certificateLogger = null, 93 ilSetting $certificateSettings = null, 94 Factory $uiFactory = null, 95 Renderer $uiRenderer = null, 96 \ilAccessHandler $access = null, 97 \ILIAS\Filesystem\Filesystem $filesystem = null, 98 ilCertificateMigrationValidator $migrationVisibleValidator = null 99 ) { 100 global $DIC; 101 102 $logger = $DIC->logger()->cert(); 103 104 if ($template === null) { 105 $template = $DIC->ui()->mainTemplate(); 106 } 107 $this->template = $template; 108 109 if ($controller === null) { 110 $controller = $DIC->ctrl(); 111 } 112 $this->controller = $controller; 113 114 if ($language === null) { 115 $language = $DIC->language(); 116 } 117 $this->language = $language; 118 119 if ($userCertificateRepository === null) { 120 $userCertificateRepository = new ilUserCertificateRepository($DIC->database(), $logger); 121 } 122 $this->userCertificateRepository = $userCertificateRepository; 123 124 if ($user === null) { 125 $user = $DIC->user(); 126 } 127 $this->user = $user; 128 129 if ($request === null) { 130 $request = $DIC->http()->request(); 131 } 132 $this->request = $request; 133 134 if ($certificateLogger === null) { 135 $certificateLogger = $DIC->logger()->cert(); 136 } 137 $this->certificateLogger = $certificateLogger; 138 139 if ($certificateSettings === null) { 140 $certificateSettings = new ilSetting("certificate"); 141 } 142 $this->certificateSettings = $certificateSettings; 143 144 if (null === $uiFactory) { 145 $uiFactory = $DIC->ui()->factory(); 146 } 147 $this->uiFactory = $uiFactory; 148 149 if (null === $uiRenderer) { 150 $uiRenderer = $DIC->ui()->renderer(); 151 } 152 $this->uiRenderer = $uiRenderer; 153 154 if (null === $access) { 155 $access = $DIC->access(); 156 } 157 $this->access = $access; 158 159 if (null === $filesystem) { 160 $filesystem = $DIC->filesystem()->web(); 161 } 162 $this->filesystem = $filesystem; 163 164 if (null === $migrationVisibleValidator) { 165 $migrationVisibleValidator = new ilCertificateMigrationValidator($this->certificateSettings); 166 } 167 $this->migrationVisibleValidator = $migrationVisibleValidator; 168 169 $this->language->loadLanguageModule('cert'); 170 } 171 172 /** 173 * @return string 174 */ 175 private function getDefaultCommand() : string 176 { 177 return 'listCertificates'; 178 } 179 180 /** 181 * @return bool 182 * @throws ilDateTimeException 183 * @throws ilException 184 */ 185 public function executeCommand() 186 { 187 $nextClass = $this->controller->getNextClass($this); 188 $cmd = $this->controller->getCmd(); 189 190 if (!$this->certificateSettings->get('active')) { 191 $this->controller->returnToParent($this); 192 } 193 194 $this->template->setTitle($this->language->txt('obj_cert')); 195 196 switch ($nextClass) { 197 case 'ilcertificatemigrationgui': 198 $migrationGui = new \ilCertificateMigrationGUI(); 199 $resultMessageString = $this->controller->forwardCommand($migrationGui); 200 $this->template->setMessage(\ilTemplate::MESSAGE_TYPE_SUCCESS, $resultMessageString, true); 201 $this->listCertificates(true); 202 break; 203 204 default: 205 if (!method_exists($this, $cmd)) { 206 $cmd = $this->getDefaultCommand(); 207 } 208 $this->{$cmd}(); 209 } 210 211 return true; 212 } 213 214 /** 215 * @param bool $migrationWasStarted 216 * @throws ilDateTimeException 217 * @throws ilWACException 218 */ 219 public function listCertificates(bool $migrationWasStarted = false) 220 { 221 global $DIC; 222 223 if (!$this->certificateSettings->get('active')) { 224 $this->controller->redirect($this); 225 return; 226 } 227 228 $this->template->setBodyClass('iosMyCertificates'); 229 230 $showMigrationBox = $this->migrationVisibleValidator->isMigrationAvailable( 231 $this->user, 232 new \ilCertificateMigration($this->user->getId()) 233 ); 234 if (!$migrationWasStarted && true === $showMigrationBox) { 235 $migrationUiEl = new \ilCertificateMigrationUIElements(); 236 $startMigrationCommand = $this->controller->getLinkTargetByClass( 237 ['ilCertificateMigrationGUI'], 238 'startMigrationAndReturnMessage', 239 false, 240 true, 241 false 242 ); 243 $messageBoxHtml = $migrationUiEl->getMigrationMessageBox($startMigrationCommand); 244 245 $this->template->setCurrentBlock('mess'); 246 $this->template->setVariable('MESSAGE', $messageBoxHtml); 247 $this->template->parseCurrentBlock('mess'); 248 } 249 250 $provider = new ilUserCertificateTableProvider( 251 $DIC->database(), 252 $this->certificateLogger, 253 $this->controller, 254 $this->language->txt('certificate_no_object_title') 255 ); 256 257 $sorting = $this->getCurrentSortation(); 258 $data = $provider->fetchDataSet( 259 $this->user->getId(), 260 [ 261 'order_field' => explode('_', $sorting)[0], 262 'order_direction' => explode('_', $sorting)[1] 263 ], 264 [] 265 ); 266 267 $uiComponents = []; 268 269 if (count($data['items']) > 0) { 270 $sortationOptions = []; 271 $cards = []; 272 273 foreach ($this->sortationOptions as $fieldAndDirection => $lngVariable) { 274 $sortationOptions[$fieldAndDirection] = $this->language->txt($lngVariable); 275 } 276 277 $sortViewControl = $this->uiFactory 278 ->viewControl() 279 ->sortation($sortationOptions) 280 ->withLabel($this->language->txt($this->sortationOptions[$sorting])) 281 ->withTargetURL($this->controller->getLinkTarget($this, 'applySortation'), 'sort_by'); 282 $uiComponents[] = $sortViewControl; 283 284 foreach ($data['items'] as $certificateData) { 285 $thumbnailImagePath = $certificateData['thumbnail_image_path']; 286 $imagePath = ilUtil::getWebspaceDir() . $thumbnailImagePath; 287 if ($thumbnailImagePath === null 288 || $thumbnailImagePath === '' 289 || !$this->filesystem->has($thumbnailImagePath) 290 ) { 291 $imagePath = \ilUtil::getImagePath('icon_cert.svg'); 292 } 293 294 $cardImage = $this->uiFactory->image()->standard( 295 ilWACSignedPath::signFile($imagePath), 296 $certificateData['title'] 297 ); 298 299 300 $sections = []; 301 302 if (strlen($certificateData['description']) > 0) { 303 $sections[] = $this->uiFactory->listing()->descriptive([ 304 $this->language->txt('cert_description_label') => $certificateData['description'] 305 ]); 306 } 307 308 309 $oldDatePresentationStatus = \ilDatePresentation::useRelativeDates(); 310 \ilDatePresentation::setUseRelativeDates(true); 311 $sections[] = $this->uiFactory->listing()->descriptive([ 312 $this->language->txt('cert_issued_on_label') => \ilDatePresentation::formatDate( 313 new \ilDateTime($certificateData['date'], \IL_CAL_UNIX) 314 ) 315 ]); 316 \ilDatePresentation::setUseRelativeDates($oldDatePresentationStatus); 317 318 $objectTypeIcon = $this->uiFactory 319 ->icon() 320 ->standard($certificateData['obj_type'], $certificateData['obj_type'], 'small'); 321 322 $objectTitle = $certificateData['title']; 323 $refIds = \ilObject::_getAllReferences($certificateData['obj_id']); 324 if (count($refIds) > 0) { 325 foreach ($refIds as $refId) { 326 if ($this->access->checkAccess('read', '', $refId)) { 327 $objectTitle = $this->uiRenderer->render( 328 $this->uiFactory->link()->standard($objectTitle, \ilLink::_getLink($refId)) 329 ); 330 break; 331 } 332 } 333 } 334 335 $sections[] = $this->uiFactory->listing()->descriptive([$this->language->txt('cert_object_label') => implode('', [ 336 $this->uiRenderer->render($objectTypeIcon), 337 $objectTitle 338 ])]); 339 340 $this->controller->setParameter($this, 'certificate_id', $certificateData['id']); 341 $downloadHref = $this->controller->getLinkTarget($this, 'download'); 342 $this->controller->clearParameters($this); 343 $sections[] = $this->uiFactory->button()->standard('Download', $downloadHref); 344 345 $card = $this->uiFactory 346 ->card() 347 ->standard($certificateData['title'], $cardImage) 348 ->withSections($sections); 349 350 $cards[] = $card; 351 } 352 353 $deck = $this->uiFactory->deck($cards); 354 355 $uiComponents[] = $this->uiFactory->divider()->horizontal(); 356 357 $uiComponents[] = $deck; 358 } else { 359 \ilUtil::sendInfo($this->language->txt('cert_currently_no_certs')); 360 } 361 362 $this->template->setContent($this->uiRenderer->render($uiComponents)); 363 } 364 365 /** 366 * @return string 367 */ 368 protected function getCurrentSortation() : string 369 { 370 $sorting = \ilSession::get(self::SORTATION_SESSION_KEY); 371 if (!array_key_exists($sorting, $this->sortationOptions)) { 372 $sorting = $this->defaultSorting; 373 } 374 375 return $sorting; 376 } 377 378 /** 379 * 380 */ 381 protected function applySortation() 382 { 383 $sorting = $this->request->getQueryParams()['sort_by'] ?? $this->defaultSorting; 384 if (!array_key_exists($sorting, $this->sortationOptions)) { 385 $sorting = $this->defaultSorting; 386 } 387 \ilSession::set(self::SORTATION_SESSION_KEY, $sorting); 388 389 $this->listCertificates(); 390 } 391 392 /** 393 * @throws \ilException 394 */ 395 public function download() 396 { 397 global $DIC; 398 399 $user = $DIC->user(); 400 $language = $DIC->language(); 401 402 $userCertificateRepository = new ilUserCertificateRepository(null, $this->certificateLogger); 403 $pdfGenerator = new ilPdfGenerator($userCertificateRepository, $this->certificateLogger); 404 405 $userCertificateId = (int) $this->request->getQueryParams()['certificate_id']; 406 407 try { 408 $userCertificate = $userCertificateRepository->fetchCertificate($userCertificateId); 409 if ((int) $userCertificate->getUserId() !== (int) $user->getId()) { 410 throw new ilException(sprintf('User "%s" tried to access certificate: "%s"', $user->getLogin(), $userCertificateId)); 411 } 412 } catch (ilException $exception) { 413 $this->certificateLogger->warning($exception->getMessage()); 414 ilUtil::sendFailure($language->txt('cert_error_no_access')); 415 $this->listCertificates(); 416 return; 417 } 418 419 $pdfAction = new ilCertificatePdfAction( 420 $this->certificateLogger, 421 $pdfGenerator, 422 new ilCertificateUtilHelper(), 423 $this->language->txt('error_creating_certificate_pdf') 424 ); 425 426 $pdfAction->downloadPdf($userCertificate->getUserId(), $userCertificate->getObjId()); 427 428 $this->listCertificates(); 429 } 430} 431