diff --git a/.gitignore b/.gitignore index 0d5946e45a2e..480177bb10e7 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ /Services/UICore/artifacts/ctrl_security.php /Services/Component/artifacts/* /Services/EventHandling/artifacts/* +/Services/Object/artifacts/* # Directories /data diff --git a/Modules/CmiXapi/classes/Certificate/class.ilCmiXapiPlaceholderValues.php b/Modules/CmiXapi/classes/Certificate/class.ilCmiXapiPlaceholderValues.php index 50dfc2d1f048..443ff0689ef1 100644 --- a/Modules/CmiXapi/classes/Certificate/class.ilCmiXapiPlaceholderValues.php +++ b/Modules/CmiXapi/classes/Certificate/class.ilCmiXapiPlaceholderValues.php @@ -33,16 +33,16 @@ class ilCmiXapiPlaceholderValues implements ilCertificatePlaceholderValues private ?\ilCertificateObjectHelper $objectHelper; -// private \ilCertificateUserObjectHelper $userObjectHelper; + // private \ilCertificateUserObjectHelper $userObjectHelper; private ?\ilCertificateUtilHelper $utilHelper; -// private ?\ilCertificateLPStatusHelper $lpStatusHelper; + // private ?\ilCertificateLPStatusHelper $lpStatusHelper; /** * @var ilCertificateDateHelper|ilDatePresentation|null */ -// private $dateHelper; + // private $dateHelper; private ?\ilLanguage $language; @@ -84,12 +84,12 @@ public function __construct( if (null === $userObjectHelper) { $userObjectHelper = new ilCertificateUserObjectHelper(); } -// $this->userObjectHelper = $userObjectHelper; + // $this->userObjectHelper = $userObjectHelper; if (null === $lpStatusHelper) { $lpStatusHelper = new ilCertificateLPStatusHelper(); } -// $this->lpStatusHelper = $lpStatusHelper; + // $this->lpStatusHelper = $lpStatusHelper; if (null === $utilHelper) { $utilHelper = new ilCertificateUtilHelper(); @@ -99,7 +99,7 @@ public function __construct( if (null === $dateHelper) { $dateHelper = new ilCertificateDateHelper(); } -// $this->dateHelper = $dateHelper; + // $this->dateHelper = $dateHelper; } /** diff --git a/Modules/CmiXapi/classes/Verification/class.ilObjCmiXapiVerificationGUI.php b/Modules/CmiXapi/classes/Verification/class.ilObjCmiXapiVerificationGUI.php index 678008da3471..70d0039e55d4 100644 --- a/Modules/CmiXapi/classes/Verification/class.ilObjCmiXapiVerificationGUI.php +++ b/Modules/CmiXapi/classes/Verification/class.ilObjCmiXapiVerificationGUI.php @@ -79,7 +79,7 @@ public function save(): void $newObj = $certificateVerificationFileService->createFile($userCertificatePresentation); } catch (\Exception $exception) { $this->tpl->setOnScreenMessage('failure', $this->lng->txt('error_creating_certificate_pdf')); -// $this->create(); + // $this->create(); } if ($newObj !== null) { diff --git a/Modules/CmiXapi/classes/XapiProxy/DataService.php b/Modules/CmiXapi/classes/XapiProxy/DataService.php index 7c741366482a..8306c6c4f865 100755 --- a/Modules/CmiXapi/classes/XapiProxy/DataService.php +++ b/Modules/CmiXapi/classes/XapiProxy/DataService.php @@ -32,10 +32,10 @@ public static function initIlias(string $client_id): void $_GET['client_id'] = $client_id; // Im Plugin war das auskommentiert(?) -// define('IL_COOKIE_HTTPONLY', true); // Default Value -// define('IL_COOKIE_EXPIRE', 0); -// define('IL_COOKIE_PATH', '/'); -// define('IL_COOKIE_DOMAIN', ''); + // define('IL_COOKIE_HTTPONLY', true); // Default Value + // define('IL_COOKIE_EXPIRE', 0); + // define('IL_COOKIE_PATH', '/'); + // define('IL_COOKIE_DOMAIN', ''); require_once("Services/Init/classes/class.ilInitialisation.php"); \ilContext::init(\ilContext::CONTEXT_SCORM); \ilInitialisation::initILIAS(); diff --git a/Modules/CmiXapi/classes/XapiProxy/XapiProxy.php b/Modules/CmiXapi/classes/XapiProxy/XapiProxy.php index 6ec9c8cac986..70c52e05df78 100755 --- a/Modules/CmiXapi/classes/XapiProxy/XapiProxy.php +++ b/Modules/CmiXapi/classes/XapiProxy/XapiProxy.php @@ -182,7 +182,7 @@ public function processStatements(\Psr\Http\Message\RequestInterface $request, $ if ($up === []) { // nothing allowed $this->log()->debug($this->msg("no allowed statements in array - fake response...")); $this->xapiProxyResponse->fakeResponseBlocked(""); - // $this->xapiProxyResponse->fakeResponseBlocked($ret); + // $this->xapiProxyResponse->fakeResponseBlocked($ret); } elseif (count($up) !== count($ret)) { // mixed request with allowed and not allowed statements $this->log()->debug($this->msg("mixed with allowed and unallowed statements")); return array($up,$ret); diff --git a/Modules/CmiXapi/classes/XapiProxy/XapiProxyPolyFill.php b/Modules/CmiXapi/classes/XapiProxy/XapiProxyPolyFill.php index 3ee4800d46c0..d26ae64b4c75 100755 --- a/Modules/CmiXapi/classes/XapiProxy/XapiProxyPolyFill.php +++ b/Modules/CmiXapi/classes/XapiProxy/XapiProxyPolyFill.php @@ -86,21 +86,21 @@ public function msg(string $msg): string public function initLrs(): void { $this->log()->debug($this->msg('initLrs')); -// if ($this->plugin) { -// try { -// $authToken = \ilXapiCmi5AuthToken::getInstanceByToken($this->token); -// } -// catch (\ilXapiCmi5Exception $e) { -// $this->log()->error($this->msg($e->getMessage())); -// header('HTTP/1.1 401 Unauthorized'); -// header('Access-Control-Allow-Origin: '.$_SERVER["HTTP_ORIGIN"]); -// header('Access-Control-Allow-Credentials: true'); -// exit; -// } -// $this->authToken = $authToken; -// $this->getLrsTypePlugin(); -// } -// else { + // if ($this->plugin) { + // try { + // $authToken = \ilXapiCmi5AuthToken::getInstanceByToken($this->token); + // } + // catch (\ilXapiCmi5Exception $e) { + // $this->log()->error($this->msg($e->getMessage())); + // header('HTTP/1.1 401 Unauthorized'); + // header('Access-Control-Allow-Origin: '.$_SERVER["HTTP_ORIGIN"]); + // header('Access-Control-Allow-Credentials: true'); + // exit; + // } + // $this->authToken = $authToken; + // $this->getLrsTypePlugin(); + // } + // else { try { $authToken = \ilCmiXapiAuthToken::getInstanceByToken($this->token); } catch (\ilCmiXapiException $e) { @@ -113,7 +113,7 @@ public function initLrs(): void $this->authToken = $authToken; $this->getLrsType(); -// } + // } } private function getLrsTypePlugin(): void @@ -128,13 +128,13 @@ private function getLrsTypePlugin(): void header('Access-Control-Allow-Credentials: true'); exit; } -// $this->defaultLrsEndpoint = $lrsType->getDefaultLrsEndpoint(); -// $this->defaultLrsKey = $lrsType->getDefaultLrsKey(); -// $this->defaultLrsSecret = $lrsType->getDefaultLrsSecret(); -// -// $this->fallbackLrsEndpoint = $lrsType->getFallbackLrsEndpoint(); -// $this->fallbackLrsKey = $lrsType->getFallbackLrsKey(); -// $this->fallbackLrsSecret = $lrsType->getFallbackLrsSecret(); + // $this->defaultLrsEndpoint = $lrsType->getDefaultLrsEndpoint(); + // $this->defaultLrsKey = $lrsType->getDefaultLrsKey(); + // $this->defaultLrsSecret = $lrsType->getDefaultLrsSecret(); + // + // $this->fallbackLrsEndpoint = $lrsType->getFallbackLrsEndpoint(); + // $this->fallbackLrsKey = $lrsType->getFallbackLrsKey(); + // $this->fallbackLrsSecret = $lrsType->getFallbackLrsSecret(); $this->lrsType = $lrsType; } catch (\Exception $e) { @@ -210,7 +210,7 @@ private function getLrsTypeAndMoreByToken(): ?\ilCmiXapiLrsType while ($row = $db->fetchObject($res)) { $type_id = (int) $row->lrs_type_id; if ($type_id) { -// $lrs = ($this->plugin) ? new \ilXapiCmi5LrsType($type_id) : new \ilCmiXapiLrsType($type_id); + // $lrs = ($this->plugin) ? new \ilXapiCmi5LrsType($type_id) : new \ilCmiXapiLrsType($type_id); $lrs = new \ilCmiXapiLrsType($type_id); } diff --git a/Modules/CmiXapi/classes/XapiProxy/XapiProxyResponse.php b/Modules/CmiXapi/classes/XapiProxy/XapiProxyResponse.php index e4bf474ae9f6..5377d0be8785 100755 --- a/Modules/CmiXapi/classes/XapiProxy/XapiProxyResponse.php +++ b/Modules/CmiXapi/classes/XapiProxy/XapiProxyResponse.php @@ -26,13 +26,13 @@ class XapiProxyResponse { -// private $dic; + // private $dic; private XapiProxy $xapiproxy; //private $xapiProxyRequest; public function __construct(XapiProxy $xapiproxy) { -// $this->dic = $GLOBALS['DIC']; + // $this->dic = $GLOBALS['DIC']; $this->xapiproxy = $xapiproxy; } diff --git a/Modules/CmiXapi/classes/XapiReport/class.ilCmiXapiHighscoreReport.php b/Modules/CmiXapi/classes/XapiReport/class.ilCmiXapiHighscoreReport.php index 9c5186169b58..0a3a76c27f0e 100755 --- a/Modules/CmiXapi/classes/XapiReport/class.ilCmiXapiHighscoreReport.php +++ b/Modules/CmiXapi/classes/XapiReport/class.ilCmiXapiHighscoreReport.php @@ -195,15 +195,15 @@ public function getUserRank(): ?int public function getResponseDebug(): string { -// foreach($this->response as $key => $item) -// { -// $user = ilCmiXapiUser::getUserFromIdent( -// ilObjectFactory::getInstanceByRefId($_GET['ref_id']), -// $tableRowData['mbox'] -// ); -// -// $this->response[$key]['realname'] = $user->getFullname(); -// } + // foreach($this->response as $key => $item) + // { + // $user = ilCmiXapiUser::getUserFromIdent( + // ilObjectFactory::getInstanceByRefId($_GET['ref_id']), + // $tableRowData['mbox'] + // ); + // + // $this->response[$key]['realname'] = $user->getFullname(); + // } return '
' . json_encode($this->response, JSON_PRETTY_PRINT) . '
'; } } diff --git a/Modules/CmiXapi/classes/class.ilCmiXapiDataSet.php b/Modules/CmiXapi/classes/class.ilCmiXapiDataSet.php index 80f9554bf769..37ac4b374ae4 100755 --- a/Modules/CmiXapi/classes/class.ilCmiXapiDataSet.php +++ b/Modules/CmiXapi/classes/class.ilCmiXapiDataSet.php @@ -131,8 +131,8 @@ public function __construct(int $a_id = 0, bool $a_reference = true) global $DIC; /** @var \ILIAS\DI\Container $DIC */ -// $this->_main_object_id = $a_id; -// $this->_dataSetMapping = ilObjCmiXapi::getInstance($a_id, $a_reference)->getDataSetMapping(); + // $this->_main_object_id = $a_id; + // $this->_dataSetMapping = ilObjCmiXapi::getInstance($a_id, $a_reference)->getDataSetMapping(); //var_dump($this->_dataSetMapping); exit; parent::__construct(); diff --git a/Modules/CmiXapi/classes/class.ilCmiXapiExporter.php b/Modules/CmiXapi/classes/class.ilCmiXapiExporter.php index 92b303752594..e7c6fffeb688 100644 --- a/Modules/CmiXapi/classes/class.ilCmiXapiExporter.php +++ b/Modules/CmiXapi/classes/class.ilCmiXapiExporter.php @@ -32,7 +32,7 @@ class ilCmiXapiExporter extends ilXmlExporter public const ENTITY = 'cmix'; public const SCHEMA_VERSION = '5.1.0'; -// private $main_object = null; + // private $main_object = null; private ?ilCmiXapiDataSet $_dataset = null; public function __construct() diff --git a/Modules/CmiXapi/classes/class.ilCmiXapiImporter.php b/Modules/CmiXapi/classes/class.ilCmiXapiImporter.php index a4aa657f5d0e..5e1f0fa19eb3 100755 --- a/Modules/CmiXapi/classes/class.ilCmiXapiImporter.php +++ b/Modules/CmiXapi/classes/class.ilCmiXapiImporter.php @@ -37,9 +37,9 @@ class ilCmiXapiImporter extends ilXmlImporter private ilObject $_cmixObj; - private ?int $_newId = null; + private ?string $_newId = null; - private int $_import_objId; + private string $_import_objId; private \ilImportMapping $_mapping; @@ -77,16 +77,18 @@ public function __construct() */ public function importXmlRepresentation(string $a_entity, string $a_id, string $a_xml, ilImportMapping $a_mapping): void { - $this->_import_objId = (int) $a_id; + $this->_import_objId = $a_id; $this->_mapping = $a_mapping; - if (false === ($this->_newId = $a_mapping->getMapping('Services/Container', 'objs', (string) $this->_import_objId))) { + if ($this->_newId = $a_mapping->getMapping('Services/Container', 'objs', (string) $this->_import_objId)) { + // container content + $this->prepareContainerObject(); + $this->getImportDirectoryContainer(); + } else { + // single object $this->prepareSingleObject(); $this->getImportDirectorySingle(); $this->_isSingleImport = true; - } else { - $this->prepareContainerObject(); - $this->getImportDirectoryContainer(); } $this->prepareLocalSourceStorage(); $this->parseXmlFileProperties(); @@ -108,7 +110,7 @@ private function prepareSingleObject(): self $this->_cmixObj->setDescription("test import"); // create the questionpool class in the ILIAS database (object_data table) $this->_cmixObj->create(true); - $this->_newId = $this->_cmixObj->getId(); + $this->_newId = (string) $this->_cmixObj->getId(); $this->_mapping->addMapping('Modules/CmiXapi', 'cmix', (string) $this->_import_objId, (string) $this->_newId); //$this->getImport(); $this->_cmixObj->update(); @@ -121,9 +123,10 @@ private function prepareSingleObject(): self */ private function prepareContainerObject(): void { - if ($this->_newId = $this->_mapping->getMapping('Services/Container', 'objs', (string) $this->_import_objId)) { + $this->_newId = $this->_mapping->getMapping('Services/Container', 'objs', (string) $this->_import_objId); + if (!is_null($this->_newId) && $this->_newId != "") { // container content - $this->_cmixObj = ilObjectFactory::getInstanceByObjId($this->_newId, false); + $this->_cmixObj = ilObjectFactory::getInstanceByObjId((int) $this->_newId, false); //$_SESSION['tst_import_subdir'] = $this->getImportPackageName(); $this->_cmixObj->save(); // this generates test id first time //var_dump([$this->getImportDirectory(), $this->_import_dirname]); exit; @@ -141,7 +144,7 @@ private function prepareContainerObject(): void private function prepareLocalSourceStorage(): self { if (true === $this->filesystemTemp->has($this->_relImportDir . '/content.zip')) { -// $this->_hasContent = true; + // $this->_hasContent = true; $this->_relWebDir = $this->_relWebDir . $this->_cmixObj->getId(); if (false === $this->filesystemWeb->has($this->_relWebDir)) { $this->filesystemWeb->createDir($this->_relWebDir); @@ -177,9 +180,9 @@ private function parseXmlFileProperties(): self /** * Finalize the new CmiXapi Object - * @return $this + * @return void */ - private function updateNewObj(): self + private function updateNewObj(): void { $this->_cmixObj->setTitle($this->_moduleProperties['Title'] . " " . $this->dic->language()->txt("copy_of_suffix")); $this->_cmixObj->setDescription($this->_moduleProperties['Description']); @@ -189,55 +192,54 @@ private function updateNewObj(): self $this->_cmixObj->setLrsTypeId((int) $this->_moduleProperties['LrsTypeId']); $this->_cmixObj->setLrsType(new ilCmiXapiLrsType((int) $this->_moduleProperties['LrsTypeId'])); } - $this->_cmixObj->setContentType($this->_moduleProperties['ContentType']); - $this->_cmixObj->setSourceType($this->_moduleProperties['SourceType']); - $this->_cmixObj->setActivityId($this->_moduleProperties['ActivityId']); - $this->_cmixObj->setInstructions($this->_moduleProperties['Instructions']); + $this->_cmixObj->setContentType((string) $this->_moduleProperties['ContentType']); + $this->_cmixObj->setSourceType((string) $this->_moduleProperties['SourceType']); + $this->_cmixObj->setActivityId((string) $this->_moduleProperties['ActivityId']); + $this->_cmixObj->setInstructions((string) $this->_moduleProperties['Instructions']); // $this->_cmixObj->setOfflineStatus($this->_moduleProperties['OfflineStatus']); - $this->_cmixObj->setLaunchUrl($this->_moduleProperties['LaunchUrl']); - $this->_cmixObj->setAuthFetchUrlEnabled($this->_moduleProperties['AuthFetchUrl']); - $this->_cmixObj->setLaunchMethod($this->_moduleProperties['LaunchMethod']); - $this->_cmixObj->setLaunchMode($this->_moduleProperties['LaunchMode']); - $this->_cmixObj->setMasteryScore($this->_moduleProperties['MasteryScore']); - $this->_cmixObj->setKeepLpStatusEnabled($this->_moduleProperties['KeepLp']); - $this->_cmixObj->setPrivacyIdent($this->_moduleProperties['PrivacyIdent']); - $this->_cmixObj->setPrivacyName($this->_moduleProperties['PrivacyName']); - $this->_cmixObj->setUserPrivacyComment($this->_moduleProperties['UsrPrivacyComment']); - $this->_cmixObj->setStatementsReportEnabled($this->_moduleProperties['ShowStatements']); - $this->_cmixObj->setXmlManifest($this->_moduleProperties['XmlManifest']); - $this->_cmixObj->setVersion($this->_moduleProperties['Version']); - $this->_cmixObj->setHighscoreEnabled($this->_moduleProperties['HighscoreEnabled']); - $this->_cmixObj->setHighscoreAchievedTS($this->_moduleProperties['HighscoreAchievedTs']); - $this->_cmixObj->setHighscorePercentage($this->_moduleProperties['HighscorePercentage']); - $this->_cmixObj->setHighscoreWtime($this->_moduleProperties['HighscoreWtime']); - $this->_cmixObj->setHighscoreOwnTable($this->_moduleProperties['HighscoreOwnTable']); - $this->_cmixObj->setHighscoreTopTable($this->_moduleProperties['HighscoreTopTable']); - $this->_cmixObj->setHighscoreTopNum($this->_moduleProperties['HighscoreTopNum']); - $this->_cmixObj->setBypassProxyEnabled($this->_moduleProperties['BypassProxy']); - $this->_cmixObj->setOnlyMoveon($this->_moduleProperties['OnlyMoveon']); - $this->_cmixObj->setAchieved($this->_moduleProperties['Achieved']); - $this->_cmixObj->setAnswered($this->_moduleProperties['Answered']); - $this->_cmixObj->setCompleted($this->_moduleProperties['Completed']); - $this->_cmixObj->setFailed($this->_moduleProperties['Failed']); - $this->_cmixObj->setInitialized($this->_moduleProperties['Initialized']); - $this->_cmixObj->setPassed($this->_moduleProperties['Passed']); - $this->_cmixObj->setProgressed($this->_moduleProperties['Progressed']); - $this->_cmixObj->setSatisfied($this->_moduleProperties['Satisfied']); - $this->_cmixObj->setTerminated($this->_moduleProperties['Terminated']); - $this->_cmixObj->setHideData($this->_moduleProperties['HideData']); - $this->_cmixObj->setTimestamp($this->_moduleProperties['Timestamp']); - $this->_cmixObj->setDuration($this->_moduleProperties['Duration']); - $this->_cmixObj->setNoSubstatements($this->_moduleProperties['NoSubstatements']); + $this->_cmixObj->setLaunchUrl((string) $this->_moduleProperties['LaunchUrl']); + $this->_cmixObj->setAuthFetchUrlEnabled((bool) $this->_moduleProperties['AuthFetchUrl']); + $this->_cmixObj->setLaunchMethod((string) $this->_moduleProperties['LaunchMethod']); + $this->_cmixObj->setLaunchMode((string) $this->_moduleProperties['LaunchMode']); + $this->_cmixObj->setMasteryScore((float) $this->_moduleProperties['MasteryScore']); + $this->_cmixObj->setKeepLpStatusEnabled((bool) $this->_moduleProperties['KeepLp']); + $this->_cmixObj->setPrivacyIdent((int) $this->_moduleProperties['PrivacyIdent']); + $this->_cmixObj->setPrivacyName((int) $this->_moduleProperties['PrivacyName']); + $this->_cmixObj->setUserPrivacyComment((string) $this->_moduleProperties['UsrPrivacyComment']); + $this->_cmixObj->setStatementsReportEnabled((bool) $this->_moduleProperties['ShowStatements']); + $this->_cmixObj->setXmlManifest((string) $this->_moduleProperties['XmlManifest']); + $this->_cmixObj->setVersion((int) $this->_moduleProperties['Version']); + $this->_cmixObj->setHighscoreEnabled((bool) $this->_moduleProperties['HighscoreEnabled']); + $this->_cmixObj->setHighscoreAchievedTS((bool) $this->_moduleProperties['HighscoreAchievedTs']); + $this->_cmixObj->setHighscorePercentage((bool) $this->_moduleProperties['HighscorePercentage']); + $this->_cmixObj->setHighscoreWtime((bool) $this->_moduleProperties['HighscoreWtime']); + $this->_cmixObj->setHighscoreOwnTable((bool) $this->_moduleProperties['HighscoreOwnTable']); + $this->_cmixObj->setHighscoreTopTable((bool) $this->_moduleProperties['HighscoreTopTable']); + $this->_cmixObj->setHighscoreTopNum((int) $this->_moduleProperties['HighscoreTopNum']); + $this->_cmixObj->setBypassProxyEnabled((bool) $this->_moduleProperties['BypassProxy']); + $this->_cmixObj->setOnlyMoveon((bool) $this->_moduleProperties['OnlyMoveon']); + $this->_cmixObj->setAchieved((bool) $this->_moduleProperties['Achieved']); + $this->_cmixObj->setAnswered((bool) $this->_moduleProperties['Answered']); + $this->_cmixObj->setCompleted((bool) $this->_moduleProperties['Completed']); + $this->_cmixObj->setFailed((bool) $this->_moduleProperties['Failed']); + $this->_cmixObj->setInitialized((bool) $this->_moduleProperties['Initialized']); + $this->_cmixObj->setPassed((bool) $this->_moduleProperties['Passed']); + $this->_cmixObj->setProgressed((bool) $this->_moduleProperties['Progressed']); + $this->_cmixObj->setSatisfied((bool) $this->_moduleProperties['Satisfied']); + $this->_cmixObj->setTerminated((bool) $this->_moduleProperties['Terminated']); + $this->_cmixObj->setHideData((bool) $this->_moduleProperties['HideData']); + $this->_cmixObj->setTimestamp((bool) $this->_moduleProperties['Timestamp']); + $this->_cmixObj->setDuration((bool) $this->_moduleProperties['Duration']); + $this->_cmixObj->setNoSubstatements((bool) $this->_moduleProperties['NoSubstatements']); $this->_cmixObj->setPublisherId((string) $this->_moduleProperties['PublisherId']); -// $this->_cmixObj->setAnonymousHomepage($this->_moduleProperties['AnonymousHomepage']); + // $this->_cmixObj->setAnonymousHomepage($this->_moduleProperties['AnonymousHomepage']); $this->_cmixObj->setMoveOn((string) $this->_moduleProperties['MoveOn']); $this->_cmixObj->setLaunchParameters((string) $this->_moduleProperties['LaunchParameters']); $this->_cmixObj->setEntitlementKey((string) $this->_moduleProperties['EntitlementKey']); - $this->_cmixObj->setSwitchToReviewEnabled($this->_moduleProperties['SwitchToReview']); + $this->_cmixObj->setSwitchToReviewEnabled((bool) $this->_moduleProperties['SwitchToReview']); $this->_cmixObj->save(); $this->_cmixObj->updateMetaData(); - return $this; } /** diff --git a/Modules/CmiXapi/classes/class.ilCmiXapiStatementsGUI.php b/Modules/CmiXapi/classes/class.ilCmiXapiStatementsGUI.php index d32c135588e8..ac3ddccb9eb4 100644 --- a/Modules/CmiXapi/classes/class.ilCmiXapiStatementsGUI.php +++ b/Modules/CmiXapi/classes/class.ilCmiXapiStatementsGUI.php @@ -199,7 +199,7 @@ protected function initTableData( } } else { $usrId = $DIC->user()->getId(); -// if (!ilCmiXapiUser::getUsersForObject($this->object->getId(), $usrId)) { + // if (!ilCmiXapiUser::getUsersForObject($this->object->getId(), $usrId)) { if (!ilCmiXapiUser::getUsersForObject($this->object->getId())) { $table->setData(array()); $table->setMaxCount(0); @@ -247,12 +247,12 @@ public function getVerbs(): ?array 'Authorization' => $defaultBasicAuth, 'Cache-Control' => 'no-cache, no-store, must-revalidate' ]; -// $fallbackHeaders = [ -// 'X-Experience-API-Version' => '1.0.3', -// 'Authorization' => $fallbackBasicAuth, -// 'Content-Type' => 'application/json;charset=utf-8', -// 'Cache-Control' => 'no-cache, no-store, must-revalidate' -// ]; + // $fallbackHeaders = [ + // 'X-Experience-API-Version' => '1.0.3', + // 'Authorization' => $fallbackBasicAuth, + // 'Content-Type' => 'application/json;charset=utf-8', + // 'Cache-Control' => 'no-cache, no-store, must-revalidate' + // ]; $pipeline = json_encode($this->getVerbsPipline()); $defaultVerbsUrl = $defaultLrs . "?pipeline=" . urlencode($pipeline); diff --git a/Modules/CmiXapi/classes/class.ilCmiXapiVerbList.php b/Modules/CmiXapi/classes/class.ilCmiXapiVerbList.php index ed5c48d4c888..2c6cc57bb696 100644 --- a/Modules/CmiXapi/classes/class.ilCmiXapiVerbList.php +++ b/Modules/CmiXapi/classes/class.ilCmiXapiVerbList.php @@ -76,7 +76,7 @@ public function getVerbUri(string $verb): string return 'http://adlnet.gov/expapi/verbs/' . $verb; } - public function getDynamicSelectOptions($verbs): array + public function getDynamicSelectOptions(?array $verbs): array { global $DIC; /* @var \ILIAS\DI\Container $DIC */ @@ -84,12 +84,14 @@ public function getDynamicSelectOptions($verbs): array '' => $DIC->language()->txt('cmix_all_verbs') ); - foreach ($verbs as $verb) { - $verb = $verb['_id']; - $options[urlencode($verb)] = self::getVerbTranslation( - $DIC->language(), - $verb - ); + if (is_array($verbs)) { + foreach ($verbs as $verb) { + $verb = $verb['_id']; + $options[urlencode($verb)] = self::getVerbTranslation( + $DIC->language(), + $verb + ); + } } return $options; diff --git a/Modules/CmiXapi/classes/class.ilObjCmiXapi.php b/Modules/CmiXapi/classes/class.ilObjCmiXapi.php index 6ca18f77e4af..20d89c2fe2e9 100755 --- a/Modules/CmiXapi/classes/class.ilObjCmiXapi.php +++ b/Modules/CmiXapi/classes/class.ilObjCmiXapi.php @@ -1306,23 +1306,23 @@ protected function doDelete(): void // TODO check xapidel } -// /** -// * @return string[] -// */ -// public function getRegistrations() : array -// { -// global $DIC; -// $res = $DIC->database()->queryF( -// "SELECT DISTINCT registration FROM " . self::DB_USERS_TABLE_NAME . " WHERE obj_id = %s", -// array('text'), -// array($this->getId()) -// ); -// $ret = []; -// while ($row = $DIC->database()->fetchAssoc($res)) { -// $ret[] = (string) $row['registration']; -// } -// return $ret; -// } + // /** + // * @return string[] + // */ + // public function getRegistrations() : array + // { + // global $DIC; + // $res = $DIC->database()->queryF( + // "SELECT DISTINCT registration FROM " . self::DB_USERS_TABLE_NAME . " WHERE obj_id = %s", + // array('text'), + // array($this->getId()) + // ); + // $ret = []; + // while ($row = $DIC->database()->fetchAssoc($res)) { + // $ret[] = (string) $row['registration']; + // } + // return $ret; + // } /** * @throws Exception diff --git a/Modules/Exercise/Submission/class.ilExerciseSubmissionTableGUI.php b/Modules/Exercise/Submission/class.ilExerciseSubmissionTableGUI.php index a30d43b6afcd..dde0d0a9dcec 100644 --- a/Modules/Exercise/Submission/class.ilExerciseSubmissionTableGUI.php +++ b/Modules/Exercise/Submission/class.ilExerciseSubmissionTableGUI.php @@ -129,6 +129,10 @@ public function __construct( $this->addMultiCommand("sendMembers", $this->lng->txt("exc_send_assignment")); + if ($this->mode == self::MODE_BY_ASSIGNMENT) { + $this->addMultiCommand("sendGradingNotification", $this->lng->txt("exc_send_grading_notification")); + } + if ($this->mode == self::MODE_BY_ASSIGNMENT && $this->ass && $this->ass->hasTeam()) { @@ -483,7 +487,9 @@ protected function parseRow( } } - if ($this->ass_type != null && $this->ass_type->supportsWebDirAccess() && $a_row['submission_obj']->hasSubmittedPrintVersion()) { + $ass_type = $this->ass_type ?: ilExAssignmentTypes::getInstance()->getById($a_ass->getType()); + + if ($ass_type->supportsWebDirAccess() && $a_row['submission_obj']->hasSubmittedPrintVersion()) { $url = $ilCtrl->getLinkTarget($this->getParentObject(), "openSubmissionView"); $items[] = $this->ui_factory->link()->standard($this->lng->txt("exc_tbl_action_open_submission"), $url)->withOpenInNewViewport(true); if ($a_row['submission_obj']->hasSubmittedPrintVersion()) { diff --git a/Modules/Exercise/classes/class.ilExerciseMailNotification.php b/Modules/Exercise/classes/class.ilExerciseMailNotification.php index 83de667ecfa7..b68c778a2695 100644 --- a/Modules/Exercise/classes/class.ilExerciseMailNotification.php +++ b/Modules/Exercise/classes/class.ilExerciseMailNotification.php @@ -24,6 +24,8 @@ class ilExerciseMailNotification extends ilMailNotification public const TYPE_FEEDBACK_FILE_ADDED = 20; public const TYPE_SUBMISSION_UPLOAD = 30; public const TYPE_FEEDBACK_TEXT_ADDED = 40; + public const TYPE_GRADING_DONE = 70; + protected \ILIAS\Exercise\InternalDomainService $domain; protected ilObjUser $user; protected int $ass_id; @@ -33,6 +35,7 @@ public function __construct() global $DIC; $this->user = $DIC->user(); + $this->domain = $DIC->exercise()->internal()->domain(); parent::__construct(); } @@ -46,6 +49,23 @@ public function getAssignmentId(): int return $this->ass_id; } + protected function addOpenSubmission(): void + { + $ass = new ilExAssignment($this->getAssignmentId()); + $types = ilExAssignmentTypes::getInstance(); + $type = $types->getById($ass->getType()); + if ($type->supportsWebDirAccess()) { + $submission = new ilExSubmission($ass, $this->user->getId()); + if ($submission->hasSubmittedPrintVersion()) { + $this->appendBody("\n\n"); + $this->appendBody(sprintf( + $this->getLanguageText('exc_submission_open_notification_link'), + $this->createPermanentLink(array(), "_" . $this->getAssignmentId() . "_" . $this->user->getId() . "_opensubmission") + )); + } + } + } + public function send(): bool { $ilUser = $this->user; @@ -141,6 +161,7 @@ public function send(): bool // $this->getLanguageText("exc_submission_no_new_files"))); //} } + $this->addOpenSubmission(); $this->appendBody("\n\n"); $this->appendBody(sprintf( @@ -189,6 +210,45 @@ public function send(): bool $this->sendMail(array($rcp)); } break; + + case self::TYPE_GRADING_DONE: + + foreach ($this->getRecipients() as $rcp) { + $this->initLanguage($rcp); + $this->initMail(); + $this->setSubject( + sprintf( + $this->getLanguageText('exc_msg_grading_done'), + $this->getObjectTitle(true) + ) + ); + $this->setBody(ilMail::getSalutation($rcp, $this->getLanguage())); + $this->appendBody("\n\n"); + $this->appendBody( + sprintf( + $this->getLanguageText('exc_msg_grading_done_body'), + $this->getObjectTitle(false) + ) + ); + $this->appendBody("\n"); + $this->appendBody( + $this->getLanguageText('obj_exc') . ": " . $this->getObjectTitle(true) + ); + $this->appendBody("\n"); + $this->appendBody( + $this->getLanguageText('exc_assignment') . ": " . + ilExAssignment::lookupTitle($this->getAssignmentId()) + ); + $this->appendBody("\n\n"); + $this->appendBody($this->getLanguageText('exc_mail_permanent_link')); + $this->appendBody("\n"); + $this->appendBody($this->createPermanentLink(array(), '_' . $this->getAssignmentId()) . + '#fb' . $this->getAssignmentId()); + $this->getMail()->appendInstallationSignature(true); + + $this->sendMail(array($rcp)); + } + break; } return true; } diff --git a/Modules/Exercise/classes/class.ilExerciseManagementGUI.php b/Modules/Exercise/classes/class.ilExerciseManagementGUI.php index ec276ee213b2..e0d50616d9b8 100644 --- a/Modules/Exercise/classes/class.ilExerciseManagementGUI.php +++ b/Modules/Exercise/classes/class.ilExerciseManagementGUI.php @@ -2320,4 +2320,31 @@ public function collectFeedbackDataFromPeer( return $data; } + + public function sendGradingNotificationObject(): void + { + + $ass_id = $this->request->getAssId(); + $selected_users = $this->request->getSelectedParticipants(); + + $graded_users = array_filter($selected_users, function ($user_id) { + return $this->assignment->getMemberStatus($user_id)->getStatus() !== "notgraded"; + }); + + if (count($graded_users) === 0) { + $this->tpl->setOnScreenMessage("failure", $this->lng->txt("exc_no_graded_mem_selected"), true); + $this->ctrl->redirect($this, $this->getViewBack()); + } + + $not = new ilExerciseMailNotification(); + $not->setType(ilExerciseMailNotification::TYPE_GRADING_DONE); + $not->setAssignmentId($ass_id); + $not->setObjId($this->exercise->getId()); + $not->setRefId($this->exercise->getRefId()); + $not->setRecipients($graded_users); + $not->send(); + $this->tpl->setOnScreenMessage("success", $this->lng->txt("exc_graded_mem_notified"), true); + $this->ctrl->redirect($this, $this->getViewBack()); + } + } diff --git a/Modules/Exercise/classes/class.ilObjExerciseGUI.php b/Modules/Exercise/classes/class.ilObjExerciseGUI.php index f233eb0d10e1..0b7b640407b6 100755 --- a/Modules/Exercise/classes/class.ilObjExerciseGUI.php +++ b/Modules/Exercise/classes/class.ilObjExerciseGUI.php @@ -855,6 +855,7 @@ public static function _goto( switch (end($parts)) { case "download": case "setdownload": + case "opensubmission": $action = $parts[3]; $member = $parts[2]; $ass_id = $parts[1]; @@ -897,6 +898,14 @@ public static function _goto( ); break; + case "opensubmission": + $ilCtrl->setParameterByClass("ilExerciseHandlerGUI", "member_id", $member); + $ilCtrl->redirectByClass( + array("ilExerciseHandlerGUI", "ilObjExerciseGUI", "ilExerciseManagementGUI"), + "openSubmissionView" + ); + break; + default: if (($parts[1] ?? "") != "") { $ilCtrl->setParameterByClass("ilExerciseHandlerGUI", "ass_id", $parts[1]); diff --git a/Modules/File/classes/Icons/IconDatabaseRepository.php b/Modules/File/classes/Icons/IconDatabaseRepository.php index 5332ab019254..a0ff08666f10 100644 --- a/Modules/File/classes/Icons/IconDatabaseRepository.php +++ b/Modules/File/classes/Icons/IconDatabaseRepository.php @@ -208,7 +208,7 @@ public function getActiveIconForSuffix(string $a_suffix): Icon public function getIconFilePathBySuffix(string $suffix): string { if ($suffix !== "") { - $icon = self::getActiveIconForSuffix($suffix); + $icon = $this->getActiveIconForSuffix($suffix); if (!$icon instanceof NullIcon) { $resource_identification = $this->irss->manage()->find($icon->getRid()); if ($resource_identification !== null) { diff --git a/Modules/File/classes/Icons/class.ilObjFileDefaultIconsObjective.php b/Modules/File/classes/Icons/class.ilObjFileDefaultIconsObjective.php index b6794cc1a7a9..7907b9c315f2 100644 --- a/Modules/File/classes/Icons/class.ilObjFileDefaultIconsObjective.php +++ b/Modules/File/classes/Icons/class.ilObjFileDefaultIconsObjective.php @@ -83,7 +83,7 @@ public function achieve(Environment $environment): Environment $scan_result = scandir(self::PATH_DEFAULT_ICON_DIR); $default_icon_filenames = preg_grep("/^icon_file_/", $scan_result); foreach ($default_icon_filenames as $default_icon_filename) { - $icon_file_prefix = "standard/icon_file_"; + $icon_file_prefix = "icon_file_"; $icon_file_suffix = ".svg"; $suffix = str_replace($icon_file_prefix, "", $default_icon_filename); $suffix = str_replace($icon_file_suffix, "", $suffix); diff --git a/Modules/File/classes/ObjectProperties/FileObjectProperties.php b/Modules/File/classes/ObjectProperties/FileObjectProperties.php new file mode 100644 index 000000000000..1d29763feb61 --- /dev/null +++ b/Modules/File/classes/ObjectProperties/FileObjectProperties.php @@ -0,0 +1,45 @@ +providers === null) { + $this->providers = new FileObjectPropertyProviders(); + } + return $this->providers; + } + + public function preload(array $object_ids): void + { + return; + } +} diff --git a/Modules/File/classes/ObjectProperties/FileObjectPropertyProviders.php b/Modules/File/classes/ObjectProperties/FileObjectPropertyProviders.php new file mode 100644 index 000000000000..f6e5d717a882 --- /dev/null +++ b/Modules/File/classes/ObjectProperties/FileObjectPropertyProviders.php @@ -0,0 +1,102 @@ +crop_definition = new CropToSquare($this->persist, $this->max_size); + $this->extract_definition = new PagesToExtract($this->persist, $this->max_size, 1, true); + } + + public function getObjectTypeSpecificTileImage( + int $obj_id, + ImageFactory $factory, + StorageService $irss + ): ?Image { + if (($flavour_path = $this->getCardImageFallbackPath( + $obj_id, + $irss + )) !== '') { + return $factory->responsive($flavour_path, ''); + } + + return null; + } + + /** + * @description Can be used to take preview flavours as card images + */ + protected function getCardImageFallbackPath( + int $obj_id, + StorageService $irss + ): string { + $rid = $irss->manage()->find(ilObjFileAccess::getListGUIData($obj_id)['rid'] ?? ''); + if ($rid === null) { + return ''; + } + if ($irss->flavours()->possible($rid, $this->crop_definition)) { + $url = $irss->consume()->flavourUrls( + $irss->flavours()->get( + $rid, + $this->crop_definition + ) + )->getURLs(false)->current(); + if ($url !== null) { + return $url; + } + } + if ($irss->flavours()->possible($rid, $this->extract_definition)) { + $url = $irss->consume()->flavourUrls( + $irss->flavours()->get( + $rid, + $this->extract_definition + ) + )->getURLs(false)->current(); + if ($url !== null) { + return $url; + } + } + return ''; + } + + public function getObjectTypeSpecificCustomIcon( + int $obj_id, + IconFactory $icon_factory, + StorageService $irss + ): ?Icon { + return null; + } +} diff --git a/Modules/File/classes/Setup/Database/class.ilFileObjectDatabaseObjective.php b/Modules/File/classes/Setup/Database/class.ilFileObjectDatabaseObjective.php index 8ae27159225b..def7511ad8ae 100644 --- a/Modules/File/classes/Setup/Database/class.ilFileObjectDatabaseObjective.php +++ b/Modules/File/classes/Setup/Database/class.ilFileObjectDatabaseObjective.php @@ -169,6 +169,15 @@ public function step_4(): void } } + public function step_5(): void + { + // replace wrong suffixes. currently they are stored with e.g. icon_file_docx and should be docx. + // update the whole table with a replace statement. + $this->database->manipulate( + "UPDATE il_file_icon_suffixes SET suffix = REPLACE(suffix, 'icon_file_', '') WHERE suffix LIKE 'icon_file_%';" + ); + } + /** * Halts the execution of these update steps if no database was * provided. diff --git a/Modules/File/classes/class.ilObjFileAccessSettingsGUI.php b/Modules/File/classes/class.ilObjFileAccessSettingsGUI.php index da802b4d5951..32390abc20fd 100644 --- a/Modules/File/classes/class.ilObjFileAccessSettingsGUI.php +++ b/Modules/File/classes/class.ilObjFileAccessSettingsGUI.php @@ -148,8 +148,25 @@ public function getAdminTabs(): void } } + protected function addFileObjectsSubTabs(): void + { + $this->tabs_gui->addSubTabTarget( + "settings", + $this->ctrl->getLinkTarget($this, self::CMD_EDIT_SETTINGS), + array(self::CMD_EDIT_SETTINGS, "view") + ); + $this->tabs_gui->addSubTabTarget( + self::SUBTAB_SUFFIX_SPECIFIC_ICONS, + $this->ctrl->getLinkTargetByClass(ilObjFileIconsOverviewGUI::class, ilObjFileIconsOverviewGUI::CMD_INDEX), + array(ilObjFileIconsOverviewGUI::CMD_INDEX, "view") + ); + } + + protected function editSettings(): void { + $this->addFileObjectsSubTabs(); + $this->tabs_gui->setSubTabActive("settings"); $form = $this->buildForm(); $this->tpl->setContent($this->ui_renderer->render($this->buildForm())); } diff --git a/Modules/File/classes/class.ilObjFileListGUI.php b/Modules/File/classes/class.ilObjFileListGUI.php index 8c94d7ea6b34..51ff4e56b0c8 100644 --- a/Modules/File/classes/class.ilObjFileListGUI.php +++ b/Modules/File/classes/class.ilObjFileListGUI.php @@ -16,7 +16,6 @@ * *********************************************************************/ -use ILIAS\FileUpload\MimeType; use ILIAS\File\Icon\IconDatabaseRepository; use ILIAS\ResourceStorage\Flavour\Definition\CropToSquare; use ILIAS\ResourceStorage\Flavour\Definition\FlavourDefinition; @@ -34,7 +33,7 @@ class ilObjFileListGUI extends ilObjectListGUI { use ilObjFileSecureString; - private bool $use_flavor_for_cards = false; + private bool $use_flavor_for_cards = true; protected string $title; private bool $persist = true; private int $max_size = 512; @@ -59,8 +58,13 @@ protected function getTileImagePath(): string return parent::getTileImagePath(); } // First we use a configured Tile Image - $img = $this->object_service->commonSettings()->tileImage()->getByObjId($this->obj_id); - if ($img->exists()) { + $object = ilObjectFactory::getInstanceByObjId($this->obj_id); + if ($object === null) { + return ''; + } + + $img = $object->getObjectProperties()->getPropertyTileImage()->getTileImage(); + if ($img !== null && $img->exists()) { return $img->getFullPath(); } @@ -109,7 +113,6 @@ protected function getCardImageFallbackPath(int $obj_id, string $type): string return ''; } - /** * initialisation */ diff --git a/Modules/LTIConsumer/classes/Certificate/class.ilCertificateSettingsLTIConsumerFormRepository.php b/Modules/LTIConsumer/classes/Certificate/class.ilCertificateSettingsLTIConsumerFormRepository.php index 31f5d54150f5..8001ad0a70aa 100644 --- a/Modules/LTIConsumer/classes/Certificate/class.ilCertificateSettingsLTIConsumerFormRepository.php +++ b/Modules/LTIConsumer/classes/Certificate/class.ilCertificateSettingsLTIConsumerFormRepository.php @@ -30,9 +30,9 @@ class ilCertificateSettingsLTIConsumerFormRepository implements ilCertificateFor { private \ilCertificateSettingsFormRepository $settingsFormRepository; -// private \ilLanguage $language; -// -// private \ilObjLTIConsumer $object; + // private \ilLanguage $language; + // + // private \ilObjLTIConsumer $object; public function __construct( ilObjLTIConsumer $object, @@ -45,8 +45,8 @@ public function __construct( ilCertificatePlaceholderDescription $placeholderDescriptionObject, ilCertificateSettingsFormRepository $settingsFormRepository = null ) { -// $this->object = $object; -// $this->language = $language; + // $this->object = $object; + // $this->language = $language; if (null === $settingsFormRepository) { $settingsFormRepository = new ilCertificateSettingsFormRepository( diff --git a/Modules/LTIConsumer/classes/Certificate/class.ilLTIConsumerPlaceholderValues.php b/Modules/LTIConsumer/classes/Certificate/class.ilLTIConsumerPlaceholderValues.php index 5de41f05353f..3d4878b831dd 100644 --- a/Modules/LTIConsumer/classes/Certificate/class.ilLTIConsumerPlaceholderValues.php +++ b/Modules/LTIConsumer/classes/Certificate/class.ilLTIConsumerPlaceholderValues.php @@ -32,7 +32,7 @@ class ilLTIConsumerPlaceholderValues implements ilCertificatePlaceholderValues private ?\ilCertificateObjectHelper $objectHelper; -// private \ilCertificateUserObjectHelper $userObjectHelper; + // private \ilCertificateUserObjectHelper $userObjectHelper; private ?\ilCertificateUtilHelper $utilHelper; @@ -82,7 +82,7 @@ public function __construct( if (null === $userObjectHelper) { $userObjectHelper = new ilCertificateUserObjectHelper(); } -// $this->userObjectHelper = $userObjectHelper; + // $this->userObjectHelper = $userObjectHelper; if (null === $lpStatusHelper) { $lpStatusHelper = new ilCertificateLPStatusHelper(); diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumeProvider.php b/Modules/LTIConsumer/classes/class.ilLTIConsumeProvider.php index 881d6be4ae6d..ab73fb28dd23 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumeProvider.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumeProvider.php @@ -1064,21 +1064,21 @@ public function isResetableToUserDefined(): bool // public function getPlattformId(): string // { - // return ILIAS_HTTP_PATH; + // return ILIAS_HTTP_PATH; // } // public function getAuthenticationRequestUrl(): string // { - // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/ltiauth.php"; + // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/ltiauth.php"; // } // public function getAccessTokenUrl(): string // { - // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/ltitoken.php"; + // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/ltitoken.php"; // } // public function getPublicKeysetUrl(): string // { - // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/lticerts.php"; + // return ILIAS_HTTP_PATH . "/Modules/LTIConsumer/lticerts.php"; // } } diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumeProviderFormGUI.php b/Modules/LTIConsumer/classes/class.ilLTIConsumeProviderFormGUI.php index 6a043cdbdb13..00019c420bc4 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumeProviderFormGUI.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumeProviderFormGUI.php @@ -205,7 +205,7 @@ public function initForm(string $formaction, string $saveCmd, string $cancelCmd) $providerUrlInp->setValue($this->provider->getProviderUrl()); $providerUrlInp->setRequired(true); $lti11->addSubItem($providerUrlInp); -// Abfrage ob Key und secret von Objekterstellern eingegeben werden soll + // Abfrage ob Key und secret von Objekterstellern eingegeben werden soll $keyGlobal = new ilCheckboxInputGUI($lng->txt('lti_con_prov_provider_key_global'), 'provider_key_global'); $keyGlobal->setValue("1"); if (!$this->provider->isProviderKeyCustomizable()) { @@ -277,7 +277,7 @@ public function initForm(string $formaction, string $saveCmd, string $cancelCmd) $item->addOption($op); $item->setValue((string) $this->provider->getPrivacyIdent()); $item->setInfo( - $lng->txt('conf_privacy_ident_info') . ' ' . ilCmiXapiUser::getIliasUuid() + $lng->txt('conf_privacy_ident_info') . ' ' . ilCmiXapiUser::getIliasUuid() . '.ilias' ); $item->setRequired(false); $this->addItem($item); @@ -599,7 +599,7 @@ public function initToolConfigForm(string $formaction, string $saveCmd, string $ $providerUrlInp->setValue($this->provider->getProviderUrl()); $providerUrlInp->setRequired(true); $lti11->addSubItem($providerUrlInp); -// Abfrage ob Key und secret von Objekterstellern eingegeben werden soll + // Abfrage ob Key und secret von Objekterstellern eingegeben werden soll $keyGlobal = new ilCheckboxInputGUI($lng->txt('lti_con_prov_provider_key_global'), 'provider_key_global'); $keyGlobal->setValue("1"); if (!$this->provider->isProviderKeyCustomizable()) { @@ -671,7 +671,7 @@ public function initToolConfigForm(string $formaction, string $saveCmd, string $ $item->addOption($op); $item->setValue((string) $this->provider->getPrivacyIdent()); $item->setInfo( - $lng->txt('conf_privacy_ident_info') . ' ' . ilCmiXapiUser::getIliasUuid() + $lng->txt('conf_privacy_ident_info') . ' ' . ilCmiXapiUser::getIliasUuid() . '.ilias' ); $item->setRequired(false); $this->addItem($item); @@ -981,7 +981,7 @@ public function getDynRegRequest(): string $template->setVariable('LTI_REG_END_URL', ilObjLTIConsumer::getRegistrationEndUrl()); $template->setVariable('LTI_SHOW_TOOL_CONFIG_URL', $showToolConfigUrl); $template->setVariable('LTI_REG_ERROR_URL', $regErrorUrl); - $DIC->ui()->mainTemplate()->setOnScreenMessage('info', $lng->txt('lti_dyn_reg_redirect_after_10_secs')); + //$DIC->ui()->mainTemplate()->setOnScreenMessage('info', $lng->txt('lti_dyn_reg_redirect_after_10_secs')); return $template->get() . $this->getHTML(); } diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerAccess.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerAccess.php index 554c23417d6a..324eb99bfe5d 100644 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerAccess.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerAccess.php @@ -92,7 +92,7 @@ public function hasStatementsAccess(): bool public function hasHighscoreAccess(): bool { -// Todo -check + // Todo -check if (!$this->object->getUseXapi()) { return false; } diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerAdministrationGUI.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerAdministrationGUI.php index 64f0627e577a..633a65594c7f 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerAdministrationGUI.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerAdministrationGUI.php @@ -123,7 +123,7 @@ public function executeCommand(): void } } -// todo? + // todo? protected function applyGlobalProviderFilterCmd(): void { $table = $this->buildProviderTable($this, self::CMD_SHOW_GLOBAL_PROVIDER); @@ -440,7 +440,7 @@ private function getIconXml(string $url, string $pId): ?string private function checkIconFileExtension(string $ext): bool { -// todo - check? + // todo - check? return false !== ($check = array_search($ext, self::ALLOWED_FILE_EXT)) ? true : false; } @@ -906,7 +906,7 @@ protected function fetchProviderMulti(): array protected function showSettingsCmd(?ilPropertyFormGUI $form = null): void { -// todo - check + // todo - check global $DIC; /* @var \ILIAS\DI\Container $DIC */ return; // no settings at all currently @@ -922,7 +922,7 @@ protected function showSettingsCmd(?ilPropertyFormGUI $form = null): void protected function saveSettingsCmd(): void { -// todo - check + // todo - check global $DIC; /* @var \ILIAS\DI\Container $DIC */ return; // no settings at all currently diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerContentGUI.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerContentGUI.php index 89e90a5c6739..74c16193e7d1 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerContentGUI.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerContentGUI.php @@ -94,7 +94,7 @@ protected function launch(): void if (ilSession::get('lti13_login_data') != null) { $form = $this->getLoginLTI13Form(); if ($form == null) { -// $this->dic->ui()->mainTemplate()->setOnScreenMessage('failure', 'initialLogin Error: ' . $err, true); + // $this->dic->ui()->mainTemplate()->setOnScreenMessage('failure', 'initialLogin Error: ' . $err, true); $this->dic->ui()->mainTemplate()->setOnScreenMessage('failure', 'initialLogin Error: ', true); } else { $response = $this->dic->http()->response()->withBody(ILIAS\Filesystem\Stream\Streams::ofString($form)); @@ -177,7 +177,7 @@ protected function getStartButtonTxt11(): string $returnUrl = !$this->object->isLaunchMethodOwnWin() ? '' : str_replace( '&', '&', - ILIAS_HTTP_PATH . "/" . $this->dic->ctrl()->getLinkTarget($this, "", "", false) + ilObjLTIConsumer::getIliasHttpPath() . "/" . $this->dic->ctrl()->getLinkTarget($this, "", "", false) ); $launchParameters = $this->object->buildLaunchParameters( @@ -231,7 +231,7 @@ protected function getStartButtonTxt13(): string $returnUrl = !$this->object->isLaunchMethodOwnWin() ? '' : str_replace( '&', '&', - ILIAS_HTTP_PATH . "/" . $this->dic->ctrl()->getLinkTarget($this, "", "", false) + ilObjLTIConsumer::getIliasHttpPath() . "/" . $this->dic->ctrl()->getLinkTarget($this, "", "", false) ); $target = $this->object->getLaunchMethod() == "newWin" ? "_blank" : "_self"; @@ -239,7 +239,7 @@ protected function getStartButtonTxt13(): string $ltiMessageHint = (string) $this->object->getRefId() . ":" . CLIENT_ID; ilSession::set('lti_message_hint', $ltiMessageHint); $output = '
'; - $output .= sprintf('', 'iss', ILIAS_HTTP_PATH) . "\n"; + $output .= sprintf('', 'iss', ilObjLTIConsumer::getIliasHttpPath()) . "\n"; $output .= sprintf('', 'target_link_uri', $this->object->getProvider()->getProviderUrl()) . "\n"; $output .= sprintf('', 'login_hint', $user_ident) . "\n"; $output .= sprintf('', 'lti_message_hint', $ltiMessageHint) . "\n"; @@ -273,7 +273,7 @@ protected function getEmbeddedAutoStartFormular(): string $ltiMessageHint = (string) $this->object->getRefId() . ":" . CLIENT_ID; ilSession::set('lti_message_hint', $ltiMessageHint); $output = ''; - $output .= sprintf('', 'iss', ILIAS_HTTP_PATH) . "\n"; + $output .= sprintf('', 'iss', ilObjLTIConsumer::getIliasHttpPath()) . "\n"; $output .= sprintf('', 'target_link_uri', $this->object->getProvider()->getProviderUrl()) . "\n"; $output .= sprintf('', 'login_hint', $user_ident) . "\n"; $output .= sprintf('', 'lti_message_hint', $ltiMessageHint) . "\n"; diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerLaunch.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerLaunch.php index 11e05f1911e0..15bb278c5208 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerLaunch.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerLaunch.php @@ -119,9 +119,9 @@ public static function signOAuth(array $a_params) case "PLAINTEXT": $method = new ILIAS\LTIOAuth\OAuthSignatureMethod_PLAINTEXT(); break; -// case "RSA_SHA1": -// $method = new ILIAS\LTIOAuth\OAuthSignatureMethod_RSA_SHA1(); -// break; + // case "RSA_SHA1": + // $method = new ILIAS\LTIOAuth\OAuthSignatureMethod_RSA_SHA1(); + // break; default: return "ERROR: unsupported signature method!"; @@ -131,7 +131,7 @@ public static function signOAuth(array $a_params) $request->sign_request($method, $consumer, $a_params["token"]); // Pass this back up "out of band" for debugging -// self::$last_oauth_base_string = $request->get_signature_base_string(); + // self::$last_oauth_base_string = $request->get_signature_base_string(); // die(self::$last_oauth_base_string); return $request->get_parameters(); diff --git a/Modules/LTIConsumer/classes/class.ilLTIConsumerResultService.php b/Modules/LTIConsumer/classes/class.ilLTIConsumerResultService.php index 1252503a22ed..3bf984be04a9 100755 --- a/Modules/LTIConsumer/classes/class.ilLTIConsumerResultService.php +++ b/Modules/LTIConsumer/classes/class.ilLTIConsumerResultService.php @@ -184,7 +184,7 @@ protected function replaceResult(\SimpleXMLElement $request): void } $lp_percentage = (int) round(100 * $result); -// Mantis #37080 + // Mantis #37080 ilLPStatus::writeStatus($this->result->obj_id, $this->result->usr_id, $lp_status, $lp_percentage, true); $code = "success"; diff --git a/Modules/LTIConsumer/classes/class.ilObjLTIConsumer.php b/Modules/LTIConsumer/classes/class.ilObjLTIConsumer.php index 00729263aaa5..24c16b112dca 100755 --- a/Modules/LTIConsumer/classes/class.ilObjLTIConsumer.php +++ b/Modules/LTIConsumer/classes/class.ilObjLTIConsumer.php @@ -658,6 +658,9 @@ public function buildLaunchParameters(ilCmiXapiUser $cmixUser, string $token, st global $DIC; /* @var \ILIAS\DI\Container $DIC */ $roles = $DIC->access()->checkAccess('write', '', $this->getRefId()) ? "Instructor" : "Learner"; + //todo if object is in course or group, roles would have to be taken from there s. Mantis 35435 - if necessary Jour Fixe topic + //$roles = "Administrator"; + if ($this->getProvider()->getAlwaysLearner() == true) { $roles = "Learner"; } @@ -1315,6 +1318,7 @@ public static function sendResponseError(int $code, string $message, $log = true public static function sendResponseJson(array $obj): void { + global $DIC; try { header('Content-Type: application/json; charset=utf-8'); header('Cache-Control: no-store'); diff --git a/Modules/LTIConsumer/classes/class.ilObjLTIConsumerGUI.php b/Modules/LTIConsumer/classes/class.ilObjLTIConsumerGUI.php index c30bd389d9e3..3ff7c3dcffc4 100755 --- a/Modules/LTIConsumer/classes/class.ilObjLTIConsumerGUI.php +++ b/Modules/LTIConsumer/classes/class.ilObjLTIConsumerGUI.php @@ -412,7 +412,7 @@ public function contentSelectionRequest(): void $ltiMessageHint = (string) $ref_id . ":" . CLIENT_ID . ":" . base64_encode($redirectUrl); $tplLogin = new ilTemplate("tpl.lti_initial_login.html", true, true, "Modules/LTIConsumer"); $tplLogin->setVariable("LTI_INITIAL_LOGIN_ACTION", $provider->getInitiateLogin()); - $tplLogin->setVariable("ISS", ILIAS_HTTP_PATH); + $tplLogin->setVariable("ISS", ilObjLTIConsumer::getIliasHttpPath()); $tplLogin->setVariable("TARGET_LINK_URL", $provider->getProviderUrl()); $tplLogin->setVariable("LOGIN_HINT", $userIdLTI); $tplLogin->setVariable("LTI_MESSAGE_HINT", $ltiMessageHint); @@ -922,61 +922,61 @@ protected function setTabs(): void ); } -// if (defined('DEVMODE') && DEVMODE) { -// $DIC->tabs()->addTab( -// 'debug', -// 'DEBUG', -// $DIC->ctrl()->getLinkTarget($this, 'debug') -// ); -// } + // if (defined('DEVMODE') && DEVMODE) { + // $DIC->tabs()->addTab( + // 'debug', + // 'DEBUG', + // $DIC->ctrl()->getLinkTarget($this, 'debug') + // ); + // } } -// protected function debug(): void -// { -// global $DIC; -// /* @var \ILIAS\DI\Container $DIC */ -// -// $DIC->tabs()->activateTab('debug'); -// -// $filter = new ilCmiXapiStatementsReportFilter(); -// $filter->setActivityId($this->object->getActivityId()); -// -// $aggregateEndPointUrl = str_replace( -// 'data/xAPI', -// 'api/statements/aggregate', -// $this->object->getProvider()->getXapiLaunchUrl() // should be named endpoint not launch url -// ); -// -// $linkBuilder = new ilCmiXapiHighscoreReportLinkBuilder( -// $this->object->getId(), -// $aggregateEndPointUrl, -// $filter -// ); -// -// $basicAuth = ilCmiXapiLrsType::buildBasicAuth( -// $this->object->getProvider()->getXapiLaunchKey(), -// $this->object->getProvider()->getXapiLaunchSecret() -// ); -// -// $request = new ilCmiXapiHighscoreReportRequest( -// $basicAuth, -// $linkBuilder -// ); -// -// try { -// $report = $request->queryReport($this->object->getId()); -// -// $DIC->ui()->mainTemplate()->setContent( -// $report->getResponseDebug() -// ); -// -// //ilUtil::sendSuccess('Object ID: '.$this->object->getId()); -// $DIC->ui()->mainTemplate()->setOnScreenMessage('info', $linkBuilder->getPipelineDebug()); -// $DIC->ui()->mainTemplate()->setOnScreenMessage('question', '
' . print_r($report->getTableData(), true) . '
'); -// } catch (Exception $e) { -// $this->tpl->setOnScreenMessage('failure', $e->getMessage()); -// } -// } + // protected function debug(): void + // { + // global $DIC; + // /* @var \ILIAS\DI\Container $DIC */ + // + // $DIC->tabs()->activateTab('debug'); + // + // $filter = new ilCmiXapiStatementsReportFilter(); + // $filter->setActivityId($this->object->getActivityId()); + // + // $aggregateEndPointUrl = str_replace( + // 'data/xAPI', + // 'api/statements/aggregate', + // $this->object->getProvider()->getXapiLaunchUrl() // should be named endpoint not launch url + // ); + // + // $linkBuilder = new ilCmiXapiHighscoreReportLinkBuilder( + // $this->object->getId(), + // $aggregateEndPointUrl, + // $filter + // ); + // + // $basicAuth = ilCmiXapiLrsType::buildBasicAuth( + // $this->object->getProvider()->getXapiLaunchKey(), + // $this->object->getProvider()->getXapiLaunchSecret() + // ); + // + // $request = new ilCmiXapiHighscoreReportRequest( + // $basicAuth, + // $linkBuilder + // ); + // + // try { + // $report = $request->queryReport($this->object->getId()); + // + // $DIC->ui()->mainTemplate()->setContent( + // $report->getResponseDebug() + // ); + // + // //ilUtil::sendSuccess('Object ID: '.$this->object->getId()); + // $DIC->ui()->mainTemplate()->setOnScreenMessage('info', $linkBuilder->getPipelineDebug()); + // $DIC->ui()->mainTemplate()->setOnScreenMessage('question', '
' . print_r($report->getTableData(), true) . '
'); + // } catch (Exception $e) { + // $this->tpl->setOnScreenMessage('failure', $e->getMessage()); + // } + // } protected function addLocatorItems(): void { diff --git a/Modules/LTIConsumer/module.xml b/Modules/LTIConsumer/module.xml index 6085e2916f01..b2e0f2410a9b 100644 --- a/Modules/LTIConsumer/module.xml +++ b/Modules/LTIConsumer/module.xml @@ -5,7 +5,7 @@ cat crs diff --git a/Modules/LTIConsumer/src/OAuth.php b/Modules/LTIConsumer/src/OAuth.php index d8400a5d5e87..a97950dc2de7 100755 --- a/Modules/LTIConsumer/src/OAuth.php +++ b/Modules/LTIConsumer/src/OAuth.php @@ -907,13 +907,13 @@ private function checkSignature(OAuthRequest $request, OAuthConsumer $consumer, $this->checkTimestamp($timestamp); $this->checkNonce($consumer, $token, $nonce, $timestamp); -// $signature_method = 'OAuthSignatureMethod_' . $this->getSignatureMethod($request); + // $signature_method = 'OAuthSignatureMethod_' . $this->getSignatureMethod($request); $signature_method = $this->getSignatureMethod($request); //check UK /** @psalm-suppress InvalidStringClass */ $method = new $signature_method(); $signature = $request->get_parameter('oauth_signature'); -// $valid_sig = $method->checkSignature( //check UK + // $valid_sig = $method->checkSignature( //check UK $valid_sig = $method->check_signature( $request, $consumer, diff --git a/Modules/LTIConsumer/templates/default/tpl.lti_dyn_reg_request.html b/Modules/LTIConsumer/templates/default/tpl.lti_dyn_reg_request.html index 1d512d01c467..a867c45a1cc6 100644 --- a/Modules/LTIConsumer/templates/default/tpl.lti_dyn_reg_request.html +++ b/Modules/LTIConsumer/templates/default/tpl.lti_dyn_reg_request.html @@ -1,11 +1,14 @@ - + \ No newline at end of file diff --git a/Modules/Portfolio/Exercise/class.ilPortfolioExerciseGUI.php b/Modules/Portfolio/Exercise/class.ilPortfolioExerciseGUI.php index 21e4730002a9..924adf2d493d 100644 --- a/Modules/Portfolio/Exercise/class.ilPortfolioExerciseGUI.php +++ b/Modules/Portfolio/Exercise/class.ilPortfolioExerciseGUI.php @@ -347,12 +347,15 @@ public function getActionButtons(): array $pe = new ilPortfolioExercise($this->user_id, $this->obj_id); $buttons = []; + $pages = ilPortfolioPage::getAllPortfolioPages($this->obj_id); foreach ($pe->getAssignmentsOfPortfolio() as $exercise) { $ass_id = $exercise["ass_id"]; $buttons[$ass_id] = []; - $submit_button = $this->getSubmitButton($ass_id); - if ($submit_button) { - $buttons[$ass_id][] = $submit_button; + if (count($pages) > 0) { + $submit_button = $this->getSubmitButton($ass_id); + if ($submit_button) { + $buttons[$ass_id][] = $submit_button; + } } $download_button = $this->getDownloadSubmissionButton($ass_id); if ($download_button) { diff --git a/Modules/Portfolio/Notification/SharedNotification.php b/Modules/Portfolio/Notification/SharedNotification.php new file mode 100644 index 000000000000..872310759c8f --- /dev/null +++ b/Modules/Portfolio/Notification/SharedNotification.php @@ -0,0 +1,112 @@ +user = $DIC->user(); + parent::__construct(); + } + + public function setSharedToObjectIds(array $a_val): void + { + $this->shared_to_obj_ids = $a_val; + } + + public function send(): bool + { + $rcp = $this->user->getId(); + + $this->initLanguage($rcp); + $this->initMail(); + $this->setSubject( + sprintf( + $this->getLanguageText('prtf_successfully_shared_prtf'), + $this->getObjectTitle(true) + ) + ); + $this->setBody(\ilMail::getSalutation($rcp, $this->getLanguage())); + $this->appendBody("\n\n"); + $this->appendBody( + sprintf( + $this->getLanguageText('prtf_successfully_shared_prtf_body'), + $this->getObjectTitle(false) + ) + ); + $this->appendObjectInformation(); + $this->appendBody("\n\n"); + $this->appendBody($this->getLanguageText('prtf_permanent_link')); + $this->appendBody("\n"); + $this->appendBody(\ilLink::_getStaticLink($this->getObjId(), "prtf")); + $this->getMail()->appendInstallationSignature(true); + + $this->sendMail(array($rcp)); + + return true; + } + + protected function appendObjectInformation(): void + { + $users = []; + foreach ($this->shared_to_obj_ids as $obj_id) { + $type = \ilObject::_lookupType($obj_id); + switch ($type) { + case "crs": + case "grp": + $this->appendBody("\n\n" . $this->getLanguage()->txt("obj_" . $type) . ": " . + \ilObject::_lookupTitle($obj_id)); + break; + case "usr": + $users[] = \ilUserUtil::getNamePresentation($obj_id); + break; + } + } + if (count($users) > 1) { + $this->appendBody("\n\n" . $this->getLanguage()->txt("users") . ": "); + $this->appendBody("\n" . implode("\n", $users)); + } + if (count($users) === 1) { + $this->appendBody("\n\n" . $this->getLanguage()->txt("user") . ": " . current($users)); + } + if (in_array(\ilWorkspaceAccessGUI::PERMISSION_REGISTERED, $this->shared_to_obj_ids, true)) { + $this->appendBody("\n\n" . $this->getLanguage()->txt("wsp_set_permission_registered")); + } + if (in_array(\ilWorkspaceAccessGUI::PERMISSION_ALL, $this->shared_to_obj_ids, true)) { + $this->appendBody("\n\n" . $this->getLanguage()->txt("wsp_set_permission_all")); + } + if (in_array(\ilWorkspaceAccessGUI::PERMISSION_ALL_PASSWORD, $this->shared_to_obj_ids, true)) { + $this->appendBody("\n\n" . $this->getLanguage()->txt("wsp_set_permission_all_password")); + } + } + + protected function initLanguage(int $a_usr_id): void + { + parent::initLanguage($a_usr_id); + $this->getLanguage()->loadLanguageModule('prtf'); + $this->getLanguage()->loadLanguageModule('wsp'); + } +} diff --git a/Modules/Portfolio/classes/class.StandardGUIRequest.php b/Modules/Portfolio/classes/class.StandardGUIRequest.php index fabae56dfdc1..e3733766699c 100644 --- a/Modules/Portfolio/classes/class.StandardGUIRequest.php +++ b/Modules/Portfolio/classes/class.StandardGUIRequest.php @@ -219,4 +219,9 @@ public function getExerciseRefId(): int { return $this->int("exc_id"); } + + public function getOwnerId(): int + { + return $this->int("owner_id"); + } } diff --git a/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php b/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php index ba190ea80577..6a93a8afa832 100644 --- a/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php +++ b/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php @@ -328,6 +328,7 @@ public function view(): void $this->tabs_gui->activateTab("pages"); + $pages = ilPortfolioPage::getAllPortfolioPages($this->getObject()->getId()); $this->gui->link( $this->lng->txt("prtf_add_page"), @@ -344,7 +345,7 @@ public function view(): void // #16571 $modal_html = ""; - if ($this->getType() === "prtf") { + if ($this->getType() === "prtf" && count($pages) > 0) { $ilToolbar->addSeparator(); $ui = $this->ui; diff --git a/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php b/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php index e78dbf6dfe92..804ead4a6e6c 100644 --- a/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php +++ b/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php @@ -303,7 +303,29 @@ public function create(): void if ($this->port_request->getCopyFormProcess() && isset($forms[self::CFORM_CLONE])) { $forms = array(self::CFORM_CLONE => $forms[self::CFORM_CLONE]); } - $tpl->setContent($this->getCreateInfoMessage() . $this->getCreationFormsHTML($forms)); + $tpl->setContent($this->getCreationFormsHTML($forms)); + } + } + + public function createFromTemplate(): void + { + $tpl = $this->tpl; + $ilErr = $this->error; + + $new_type = $this->port_request->getNewType(); + + // add new object to custom parent container + $this->ctrl->saveParameter($this, "crtptrefid"); + // use forced callback after object creation + $this->ctrl->saveParameter($this, "crtcb"); + + if (!$this->checkPermissionBool("create", "", $new_type)) { + $ilErr->raiseError($this->lng->txt("permission_denied"), $ilErr->MESSAGE); + } else { + $this->lng->loadLanguageModule($new_type); + $this->ctrl->setParameter($this, "new_type", $new_type); + $form = $this->initCreateFromTemplateForm(); + $tpl->setContent($form->getHTML()); } } @@ -371,98 +393,46 @@ protected function initCreateForm(string $new_type): ilPropertyFormGUI $ti->setRequired(true); $form->addItem($ti); - $main = new ilRadioGroupInputGUI($this->lng->txt("prtf_creation_mode"), "mode"); - $main->setValue("mode_scratch"); - $form->addItem($main); - - $opt_scratch = new ilRadioOption($this->lng->txt("prtf_creation_mode_scratch"), "mode_scratch"); - $main->addOption($opt_scratch); - - - // 1st page - - $type = new ilRadioGroupInputGUI($this->lng->txt("prtf_first_page_title"), "ptype"); - $type->setRequired(true); - $opt_scratch->addSubItem($type); + $form->setTitle($this->lng->txt("prtf_create_portfolio")); + $form->addCommandButton("save", $this->lng->txt("create")); + $form->addCommandButton("toRepository", $this->lng->txt("cancel")); - $type_page = new ilRadioOption($this->lng->txt("page"), "page"); - $type->addOption($type_page); + return $form; + } - // page type: page - $tf = new ilTextInputGUI($this->lng->txt("title"), "fpage"); - $tf->setMaxLength(128); - $tf->setSize(40); - $tf->setRequired(true); - $type_page->addSubItem($tf); - - // page templates - $templates = ilPageLayout::activeLayouts(ilPageLayout::MODULE_PORTFOLIO); - if ($templates) { - $options = array(0 => $this->lng->txt("none")); - foreach ($templates as $templ) { - $templ->readObject(); - $options[$templ->getId()] = $templ->getTitle(); - } + protected function initCreateFromTemplateForm(): ilPropertyFormGUI + { + $ilSetting = $this->settings; - $use_template = new ilSelectInputGUI($this->lng->txt("prtf_use_page_layout"), "tmpl"); - $use_template->setRequired(true); - $use_template->setOptions($options); - $type_page->addSubItem($use_template); - } + $this->ctrl->setParameter($this, "new_type", $this->getType()); - // page type: blog - if (!$ilSetting->get('disable_wsp_blogs')) { - $options = array(); - $tree = new ilWorkspaceTree($this->user_id); - $root = $tree->readRootId(); - if ($root) { - $root = $tree->getNodeData($root); - foreach ($tree->getSubTree($root) as $node) { - if ($node["type"] == "blog") { - $options[$node["obj_id"]] = $node["title"]; - } - } - asort($options); - } - if (count($options)) { - $type_blog = new ilRadioOption($this->lng->txt("obj_blog"), "blog"); - $type->addOption($type_blog); - - $obj = new ilSelectInputGUI($this->lng->txt("obj_blog"), "blog"); - $obj->setRequired(true); - $obj->setOptions(array("" => $this->lng->txt("please_select")) + $options); - $type_blog->addSubItem($obj); - } else { - $type->setValue("page"); - } - } + $form = new ilPropertyFormGUI(); + $form->setFormAction($this->ctrl->getFormAction($this)); + // title + $ti = new ilTextInputGUI($this->lng->txt("title"), "title"); + $ti->setSize(min(40, ilObject::TITLE_LENGTH)); + $ti->setMaxLength(ilObject::TITLE_LENGTH); + $ti->setRequired(true); + $form->addItem($ti); // portfolio templates - - $opt_tmpl = new ilRadioOption($this->lng->txt("prtf_creation_mode_template"), "mode_tmpl"); - $main->addOption($opt_tmpl); - $templates = ilObjPortfolioTemplate::getAvailablePortfolioTemplates(); - if (!count($templates)) { - $opt_tmpl->setDisabled(true); - } else { + if (count($templates)) { $tmpl = new ilSelectInputGUI($this->lng->txt("obj_prtt"), "prtt"); $tmpl->setRequired(true); $tmpl->setOptions(array("" => $this->lng->txt("please_select")) + $templates); - $opt_tmpl->addSubItem($tmpl); + $form->addItem($tmpl); // incoming from repository $template_id = $this->port_request->getPortfolioTemplateId(); if ($template_id > 0) { $tmpl->setValue($template_id); - $main->setValue("mode_tmpl"); } } - - $form->setTitle($this->lng->txt("prtf_create_portfolio")); - $form->addCommandButton("save", $this->lng->txt("create")); + $form->setTitle($this->lng->txt("prtf_add_portfolio_from_template")); + $form->addCommandButton("saveFromTemplate", $this->lng->txt("create")); $form->addCommandButton("toRepository", $this->lng->txt("cancel")); return $form; @@ -471,38 +441,27 @@ protected function initCreateForm(string $new_type): ilPropertyFormGUI public function save(): void { $form = $this->initCreateForm("prtf"); + parent::save(); + } + + public function saveFromTemplate(): void + { + $form = $this->initCreateFromTemplateForm(); // trigger portfolio template "import" process - if ($form->checkInput() && $form->getInput("mode") == "mode_tmpl") { + if ($form->checkInput()) { $this->createFromTemplateDirect( $form->getInput("title"), $this->port_request->getPortfolioTemplate() ); return; + } else { + $form->setValuesByPost(); + $this->tpl->setContent($form->getHTML()); } - - parent::save(); } protected function afterSave(ilObject $new_object): void { - // create 1st page / blog - $page = $this->getPageInstance(null, $new_object->getId()); - if ($this->port_request->getPageType() === "page") { - $page->setType(ilPortfolioPage::TYPE_PAGE); - $page->setTitle($this->port_request->getPageTitle()); - - // use template as basis - $layout_id = $this->port_request->getTemplateId(); - if ($layout_id) { - $layout_obj = new ilPageLayout($layout_id); - $page->setXMLContent($layout_obj->getXMLContent()); - } - } else { - $page->setType(ilPortfolioPage::TYPE_BLOG); - $page->setTitle($this->port_request->getBlogTitle()); - } - $page->create(); - $this->tpl->setOnScreenMessage('success', $this->lng->txt("prtf_portfolio_created"), true); $this->ctrl->setParameter($this, "prt_id", $new_object->getId()); $this->ctrl->redirect($this, "view"); @@ -535,14 +494,6 @@ protected function initEditForm(): ilPropertyFormGUI $ti->setValue($this->object->getTitle()); $form->addItem($ti); - /* description - $ta = new ilTextAreaInputGUI($this->lng->txt("description"), "desc"); - $ta->setCols(40); - $ta->setRows(2); - $ta->setValue($this->object->getDescription()); - $form->addItem($ta); - */ - // :TODO: online $online = new ilCheckboxInputGUI($this->lng->txt("online"), "online"); $online->setChecked($this->object->isOnline()); diff --git a/Modules/Portfolio/classes/class.ilPortfolioAccessHandler.php b/Modules/Portfolio/classes/class.ilPortfolioAccessHandler.php index 631268d49277..c3029f41ec81 100644 --- a/Modules/Portfolio/classes/class.ilPortfolioAccessHandler.php +++ b/Modules/Portfolio/classes/class.ilPortfolioAccessHandler.php @@ -421,7 +421,6 @@ public function findSharedObjects( $ilDB = $this->db; $ilUser = $this->user; $obj_ids = []; - if (!$a_filter["acl_type"]) { $obj_ids = self::getPossibleSharedTargets(); } else { @@ -489,7 +488,7 @@ public function findSharedObjects( $sql .= " AND acl.tstamp > " . $ilDB->quote($dt->get(IL_CAL_UNIX), "integer"); } - if ($a_filter["crsgrp"]) { + if ($a_filter["crsgrp"] ?? false) { $part = ilParticipants::getInstanceByObjId($a_filter['crsgrp']); $part = $part->getParticipants(); if (!count($part)) { @@ -622,4 +621,31 @@ public function editPortfolios(): bool { return (bool) $this->settings->get('user_portfolios'); } + + public function addMissingPermissionForObjects(int $node_id, array $objects): bool + { + $existing = $this->getPermissions($node_id); + $added_obj_ids = []; + foreach ($objects as $object_id) { + if (!in_array($object_id, $existing)) { + $added_obj_ids[] = $object_id; + $this->addPermission($node_id, $object_id); + $added = true; + } + } + $this->sendSharedNotification($node_id, $added_obj_ids); + return (count($added_obj_ids) > 0); + } + + protected function sendSharedNotification(int $node_id, array $object_ids): void + { + if (count($object_ids) === 0) { + return; + } + $not = new \ILIAS\Portfolio\Notification\SharedNotification(); + $not->setObjId($node_id); + $not->setSharedToObjectIds($object_ids); + //$not->setRecipients($user_ids); + $not->send(); + } } diff --git a/Modules/Portfolio/classes/class.ilPortfolioRepositoryGUI.php b/Modules/Portfolio/classes/class.ilPortfolioRepositoryGUI.php index 865593e462fb..3c884ecd431e 100644 --- a/Modules/Portfolio/classes/class.ilPortfolioRepositoryGUI.php +++ b/Modules/Portfolio/classes/class.ilPortfolioRepositoryGUI.php @@ -185,6 +185,14 @@ protected function show(): void $ilCtrl->getLinkTargetByClass("ilObjPortfolioGUI", "create") )->emphasised()->toToolbar(true); + $templates = ilObjPortfolioTemplate::getAvailablePortfolioTemplates(); + if (count($templates) > 0) { + $this->gui->link( + $this->lng->txt("prtf_add_portfolio_from_template"), + $ilCtrl->getLinkTargetByClass("ilObjPortfolioGUI", "createFromTemplate") + )->emphasised()->toToolbar(true); + } + $portfolio_list = $this->getPortfolioList(); $tpl->setContent($portfolio_list); @@ -302,8 +310,10 @@ protected function getPortfolioList(): string // ... handed in // exercise portfolio? $exercises = ilPortfolioExerciseGUI::checkExercise($this->user_id, $port["id"], false, true); + $visible_to_tutor = false; foreach ($exercises as $exinfo) { if ($exinfo["submitted"]) { + $visible_to_tutor = true; $props[$exinfo["ass_title"]] = str_replace("$1", $exinfo["submitted_date"], $lng->txt("prtf_submission_on")); } else { @@ -311,6 +321,9 @@ protected function getPortfolioList(): string //$props[$exinfo["ass_title"]] = "" . $lng->txt("prtf_no_submission") . ""; } } + if ($visible_to_tutor) { + $props[$lng->txt("prtf_visible_for_tutor")] = $lng->txt("yes"); + } $items[] = $f->item()->standard($f->button()->shy($port["title"], $preview_action)) @@ -507,7 +520,7 @@ protected function setDefaultGlobal(): void $prtf_id = $this->port_request->getPortfolioId(); if ($prtf_id && $this->checkAccess("write")) { - $this->access_handler->addPermission($prtf_id, ilWorkspaceAccessGUI::PERMISSION_ALL); + $this->access_handler->addMissingPermissionForObjects($prtf_id, ilWorkspaceAccessGUI::PERMISSION_ALL); $this->setDefault($prtf_id); } $ilCtrl->redirect($this, "show"); @@ -519,7 +532,7 @@ protected function setDefaultRegistered(): void $prtf_id = $this->port_request->getPortfolioId(); if ($prtf_id && $this->checkAccess("write")) { - $this->access_handler->addPermission($prtf_id, ilWorkspaceAccessGUI::PERMISSION_REGISTERED); + $this->access_handler->addMissingPermissionForObjects($prtf_id, ilWorkspaceAccessGUI::PERMISSION_REGISTERED); $this->setDefault($prtf_id); } $ilCtrl->redirect($this, "show"); @@ -571,9 +584,7 @@ protected function showOther( ): void { $tpl = $this->tpl; $ilTabs = $this->tabs; - $ilTabs->activateTab("otpf"); - $tbl = new ilWorkspaceShareTableGUI($this, "showOther", $this->getWorkspaceAccess(), null, $a_load_data); $tpl->setContent($tbl->getHTML()); } @@ -593,6 +604,35 @@ protected function resetShareFilter(): void $tbl->resetOffset(); $tbl->resetFilter(); - $this->showOther(); + $this->showOther(false); } + + public function redirectSendMailToSharer(): void + { + $owner_id = $this->port_request->getOwnerId(); + $prt_id = $this->port_request->getPortfolioId(); + + if ($owner_id > 0) { + $login = ilObjUser::_lookupLogin($owner_id); + + // #16530 - see ilObjCourseGUI::createMailSignature + $sig = chr(13) . chr(10) . chr(13) . chr(10); + $sig .= $this->lng->txt('prtf_permanent_link'); + $sig .= chr(13) . chr(10) . chr(13) . chr(10); + $sig .= ilLink::_getStaticLink($prt_id, "prtf", true); + $sig = rawurlencode(base64_encode($sig)); + + ilUtil::redirect(ilMailFormCall::getRedirectTarget( + $this, + "showotherFilter", + array(), + array( + 'type' => 'new', + 'rcp_to' => $login, + ilMailFormCall::SIGNATURE_KEY => $sig + ) + )); + } + } + } diff --git a/Modules/Scorm2004/classes/adlparser/SeqActivity.php b/Modules/Scorm2004/classes/adlparser/SeqActivity.php index e83a3ae562c6..58420c4e1583 100644 --- a/Modules/Scorm2004/classes/adlparser/SeqActivity.php +++ b/Modules/Scorm2004/classes/adlparser/SeqActivity.php @@ -324,9 +324,9 @@ public function setAttemptAbDur(?string $iDur): void { if ($iDur != null) { $this->mActivityAbDurControl = true; - //to be implemented - //convert duration - //$this->mActivityAbDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); + //to be implemented + //convert duration + //$this->mActivityAbDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); } else { $this->mActivityAbDurControl = false; } @@ -336,8 +336,8 @@ public function setAttemptExDur(?string $iDur): void { if ($iDur != null) { $this->mAttemptExDurControl = true; - //to be implemented - // $this->mAttemptExDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); + //to be implemented + // $this->mAttemptExDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); } else { $this->mAttemptExDurControl = false; } @@ -347,7 +347,7 @@ public function setActivityAbDur(?string $iDur): void { if ($iDur != null) { $this->mActivityAbDurControl = true; - //$this->mActivityAbDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); + //$this->mActivityAbDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); } else { $this->mActivityAbDurControl = false; } @@ -357,7 +357,7 @@ public function setActivityExDur(?string $iDur): void { if ($iDur != null) { $this->mmActivityExDurControl = true; - // $this->mmActivityExDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); + // $this->mmActivityExDur = new ADLDuration(ADLDuration.FORMAT_SCHEMA, iDur); } else { $this->mmActivityExDurControl = false; } diff --git a/Modules/Scorm2004/classes/buildRTE.php b/Modules/Scorm2004/classes/buildRTE.php index b3a75b963ef4..329e5dca8d9c 100644 --- a/Modules/Scorm2004/classes/buildRTE.php +++ b/Modules/Scorm2004/classes/buildRTE.php @@ -60,10 +60,10 @@ function minimizeJavascriptSimple(string $javascript): string //minimize all scripts foreach ($mandatory_scripts as $file) { $inp = file_get_contents($location . "/" . $file); -// jsMin should be renewed -// $jsMin = new JSMin($inp, false); -// $jsMin->minify(); -// $a_outjsmin[] = $jsMin->out; + // jsMin should be renewed + // $jsMin = new JSMin($inp, false); + // $jsMin->minify(); + // $a_outjsmin[] = $jsMin->out; $a_outjsmin[] = minimizeJavascriptSimple($inp); $outAr[] = $inp; } diff --git a/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModuleGUI.php b/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModuleGUI.php index c48d75bc69bb..e79903afafa8 100755 --- a/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModuleGUI.php +++ b/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModuleGUI.php @@ -412,7 +412,7 @@ public function getPropertiesFormValues(): void { $values = array(); $values["Fobject_title"] = $this->object->getTitle(); - $values["Fobject_description"] = $this->object->getDescription(); + $values["Fobject_description"] = $this->object->getLongDescription(); if (!$this->object->getOfflineStatus()) { $values["cobj_online"] = true; } @@ -492,7 +492,7 @@ public function saveProperties(): void $this->object->setWidth($t_width); $this->object->setHeight($t_height); $this->object->setCreditMode($this->dic->http()->wrapper()->post()->retrieve('credit_mode', $this->dic->refinery()->kindlyTo()->string())); -// $this->object->setMaxAttempt($this->dic->http()->wrapper()->post()->retrieve('max_attempt',$this->dic->refinery()->kindlyTo()->int())); + // $this->object->setMaxAttempt($this->dic->http()->wrapper()->post()->retrieve('max_attempt',$this->dic->refinery()->kindlyTo()->int())); $this->object->setAutoReviewChar($t_auto_review); $this->object->setDefaultLessonMode($this->dic->http()->wrapper()->post()->retrieve('lesson_mode', $this->dic->refinery()->kindlyTo()->string())); $this->object->setSession($t_session); @@ -508,7 +508,7 @@ public function saveProperties(): void $this->object->setTime_from_lms($this->dic->http()->wrapper()->post()->has('cobj_time_from_lms')); $this->object->setCheck_values($this->dic->http()->wrapper()->post()->has('cobj_check_values')); $this->object->setAutoSuspend($t_auto_suspend); -// $this->object->setOfflineMode($tmpOfflineMode); + // $this->object->setOfflineMode($tmpOfflineMode); $this->object->setDebug($this->dic->http()->wrapper()->post()->has('cobj_debug'));//ilUtil::yn2tf($this->dic->http()->wrapper()->post()->retrieve('cobj_debug',$this->dic->refinery()->kindlyTo()->string()))); $this->object->setIdSetting($this->dic->http()->wrapper()->post()->retrieve('id_setting', $this->dic->refinery()->kindlyTo()->int())); $this->object->setNameSetting($this->dic->http()->wrapper()->post()->retrieve('name_setting', $this->dic->refinery()->kindlyTo()->int())); diff --git a/Modules/Scorm2004/classes/class.ilSCORM13PlayerGUI.php b/Modules/Scorm2004/classes/class.ilSCORM13PlayerGUI.php index d4565aee9648..f521e422b81f 100755 --- a/Modules/Scorm2004/classes/class.ilSCORM13PlayerGUI.php +++ b/Modules/Scorm2004/classes/class.ilSCORM13PlayerGUI.php @@ -239,7 +239,7 @@ public function executeCommand(): void null, $this->userId ); - //error_log("Saved CMI Data"); + //error_log("Saved CMI Data"); } else { $this->fetchCMIData(); } @@ -413,7 +413,7 @@ public function getPlayer(): void $config['package_url'] = $this->getDataDirectory() . "/"; //editor - // $config['envEditor'] = $this->envEditor; + $config['envEditor'] = 0; //debug $config['debug'] = $this->slm->getDebug(); diff --git a/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php b/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php index 37ffb6114068..35a40ccf54dd 100755 --- a/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php +++ b/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php @@ -1,7 +1,5 @@ @@ -99,7 +99,7 @@ public static function checkIfAllowed(int $packageId, int $userId, int $hash): v array($packageId, $userId, date('Y-m-d H:i:s')) ); $rowtmp = $ilDB->fetchAssoc($res); - if ((int) $rowtmp['hash'] == $hash) { + if ($rowtmp && (int) $rowtmp['hash'] == $hash) { return; } @@ -458,17 +458,17 @@ public static function writeGObjective(int $user, int $package, ?array $g_data): foreach ($value as $skey => $svalue) { $ilLog->debug("SCORM2004 writeGObjective -skey: " . $skey); //we always have objective and learner id -// var_dump($svalue->$user->{"null"}); -// die(); -// if ($g_data->$key->$skey->$user->$package) { //check -// $o_value = $g_data->$key->$skey->$user->$package; -// $scope = $package; -// } else { //UK: is this okay? can $scope=0 and $user->{"null"}; when is $scope used? -// //scope 0 -// $o_value = $g_data->$key->$skey->$user->{"null"}; -// //has to be converted to NULL in JS Later -// $scope = 0; -// } + // var_dump($svalue->$user->{"null"}); + // die(); + // if ($g_data->$key->$skey->$user->$package) { //check + // $o_value = $g_data->$key->$skey->$user->$package; + // $scope = $package; + // } else { //UK: is this okay? can $scope=0 and $user->{"null"}; when is $scope used? + // //scope 0 + // $o_value = $g_data->$key->$skey->$user->{"null"}; + // //has to be converted to NULL in JS Later + // $scope = 0; + // } if (isset($svalue->$user->$package)) { $o_value = $svalue->$user->$package; $scope = $package; @@ -485,9 +485,9 @@ public static function writeGObjective(int $user, int $package, ?array $g_data): $dbuser = $user; if ($key === "status") { //special handling for status -// $completed = $g_data->$key->$skey->$user->{"completed"}; -// $measure = $g_data->$key->$skey->$user->{"measure"}; -// $satisfied = $g_data->$key->$skey->$user->{"satisfied"}; + // $completed = $g_data->$key->$skey->$user->{"completed"}; + // $measure = $g_data->$key->$skey->$user->{"measure"}; + // $satisfied = $g_data->$key->$skey->$user->{"satisfied"}; $completed = $svalue->$user->{"completed"}; $measure = $svalue->$user->{"measure"}; $satisfied = $svalue->$user->{"satisfied"}; @@ -530,7 +530,7 @@ public static function writeGObjective(int $user, int $package, ?array $g_data): array('text', 'text', 'text', 'text', 'integer', 'integer'), array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id) ); -// $ilLog->debug("SCORM2004 cmi_gobjective Update status=" . $completed . " scope_id=" . $pkg_id . " measure=" . $measure . " satisfied=" . $satisfied . " objective_id=" . $obj); + // $ilLog->debug("SCORM2004 cmi_gobjective Update status=" . $completed . " scope_id=" . $pkg_id . " measure=" . $measure . " satisfied=" . $satisfied . " objective_id=" . $obj); } } else { //add it to the rows_to_insert //create the row if this is the first time it has been found diff --git a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php index ab163653cd08..cfc30cd7658d 100644 --- a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php +++ b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php @@ -246,8 +246,8 @@ protected function fillHeaderExcel(ilExcel $a_excel, int &$a_row): void protected function fillRowExcel(ilExcel $a_excel, int &$a_row, array $a_set): void { -// $lng = $this->lng; -// $lng->loadLanguageModule("trac"); + // $lng = $this->lng; + // $lng->loadLanguageModule("trac"); $cnt = 0; foreach ($this->getSelectedColumns() as $c) { if ($c !== 'status') { @@ -272,8 +272,8 @@ protected function fillHeaderCSV(ilCSVWriter $a_csv): void protected function fillRowCSV(ilCSVWriter $a_csv, array $a_set): void { -// $lng = $this->lng; -// $lng->loadLanguageModule("trac"); + // $lng = $this->lng; + // $lng->loadLanguageModule("trac"); foreach ($this->getSelectedColumns() as $c) { if ($c !== 'status') { $val = $this->parseValue($c, $a_set[$c], "user"); diff --git a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingTableGUI.php b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingTableGUI.php index 3799a458bac1..81cf382ff09f 100755 --- a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingTableGUI.php +++ b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingTableGUI.php @@ -56,9 +56,9 @@ public function __construct(object $a_parent_obj, string $a_parent_cmd = "") */ protected function fillRow(array $a_set): void { -// $lng = $this->lng; -// $ilCtrl = $this->ctrl; -// $ilAccess = $this->access; + // $lng = $this->lng; + // $ilCtrl = $this->ctrl; + // $ilAccess = $this->access; $this->tpl->setVariable("USER_NAME", $a_set["user_full_name"]); $this->tpl->setVariable("USER_ID", $a_set["user_id"]); diff --git a/Modules/Scorm2004/classes/class.ilScorm2004DataSet.php b/Modules/Scorm2004/classes/class.ilScorm2004DataSet.php index b3f5c53433e7..c6206bcd6e42 100644 --- a/Modules/Scorm2004/classes/class.ilScorm2004DataSet.php +++ b/Modules/Scorm2004/classes/class.ilScorm2004DataSet.php @@ -91,55 +91,55 @@ public function readData(string $a_entity, string $a_version, array $a_ids): voi } -// /** -// * Determine the dependent sets of data -// * @return mixed[] -// */ -// protected function getDependencies( -// string $a_entity, -// string $a_version, -// ?array $a_rec = null, -// ?array $a_ids = null -// ) : array { -// switch ($a_entity) { -// case "sahs": -// return array(); -// -// } -// return []; -// } - -// /** -// * Get xml record -// * @param string $a_entity -// * @param string $a_version -// * @param array $a_set -// * @return array -// * @throws ilFileUtilsException -// */ -// public function getXmlRecord(string $a_entity, string $a_version, array $a_set) : array -// { -// if ($a_entity == "sahs") { -// // build traditional author export file -// $lm = new ilObjSCORM2004LearningModule($a_set["Id"], false); -// $export = new ilScorm2004Export($lm, 'SCORM 2004 3rd'); -// $zip = $export->buildExportFile(); -// -// // move it to temp dir -// $tmpdir = ilFileUtils::ilTempnam(); -// ilFileUtils::makeDir($tmpdir); -// $exp_temp = $tmpdir . DIRECTORY_SEPARATOR . basename($zip); -// ilFileUtils::rename($zip, $exp_temp); -// -// $this->temp_dir[$a_set["Id"]] = $tmpdir; -// -// // include temp dir -// $a_set["Dir"] = $tmpdir; -// $a_set["File"] = basename($zip); -// } -// -// return $a_set; -// } + // /** + // * Determine the dependent sets of data + // * @return mixed[] + // */ + // protected function getDependencies( + // string $a_entity, + // string $a_version, + // ?array $a_rec = null, + // ?array $a_ids = null + // ) : array { + // switch ($a_entity) { + // case "sahs": + // return array(); + // + // } + // return []; + // } + + // /** + // * Get xml record + // * @param string $a_entity + // * @param string $a_version + // * @param array $a_set + // * @return array + // * @throws ilFileUtilsException + // */ + // public function getXmlRecord(string $a_entity, string $a_version, array $a_set) : array + // { + // if ($a_entity == "sahs") { + // // build traditional author export file + // $lm = new ilObjSCORM2004LearningModule($a_set["Id"], false); + // $export = new ilScorm2004Export($lm, 'SCORM 2004 3rd'); + // $zip = $export->buildExportFile(); + // + // // move it to temp dir + // $tmpdir = ilFileUtils::ilTempnam(); + // ilFileUtils::makeDir($tmpdir); + // $exp_temp = $tmpdir . DIRECTORY_SEPARATOR . basename($zip); + // ilFileUtils::rename($zip, $exp_temp); + // + // $this->temp_dir[$a_set["Id"]] = $tmpdir; + // + // // include temp dir + // $a_set["Dir"] = $tmpdir; + // $a_set["File"] = basename($zip); + // } + // + // return $a_set; + // } public function afterXmlRecordWriting(string $a_entity, string $a_version, array $a_set): void { @@ -152,49 +152,49 @@ public function afterXmlRecordWriting(string $a_entity, string $a_version, array } -// /** -// * Import record -// * @param string $a_entity -// * @param array $a_types -// * @param array $a_rec -// * @param ilImportMapping $a_mapping -// * @param string $a_schema_version -// */ -// public function importRecord( -// string $a_entity, -// array $a_types, -// array $a_rec, -// ilImportMapping $a_mapping, -// string $a_schema_version -// ) : void { -// switch ($a_entity) { -// case "sahs": -// $new_obj_id = $a_mapping->getMapping("Services/Container", "objs", $a_rec["Id"]); -// $lm = new ilObjSCORM2004LearningModule($new_obj_id, false); -// -//// $lm->setEditable($a_rec["Editable"]); -// $lm->setImportSequencing(false); -// $lm->setSequencingExpertMode(false); -// $lm->setSubType("scorm2004"); -// -// $dir = str_replace("..", "", $a_rec["Dir"]); -// if ($dir != "" && $this->getImportDirectory() != "") { -// $source_dir = $this->getImportDirectory() . "/" . $dir; -// $file_path = $lm->getDataDirectory() . "/" . $a_rec["File"]; -// ilFileUtils::rename($source_dir . "/" . $a_rec["File"], $file_path); -// -// ilFileUtils::unzip($file_path); -// ilFileUtils::renameExecutables($lm->getDataDirectory()); -// $title = $lm->readObject(); -// if ($title != "") { -// ilObject::_writeTitle($lm->getId(), $title); -// } -// -// $lm->setLearningProgressSettingsAtUpload(); -// $lm->update(); -// } -// break; -// -// } -// } + // /** + // * Import record + // * @param string $a_entity + // * @param array $a_types + // * @param array $a_rec + // * @param ilImportMapping $a_mapping + // * @param string $a_schema_version + // */ + // public function importRecord( + // string $a_entity, + // array $a_types, + // array $a_rec, + // ilImportMapping $a_mapping, + // string $a_schema_version + // ) : void { + // switch ($a_entity) { + // case "sahs": + // $new_obj_id = $a_mapping->getMapping("Services/Container", "objs", $a_rec["Id"]); + // $lm = new ilObjSCORM2004LearningModule($new_obj_id, false); + // + //// $lm->setEditable($a_rec["Editable"]); + // $lm->setImportSequencing(false); + // $lm->setSequencingExpertMode(false); + // $lm->setSubType("scorm2004"); + // + // $dir = str_replace("..", "", $a_rec["Dir"]); + // if ($dir != "" && $this->getImportDirectory() != "") { + // $source_dir = $this->getImportDirectory() . "/" . $dir; + // $file_path = $lm->getDataDirectory() . "/" . $a_rec["File"]; + // ilFileUtils::rename($source_dir . "/" . $a_rec["File"], $file_path); + // + // ilFileUtils::unzip($file_path); + // ilFileUtils::renameExecutables($lm->getDataDirectory()); + // $title = $lm->readObject(); + // if ($title != "") { + // ilObject::_writeTitle($lm->getId(), $title); + // } + // + // $lm->setLearningProgressSettingsAtUpload(); + // $lm->update(); + // } + // break; + // + // } + // } } diff --git a/Modules/Scorm2004/classes/ilSCORM13Package.php b/Modules/Scorm2004/classes/ilSCORM13Package.php index cf2be84e02e3..56c89a877915 100755 --- a/Modules/Scorm2004/classes/ilSCORM13Package.php +++ b/Modules/Scorm2004/classes/ilSCORM13Package.php @@ -34,12 +34,12 @@ class ilSCORM13Package public const WRAPPER_JS = './Modules/Scorm2004/scripts/converter/GenericRunTimeWrapper1.0_aadlc/SCOPlayerWrapper.js'; -// private $packageFile; + // private $packageFile; private string $packageFolder; private string $packagesFolder; private array $packageData = []; -// private $slm; -// private $slm_tree; + // private $slm; + // private $slm_tree; public \DOMDocument $imsmanifest; /** @@ -47,13 +47,13 @@ class ilSCORM13Package */ public $manifest; public array $diagnostic; -// public $status; + // public $status; public int $packageId; public string $packageName = ""; public string $packageHash = ""; public int $userId; -// private $idmap = array(); + // private $idmap = array(); private float $progress = 0.0; /** @@ -362,20 +362,20 @@ public function dbImport(object $node, ?int &$lft = 1, ?int $depth = 1, ?int $pa break; case 'language': $names[] = 'c_language'; break; - case 'condition': $names[] = 'c_condition'; - break; + // case 'condition': $names[] = 'c_condition'; + // break; case 'operator': $names[] = 'c_operator'; break; -// case 'condition': $names[] = 'c_condition';break; + // case 'condition': $names[] = 'c_condition';break; case 'readnormalizedmeasure': $names[] = 'readnormalmeasure'; break; case 'writenormalizedmeasure': $names[] = 'writenormalmeasure'; break; - case 'minnormalizedmeasure': $names[] = 'minnormalmeasure'; - break; + // case 'minnormalizedmeasure': $names[] = 'minnormalmeasure'; + // break; case 'primary': $names[] = 'c_primary'; break; -// case 'minnormalizedmeasure': $names[] = 'minnormalmeasure';break; + // case 'minnormalizedmeasure': $names[] = 'minnormalmeasure';break; case 'persistpreviousattempts': $names[] = 'persistprevattempts'; break; case 'identifier': $names[] = 'c_identifier'; diff --git a/Modules/Scorm2004/scripts/buildrte/rte-min.js b/Modules/Scorm2004/scripts/buildrte/rte-min.js index a055a644cd37..c74f7abc7498 100644 --- a/Modules/Scorm2004/scripts/buildrte/rte-min.js +++ b/Modules/Scorm2004/scripts/buildrte/rte-min.js @@ -1,5 +1,49 @@ -// Build: 2021417225304 - +// Build: 2023416234957 +/* + +-----------------------------------------------------------------------------+ + | ILIAS open source | + +-----------------------------------------------------------------------------+ + | Copyright (c) 1998-2006 ILIAS open source, University of Cologne | + | | + | This program is free software; you can redistribute it and/or | + | modify it under the terms of the GNU General Public License | + | as published by the Free Software Foundation; either version 2 | + | of the License, or (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of the GNU General Public License | + | along with this program; if not, write to the Free Software | + | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | + +-----------------------------------------------------------------------------+ +*/ +/* + JS port of ADL ADLAuxiliaryResource.java + @author Alex Killing + This .js file is GPL licensed (see above) but based on + ADLAuxiliaryResource.java by ADL Co-Lab, which is licensed as: + Advanced Distributed Learning Co-Laboratory (ADL Co-Lab) Hub grants you + ("Licensee") a non-exclusive, royalty free, license to use, modify and + redistribute this software in source and binary code form, provided that + i) this copyright notice and license appear on all copies of the software; + and ii) Licensee does not utilize the software in a manner which is + disparaging to ADL Co-Lab Hub. + This software is provided "AS IS," without a warranty of any kind. ALL + EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING + ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE + OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. ADL Co-Lab Hub AND ITS LICENSORS + SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF + USING, MODIFYING OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO + EVENT WILL ADL Co-Lab Hub OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, + PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, + INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE + THEORY OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE + SOFTWARE, EVEN IF ADL Co-Lab Hub HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + DAMAGES. +*/ function ADLAuxiliaryResource() {} ADLAuxiliaryResource.prototype={mTitle:null,mResourceID:null,mParameter:null}; diff --git a/Modules/Scorm2004/scripts/buildrte/rte.js b/Modules/Scorm2004/scripts/buildrte/rte.js index 3df0d14c918a..8469237f26a2 100644 --- a/Modules/Scorm2004/scripts/buildrte/rte.js +++ b/Modules/Scorm2004/scripts/buildrte/rte.js @@ -1,4 +1,4 @@ -// Build: 2021417225304 +// Build: 2023416234957 /* +-----------------------------------------------------------------------------+ | ILIAS open source | diff --git a/Modules/Scorm2004/scripts/rtemain/main.js b/Modules/Scorm2004/scripts/rtemain/main.js index 4c1853c4bb0c..2b095bb1b6f1 100644 --- a/Modules/Scorm2004/scripts/rtemain/main.js +++ b/Modules/Scorm2004/scripts/rtemain/main.js @@ -4100,8 +4100,9 @@ function sendLogEntry(timespan,action,key,value,result,errorCode) setTimeout("refreshDebugger()",2000); } else { // var result = sendJSONRequest(this.config.post_log_url, logEntry,refreshDebugger(true)); - refreshDebugger(true); - } + setTimeout("refreshDebugger()",1000); + setTimeout("refreshDebugger(true)",2000); + } } function removeByElement(arrayName,arrayElement) diff --git a/Modules/Scorm2004/test/ilModulesScorm2004Suite.php b/Modules/Scorm2004/test/ilModulesScorm2004Suite.php index 4692d0723e8e..1aabc5ee3f26 100644 --- a/Modules/Scorm2004/test/ilModulesScorm2004Suite.php +++ b/Modules/Scorm2004/test/ilModulesScorm2004Suite.php @@ -64,8 +64,8 @@ public static function suite(): self } if (defined('ILIAS_PHPUNIT_CONTEXT')) { -// include_once("./Services/PHPUnit/classes/class.ilUnitUtil.php"); -// ilUnitUtil::performInitialisation(); + // include_once("./Services/PHPUnit/classes/class.ilUnitUtil.php"); + // ilUnitUtil::performInitialisation(); } else { chdir(__DIR__); chdir('../../../'); diff --git a/Modules/ScormAicc/Editing/classes/class.ilSAHSEditGUI.php b/Modules/ScormAicc/Editing/classes/class.ilSAHSEditGUI.php index f7036f634794..2c9bbf0b1eca 100755 --- a/Modules/ScormAicc/Editing/classes/class.ilSAHSEditGUI.php +++ b/Modules/ScormAicc/Editing/classes/class.ilSAHSEditGUI.php @@ -38,10 +38,7 @@ class ilSAHSEditGUI implements ilCtrlBaseClassInterface protected ilCtrl $ctrl; protected int $refId; - /** - * @var ilObjSCORMLearningModuleGUI|ilObjSCORM2004LearningModuleGUI - */ - protected $slm_gui; + protected ilObjSCORMLearningModuleGUI|ilObjSCORM2004LearningModuleGUI $slm_gui; /** * @throws ilCtrlException diff --git a/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php b/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php index a2c5f7b33f63..418a65749e82 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php @@ -1,7 +1,5 @@ @@ -251,7 +251,6 @@ public static function _insertTrackData(int $a_sahs_id, string $a_lval, string $ //erase later see ilSCORM2004StoreData /** * like necessary because of Oracle - * @return mixed[] */ public static function _getCompleted(object $scorm_item_id, int $a_obj_id): array { @@ -395,7 +394,6 @@ public static function lookupLastAccessTimes(int $a_obj_id): array /** * Get all tracked users - * @return mixed[] */ public static function _getTrackedUsers(int $a_obj_id): array { @@ -420,7 +418,6 @@ public static function _getTrackedUsers(int $a_obj_id): array /** * like necessary because of Oracle - * @return mixed[] */ public static function _getFailed(object $scorm_item_id, int $a_obj_id): array { @@ -493,7 +490,7 @@ public static function _getCountCompletedPerUser(array $a_scorm_item_ids, int $a //not correct because of assets! /** * Get info about - * @return array + * @return array */ public static function _getProgressInfo(array $sco_item_ids, int $a_obj_id): array { @@ -536,10 +533,9 @@ public static function _getProgressInfo(array $sco_item_ids, int $a_obj_id): arr } /** - * @param array|int $scorm_item_id * @return array */ - public static function _getInProgress($scorm_item_id, int $a_obj_id, ?array $a_blocked_user_ids = null): array + public static function _getInProgress(array|int $scorm_item_id, int $a_obj_id, ?array $a_blocked_user_ids = null): array { global $DIC; $ilDB = $DIC->database(); @@ -622,10 +618,7 @@ public static function checkIfAllowed(int $packageId, int $userId, int $hash): v array($packageId, $userId, date('Y-m-d H:i:s')) ); $rowtmp = $ilDB->fetchAssoc($res); - if ($rowtmp['hash'] == $hash) { - //ok - do nothing - // die("allowed"); - } else { + if (! ($rowtmp && $rowtmp['hash'] == $hash)) { //output used by api die("not allowed"); } diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMExplorer.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMExplorer.php index fea0d832a77d..08e1e4d1be3a 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMExplorer.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMExplorer.php @@ -92,9 +92,8 @@ public function setOutput($a_parent_id, int $a_depth = 1, int $a_obj_id = 0, $a_ } /** - * recursive creating of outputs - * @return mixed[] - */ + * recursive creating of outputs + */ protected function createOutputArray(int $a_parent_id, array $options = array()): array { global $ilErr; diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMObject.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMObject.php index 2f45ee952d48..9894261653dd 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMObject.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMObject.php @@ -180,10 +180,7 @@ public function delete(): void ); } - /** - * @return ilSCORMItem|ilSCORMManifest|ilSCORMOrganization|ilSCORMOrganizations|ilSCORMResource|ilSCORMResources - */ - public static function &_getInstance(int $a_id, int $a_slm_id) + public static function &_getInstance(int $a_id, int $a_slm_id): ilSCORMItem|ilSCORMManifest|ilSCORMOrganization|ilSCORMOrganizations|ilSCORMResource|ilSCORMResources { global $DIC; $ilDB = $DIC->database(); diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMObjectGUI.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMObjectGUI.php index 4c48fde53807..85f952c7b593 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMObjectGUI.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMObjectGUI.php @@ -27,10 +27,7 @@ */ class ilSCORMObjectGUI { - /** - * @var ilSCORMManifest|ilSCORMItem|ilSCORMOrganization|ilSCORMOrganizations - */ - public $sc_object; + public ilSCORMManifest|ilSCORMItem|ilSCORMOrganization|ilSCORMOrganizations $sc_object; public ilGlobalTemplate $tpl; public ilLanguage $lng; @@ -47,10 +44,7 @@ public function __construct(int $a_id = 0) $this->lng = $lng; } - /** - * @return ilSCORMItemGUI|ilSCORMManifestGUI|ilSCORMOrganizationGUI|ilSCORMOrganizationsGUI|ilSCORMResourceGUI|ilSCORMResourcesGUI - */ - public function &getInstance(int $a_id) + public function &getInstance(int $a_id): ilSCORMItemGUI|ilSCORMManifestGUI|ilSCORMOrganizationGUI|ilSCORMOrganizationsGUI|ilSCORMResourceGUI|ilSCORMResourcesGUI { $object = new ilSCORMObject($a_id); switch ($object->getType()) { diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMPackageParser.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMPackageParser.php index c6ef01a35f7b..203772ddbc47 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMPackageParser.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMPackageParser.php @@ -165,15 +165,19 @@ public function getCurrentParent(): int * @param array $a_attribs * @return void */ - public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs): void + public function handlerBeginTag(XMLParser $a_xml_parser, string $a_name, array $a_attribs): void { //echo "
handlerBeginTag:".$a_name; switch ($a_name) { case "manifest": + $mVersion = ""; + if (isset($a_attribs["version"])) { + $mVersion = $a_attribs["version"]; + } $manifest = new ilSCORMManifest(); $manifest->setSLMId($this->slm_object->getId()); $manifest->setImportId($a_attribs["identifier"]); - $manifest->setVersion($a_attribs["version"]); + $manifest->setVersion($mVersion); if (isset($a_attribs["xml:base"])) { $manifest->setXmlBase($a_attribs["xml:base"]); } @@ -274,6 +278,7 @@ public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs) $dependency->setIdentifierRef($a_attribs["identifierref"]); $this->current_resource->addDependency($dependency); break; + } $this->beginElement($a_name); } @@ -284,7 +289,7 @@ public function handlerBeginTag($a_xml_parser, string $a_name, array $a_attribs) * @param string $a_name * @return void */ - public function handlerEndTag($a_xml_parser, string $a_name): void + public function handlerEndTag(XMLParser $a_xml_parser, string $a_name): void { //echo "
handlerEndTag:".$a_name; @@ -310,6 +315,7 @@ public function handlerEndTag($a_xml_parser, string $a_name): void $this->current_resource->update(); array_pop($this->parent_stack); break; + } $this->endElement($a_name); } @@ -320,7 +326,7 @@ public function handlerEndTag($a_xml_parser, string $a_name): void * @param string|null $a_data * @return void */ - public function handlerCharacterData($a_xml_parser, ?string $a_data): void + public function handlerCharacterData(XMLParser $a_xml_parser, ?string $a_data): void { //echo "
handlerCharacterData:".$this->getCurrentElement().":".$a_data; // DELETE WHITESPACES AND NEWLINES OF CHARACTER DATA @@ -364,6 +370,7 @@ public function handlerCharacterData($a_xml_parser, ?string $a_data): void case "adlcp:masteryscore": $this->item_stack[count($this->item_stack) - 1]->setMasteryScore($a_data); break; + } } } diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMPresentationGUI.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMPresentationGUI.php index d8a56ba6d794..a210963317cb 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMPresentationGUI.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMPresentationGUI.php @@ -510,10 +510,8 @@ public function downloadCertificate(): void $certificateLogger = $DIC->logger()->root(); $ilUserCertificateRepository = new ilUserCertificateRepository(); - $pdfGenerator = new ilPdfGenerator($ilUserCertificateRepository, $certificateLogger); - + $pdfGenerator = new ilPdfGenerator($ilUserCertificateRepository); $pdfAction = new ilCertificatePdfAction( - $certificateLogger, $pdfGenerator, new ilCertificateUtilHelper(), $this->lng->txt('error_creating_certificate_pdf') diff --git a/Modules/ScormAicc/classes/SCORM/class.ilSCORMResource.php b/Modules/ScormAicc/classes/SCORM/class.ilSCORMResource.php index 0a9fc6663024..ccc5e2a5951d 100755 --- a/Modules/ScormAicc/classes/SCORM/class.ilSCORMResource.php +++ b/Modules/ScormAicc/classes/SCORM/class.ilSCORMResource.php @@ -102,9 +102,6 @@ public function addFile(ilSCORMResourceFile $a_file_obj): void $this->files[] = &$a_file_obj; } - /** - * @return mixed[] - */ public function &getFiles(): array { return $this->files; @@ -115,9 +112,6 @@ public function addDependency(ilSCORMResourceDependency $a_dependency): void $this->dependencies[] = &$a_dependency; } - /** - * @return mixed[] - */ public function &getDependencies(): array { return $this->dependencies; diff --git a/Modules/ScormAicc/classes/Verification/class.ilObjSCORMVerificationGUI.php b/Modules/ScormAicc/classes/Verification/class.ilObjSCORMVerificationGUI.php index 6b1153ce153a..3a223008db77 100644 --- a/Modules/ScormAicc/classes/Verification/class.ilObjSCORMVerificationGUI.php +++ b/Modules/ScormAicc/classes/Verification/class.ilObjSCORMVerificationGUI.php @@ -172,11 +172,7 @@ public static function _goto(string $a_target): void $DIC->ctrl->redirectByClass(ilSharedResourceGUI::class); } - /** - * @param mixed $default - * @return mixed - */ - protected function getRequestValue(string $key, $default = null) + protected function getRequestValue(string $key, mixed $default = null): mixed { if (isset($this->request->getQueryParams()[$key])) { return $this->request->getQueryParams()[$key]; diff --git a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php index 12b2241bdd9f..62c946d54f4a 100755 --- a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php +++ b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModule.php @@ -70,13 +70,17 @@ class ilObjSAHSLearningModule extends ilObject protected string $api_adapter = 'API'; + protected \ILIAS\DI\UIServices $ui; + /** * Constructor - * @param integer reference_id or object_id - * @param boolean treat the id as reference_id (true) or object_id (false) + * @param integer $a_id reference_id or object_id + * @param boolean $a_call_by_reference treat the id as reference_id (true) or object_id (false) */ public function __construct(int $a_id = 0, bool $a_call_by_reference = true) { + global $DIC; + $this->ui = $DIC->ui(); $this->type = "sahs"; parent::__construct($a_id, $a_call_by_reference); } @@ -1350,7 +1354,7 @@ public function getApiStudentName(): string /** * get button for view */ - public function getViewButton(): ilLinkButton + public function getViewButton(): \ILIAS\UI\Component\Button\Primary { $setUrl = "ilias.php?baseClass=ilSAHSPresentationGUI&ref_id=" . $this->getRefID(); // $setUrl = $this->getLinkTargetByClass("ilsahspresentationgui", "")."&ref_id=".$this->getRefID(); @@ -1365,11 +1369,17 @@ public function getViewButton(): ilLinkButton $setUrl = "javascript:void(0); onclick=startSAHS('" . $setUrl . "','ilContObj" . $this->getId() . "'," . $om . "," . $width . "," . $height . ");"; $setTarget = ""; } - $button = ilLinkButton::getInstance(); - $button->setCaption("view"); - $button->setPrimary(true); - $button->setUrl($setUrl); - $button->setTarget($setTarget); + //todo $setTarget ? + $button = $this->ui->factory()->button()->primary( + $this->lng->txt("view"), + $setUrl + ); + + // $button = ilLinkButton::getInstance(); + // $button->setCaption("view"); + // $button->setPrimary(true); + // $button->setUrl($setUrl); + // $button->setTarget($setTarget); return $button; } } diff --git a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleAccess.php b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleAccess.php index d2ec0597fc70..a3844509b21a 100644 --- a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleAccess.php +++ b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleAccess.php @@ -100,7 +100,7 @@ public static function _checkGoto(string $target): bool /** * Returns the number of bytes used on the harddisk by the learning module * with the specified object id. - * @param int object id of a file object. + * @param int $a_id object id of a file object. */ public static function _lookupDiskUsage(int $a_id): int { diff --git a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleGUI.php b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleGUI.php index a44fe1e83684..11e5b5355d9b 100755 --- a/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleGUI.php +++ b/Modules/ScormAicc/classes/class.ilObjSAHSLearningModuleGUI.php @@ -184,7 +184,7 @@ protected function infoScreen(): void protected function infoScreenForward(): void { if (!$this->checkPermissionBool("visible") && !$this->checkPermissionBool("read")) { - $this->error->raiseError($this->lng->txt("msg_no_perm_read")); + $this->error->raiseError($this->lng->txt("msg_no_perm_read"), $this->error->MESSAGE); } $info = new ilInfoScreenGUI($this); @@ -866,10 +866,9 @@ public function setSettingsSubTabs(): void } /** - * @return mixed * @throws ilCtrlException */ - public function export() + public function export(): mixed { $GLOBALS['DIC']->tabs()->setTabActive('export'); $exp_gui = new ilExportGUI($this); diff --git a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php index ca3f5b5e2a0d..08ccaaac4cfa 100755 --- a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php +++ b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php @@ -30,8 +30,8 @@ class ilObjSCORMLearningModule extends ilObjSAHSLearningModule { /** * Constructor - * @param integer reference_id or object_id - * @param boolean treat the id as reference_id (true) or object_id (false) + * @param integer $a_id reference_id or object_id + * @param boolean $a_call_by_reference treat the id as reference_id (true) or object_id (false) */ public function __construct(int $a_id = 0, bool $a_call_by_reference = true) { diff --git a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModuleGUI.php b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModuleGUI.php index 25491b70602a..5f05bbc296bc 100755 --- a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModuleGUI.php +++ b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModuleGUI.php @@ -341,7 +341,7 @@ public function getPropertiesFormValues(): void { $values = array(); $values["Fobject_title"] = $this->object->getTitle(); - $values["Fobject_description"] = $this->object->getDescription(); + $values["Fobject_description"] = $this->object->getLongDescription(); if (!$this->object->getOfflineStatus()) { $values["cobj_online"] = true; } @@ -531,6 +531,7 @@ public function newModuleVersionUpload(): void //do testing for converted versions as well as earlier ILIAS version messed up utf8 conversion if (strcmp($new_manifest, $old_manifest) == 0 || strcmp(utf8_encode($new_manifest), $old_manifest) == 0 || strcmp($reload_manifest, $old_manifest) == 0 || strcmp(utf8_encode($reload_manifest), $old_manifest) == 0) { + //get exisiting module version $module_version = $this->object->getModuleVersion() + 1; diff --git a/Modules/ScormAicc/classes/class.ilSCORMTrackingItems.php b/Modules/ScormAicc/classes/class.ilSCORMTrackingItems.php index 6a5c411d5822..e34d92372ff4 100644 --- a/Modules/ScormAicc/classes/class.ilSCORMTrackingItems.php +++ b/Modules/ScormAicc/classes/class.ilSCORMTrackingItems.php @@ -240,9 +240,6 @@ public function scoTitlesForExportSelected(int $obj_id): array return $scoTitles; } - /** - * @return mixed[] - */ public function markedLearningStatusForExportSelected(array $a_scos, int $obj_id): array { global $DIC; @@ -378,9 +375,6 @@ public function exportSelectedCore( return $returnData; } - /** - * @return mixed[] - */ public function getScormTrackingValue(int $obj_id, array $a_user, array $a_sco, array $a_empty, string $lvalue): array { global $DIC; @@ -926,10 +920,7 @@ public function exportSelectedSuccessRows( return $returnData; } - /** - * @return float|string - */ - public function SCORMTimeToSeconds(string $a_time) + public function SCORMTimeToSeconds(string $a_time): float|string { if ($a_time == "") { return ""; diff --git a/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php b/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php index f77f14a8f219..53bd532a6dda 100644 --- a/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php +++ b/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php @@ -36,8 +36,6 @@ class ilSCORMTrackingItemsTableGUI extends ilTable2GUI /** * @throws ilCtrlException - * @param mixed[] $a_userSelected - * @param mixed[] $a_scosSelected */ public function __construct(int $a_obj_id, ?object $a_parent_obj, string $a_parent_cmd, array $a_userSelected, array $a_scosSelected, string $a_report) { @@ -199,11 +197,7 @@ public function getItems(): void $this->setData($tr_data); } - /** - * @param string|float|int|null $value - * @return string|float|int|null - */ - protected function parseValue(string $id, $value, string $type) + protected function parseValue(string $id, string|float|int|null $value, string $type): string|float|int|null { global $DIC; $lng = $DIC->language(); diff --git a/Modules/ScormAicc/classes/class.ilScormAiccDataSet.php b/Modules/ScormAicc/classes/class.ilScormAiccDataSet.php index 98ec59bbea53..42dd8cafa2df 100755 --- a/Modules/ScormAicc/classes/class.ilScormAiccDataSet.php +++ b/Modules/ScormAicc/classes/class.ilScormAiccDataSet.php @@ -76,9 +76,6 @@ public function __construct() } } - /** - * @return mixed[] - */ protected function getDependencies( string $a_entity, string $a_version, diff --git a/Modules/ScormAicc/module.xml b/Modules/ScormAicc/module.xml index cc42170a9ee8..2d8bf3459eac 100644 --- a/Modules/ScormAicc/module.xml +++ b/Modules/ScormAicc/module.xml @@ -1,4 +1,4 @@ - + diff --git a/Modules/StudyProgramme/classes/ilStudyProgrammeUserTableRow.php b/Modules/StudyProgramme/classes/ilStudyProgrammeUserTableRow.php index 023b0665ac59..8524b1a5bd74 100644 --- a/Modules/StudyProgramme/classes/ilStudyProgrammeUserTableRow.php +++ b/Modules/StudyProgramme/classes/ilStudyProgrammeUserTableRow.php @@ -26,7 +26,7 @@ class ilStudyProgrammeUserTableRow protected PRGProgressId $id; protected int $ass_id; protected int $usr_id; - protected int $pgs_id; + protected int $node_id; protected bool $is_root_progress; protected int $status_raw; protected bool $active_raw; diff --git a/Modules/Test/classes/MainSettings/class.ilObjTestSettingsMainGUI.php b/Modules/Test/classes/MainSettings/class.ilObjTestSettingsMainGUI.php index 853f25fe9861..a72035e52c10 100644 --- a/Modules/Test/classes/MainSettings/class.ilObjTestSettingsMainGUI.php +++ b/Modules/Test/classes/MainSettings/class.ilObjTestSettingsMainGUI.php @@ -649,8 +649,9 @@ private function getParticipantsFunctionalitySettingsForStorage(array $section): ->withUsePreviousAnswerAllowed($section['use_previous_answers']) ->withSuspendTestAllowed($section['allow_suspend_test']) ->withPostponedQuestionsMoveToEnd($section['postponed_questions_behaviour']) - ->withQuestionListMode($section['enable_question_list']) - ->withQuestionMarkingEnabled($section['enable_question_marking']); + ->withUsrPassOverviewMode($section['usr_pass_overview']) + ->withQuestionMarkingEnabled($section['enable_question_marking']) + ->withQuestionListEnabled($section['enable_question_list']); } private function getFinishingSettingsForStorage(array $section): ilObjTestSettingsFinishing diff --git a/Modules/Test/classes/MainSettings/ilObjTestMainSettingsDatabaseRepository.php b/Modules/Test/classes/MainSettings/ilObjTestMainSettingsDatabaseRepository.php index 3459c54c5388..4b21ab705d1d 100644 --- a/Modules/Test/classes/MainSettings/ilObjTestMainSettingsDatabaseRepository.php +++ b/Modules/Test/classes/MainSettings/ilObjTestMainSettingsDatabaseRepository.php @@ -84,8 +84,9 @@ protected function doSelect(string $where_part): ilObjTestMainSettings . 'use_previous_answers,' . PHP_EOL . 'show_cancel,' . PHP_EOL . 'sequence_settings,' . PHP_EOL - . 'show_summary,' . PHP_EOL + . 'usr_pass_overview_mode,' . PHP_EOL . 'show_marker,' . PHP_EOL + . 'show_questionlist,' . PHP_EOL . 'enable_examview,' . PHP_EOL . 'showfinalstatement,' . PHP_EOL . 'finalstatement,' . PHP_EOL @@ -167,8 +168,9 @@ protected function doSelect(string $where_part): ilObjTestMainSettings (bool) $row['use_previous_answers'], (bool) $row['show_cancel'], (bool) $row['sequence_settings'], - $row['show_summary'], - (bool) $row['show_marker'] + $row['usr_pass_overview_mode'], + (bool) $row['show_marker'], + (bool) $row['show_questionlist'] ), new ilObjTestSettingsFinishing( $test_id, diff --git a/Modules/Test/classes/MainSettings/ilObjTestSettingsParticipantFunctionality.php b/Modules/Test/classes/MainSettings/ilObjTestSettingsParticipantFunctionality.php index cbe308710d3e..460d6c1fd7d0 100644 --- a/Modules/Test/classes/MainSettings/ilObjTestSettingsParticipantFunctionality.php +++ b/Modules/Test/classes/MainSettings/ilObjTestSettingsParticipantFunctionality.php @@ -30,8 +30,9 @@ public function __construct( protected bool $use_previous_answers_allowed = false, protected bool $suspend_test_allowed = false, protected bool $postponed_questions_move_to_end = false, - protected int $question_list_mode = 0, - protected bool $question_marking_enabled = false + protected int $usrpass_overview_mode = 0, + protected bool $question_marking_enabled = false, + protected bool $question_list_enabled = false ) { parent::__construct($test_id); } @@ -69,7 +70,12 @@ public function toForm( )->withValue($this->getPostponedQuestionsMoveToEnd() ? '1' : '0') ->withAdditionalTransformation($refinery->kindlyTo()->bool()); - $inputs['enable_question_list'] = $this->getInputEnableQuestionList( + $inputs['enable_question_list'] = $f->checkbox( + $lng->txt('tst_enable_questionlist'), + $lng->txt('tst_enable_questionlist_description') + )->withValue($this->getQuestionListEnabled()); + + $inputs['usr_pass_overview'] = $this->getInputUsrPassOverview( $lng, $f, $refinery @@ -83,7 +89,7 @@ public function toForm( return $f->section($inputs, $lng->txt('tst_sequence_properties')); } - private function getInputEnableQuestionList( + private function getInputUsrPassOverview( \ilLanguage $lng, FieldFactory $f, Refinery $refinery @@ -94,46 +100,46 @@ static function (?array $vs): int { return 0; } - $question_list_mode = 1; + $usrpass_overview_mode = 1; if ($vs['show_at_beginning'] === true) { - $question_list_mode += 2; + $usrpass_overview_mode += 2; } if ($vs['show_at_end'] === true) { - $question_list_mode += 4; + $usrpass_overview_mode += 4; } if ($vs['show_description'] === true) { - $question_list_mode += 8; + $usrpass_overview_mode += 8; } - return $question_list_mode; + return $usrpass_overview_mode; } ); - $sub_inputs_question_list['show_at_beginning'] = $f->checkbox( + $sub_inputs_usrpass_questionlist['show_at_beginning'] = $f->checkbox( $lng->txt('tst_list_of_questions_start') ); - $sub_inputs_question_list['show_at_end'] = $f->checkbox( + $sub_inputs_usrpass_questionlist['show_at_end'] = $f->checkbox( $lng->txt('tst_list_of_questions_end') ); - $sub_inputs_question_list['show_description'] = $f->checkbox( + $sub_inputs_usrpass_questionlist['show_description'] = $f->checkbox( $lng->txt('tst_list_of_questions_with_description') ); - $enable_question_list = $f->optionalGroup( - $sub_inputs_question_list, + $enable_usrpass_questionlist = $f->optionalGroup( + $sub_inputs_usrpass_questionlist, $lng->txt('tst_show_summary'), $lng->txt('tst_show_summary_description') )->withValue(null) ->withAdditionalTransformation($trafo); - if ($this->getQuestionListEnabled() === false) { - return $enable_question_list; + if ($this->getUsrPassOverviewEnabled() === false) { + return $enable_usrpass_questionlist; } - return $enable_question_list->withValue( + return $enable_usrpass_questionlist->withValue( [ 'show_at_beginning' => $this->getShownQuestionListAtBeginning(), 'show_at_end' => $this->getShownQuestionListAtEnd(), @@ -148,8 +154,9 @@ public function toStorage(): array 'use_previous_answers' => ['integer', (int) $this->getUsePreviousAnswerAllowed()], 'show_cancel' => ['integer', (int) $this->getSuspendTestAllowed()], 'sequence_settings' => ['integer', (int) $this->getPostponedQuestionsMoveToEnd()], - 'show_summary' => ['integer', $this->getQuestionListMode()], - 'show_marker' => ['integer', (int) $this->getQuestionMarkingEnabled()] + 'usr_pass_overview_mode' => ['integer', $this->getUsrPassOverviewMode()], + 'show_marker' => ['integer', (int) $this->getQuestionMarkingEnabled()], + 'show_questionlist' => ['integer', $this->getQuestionListEnabled()] ]; } @@ -186,13 +193,24 @@ public function withPostponedQuestionsMoveToEnd(bool $postponed_questions_move_t return $clone; } - public function getQuestionListMode(): int + public function getQuestionListEnabled(): bool { - return $this->question_list_mode; + return $this->question_list_enabled; } - public function getQuestionListEnabled(): bool + public function withQuestionListEnabled(bool $question_list_enabled): self + { + $clone = clone $this; + $clone->question_list_enabled = $question_list_enabled; + return $clone; + } + + public function getUsrPassOverviewMode(): int + { + return $this->usrpass_overview_mode; + } + public function getUsrPassOverviewEnabled(): bool { - if (($this->question_list_mode & 1) > 0) { + if (($this->usrpass_overview_mode & 1) > 0) { return true; } @@ -200,7 +218,7 @@ public function getQuestionListEnabled(): bool } public function getShownQuestionListAtBeginning(): bool { - if (($this->question_list_mode & 2) > 0) { + if (($this->usrpass_overview_mode & 2) > 0) { return true; } @@ -208,7 +226,7 @@ public function getShownQuestionListAtBeginning(): bool } public function getShownQuestionListAtEnd(): bool { - if (($this->question_list_mode & 4) > 0) { + if (($this->usrpass_overview_mode & 4) > 0) { return true; } @@ -216,16 +234,16 @@ public function getShownQuestionListAtEnd(): bool } public function getShowDescriptionInQuestionList(): bool { - if (($this->question_list_mode & 8) > 0) { + if (($this->usrpass_overview_mode & 8) > 0) { return true; } return false; } - public function withQuestionListMode(int $question_list_mode): self + public function withUsrPassOverviewMode(int $usrpass_overview_mode): self { $clone = clone $this; - $clone->question_list_mode = $question_list_mode; + $clone->usrpass_overview_mode = $usrpass_overview_mode; return $clone; } diff --git a/Modules/Test/classes/Results/class.ilQuestionResult.php b/Modules/Test/classes/Results/class.ilQuestionResult.php new file mode 100644 index 000000000000..1de0a45ad2ad --- /dev/null +++ b/Modules/Test/classes/Results/class.ilQuestionResult.php @@ -0,0 +1,104 @@ +id; + } + public function getType(): string + { + return $this->type; + } + public function getTitle(): string + { + return $this->title; + } + public function getUserAnswer(): string + { + return $this->usr_solution; + } + public function getBestSolution(): string + { + return $this->best_solution; + } + public function getQuestionScore(): float + { + return $this->question_score; + } + public function getUserScore(): float + { + return $this->usr_score; + } + public function getUserScorePercent(): float + { + return 100 / $this->getQuestionScore() * $this->getUserScore(); + } + public function getCorrect(): int + { + if ($this->getUserScore() === 0.0) { + return self::CORRECT_NONE; + } + if ($this->getUserScore() === $this->getQuestionScore()) { + return self::CORRECT_FULL; + } + return self::CORRECT_PARTIAL; + } + public function getFeedback(): string + { + return $this->feedback; + } + public function isWorkedThrough(): bool + { + return $this->workedthrough; + } + public function isAnswered(): bool + { + return $this->answered; + } + public function getContentForRecapitulation(): ?string + { + return $this->content_for_recapitulation; + } +} diff --git a/Modules/Test/classes/Results/class.ilTestPassResult.php b/Modules/Test/classes/Results/class.ilTestPassResult.php new file mode 100644 index 000000000000..8183a25d9168 --- /dev/null +++ b/Modules/Test/classes/Results/class.ilTestPassResult.php @@ -0,0 +1,60 @@ +settings; + } + + public function getActiveId(): int + { + return $this->active_id; + } + + public function getPass(): int + { + return $this->pass_id; + } + + /** + * @return ilQuestionResult[]; + */ + public function getQuestionResults(): array + { + return $this->question_results; + } +} diff --git a/Modules/Test/classes/Results/class.ilTestPassResultsSettings.php b/Modules/Test/classes/Results/class.ilTestPassResultsSettings.php new file mode 100644 index 000000000000..ee38a967a432 --- /dev/null +++ b/Modules/Test/classes/Results/class.ilTestPassResultsSettings.php @@ -0,0 +1,66 @@ +show_hidden_questions; + } + + public function getShowOptionalQuestions(): bool + { + return $this->show_optional_questions; + } + + public function getShowBestSolution(): bool + { + return $this->show_best_solution; + } + + public function getShowFeedback(): bool + { + return $this->show_feedback; + } + + public function getQuestionTextOnly(): bool + { + return $this->question_text_only; + } + + public function getShowRecapitulation(): bool + { + return $this->show_recapitulation; + } +} diff --git a/Modules/Test/classes/Results/class.ilTestPassResultsTable.php b/Modules/Test/classes/Results/class.ilTestPassResultsTable.php new file mode 100644 index 000000000000..589e1ad03225 --- /dev/null +++ b/Modules/Test/classes/Results/class.ilTestPassResultsTable.php @@ -0,0 +1,246 @@ +getViewControlsParameter(); + $results = $this->applyControls($mode, $sortation, $test_results->getQuestionResults()); + $target = new URLBuilder($data_factory->uri($http->request()->getUri()->__toString())); + + $this->table = $ui_factory->table()->presentation( + $title, + $this->getViewControls($ui_factory, $lng, $target, $mode, $sortation), + $this->getMapping() + ) + ->withEnvironment([ + self::ENV => $test_results->getSettings(), + self::LNG => $lng + ]) + ->withData($results); + } + + public function render(): string + { + return $this->ui_renderer->render($this->table); + } + + /** + * @param ilQuestionResult[] $question_results + */ + protected function applyControls( + string $mode, + string $sortation, + array $question_results + ) { + switch($mode) { + case self::MODE_OPT_CORRECT: + $filter = static fn($qr) => $qr->getCorrect() === ilQuestionResult::CORRECT_FULL; + break; + case self::MODE_OPT_INCORRECT: + $filter = static fn($qr) => $qr->getCorrect() !== ilQuestionResult::CORRECT_FULL; + break; + case self::MODE_OPT_ALL: + default: + $filter = static fn($qr) => true; + } + $question_results = array_filter($question_results, $filter); + + if ($sortation === self::SORT_OPT_POSSIBLESCORE) { + usort( + $question_results, + static fn(ilQuestionResult $a, ilQuestionResult $b) => $a->getQuestionScore() <=> $b->getQuestionScore() + ); + $question_results = array_reverse($question_results); + } + return $question_results; + } + + protected function getViewControlsParameter(): array + { + $request = $this->http->wrapper()->query(); + $pre = implode(URLBuilder::SEPARATOR, self::URL_NAMESPACE) . URLBuilder::SEPARATOR; + + $mode = $request->has($pre . self::PARAM_MODE) ? + $request->retrieve($pre . self::PARAM_MODE, $this->refinery->kindlyTo()->string()) : self::MODE_OPT_ALL; + + $sortation = $request->has($pre . self::PARAM_SORT) ? + $request->retrieve($pre . self::PARAM_SORT, $this->refinery->kindlyTo()->string()) : self::SORT_OPT_ORDEROFAPPEARANCE; + + return [$mode, $sortation]; + } + + /** + * return \ILIAS\UI\ViewControl\ViewControl[] + */ + protected function getViewControls( + UIFactory $ui_factory, + ilLanguage $lng, + URLBuilder $target, + string $mode, + string $sortation + ): array { + $builder = $target->acquireParameter(self::URL_NAMESPACE, self::PARAM_MODE); + [$target, $token] = $builder; + + $modes = [ + $lng->txt('resulttable_all') => $target->withParameter($token, self::MODE_OPT_ALL)->buildURI()->__toString(), + $lng->txt('resulttable_correct') => $target->withParameter($token, self::MODE_OPT_CORRECT)->buildURI()->__toString(), + $lng->txt('resulttable_incorrect') => $target->withParameter($token, self::MODE_OPT_INCORRECT)->buildURI()->__toString(), + ]; + $check = [self::MODE_OPT_ALL, self::MODE_OPT_CORRECT, self::MODE_OPT_INCORRECT]; + $active = array_search($mode, $check); + + $vc_mode = $ui_factory->viewControl()->mode($modes, $lng->txt('ta_resulttable_vc_mode_aria')) + ->withActive(array_keys($modes)[$active]); + + $options = [ + self::SORT_OPT_ORDEROFAPPEARANCE => $lng->txt('resulttable_vc_sort_iooa'), + self::SORT_OPT_POSSIBLESCORE => $lng->txt('resulttable_vc_sort_posscore') + ]; + + $pre = implode(URLBuilder::SEPARATOR, self::URL_NAMESPACE) . URLBuilder::SEPARATOR; + $vc_sort = $ui_factory->viewControl()->sortation($options)->withTargetURL( + $target->buildURI()->__toString(), + $pre . self::PARAM_SORT + ) + ->withLabel($options[$sortation]); + + return [ + $vc_mode, + $vc_sort + ]; + } + + protected function getMapping(): \Closure + { + return function ($row, $question, $ui_factory, $environment) { + $env = $environment[self::ENV]; + $lng = $environment[self::LNG]; + + $title = sprintf( + '%s [ID: %s]', + $question->getTitle(), + (string)$question->getId() + ); + + $important_fields = [ + $lng->txt('question_id') => (string)$question->getId(), + $lng->txt('question_type') => $question->getType(), + $lng->txt('points') => sprintf( + '%s/%s (%s%%)', + (string)$question->getUserScore(), + (string)$question->getQuestionScore(), + (string)$question->getUserScorePercent() + ) + ]; + $stats = $ui_factory->listing()->characteristicValue()->text($important_fields); + $user_answer = $question->getUserAnswer(); + $best_solution = $env->getShowBestSolution() ? $question->getBestSolution() : ''; + + + $feedback = $ui_factory->listing()->descriptive([ + $lng->txt('tst_feedback') => $question->getFeedback() + ]); + + $contents = []; + + $contents[] = $stats; + if ($env->getShowFeedback()) { + $contents[] = $feedback; + } + + if ($recap = $question->getContentForRecapitulation()) { + $contents[] = $ui_factory->listing()->descriptive([ + $lng->txt('suggested_solution') => $recap + ]); + } + + + $answers = $ui_factory->layout()->alignment()->horizontal()->evenlyDistributed( + $ui_factory->listing()->descriptive([$lng->txt('tst_header_participant') => $user_answer]), + $ui_factory->listing()->descriptive([$lng->txt('tst_header_solution') => $best_solution]) + ); + $contents[] = $answers; + + $content = $ui_factory->layout()->alignment()->vertical(...$contents); + + switch($question->getCorrect()) { + case ilQuestionResult::CORRECT_FULL: + $icon_name = 'icon_ok.svg'; + $label = $lng->txt("answer_is_right"); + break; + case ilQuestionResult::CORRECT_PARTIAL: + $icon_name = 'icon_mostly_ok.svg'; + $label = $lng->txt("answer_is_not_correct_but_positive"); + break; + case ilQuestionResult::CORRECT_NONE: + $icon_name = 'icon_not_ok.svg'; + $label = $lng->txt("answer_is_wrong"); + break; + } + $path = ilUtil::getImagePath('standard/' . $icon_name); + $correct_icon = $ui_factory->symbol()->icon()->custom( + $path, + $label + ); + + return $row + ->withHeadline($title) + ->withLeadingSymbol($correct_icon) + ->withImportantFields($important_fields) + ->withContent($content); + }; + } +} diff --git a/Modules/Test/classes/Results/class.ilTestResultsFactory.php b/Modules/Test/classes/Results/class.ilTestResultsFactory.php new file mode 100644 index 000000000000..8378ed0fbc0b --- /dev/null +++ b/Modules/Test/classes/Results/class.ilTestResultsFactory.php @@ -0,0 +1,192 @@ +getPassResultsSettings($test_obj, $is_user_output); + return $this->buildPassResults( + $settings, + $test_obj, + $active_id, + $pass_id, + $is_user_output + ); + } + + protected function buildPassResults( + ilTestPassResultsSettings $settings, + ilObjTest $test_obj, + int $active_id, + int $pass_id, + bool $is_user_output + ): ilTestPassResult { + $question_results = []; + + $results = $test_obj->getTestResult( + $active_id, + $pass_id, + false, //$ordered_sequence + $settings->getShowHiddenQuestions(), + $settings->getShowOptionalQuestions() + ); + + // params of getSolutionOutput + $graphical_output = false; + $result_output = false; + $show_question_only = $settings->getQuestionTextOnly(); + $show_feedback = false; //general + $show_correct_solution = false; + $show_manual_scoring = false; + $show_question_text = true; + $show_inline_feedback = true; + + foreach ($results as $idx => $qresult) { + if (!is_numeric($idx)) { + continue; + } + + $qid = $qresult['qid']; + $type = $qresult['type']; + $title = $qresult['title']; + $question_score = $qresult['max']; + $usr_score = $qresult['reached']; + $workedthrough = (bool)$qresult['workedthrough']; + $answered = (bool)$qresult['answered']; + + $question_gui = $test_obj->createQuestionGUI("", $qid); + $shuffle_trafo = $this->shuffler->getAnswerShuffleFor($qid, $active_id, $pass_id); + $question_gui->object->setShuffler($shuffle_trafo); + + $graphical_output = true; + $show_correct_solution = false; + $show_inline_feedback = $settings->getShowFeedback(); + $usr_solution = $question_gui->getSolutionOutput( + $active_id, + $pass_id, + $graphical_output, + $result_output, + $show_question_only, + $show_feedback, + $show_correct_solution, + $show_manual_scoring, + $show_question_text, + $show_inline_feedback + ); + + $graphical_output = false; + $show_correct_solution = true; + $show_inline_feedback = false; + $best_solution = $question_gui->getSolutionOutput( + $active_id, + $pass_id, + $graphical_output, + $result_output, + $show_question_only, + $show_feedback, + $show_correct_solution, + $show_manual_scoring, + $show_question_text, + $show_inline_feedback + ); + + if ($show_question_only) { + $usr_solution = $this->ui_renderer->render($this->ui_factory->legacy('
' . $usr_solution . '
')); + $best_solution = $this->ui_renderer->render($this->ui_factory->legacy('
' . $best_solution . '
')); + } + + $feedback = $question_gui->getGenericFeedbackOutput($active_id, $pass_id); + + $recapitulation = null; + if ($is_user_output && $settings->getShowRecapitulation()) { + $recapitulation = $question_gui->object->getSuggestedSolutionOutput(); + } + + $question_results[] = new ilQuestionResult( + $qid, + $type, + $title, + $question_score, + $usr_score, + $usr_solution, + $best_solution, + $feedback, + $workedthrough, + $answered, + $recapitulation + ); + } + + return new ilTestPassResult( + $settings, + $active_id, + $pass_id, + $question_results + ); + } + + protected function getPassResultsSettings( + ilObjTest $test_obj, + bool $is_user_output + ): ilTestPassResultsSettings { + $settings = $test_obj->getScoreSettings(); + $settings_summary = $settings->getResultSummarySettings(); + $settings_result = $settings->getResultDetailsSettings(); + + $show_hidden_questions = false; + $show_optional_questions = true; + $show_best_solution = $is_user_output ? + $settings_result->getShowSolutionListComparison() : + (bool)ilSession::get('tst_results_show_best_solutions'); + $show_feedback = $settings_result->getShowSolutionFeedback(); + $show_question_text_only = $settings_result->getShowSolutionAnswersOnly(); + $show_content_for_recapitulation = $settings_result->getShowSolutionSuggested(); + + return new ilTestPassResultsSettings( + $show_hidden_questions, + $show_optional_questions, + $show_best_solution, + $show_feedback, + $show_question_text_only, + $show_content_for_recapitulation + ); + } +} diff --git a/Modules/Test/classes/Results/class.ilTestResultsPresentationFactory.php b/Modules/Test/classes/Results/class.ilTestResultsPresentationFactory.php new file mode 100644 index 000000000000..286437be7d99 --- /dev/null +++ b/Modules/Test/classes/Results/class.ilTestResultsPresentationFactory.php @@ -0,0 +1,58 @@ +ui_factory, + $this->ui_renderer, + $this->refinery, + $this->http, + $this->data_factory, + $this->lng, + $pass_results, + $title + ); + } +} diff --git a/Modules/Test/classes/ScoreReporting/class.ilObjTestScoreSettingsDatabaseRepository.php b/Modules/Test/classes/ScoreReporting/class.ilObjTestScoreSettingsDatabaseRepository.php index 74ed43602466..5779ae49ba9d 100644 --- a/Modules/Test/classes/ScoreReporting/class.ilObjTestScoreSettingsDatabaseRepository.php +++ b/Modules/Test/classes/ScoreReporting/class.ilObjTestScoreSettingsDatabaseRepository.php @@ -98,7 +98,6 @@ protected function doSelect(string $where_part): ilObjTestScoreSettings //->withShowPassDetails derived from results_presentation with bit RESULTPRES_BIT_PASS_DETAILS (new ilObjTestSettingsResultDetails($test_id)) ->withResultsPresentation((int)$row['results_presentation']) - ->withPrintBestSolutionWithResult((bool) $row['print_bs_with_res']) ->withShowExamIdInTestResults((bool) $row['examid_in_test_res']) ->withExportSettings((int) $row['exportsettings']) ->withTaxonomyFilterIds($tax_filter_ids), diff --git a/Modules/Test/classes/ScoreReporting/ilObjTestSettingsResultDetails.php b/Modules/Test/classes/ScoreReporting/ilObjTestSettingsResultDetails.php index a91fef9c7a8d..33936d68cd84 100644 --- a/Modules/Test/classes/ScoreReporting/ilObjTestSettingsResultDetails.php +++ b/Modules/Test/classes/ScoreReporting/ilObjTestSettingsResultDetails.php @@ -52,45 +52,6 @@ public function toForm( Refinery $refinery, array $environment = null ): FormInput { - $bool_with_optional_addition = $refinery->custom()->transformation( - function ($v) { - if (!$v) { - return [false, false]; //[enabled, show_best_solution] - } - return [true, array_shift($v)]; - } - ); - - $optgroup_lists = $f->optionalGroup( - [ - $f->checkbox( - $lng->txt('tst_results_print_best_solution'), - $lng->txt('tst_results_print_best_solution_info') - )->withValue($this->getShowSolutionListComparison()) - ], - $lng->txt('tst_show_solution_details'), - $lng->txt('tst_show_solution_details_desc') - )->withAdditionalTransformation($bool_with_optional_addition); - - if (!$this->getShowSolutionListOwnAnswers()) { - $optgroup_lists = $optgroup_lists->withValue(null); - } - - $optgroup_singlepage = $f->optionalGroup( - [ - $f->checkbox( - $lng->txt('tst_results_print_best_solution_singlepage'), - $lng->txt('tst_results_print_best_solution_singlepage_info') - )->withValue($this->getPrintBestSolutionWithResult()) - ], - $lng->txt('tst_show_solution_details_singlepage'), - $lng->txt('tst_show_solution_details_singlepage_desc') - )->withAdditionalTransformation($bool_with_optional_addition); - if (!$this->getShowSolutionDetails()) { - $optgroup_singlepage = $optgroup_singlepage->withValue(null); - } - - $taxonomy_options = $environment['taxonomy_options']; $taxonomy_ids = $f->multiselect( $lng->txt('tst_results_tax_filters'), @@ -99,9 +60,11 @@ function ($v) { ); $fields = [ - 'solution_details' => $optgroup_lists, - 'solution_details_singlepage' => $optgroup_singlepage, - + 'solution_best_solution' => + $f->checkbox( + $lng->txt('tst_results_print_best_solution'), + $lng->txt('tst_results_print_best_solution_info') + )->withValue($this->getShowSolutionListComparison()), 'solution_feedback' => $f->checkbox( $lng->txt('tst_show_solution_feedback'), $lng->txt('tst_show_solution_feedback_desc') @@ -138,13 +101,8 @@ function ($v) { ->withAdditionalTransformation( $refinery->custom()->transformation( function ($v) { - list($solution_list_details, $solution_list_best_solution) = $v['solution_details']; - list($solution_sp_details, $solution_sp_best_solution) = $v['solution_details_singlepage']; return (clone $this) - ->withShowSolutionListOwnAnswers($solution_list_details) - ->withShowSolutionListComparison($solution_list_best_solution) - ->withShowSolutionDetails($solution_sp_details) - ->withPrintBestSolutionWithResult($solution_sp_best_solution) + ->withShowSolutionListComparison($v['solution_best_solution']) ->withShowSolutionFeedback($v['solution_feedback']) ->withShowSolutionSuggested($v['solution_suggested']) ->withShowSolutionPrintview($v['solution_printview']) @@ -160,7 +118,6 @@ function ($v) { public function toStorage(): array { return [ - 'print_bs_with_res' => ['integer', (int) $this->getPrintBestSolutionWithResult()], 'results_presentation' => ['integer', $this->getResultsPresentation()], 'examid_in_test_res' => ['integer', (int) $this->getShowExamIdInTestResults()], 'exportsettings' => ['integer', (int) $this->getExportSettings()], @@ -169,18 +126,6 @@ public function toStorage(): array ]; } - - public function getPrintBestSolutionWithResult(): bool - { - return $this->print_bs_with_res; - } - public function withPrintBestSolutionWithResult(bool $print_bs_with_res): self - { - $clone = clone $this; - $clone->print_bs_with_res = $print_bs_with_res; - return $clone; - } - public function getResultsPresentation(): int { return $this->results_presentation; @@ -232,15 +177,6 @@ public function withShowPassDetails(bool $flag): self return $this->modifyResultPresentation(self::RESULTPRES_BIT_PASS_DETAILS, $flag); } - public function getShowSolutionDetails(): bool - { - return $this->compareResultPresentation(self::RESULTPRES_BIT_SOLUTION_DETAILS); - } - public function withShowSolutionDetails(bool $flag): self - { - return $this->modifyResultPresentation(self::RESULTPRES_BIT_SOLUTION_DETAILS, $flag); - } - public function getShowSolutionPrintview(): bool { return $this->compareResultPresentation(self::RESULTPRES_BIT_SOLUTION_PRINTVIEW); @@ -295,15 +231,6 @@ public function withShowSolutionListComparison(bool $flag): self return $this->modifyResultPresentation(self::RESULTPRES_BIT_SOLUTION_LISTCOMPARE, $flag); } - public function getShowSolutionListOwnAnswers(): bool - { - return $this->compareResultPresentation(self::RESULTPRES_BIT_SOLUTION_LISTOWNANSWERS); - } - public function withShowSolutionListOwnAnswers(bool $flag): self - { - return $this->modifyResultPresentation(self::RESULTPRES_BIT_SOLUTION_LISTOWNANSWERS, $flag); - } - public function getExportSettings(): int { return $this->exportsettings; diff --git a/Modules/Test/classes/Screen/class.ilTestPlayerLayoutProvider.php b/Modules/Test/classes/Screen/class.ilTestPlayerLayoutProvider.php index 5fe0046113bb..9bd737bef0f4 100644 --- a/Modules/Test/classes/Screen/class.ilTestPlayerLayoutProvider.php +++ b/Modules/Test/classes/Screen/class.ilTestPlayerLayoutProvider.php @@ -22,6 +22,7 @@ use ILIAS\GlobalScreen\Scope\Layout\Factory\LogoModification; use ILIAS\GlobalScreen\Scope\Layout\Factory\MainBarModification; use ILIAS\GlobalScreen\Scope\Layout\Factory\MetaBarModification; +use ILIAS\GlobalScreen\Scope\Layout\Factory\TitleModification; use ILIAS\GlobalScreen\Scope\Layout\Factory\ShortTitleModification; use ILIAS\GlobalScreen\Scope\Layout\Factory\ViewTitleModification; use ILIAS\GlobalScreen\Scope\Layout\Provider\AbstractModificationProvider; @@ -44,58 +45,66 @@ class ilTestPlayerLayoutProvider extends AbstractModificationProvider implements ModificationProvider { public const TEST_PLAYER_KIOSK_MODE_ENABLED = 'test_player_kiosk_mode_enabled'; - public const TEST_PLAYER_TITLE = 'test_player_kiosk_mode_title'; - public const TEST_PLAYER_SHORT_TITLE = 'test_player_kiosk_mode_instance_name'; + public const TEST_PLAYER_TITLE = 'test_player_title'; + public const TEST_PLAYER_VIEW_TITLE = 'test_player_view_title'; + public const TEST_PLAYER_SHORT_TITLE = 'test_player_instance_name'; + public const TEST_PLAYER_QUESTIONLIST = 'test_player_questionlist'; + private const MODIFICATION_PRIORITY = 5; //slightly above "low" public function isInterestedInContexts(): ContextCollection { return $this->context_collection->repository(); } - public function getLogoModification(CalledContexts $called_contexts): ?LogoModification + public function getMainBarModification(CalledContexts $called_contexts): ?MainBarModification { - if ($this->isKioskModeEnabled($called_contexts)) { - $logo = $this->globalScreen()->layout()->factory()->logo(); - - $logo = $logo->withModification(function (?Image $current): ?Image { - return null; - }); + $mainbar = $this->globalScreen()->layout()->factory()->mainbar(); + $additionalData = $called_contexts->current()->getAdditionalData(); + $has_question_list = $additionalData->exists(self::TEST_PLAYER_QUESTIONLIST); + $is_kiosk_mode = $this->isKioskModeEnabled($called_contexts); - return $logo->withHighPriority(); + if (! $is_kiosk_mode && ! $has_question_list) { + return null; } - return null; - } - - public function getResponsiveLogoModification(CalledContexts $called_contexts): ?LogoModification - { - if ($this->isKioskModeEnabled($called_contexts)) { - $logo = $this->globalScreen()->layout()->factory()->logo(); + if ($is_kiosk_mode && ! $has_question_list) { + $mainbar_modification = static fn(?MainBar $mainbar): ?MainBar => null; + } - $logo = $logo->withModification(function (?Image $current): ?Image { - return null; - }); + if ($has_question_list) { + $f = $this->dic->ui()->factory(); + $r = $this->dic->ui()->renderer(); + $lng = $this->dic->language(); + $question_listing = $called_contexts->current()->getAdditionalData()->get(self::TEST_PLAYER_QUESTIONLIST); - return $logo->withHighPriority(); - } + $mainbar_modification = static function (?MainBar $mainbar) use ($f, $r, $lng, $question_listing, $is_kiosk_mode): ?MainBar { + if ($is_kiosk_mode) { + $mainbar = $mainbar->withClearedEntries(); + } - return null; - } + $icon = $f->symbol()->icon()->standard('tst', $lng->txt("more")); + $tools_button = $f->button()->bulky($icon, $lng->txt("tools"), "#") + ->withEngagedState(true); - public function getMainBarModification(CalledContexts $called_contexts): ?MainBarModification - { - if ($this->isKioskModeEnabled($called_contexts)) { - $mainBar = $this->globalScreen()->layout()->factory()->mainbar(); + $question_listing = $f->legacy($r->render($question_listing)); - $mainBar = $mainBar->withModification(function (?MainBar $current): ?MainBar { - return null; - }); + $label = $lng->txt('mainbar_button_label_questionlist'); + $entry = $f->maincontrols()->slate()->legacy( + $label, + $f->symbol()->icon()->standard("tst", $label), + $question_listing + ); - return $mainBar->withHighPriority(); + return $mainbar + ->withToolsButton($tools_button) + ->withAdditionalToolEntry('questionlist', $entry); + }; } - return null; + return $mainbar + ->withModification($mainbar_modification) + ->withPriority(self::MODIFICATION_PRIORITY); } public function getMetaBarModification(CalledContexts $called_contexts): ?MetaBarModification @@ -107,7 +116,8 @@ public function getMetaBarModification(CalledContexts $called_contexts): ?MetaBa return null; }); - return $metaBar->withHighPriority(); + return $metaBar + ->withPriority(self::MODIFICATION_PRIORITY); } return null; @@ -122,7 +132,8 @@ public function getFooterModification(CalledContexts $called_contexts): ?FooterM return null; }); - return $footer->withHighPriority(); + return $footer + ->withPriority(self::MODIFICATION_PRIORITY); } return null; @@ -149,7 +160,7 @@ function (?string $content) use ($title): ?string { return $title; } ) - ->withHighPriority(); + ->withPriority(self::MODIFICATION_PRIORITY); } return null; } @@ -157,6 +168,26 @@ function (?string $content) use ($title): ?string { public function getViewTitleModification(CalledContexts $called_contexts): ?ViewTitleModification { if ($this->isKioskModeEnabled($called_contexts)) { + $title = $called_contexts->current()->getAdditionalData()->get(self::TEST_PLAYER_VIEW_TITLE); + if (is_null($title)) { + $title = ''; + } + return $this->globalScreen()->layout()->factory()->view_title() + ->withModification( + function (?string $content) use ($title): ?string { + return $title; + } + ) + ->withPriority(self::MODIFICATION_PRIORITY); + } + return null; + } + + public function getTitleModification(CalledContexts $called_contexts): ?TitleModification + { + $additionalData = $called_contexts->current()->getAdditionalData(); + $has_title = $additionalData->exists(self::TEST_PLAYER_TITLE); + if ($has_title) { $title = $called_contexts->current()->getAdditionalData()->get(self::TEST_PLAYER_TITLE); if ($title == null) { $title = ''; @@ -167,7 +198,7 @@ function (?string $content) use ($title): ?string { return $title; } ) - ->withHighPriority(); + ->withPriority(self::MODIFICATION_PRIORITY); } return null; } diff --git a/Modules/Test/classes/Setup/class.ilTest9DBUpdateSteps.php b/Modules/Test/classes/Setup/class.ilTest9DBUpdateSteps.php index b201a7c954c8..64dba27c03ea 100644 --- a/Modules/Test/classes/Setup/class.ilTest9DBUpdateSteps.php +++ b/Modules/Test/classes/Setup/class.ilTest9DBUpdateSteps.php @@ -180,6 +180,20 @@ public function step_8(): void } public function step_9(): void + { + if (!$this->db->tableColumnExists('tst_tests', 'show_questionlist')) { + $this->db->addTableColumn( + 'tst_tests', + 'show_questionlist', + [ + 'type' => 'integer', + 'length' => 1 + ] + ); + } + } + + public function step_10(): void { if ($this->db->tableColumnExists('tst_tests', 'sign_submission')) { $this->db->dropTableColumn( @@ -188,4 +202,29 @@ public function step_9(): void ); } } + + public function step_11(): void + { + if ($this->db->tableColumnExists('tst_tests', 'show_summary')) { + $this->db->renameTableColumn( + 'tst_tests', + 'show_summary', + 'usr_pass_overview_mode' + ); + } + } + + public function step_12(): void + { + if (!$this->db->tableColumnExists('tst_tests', 'show_questionlist')) { + $this->db->addTableColumn( + 'tst_tests', + 'show_questionlist', + [ + 'type' => 'integer', + 'length' => 1 + ] + ); + } + } } diff --git a/Modules/Test/classes/Setup/class.ilTestSetupAgent.php b/Modules/Test/classes/Setup/class.ilTestSetupAgent.php index 1f15f3403def..138c095d7862 100644 --- a/Modules/Test/classes/Setup/class.ilTestSetupAgent.php +++ b/Modules/Test/classes/Setup/class.ilTestSetupAgent.php @@ -26,6 +26,7 @@ use ILIAS\Refinery\Transformation; use ILIAS\Test\Setup\ilManScoringSettingsToOwnDbTableMigration; use ILIAS\Test\Setup\ilRemoveDynamicTestsAndCorrespondingDataMigration; +use ILIAS\Test\Setup\ilSeparateQuestionListSettingMigration; class ilTestSetupAgent extends NullAgent { @@ -65,7 +66,8 @@ public function getMigrations(): array { return [ new ilManScoringSettingsToOwnDbTableMigration(), - new ilRemoveDynamicTestsAndCorrespondingDataMigration() + new ilRemoveDynamicTestsAndCorrespondingDataMigration(), + new ilSeparateQuestionListSettingMigration() ]; } } diff --git a/Modules/Test/classes/Setup/ilSeparateQuestionListSettingMigration.php b/Modules/Test/classes/Setup/ilSeparateQuestionListSettingMigration.php new file mode 100644 index 000000000000..e4fefec87d1c --- /dev/null +++ b/Modules/Test/classes/Setup/ilSeparateQuestionListSettingMigration.php @@ -0,0 +1,87 @@ +db = $environment->getResource(Setup\Environment::RESOURCE_DATABASE); + } + + /** + * @throws Exception + */ + public function step(Environment $environment): void + { + $this->db->manipulate( + 'UPDATE tst_tests SET show_questionlist = 1 WHERE usr_pass_overview_mode > 0' + ); + + $this->db->manipulate( + 'UPDATE tst_tests SET show_questionlist = 0 WHERE usr_pass_overview_mode = 0' + ); + } + + public function getRemainingAmountOfSteps(): int + { + $result = $this->db->query( + "SELECT count(*) as cnt FROM tst_tests WHERE show_questionlist is NULL" + ); + $row = $this->db->fetchAssoc($result); + + return (int) $row['cnt'] ?? 0; + } +} diff --git a/Modules/Test/classes/Skills/class.TestSkillDBRepository.php b/Modules/Test/classes/Skills/class.TestSkillDBRepository.php new file mode 100644 index 000000000000..5a88c21b8a17 --- /dev/null +++ b/Modules/Test/classes/Skills/class.TestSkillDBRepository.php @@ -0,0 +1,48 @@ + + */ +class TestSkillDBRepository +{ + protected \ilDBInterface $db; + + public function __construct( + \ilDBInterface $db = null + ) { + global $DIC; + + $this->db = ($db) ?: $DIC->database(); + } + + public function removeForSkill(int $skill_node_id, bool $is_reference): void + { + if (!$is_reference) { + $this->db->manipulate("DELETE FROM tst_skl_thresholds " . + " WHERE skill_base_fi = " . $this->db->quote($skill_node_id, "integer")); + } else { + $this->db->manipulate("DELETE FROM tst_skl_thresholds " . + " WHERE skill_tref_fi = " . $this->db->quote($skill_node_id, "integer")); + } + } +} diff --git a/Modules/Test/classes/class.ilObjTest.php b/Modules/Test/classes/class.ilObjTest.php index b8905978bb1e..c071dea0d3b0 100755 --- a/Modules/Test/classes/class.ilObjTest.php +++ b/Modules/Test/classes/class.ilObjTest.php @@ -134,8 +134,10 @@ public function __construct(int $id = 0, bool $a_call_by_reference = true) $this->component_repository = $DIC['component.repository']; $this->component_factory = $DIC['component.factory']; $this->filesystem_web = $DIC->filesystem()->web(); - $this->testManScoringDoneHelper = new TestManScoringDoneHelper(); - $this->participant_access_filter = new ilTestParticipantAccessFilterFactory($DIC['ilAccess']); + + $local_dic = $this->getLocalDIC(); + $this->participant_access_filter = $local_dic['participantAccessFilterFactory']; + $this->testManScoringDoneHelper = $local_dic['manScoringDoneHelper']; $this->mark_schema = new ASS_MarkSchema($DIC['ilDB'], $DIC['lng'], $DIC['ilUser']->getId()); $this->mark_schema->createSimpleSchema( @@ -166,6 +168,11 @@ public function __construct(int $id = 0, bool $a_call_by_reference = true) ); } + public function getLocalDIC(): ILIAS\DI\Container + { + return ilTestDIC::dic(); + } + /** * returns the object title prepared to be used as a filename */ @@ -3435,9 +3442,13 @@ public function fromXML(ilQTIAssessment $assessment) case 'pass_deletion_allowed': $result_summary_settings = $result_summary_settings->withPassDeletionAllowed((bool) $metadata["entry"]); break; - case "show_summary": - $participant_functionality_settings = $participant_functionality_settings->withQuestionListMode((int) $metadata["entry"]); + case "usr_pass_overview_mode": + $participant_functionality_settings = $participant_functionality_settings->withUsrPassOverviewMode((int) $metadata["entry"]); break; + case "question_list": + $participant_functionality_settings = $participant_functionality_settings->withQuestionListEnabled((bool) $metadata["entry"]); + break; + case "reporting_date": $result_summary_settings = $result_summary_settings->withReportingDate( $metadata['ReportingDate'] !== null ? @@ -3861,8 +3872,8 @@ public function toXML(): string // solution details $a_xml_writer->xmlStartTag("qtimetadatafield"); - $a_xml_writer->xmlElement("fieldlabel", null, "show_summary"); - $a_xml_writer->xmlElement("fieldentry", null, sprintf("%d", $main_settings->getParticipantFunctionalitySettings()->getQuestionListMode())); + $a_xml_writer->xmlElement("fieldlabel", null, "usr_pass_overview_mode"); + $a_xml_writer->xmlElement("fieldentry", null, sprintf("%d", $main_settings->getParticipantFunctionalitySettings()->getUsrPassOverviewMode())); $a_xml_writer->xmlEndTag("qtimetadatafield"); // solution details @@ -3871,10 +3882,6 @@ public function toXML(): string $a_xml_writer->xmlElement("fieldentry", null, sprintf("%d", $this->getScoreReporting())); $a_xml_writer->xmlEndTag("qtimetadatafield"); - $a_xml_writer->xmlStartTag("qtimetadatafield"); - $a_xml_writer->xmlElement("fieldlabel", null, "solution_details"); - $a_xml_writer->xmlElement("fieldentry", null, (int) $this->getShowSolutionDetails()); - $a_xml_writer->xmlEndTag("qtimetadatafield"); $a_xml_writer->xmlStartTag("qtimetadatafield"); $a_xml_writer->xmlElement("fieldlabel", null, "print_bs_with_res"); $a_xml_writer->xmlElement("fieldentry", null, (int) $this->getShowSolutionDetails() ? (int) $this->isBestSolutionPrintedWithResult() : 0); @@ -5871,7 +5878,7 @@ public function getShuffleQuestions(): bool */ public function getListOfQuestionsSettings() { - return $this->getMainSettings()->getParticipantFunctionalitySettings()->getQuestionListMode(); + return $this->getMainSettings()->getParticipantFunctionalitySettings()->getUsrPassOverviewMode(); } public function getListOfQuestions(): bool @@ -5879,6 +5886,11 @@ public function getListOfQuestions(): bool return $this->getMainSettings()->getParticipantFunctionalitySettings()->getQuestionListEnabled(); } + public function getUsrPassOverviewEnabled(): bool + { + return $this->getMainSettings()->getParticipantFunctionalitySettings()->getUsrPassOverviewEnabled(); + } + public function getListOfQuestionsStart(): bool { return $this->getMainSettings()->getParticipantFunctionalitySettings()->getShownQuestionListAtBeginning(); @@ -5902,14 +5914,6 @@ public function getShowPassDetails(): bool return $this->getScoreSettings()->getResultDetailsSettings()->getShowPassDetails(); } - /** - * Returns if the solution details should be presented to the user or not - */ - public function getShowSolutionDetails(): bool - { - return $this->getScoreSettings()->getResultDetailsSettings()->getShowSolutionDetails(); - } - /** * Returns if the solution printview should be presented to the user or not */ @@ -6362,7 +6366,7 @@ public function addDefaults($a_name) 'use_previous_answers' => (int) $main_settings->getParticipantFunctionalitySettings()->getUsePreviousAnswerAllowed(), 'ShowCancel' => (int) $main_settings->getParticipantFunctionalitySettings()->getSuspendTestAllowed(), 'SequenceSettings' => (int) $main_settings->getParticipantFunctionalitySettings()->getPostponedQuestionsMoveToEnd(), - 'ListOfQuestionsSettings' => $main_settings->getParticipantFunctionalitySettings()->getQuestionListMode(), + 'ListOfQuestionsSettings' => $main_settings->getParticipantFunctionalitySettings()->getUsrPassOverviewMode(), 'ShowMarker' => (int) $main_settings->getParticipantFunctionalitySettings()->getQuestionMarkingEnabled(), 'enable_examview' => $main_settings->getFinishingSettings()->getShowAnswerOverview(), @@ -6486,7 +6490,7 @@ public function applyDefaults($test_defaults): bool ->withUsePreviousAnswerAllowed((bool) $testsettings['use_previous_answers']) ->withSuspendTestAllowed((bool) $testsettings['ShowCancel']) ->withPostponedQuestionsMoveToEnd((bool) $testsettings['SequenceSettings']) - ->withQuestionListMode($testsettings['ListOfQuestionsSettings']) + ->withUsrPassOverviewMode($testsettings['ListOfQuestionsSettings']) ->withQuestionMarkingEnabled((bool) $testsettings['ShowMarker']) ) ->withFinishingSettings( diff --git a/Modules/Test/classes/class.ilObjTestGUI.php b/Modules/Test/classes/class.ilObjTestGUI.php index a73574dd64de..c23501cb1a7e 100755 --- a/Modules/Test/classes/class.ilObjTestGUI.php +++ b/Modules/Test/classes/class.ilObjTestGUI.php @@ -121,6 +121,7 @@ public function __construct($refId = null) $this->questioninfo = $DIC->testQuestionPool()->questionInfo(); $this->type = 'tst'; $this->testrequest = $DIC->test()->internal()->request(); + $ref_id = 0; if ($this->testrequest->hasRefId() && is_numeric($this->testrequest->getRefId())) { $ref_id = $this->testrequest->getRefId(); @@ -1445,7 +1446,7 @@ public function importVerifiedFileObject() if (is_file(ilSession::get("tst_import_dir") . '/' . ilSession::get("tst_import_subdir") . "/manifest.xml")) { $newObj->saveToDb(); - ilSession::set('tst_import_idents', $_POST['ident']); + ilSession::set('tst_import_idents', $_POST['ident'] ?? ''); ilSession::set('tst_import_qst_parent', $questionParentObjId); $fileName = ilSession::get('tst_import_subdir') . '.zip'; diff --git a/Services/Object/classes/Setup/class.Agent.php b/Modules/Test/classes/class.ilTestAppEventListener.php similarity index 50% rename from Services/Object/classes/Setup/class.Agent.php rename to Modules/Test/classes/class.ilTestAppEventListener.php index 26a3f045df4d..bcc48e91ee30 100644 --- a/Services/Object/classes/Setup/class.Agent.php +++ b/Modules/Test/classes/class.ilTestAppEventListener.php @@ -16,24 +16,24 @@ * *********************************************************************/ -namespace ILIAS\Object\Setup; +declare(strict_types=1); -use ILIAS\Setup; -use ILIAS\Setup\Objective; -use ILIAS\Setup\Metrics; +use ILIAS\Test\Skills\TestSkillDBRepository; /** - * @author Alexander Killing + * @author Thomas Famula */ -class Agent extends Setup\Agent\NullAgent +class ilTestAppEventListener implements ilAppEventListener { - public function getUpdateObjective(Setup\Config $config = null): Setup\Objective + /** + * @inheritDoc + */ + public static function handleEvent(string $a_component, string $a_event, array $a_parameter): void { - return new \ilDatabaseUpdateStepsExecutedObjective(new ilObjectDBUpdateSteps()); - } + $test_skill_repo = new TestSkillDBRepository(); - public function getStatusObjective(Metrics\Storage $storage): Objective - { - return new \ilDatabaseUpdateStepsMetricsCollectedObjective($storage, new ilObjectDBUpdateSteps()); + if ($a_component === "Services/Skill" && $a_event === "deleteSkill") { + $test_skill_repo->removeForSkill($a_parameter["node_id"], $a_parameter["is_reference"]); + } } } diff --git a/Modules/Test/classes/class.ilTestDIC.php b/Modules/Test/classes/class.ilTestDIC.php new file mode 100644 index 000000000000..1673e4a99fa4 --- /dev/null +++ b/Modules/Test/classes/class.ilTestDIC.php @@ -0,0 +1,75 @@ + + new ilTestShuffler($dic['refinery']); + + $dic['factory.results'] = static fn($c): ilTestResultsFactory => + new ilTestResultsFactory( + $c['shuffler'], + $dic['ui.factory'], + $dic['ui.renderer'] + ); + + $dic['factory.results_presentation'] = static fn($c): ilTestResultsPresentationFactory => + new ilTestResultsPresentationFactory( + $dic['ui.factory'], + $dic['ui.renderer'], + $dic['refinery'], + new ILIAS\Data\Factory(), + $dic['http'], + $dic['lng'] + ); + + + $dic['participantAccessFilterFactory'] = static fn($c): ilTestParticipantAccessFilterFactory => + new ilTestParticipantAccessFilterFactory($dic['ilAccess']); + + $dic['manScoringDoneHelper'] = static fn($c): TestManScoringDoneHelper => + new TestManScoringDoneHelper(); + + $dic['request.internal'] = static fn($c): InternalRequestService => + new InternalRequestService($dic['http'], $dic['refinery']); + + return $dic; + } +} diff --git a/Modules/Test/classes/class.ilTestEvaluationGUI.php b/Modules/Test/classes/class.ilTestEvaluationGUI.php index c211d77fe3e8..28f0b957c166 100644 --- a/Modules/Test/classes/class.ilTestEvaluationGUI.php +++ b/Modules/Test/classes/class.ilTestEvaluationGUI.php @@ -48,8 +48,6 @@ class ilTestEvaluationGUI extends ilTestServiceGUI protected ilTestAccess $testAccess; protected ilTestProcessLockerFactory $processLockerFactory; - protected ilTestParticipantAccessFilterFactory $participant_access_filter; - /** * ilTestEvaluationGUI constructor * @@ -64,6 +62,7 @@ public function __construct(ilObjTest $object) global $DIC; $this->participant_access_filter = new ilTestParticipantAccessFilterFactory($this->access); $this->ui = $DIC->ui(); + $this->processLockerFactory = new ilTestProcessLockerFactory( new ilSetting('assessment'), $this->db @@ -331,6 +330,7 @@ public function outEvaluation() } $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print"); + if ($this->object->getShowSolutionAnswersOnly()) { $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print"); } @@ -863,47 +863,6 @@ public function outParticipantsPassDetails() ); } - $testResultHeaderLabelBuilder = new ilTestResultHeaderLabelBuilder($this->lng, $ilObjDataCache); - - $objectivesList = null; - - if ($this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) { - $testSequence = $this->testSequenceFactory->getSequenceByActiveIdAndPass($active_id, $pass); - $testSequence->loadFromDb(); - $testSequence->loadQuestions(); - - $objectivesAdapter = ilLOTestQuestionAdapter::getInstance($testSession); - - $objectivesList = $this->buildQuestionRelatedObjectivesList($objectivesAdapter, $testSequence); - $objectivesList->loadObjectivesTitles(); - - $testResultHeaderLabelBuilder->setObjectiveOrientedContainerId($testSession->getObjectiveOrientedContainerId()); - $testResultHeaderLabelBuilder->setUserId($testSession->getUserId()); - $testResultHeaderLabelBuilder->setTestObjId($this->object->getId()); - $testResultHeaderLabelBuilder->setTestRefId($this->object->getRefId()); - $testResultHeaderLabelBuilder->initObjectiveOrientedMode(); - } - - $result_array = $this->getFilteredTestResult($active_id, $pass, false, !$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()); - - $overviewTableGUI = $this->getPassDetailsOverviewTableGUI( - $result_array, - $active_id, - $pass, - $this, - "outParticipantsPassDetails", - '', - true, - $objectivesList - ); - $overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1)); - $user_data = $this->getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, false); - $user_id = $this->object->_getUserIdFromActiveId($active_id); - - $template = new ilTemplate("tpl.il_as_tst_pass_details_overview_participants.html", true, true, "Modules/Test"); - - $toolbar = $this->buildUserTestResultsToolbarGUI(); - if ($this->testrequest->isset('show_best_solutions')) { ilSession::set('tst_results_show_best_solutions', true); } elseif ($this->testrequest->isset('hide_best_solutions')) { @@ -912,6 +871,18 @@ public function outParticipantsPassDetails() ilSession::clear('tst_results_show_best_solutions'); } + $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print"); + if ($this->object->getShowSolutionAnswersOnly()) { + $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print"); + } + + $template = new ilTemplate("tpl.il_as_tst_pass_details_overview_participants.html", true, true, "Modules/Test"); + + $this->populateExamId($template, $active_id, (int) $pass); + $this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass)); + + + $toolbar = $this->buildUserTestResultsToolbarGUI(); if (ilSession::get('tst_results_show_best_solutions')) { $this->ctrl->setParameter($this, 'hide_best_solutions', '1'); $toolbar->setHideBestSolutionsLinkTarget($this->ctrl->getLinkTarget($this, 'outParticipantsPassDetails')); @@ -934,37 +905,31 @@ public function outParticipantsPassDetails() $template->parseCurrentBlock(); } - $list_of_answers = $this->getPassListOfAnswers($result_array, $active_id, $pass, ilSession::get('tst_results_show_best_solutions'), false, false, false, true, $objectivesList, $testResultHeaderLabelBuilder); - $template->setVariable("LIST_OF_ANSWERS", $list_of_answers); - $template->setVariable("PASS_DETAILS", $this->ctrl->getHTML($overviewTableGUI)); - - $data = $this->object->getCompleteEvaluationData(); - $result = $data->getParticipant($active_id)->getReached() . " " . strtolower($this->lng->txt("of")) . " " . $data->getParticipant($active_id)->getMaxpoints() . " (" . sprintf("%2.2f", $data->getParticipant($active_id)->getReachedPointsInPercent()) . " %" . ")"; - $template->setCurrentBlock('total_score'); - $template->setVariable("TOTAL_RESULT_TEXT", $this->lng->txt('tst_stat_result_resultspoints')); - $template->setVariable("TOTAL_RESULT", $result); - $template->parseCurrentBlock(); - - if (!$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) { - $template->setVariable("USER_DATA", $user_data); - - $uname = $this->object->userLookupFullName($user_id); - $template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name_pass"), $pass + 1, $uname)); + $title = sprintf( + $this->lng->txt("tst_result_user_name_pass"), + $pass + 1, + ilObjUser::_lookupFullname($this->object->_getUserIdFromActiveId($active_id)) + ); - $template->setVariable("TEXT_RESULTS", $testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1)); - } + $pass_results = $this->results_factory->getPassResultsFor( + $this->object, + $active_id, + $pass, + false + ); - $template->setVariable("FORMACTION", $this->ctrl->getFormAction($this)); + $table = $this->results_presentation_factory->getPassResultsPresentationTable( + $pass_results, + $title + ); - $this->populateExamId($template, $active_id, $pass); - $this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass)); + $this->tpl->addCss(ilObjStyleSheet::getContentStylePath(0)); - $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print"); - if ($this->object->getShowSolutionAnswersOnly()) { - $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print"); - } - - $this->tpl->setVariable("ADM_CONTENT", $template->get()); + $this->tpl->setVariable( + "ADM_CONTENT", + $template->get() + . $table->render() + ); } public function outParticipantsResultsOverview() @@ -1149,14 +1114,10 @@ public function outUserPassDetails(): void $result_array = $this->getFilteredTestResult($active_id, $pass, $considerHiddenQuestions, $considerOptionalQuestions); $command_solution_details = ""; - if ($this->object->getShowSolutionDetails()) { + if ($this->object->getShowSolutionListComparison()) { $command_solution_details = "outCorrectSolution"; } - //$questionAnchorNav = $this->object->canShowSolutionPrintview(); - $questionAnchorNav = - $this->object->getShowSolutionListOwnAnswers(); - $tpl = new ilTemplate('tpl.il_as_tst_pass_details_overview_participants.html', true, true, "Modules/Test"); $toolbar = $this->buildUserTestResultsToolbarGUI(); @@ -1191,19 +1152,6 @@ public function outUserPassDetails(): void $gradingMessageBuilder->sendMessage(); } - $overviewTableGUI = $this->getPassDetailsOverviewTableGUI( - $result_array, - $active_id, - $pass, - $this, - "outUserPassDetails", - $command_solution_details, - $questionAnchorNav, - $objectivesList - ); - $overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1)); - $tpl->setVariable("PASS_DETAILS", $this->ctrl->getHTML($overviewTableGUI)); - $data = $this->object->getCompleteEvaluationData(); $percent = $data->getParticipant($active_id)->getPass($pass)->getReachedPoints() / $data->getParticipant($active_id)->getPass($pass)->getMaxPoints() * 100; $result = $data->getParticipant($active_id)->getPass($pass)->getReachedPoints() . " " . strtolower($this->lng->txt("of")) . " " . $data->getParticipant($active_id)->getPass($pass)->getMaxPoints() . " (" . sprintf("%2.2f", $percent) . " %" . ")"; @@ -1212,36 +1160,9 @@ public function outUserPassDetails(): void $tpl->setVariable("TOTAL_RESULT", $result); $tpl->parseCurrentBlock(); - if ($this->object->getShowSolutionListOwnAnswers()) { - $list_of_answers = $this->getPassListOfAnswers( - $result_array, - $active_id, - $pass, - $this->object->getShowSolutionListComparison(), - false, - false, - false, - true, - $objectivesList, - $testResultHeaderLabelBuilder - ); - $tpl->setVariable("LIST_OF_ANSWERS", $list_of_answers); - } - $tpl->setVariable("TEXT_RESULTS", $testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1)); $tpl->setVariable("FORMACTION", $this->ctrl->getFormAction($this)); - $uname = $this->object->userLookupFullName($user_id, true); - $user_data = $this->getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $active_id, true); - if (!$this->getObjectiveOrientedContainer()->isObjectiveOrientedPresentationRequired()) { - if ($this->object->getAnonymity()) { - $tpl->setVariable("TEXT_HEADING", $this->lng->txt("tst_result_pass")); - } else { - $tpl->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name_pass"), $pass + 1, $uname)); - $tpl->setVariable("USER_DATA", $user_data); - } - } - $this->populateExamId($tpl, $active_id, (int) $pass); $this->populatePassFinishDate($tpl, ilObjTest::lookupLastTestPassAccess($active_id, $pass)); @@ -1250,7 +1171,31 @@ public function outUserPassDetails(): void $this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print_hide_content.css", "Modules/Test"), "print"); } - $this->tpl->setContent($tpl->get()); + $title = sprintf( + $this->lng->txt("tst_result_user_name_pass"), + $pass + 1, + ilObjUser::_lookupFullname($this->object->_getUserIdFromActiveId($active_id)) + ); + + $pass_results = $this->results_factory->getPassResultsFor( + $this->object, + $active_id, + $pass, + true + ); + + $table = $this->results_presentation_factory->getPassResultsPresentationTable( + $pass_results, + $title + ); + + $tpl->setVariable("LIST_OF_ANSWERS", $table->render()); + + $this->tpl->addCss(ilObjStyleSheet::getContentStylePath(0)); + + $this->tpl->setContent( + $tpl->get() + ); } public function outUserResultsOverview() diff --git a/Modules/Test/classes/class.ilTestNavigationToolbarGUI.php b/Modules/Test/classes/class.ilTestNavigationToolbarGUI.php index 17a6bd9cdd3d..2ea7bf415e02 100644 --- a/Modules/Test/classes/class.ilTestNavigationToolbarGUI.php +++ b/Modules/Test/classes/class.ilTestNavigationToolbarGUI.php @@ -28,71 +28,21 @@ */ class ilTestNavigationToolbarGUI extends ilToolbarGUI { - /** - * @var ilCtrl - */ - protected $ctrl; - - /** - * @var ilTestPlayerAbstractGUI - */ - protected $playerGUI; - - /** - * @var bool - */ - private $suspendTestButtonEnabled = false; - - /** - * @var bool - */ - private $questionListButtonEnabled = false; - - /** - * @var bool - */ - private $questionTreeButtonEnabled = false; - + private bool $suspendTestButtonEnabled = false; private bool $questionTreeVisible = false; - - /** - * @var bool - */ - private $questionSelectionButtonEnabled = false; - - /** - * @var bool - */ - private $finishTestButtonEnabled = false; - - /** - * @var string - */ - private $finishTestCommand = ''; - - /** - * @var bool - */ - private $finishTestButtonPrimary = false; - - /** - * @var bool - */ - private $disabledStateEnabled = false; + private bool $questionSelectionButtonEnabled = false; + private bool $finishTestButtonEnabled = false; + private string $finishTestCommand = ''; + private bool $finishTestButtonPrimary = false; + private bool $disabledStateEnabled = false; private bool $user_has_attempts_left = true; protected ?Interruptive $finish_test_modal = null; + protected bool $user_pass_overview_button_enabled = false; - /** - * @param ilCtrl $ctrl - * @param ilLanguage $lng - * @param ilTestPlayerAbstractGUI $playerGUI - */ - public function __construct(ilCtrl $ctrl, ilLanguage $lng, ilTestPlayerAbstractGUI $playerGUI) - { - $this->ctrl = $ctrl; - $this->lng = $lng; - $this->playerGUI = $playerGUI; - + public function __construct( + protected ilCtrl $ctrl, + protected ilTestPlayerAbstractGUI $playerGUI + ) { parent::__construct(); } @@ -125,33 +75,17 @@ public function setSuspendTestButtonEnabled($suspendTestButtonEnabled) /** * @return boolean */ - public function isQuestionListButtonEnabled(): bool + public function isUserPassOverviewEnabled(): bool { - return $this->questionListButtonEnabled; + return $this->user_pass_overview_button_enabled; } /** * @param boolean $questionListButtonEnabled */ - public function setQuestionListButtonEnabled($questionListButtonEnabled) - { - $this->questionListButtonEnabled = $questionListButtonEnabled; - } - - /** - * @return boolean - */ - public function isQuestionTreeButtonEnabled(): bool - { - return $this->questionTreeButtonEnabled; - } - - /** - * @param boolean $questionTreeButtonEnabled - */ - public function setQuestionTreeButtonEnabled($questionTreeButtonEnabled) + public function setUserPassOverviewEnabled(bool $user_pass_overview_button_enabled) { - $this->questionTreeButtonEnabled = $questionTreeButtonEnabled; + $this->user_pass_overview_button_enabled = $user_pass_overview_button_enabled; } /** @@ -249,12 +183,8 @@ public function setDisabledStateEnabled($disabledStateEnabled) public function build() { - if ($this->isQuestionTreeButtonEnabled()) { - $this->addQuestionTreeButton(); - } - - if ($this->isQuestionListButtonEnabled()) { - $this->addQuestionListButton(); + if ($this->isUserPassOverviewEnabled()) { + $this->addPassOverviewButton(); } if ($this->isQuestionSelectionButtonEnabled()) { @@ -287,7 +217,7 @@ private function addSuspendTestButton() $this->addComponent($button); } - private function addQuestionListButton() + private function addPassOverviewButton() { $button = $this->ui->factory()->button()->standard( $this->lng->txt('question_summary_btn'), @@ -305,21 +235,6 @@ private function addQuestionSelectionButton() $this->addComponent($button); } - private function addQuestionTreeButton() - { - if ($this->isQuestionTreeVisible()) { - $btn_cap = $this->lng->txt('tst_hide_side_list'); - } else { - $btn_cap = $this->lng->txt('tst_show_side_list'); - } - - $button = $this->ui->factory()->button()->standard( - $btn_cap, - $this->ctrl->getLinkTarget($this->playerGUI, ilTestPlayerCommands::TOGGLE_SIDE_LIST) - ); - $this->addComponent($button); - } - private function addFinishTestButton(): void { if ($this->userHasAttemptsLeft()) { diff --git a/Modules/Test/classes/class.ilTestOutputGUI.php b/Modules/Test/classes/class.ilTestOutputGUI.php index 7eedd80e3e87..49ba06b4e3e8 100755 --- a/Modules/Test/classes/class.ilTestOutputGUI.php +++ b/Modules/Test/classes/class.ilTestOutputGUI.php @@ -55,23 +55,6 @@ public function executeCommand() $this->initAssessmentSettings(); - $this->global_screen->tool()->context()->current()->addAdditionalData( - ilTestPlayerLayoutProvider::TEST_PLAYER_KIOSK_MODE_ENABLED, - $this->object->getKioskMode() - ); - $this->global_screen->tool()->context()->current()->addAdditionalData( - ilTestPlayerLayoutProvider::TEST_PLAYER_TITLE, - $this->object->getTitle() - ); - $instance_name = $this->settings->get('short_inst_name') ?? ''; - if (trim($instance_name) === '') { - $instance_name = 'ILIAS'; - } - $this->global_screen->tool()->context()->current()->addAdditionalData( - ilTestPlayerLayoutProvider::TEST_PLAYER_SHORT_TITLE, - $instance_name - ); - $testSessionFactory = new ilTestSessionFactory($this->object, $this->db, $this->user); $this->test_session = $testSessionFactory->getSession($this->testrequest->int('active_id')); @@ -92,6 +75,29 @@ public function executeCommand() $this->handlePasswordProtectionRedirect(); + + $instance_name = $this->settings->get('short_inst_name') ?? ''; + if (trim($instance_name) === '') { + $instance_name = 'ILIAS'; + } + $this->global_screen->tool()->context()->current()->addAdditionalData( + ilTestPlayerLayoutProvider::TEST_PLAYER_SHORT_TITLE, + $instance_name + ); + $this->global_screen->tool()->context()->current()->addAdditionalData( + ilTestPlayerLayoutProvider::TEST_PLAYER_KIOSK_MODE_ENABLED, + $this->object->getKioskMode() + ); + $this->global_screen->tool()->context()->current()->addAdditionalData( + ilTestPlayerLayoutProvider::TEST_PLAYER_VIEW_TITLE, + $this->object->getTitle() + ); + $this->global_screen->tool()->context()->current()->addAdditionalData( + ilTestPlayerLayoutProvider::TEST_PLAYER_TITLE, + $this->getTestPlayerTitle() + ); + + $cmd = $this->getCommand($cmd); switch ($next_class) { @@ -948,4 +954,29 @@ protected function handlePrimaryButton(ilTestNavigationToolbarGUI $navigationToo return $isNextPrimary; } + + protected function getTestPlayerTitle(): string + { + $test_title = $this->object->getShowKioskModeTitle() ? $this->object->getTitle() : ''; + $user_name = $this->object->getShowKioskModeParticipant() ? $this->user->getFullname() : ''; + $exam_id = ''; + if ($this->object->isShowExamIdInTestPassEnabled()) { + $exam_id = $this->lng->txt("exam_id") + . ' ' + . ilObjTest::buildExamId( + $this->test_session->getActiveId(), + $this->test_session->getPass(), + $this->object->getId() + ); + } + + $layout = $this->ui_factory->layout()->alignment()->vertical( + $this->ui_factory->legacy($test_title), + $this->ui_factory->layout()->alignment()->horizontal()->dynamicallyDistributed( + $this->ui_factory->legacy($user_name), + $this->ui_factory->legacy($exam_id) + ) + ); + return $this->ui_renderer->render($layout); + } } diff --git a/Modules/Test/classes/class.ilTestPasswordChecker.php b/Modules/Test/classes/class.ilTestPasswordChecker.php index 82a1e7f56269..0eb9d772b1a1 100644 --- a/Modules/Test/classes/class.ilTestPasswordChecker.php +++ b/Modules/Test/classes/class.ilTestPasswordChecker.php @@ -56,19 +56,11 @@ public function __construct(ilRbacSystem $rbacsystem, ilObjUser $user, ilObjTest public function isPasswordProtectionPageRedirectRequired(): bool { - if (!$this->isTestPasswordEnabled()) { - return false; - } - - if ($this->isPrivilegedParticipant()) { - return false; - } - - if ($this->isUserEnteredPasswordCorrect()) { - return false; - } - - return true; + return ( + $this->isTestPasswordEnabled() + && !$this->isPrivilegedParticipant() + && !$this->isUserEnteredPasswordCorrect() + ); } protected function isTestPasswordEnabled(): bool diff --git a/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php b/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php index 3e44a4c5c161..b8f97de33f0f 100755 --- a/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php +++ b/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php @@ -44,6 +44,7 @@ abstract class ilTestPlayerAbstractGUI extends ilTestServiceGUI public bool $maxProcessingTimeReached; public bool $endingTimeReached; + public int $ref_id; protected ilTestPasswordChecker $passwordChecker; protected ilTestProcessLocker $processLocker; @@ -612,13 +613,6 @@ protected function submitIntermediateSolutionCmd() $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION); } - public function toggleSideListCmd(): void - { - $show_side_list = $this->user->getPref('side_list_of_questions'); - $this->user->writePref('side_list_of_questions', (string) !$show_side_list); - $this->ctrl->redirect($this, ilTestPlayerCommands::SHOW_QUESTION); - } - protected function markQuestionAndSaveIntermediateCmd(): void { $this->handleIntermediateSubmit(); @@ -812,45 +806,6 @@ public function showFinalStatementCmd() $this->tpl->setVariable($this->getContentBlockName(), $template->get()); } - public function getKioskHead(): string - { - /** - * this is an abomination for release_8 + release_9! - * @todo Implement proper "kiosk-handling" for ILIAS 10. - */ - $this->tpl->addCSS('Modules/Test/templates/default/test_kiosk_header.css'); - //end of hack - - $template = new ilTemplate('tpl.il_as_tst_kiosk_head.html', true, true, 'Modules/Test'); - if ($this->object->getShowKioskModeTitle()) { - $template->setCurrentBlock("kiosk_show_title"); - $template->setVariable("TEST_TITLE", $this->object->getTitle()); - $template->parseCurrentBlock(); - } - if ($this->object->getShowKioskModeParticipant()) { - $template->setCurrentBlock("kiosk_show_participant"); - $template->setVariable("PARTICIPANT_NAME_TXT", $this->lng->txt("login_as")); - $template->setVariable("PARTICIPANT_NAME", $this->user->getFullname()); - $template->setVariable("PARTICIPANT_LOGIN", $this->user->getLogin()); - $template->setVariable("PARTICIPANT_MATRICULATION", $this->user->getMatriculation()); - $template->setVariable("PARTICIPANT_EMAIL", $this->user->getEmail()); - $template->parseCurrentBlock(); - } - if ($this->object->isShowExamIdInTestPassEnabled()) { - $exam_id = ilObjTest::buildExamId( - $this->test_session->getActiveId(), - $this->test_session->getPass(), - $this->object->getId() - ); - - $template->setCurrentBlock("kiosk_show_exam_id"); - $template->setVariable("EXAM_ID_TXT", $this->lng->txt("exam_id")); - $template->setVariable("EXAM_ID", $exam_id); - $template->parseCurrentBlock(); - } - return $template->get(); - } - protected function prepareTestPage($presentationMode, $sequenceElement, $questionId) { $this->navigation_history->addItem( @@ -879,12 +834,9 @@ protected function prepareTestPage($presentationMode, $sequenceElement, $questio return; } - if ($this->object->getKioskMode()) { - $this->populateKioskHead(); - } - $this->tpl->setVariable("TEST_ID", (string) $this->object->getTestId()); $this->tpl->setVariable("LOGIN", $this->user->getLogin()); + $this->tpl->setVariable("SEQ_ID", $sequenceElement); $this->tpl->setVariable("QUEST_ID", $questionId); @@ -1282,21 +1234,48 @@ public function checkWorkingTimeCmd(): void protected function showSideList($current_sequence_element): void { - $side_list_active = $this->user->getPref('side_list_of_questions'); + $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence, false); + $questions = []; + $active = 0; - if (!$side_list_active) { - return; + foreach ($questionSummaryData as $idx => $row) { + $title = ilLegacyFormElementsUtil::prepareFormOutput($row['title']); + if (strlen($row['description'])) { + $description = " title=\"" . htmlspecialchars($row['description']) . "\" "; + } else { + $description = ""; + } + + if (!$row['disabled']) { + $this->ctrl->setParameter($this, 'pmode', ''); + $this->ctrl->setParameter($this, 'sequence', $row['sequence']); + $action = $this->ctrl->getLinkTarget($this, ilTestPlayerCommands::SHOW_QUESTION); + $this->ctrl->setParameter($this, 'pmode', ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW); + $this->ctrl->setParameter($this, 'sequence', $this->getCurrentSequenceElement($current_sequence_element)); + } + + $status = ILIAS\UI\Component\Listing\Workflow\Step::NOT_STARTED; + + if ($row['worked_through'] || $row['isAnswered']) { + $status = ILIAS\UI\Component\Listing\Workflow\Step::IN_PROGRESS; + } + + $questions[] = $this->ui_factory->listing()->workflow() + ->step($title, $description, $action) + ->withStatus($status); + $active = $row['sequence'] == $current_sequence_element ? $idx : $active; } - $question_summary_data = $this->service->getQuestionSummaryData($this->testSequence, false); + $question_listing = $this->ui_factory->listing()->workflow()->linear( + $this->lng->txt('mainbar_button_label_questionlist'), + $questions + )->withActive($active); + - $question_side_list_gui = new ilTestQuestionSideListGUI($this->ctrl, $this->lng); - $question_side_list_gui->setTargetGUI($this); - $question_side_list_gui->setQuestionSummaryData($question_summary_data); - $question_side_list_gui->setCurrentSequenceElement($current_sequence_element); - $question_side_list_gui->setCurrentPresentationMode(ilTestPlayerAbstractGUI::PRESENTATION_MODE_VIEW); - $question_side_list_gui->setDisabled(false); - $this->tpl->setVariable('LIST_OF_QUESTIONS', $question_side_list_gui->getHTML()); + $this->global_screen->tool()->context()->current()->addAdditionalData( + ilTestPlayerLayoutProvider::TEST_PLAYER_QUESTIONLIST, + $question_listing + ); } abstract protected function isQuestionSummaryFinishTestButtonRequired(); @@ -1327,16 +1306,6 @@ public function outQuestionSummaryCmd( $this->tpl->setOnScreenMessage('failure', $this->lng->txt('not_all_obligations_answered')); } - if ($this->object->getKioskMode() && $fullpage) { - $head = $this->getKioskHead(); - if (strlen($head)) { - $this->tpl->setCurrentBlock("kiosk_options"); - $this->tpl->setVariable("KIOSK_HEAD", $head); - $this->tpl->parseCurrentBlock(); - } - } - - $active_id = $this->test_session->getActiveId(); $questionSummaryData = $this->service->getQuestionSummaryData($this->testSequence, $obligationsFilter); @@ -1583,10 +1552,6 @@ protected function prepareSummaryPage() 'tpl.il_as_tst_question_summary.html', 'Modules/Test' ); - - if ($this->object->getKioskMode()) { - $this->populateKioskHead(); - } } protected function initTestPageTemplate() @@ -1617,17 +1582,6 @@ protected function initTestPageTemplate() ); } - protected function populateKioskHead() - { - $head = $this->getKioskHead(); - - if (strlen($head)) { - $this->tpl->setCurrentBlock("kiosk_options"); - $this->tpl->setVariable("KIOSK_HEAD", $head); - $this->tpl->parseCurrentBlock(); - } - } - protected function handlePasswordProtectionRedirect() { /** @@ -1769,20 +1723,20 @@ protected function populateHelperGuiContent($helperGui) protected function getTestNavigationToolbarGUI(): ilTestNavigationToolbarGUI { - $navigation_toolbar = new ilTestNavigationToolbarGUI($this->ctrl, $this->lng, $this); - + $navigation_toolbar = new ilTestNavigationToolbarGUI($this->ctrl, $this); $navigation_toolbar->setSuspendTestButtonEnabled($this->object->getShowCancel()); - $navigation_toolbar->setQuestionTreeButtonEnabled($this->object->getListOfQuestions()); - $navigation_toolbar->setQuestionTreeVisible((bool) $this->user->getPref('side_list_of_questions')); - $navigation_toolbar->setQuestionListButtonEnabled($this->object->getListOfQuestions()); + $navigation_toolbar->setUserPassOverviewEnabled($this->object->getUsrPassOverviewEnabled()); $navigation_toolbar->setFinishTestCommand($this->getFinishTestCommand()); - return $navigation_toolbar; } protected function buildReadOnlyStateQuestionNavigationGUI($questionId): ilTestQuestionNavigationGUI { - $navigationGUI = new ilTestQuestionNavigationGUI($this->lng); + $navigationGUI = new ilTestQuestionNavigationGUI( + $this->lng, + $this->ui_factory, + $this->ui_renderer + ); if (!$this->isParticipantsAnswerFixed($questionId)) { $navigationGUI->setEditSolutionCommand(ilTestPlayerCommands::EDIT_SOLUTION); @@ -1812,7 +1766,11 @@ protected function buildReadOnlyStateQuestionNavigationGUI($questionId): ilTestQ protected function buildEditableStateQuestionNavigationGUI($questionId): ilTestQuestionNavigationGUI { - $navigationGUI = new ilTestQuestionNavigationGUI($this->lng); + $navigationGUI = new ilTestQuestionNavigationGUI( + $this->lng, + $this->ui_factory, + $this->ui_renderer + ); if ($this->object->isForceInstantFeedbackEnabled()) { $navigationGUI->setSubmitSolutionCommand(ilTestPlayerCommands::SUBMIT_SOLUTION); @@ -2210,7 +2168,7 @@ protected function getQuestionGuiInstance($question_id, $fromCache = true): obje $question_gui->setPresentationContext(assQuestionGUI::PRESENTATION_CONTEXT_TEST); $question_gui->object->setObligationsToBeConsidered($this->object->areObligationsEnabled()); $question_gui->populateJavascriptFilesRequiredForWorkForm($tpl); - $question_gui->object->setShuffler($this->buildQuestionAnswerShuffler( + $question_gui->object->setShuffler($this->shuffler->getAnswerShuffleFor( $question_id, $this->test_session->getActiveId(), $this->test_session->getPass() @@ -2233,9 +2191,7 @@ protected function getQuestionInstance(int $question_id, bool $from_cache = true if ($from_cache && isset($this->cachedQuestionObjects[$question_id])) { return $this->cachedQuestionObjects[$question_id]; } - $question = assQuestion::instantiateQuestion($question_id); - $ass_settings = new ilSetting('assessment'); $process_locker_factory = new ilAssQuestionProcessLockerFactory($ass_settings, $this->db); @@ -2308,12 +2264,28 @@ protected function populateDiscardSolutionModal() $tpl->setVariable('CONFIRMATION_TEXT', $this->lng->txt('discard_answer_confirmation')); - $button = $this->ui_factory->button()->standard($this->lng->txt('discard_answer'), '#'); + $button = $this->ui_factory->button()->standard($this->lng->txt('discard_answer'), '#') + ->withAdditionalOnLoadCode( + fn($id) => "document.getElementById('$id').addEventListener( + 'click', + (event)=>{ + event.target.name = 'cmd[discardSolution]'; + event.target.form.requestSubmit(event.target); + } + )" + ); + $tpl->setCurrentBlock('buttons'); $tpl->setVariable('BUTTON', $this->ui_renderer->render($button)); $tpl->parseCurrentBlock(); - $button = $this->ui_factory->button()->primary($this->lng->txt('cancel'), '#'); + $button = $this->ui_factory->button()->primary($this->lng->txt('cancel'), '#') + ->withAdditionalOnLoadCode( + fn($id) => "document.getElementById('$id').addEventListener( + 'click', + ()=>$('#tst_discard_solution_modal').modal('hide') + );" + ); $tpl->setCurrentBlock('buttons'); $tpl->setVariable('BUTTON', $this->ui_renderer->render($button)); $tpl->parseCurrentBlock(); diff --git a/Modules/Test/classes/class.ilTestQuestionNavigationGUI.php b/Modules/Test/classes/class.ilTestQuestionNavigationGUI.php index 34b7b25b8911..ff560c47625e 100644 --- a/Modules/Test/classes/class.ilTestQuestionNavigationGUI.php +++ b/Modules/Test/classes/class.ilTestQuestionNavigationGUI.php @@ -18,6 +18,8 @@ declare(strict_types=1); +use ILIAS\UI\Factory as UIFactory; +use ILIAS\UI\Renderer as UIRenderer; use ILIAS\UI\Component\Button\Button; /** @@ -33,11 +35,6 @@ class ilTestQuestionNavigationGUI public const CSS_CLASS_SUBMIT_BUTTONS = 'ilc_qsubmit_Submit'; private \ILIAS\DI\UIServices $ui; - /** - * @var ilLanguage - */ - protected $lng; - /** * @var string */ @@ -120,11 +117,13 @@ class ilTestQuestionNavigationGUI /** * @param ilLanguage $lng */ - public function __construct(ilLanguage $lng) - { - $this->lng = $lng; - global $DIC; - $this->ui = $DIC->ui(); + + + public function __construct( + protected ilLanguage $lng, + protected UIFactory $ui_factory, + protected UIRenderer $ui_renderer + ) { } /** @@ -371,110 +370,57 @@ public function setAnythingRendered() $this->anythingRendered = true; } - // fau: testNav - generate question actions menu - /** - * Get the HTML of an actions menu below the title - * @return string - */ public function getActionsHTML(): string { $tpl = $this->getTemplate('actions'); - - $actions = new ilGroupedListGUI(); - $actions->setAsDropDown(true, true); + $actions = []; if ($this->getQuestionMarkLinkTarget()) { - $actions->addEntry( - $this->getQuestionMarkActionLabel(), - $this->getQuestionMarkLinkTarget(), - '', - '', - 'ilTestQuestionAction', - 'tst_mark_question_action' - ); - $actions->addSeparator(); - } - - if ($this->getRevertChangesLinkTarget()) { - $actions->addEntry( - $this->lng->txt('tst_revert_changes'), - $this->getRevertChangesLinkTarget(), - '', - '', - 'ilTestQuestionAction ilTestRevertChangesAction', - 'tst_revert_changes_action' - ); - } else { - $actions->addEntry( - $this->lng->txt('tst_revert_changes'), - '#', - '', - '', - 'ilTestQuestionAction ilTestRevertChangesAction disabled', - 'tst_revert_changes_action' - ); - } - - if ($this->isDiscardSolutionButtonEnabled()) { - $actions->addEntry( - $this->lng->txt('discard_answer'), - '#', - '', - '', - 'ilTestQuestionAction ilTestDiscardSolutionAction', - 'tst_discard_solution_action' + $this->renderActionsIcon( + $tpl, + $this->getQuestionMarkIconSource(), + $this->getQuestionMarkIconLabel(), + 'ilTestMarkQuestionIcon' ); - } else { - $actions->addEntry( - $this->lng->txt('discard_answer'), - '#', - '', - '', - 'ilTestQuestionAction ilTestDiscardSolutionAction disabled', - 'tst_discard_solution_action' + $actions[] = $this->ui_factory->button()->shy( + $this->getQuestionMarkActionLabel(), + $this->getQuestionMarkLinkTarget() ); } if ($this->getSkipQuestionLinkTarget()) { - $actions->addEntry( - $this->lng->txt('postpone_question'), - $this->getSkipQuestionLinkTarget(), - '', - '', - 'ilTestQuestionAction', - 'tst_skip_question_action' - ); - } elseif (self::SHOW_DISABLED_COMMANDS) { - $actions->addEntry( + $actions[] = $this->ui_factory->button()->shy( $this->lng->txt('postpone_question'), - '#', - '', - '', - 'ilTestQuestionAction disabled', - 'tst_skip_question_action' + $this->getSkipQuestionLinkTarget() ); } - if ($this->getQuestionMarkLinkTarget()) { - $this->renderActionsIcon( - $tpl, - $this->getQuestionMarkIconSource(), - $this->getQuestionMarkIconLabel(), - 'ilTestMarkQuestionIcon' - ); + if ($actions !== []) { + $actions[] = $this->ui_factory->divider()->horizontal(); } - $list = new ilAdvancedSelectionListGUI(); - $list->setSelectionHeaderClass('btn-primary'); - $list->setId('QuestionActions'); - $list->setListTitle($this->lng->txt("actions")); - $list->setStyle(1); - $list->setGroupedList($actions); - $tpl->setVariable('ACTION_MENU', $list->getHTML()); + $actions[] = $this->ui_factory->button()->shy( + $this->lng->txt('tst_revert_changes'), + $this->getRevertChangesLinkTarget() + )->withUnavailableAction(!$this->getRevertChangesLinkTarget()); + + $actions[] = $this->ui_factory->button()->shy( + $this->lng->txt('discard_answer'), + '#' + ) + ->withUnavailableAction(!$this->isDiscardSolutionButtonEnabled()) + ->withAdditionalOnLoadCode( + fn($id) => "document.getElementById('$id').addEventListener( + 'click', + ()=>$('#tst_discard_solution_modal').modal('show') + )" + ); + + $list = $this->ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt("actions")); + $tpl->setVariable('ACTION_MENU', $this->ui_renderer->render($list)); return $tpl->get(); } - // fau. /** @@ -498,7 +444,7 @@ public function getHTML(): string // fau: testNav - skip question (postpone) is moved to the actions menu. if ($this->getInstantFeedbackCommand()) { - $this->renderSubmitButton( + $this->renderInstantFeedbackButton( $tpl, $this->getInstantFeedbackCommand(), $this->getCheckButtonLabel(), @@ -642,7 +588,7 @@ private function parseButtonsBlock(ilTemplate $tpl) private function renderButtonInstance(ilTemplate $tpl, Button $button) { $tpl->setCurrentBlock("button_instance"); - $tpl->setVariable("BUTTON_INSTANCE", $this->ui->renderer()->render($button)); + $tpl->setVariable("BUTTON_INSTANCE", $this->ui_renderer->render($button)); $tpl->parseCurrentBlock(); $this->parseButtonsBlock($tpl); @@ -655,19 +601,47 @@ private function renderButtonInstance(ilTemplate $tpl, Button $button) * @param $label * @param bool|false $primary */ - private function renderSubmitButton(ilTemplate $tpl, $command, $label, $primary = false) - { - if ($primary) { - $this->renderButtonInstance( - $tpl, - $this->ui->factory()->button()->primary($label, $command) - ); - } else { + private function renderSubmitButton( + ilTemplate $tpl, + string $command, + string $label + ): void { + $this->renderButtonInstance( + $tpl, + $this->ui_factory->button()->standard($label, $command) + ); + } + + private function renderInstantFeedbackButton( + ilTemplate $tpl, + string $command, + string $label, + bool $is_primary + ): void { + $on_load_code = $this->getOnLoadCode($command); + if ($is_primary) { $this->renderButtonInstance( $tpl, - $this->ui->factory()->button()->standard($label, $command) + $this->ui_factory->button()->primary($label, '')->withAdditionalOnLoadCode($on_load_code) ); + return; } + + $this->renderButtonInstance( + $tpl, + $this->ui_factory->button()->standard($label, '')->withAdditionalOnLoadCode($on_load_code) + ); + } + + private function getOnLoadCode(string $command): Closure + { + return static function ($id) use ($command): string { + return "document.getElementById('$id').addEventListener('click', " + . '(e) => {' + . " e.target.setAttribute('name', 'cmd[$command]');" + . ' e.target.form.requestSubmit(e.target);' + . '});'; + }; } /** diff --git a/Modules/Test/classes/class.ilTestQuestionSideListGUI.php b/Modules/Test/classes/class.ilTestQuestionSideListGUI.php deleted file mode 100644 index 74273e2f24ff..000000000000 --- a/Modules/Test/classes/class.ilTestQuestionSideListGUI.php +++ /dev/null @@ -1,271 +0,0 @@ - - * @version $Id$ - * - * @package Modules/Test - */ -class ilTestQuestionSideListGUI -{ - /** - * @var ilCtrl - */ - protected $ctrl; - - /** - * @var ilLanguage - */ - protected $lng; - - /** - * @var ilTestPlayerAbstractGUI - */ - private $targetGUI; - - /** - * @var array - */ - private $questionSummaryData; - - /** - * @var integer - */ - private $currentSequenceElement; - - /** - * @var string - */ - private $currentPresentationMode; - - /** - * @var bool - */ - private $disabled; - - /** - * @param ilCtrl $ctrl - * @param ilLanguage $lng - */ - public function __construct(ilCtrl $ctrl, ilLanguage $lng) - { - $this->ctrl = $ctrl; - $this->lng = $lng; - - $this->questionSummaryData = array(); - $this->currentSequenceElement = null; - $this->disabled = false; - } - - /** - * @return ilTestPlayerAbstractGUI - */ - public function getTargetGUI(): ilTestPlayerAbstractGUI - { - return $this->targetGUI; - } - - /** - * @param ilTestPlayerAbstractGUI $targetGUI - */ - public function setTargetGUI($targetGUI) - { - $this->targetGUI = $targetGUI; - } - - /** - * @return array - */ - public function getQuestionSummaryData(): array - { - return $this->questionSummaryData; - } - - /** - * @param array $questionSummaryData - */ - public function setQuestionSummaryData($questionSummaryData) - { - $this->questionSummaryData = $questionSummaryData; - } - - /** - * @return int - */ - public function getCurrentSequenceElement(): ?int - { - return $this->currentSequenceElement; - } - - /** - * @param int $currentSequenceElement - */ - public function setCurrentSequenceElement($currentSequenceElement) - { - $this->currentSequenceElement = $currentSequenceElement; - } - - /** - * @return string - */ - public function getCurrentPresentationMode(): string - { - return $this->currentPresentationMode; - } - - /** - * @param string $currentPresentationMode - */ - public function setCurrentPresentationMode($currentPresentationMode) - { - $this->currentPresentationMode = $currentPresentationMode; - } - - /** - * @return boolean - */ - public function isDisabled(): bool - { - return $this->disabled; - } - - /** - * @param boolean $disabled - */ - public function setDisabled($disabled) - { - $this->disabled = $disabled; - } - - /** - * @return ilPanelGUI - */ - private function buildPanel(): ilPanelGUI - { - $panel = ilPanelGUI::getInstance(); - $panel->setHeadingStyle(ilPanelGUI::HEADING_STYLE_SUBHEADING); - $panel->setPanelStyle(ilPanelGUI::PANEL_STYLE_SECONDARY); - $panel->setHeading($this->lng->txt('list_of_questions')); - return $panel; - } - - /** - * @return string - */ - private function renderList(): string - { - $tpl = new ilTemplate('tpl.il_as_tst_list_of_questions_short.html', true, true, 'Modules/Test'); - - foreach ($this->getQuestionSummaryData() as $row) { - $title = ilLegacyFormElementsUtil::prepareFormOutput($row['title']); - - if (strlen($row['description'])) { - $description = " title=\"" . htmlspecialchars($row['description']) . "\" "; - } else { - $description = ""; - } - - $active = ($row['sequence'] == $this->getCurrentSequenceElement()) ? ' active' : ''; - - $class = ( - $row['worked_through'] ? 'answered' . $active : 'unanswered' . $active - ); - - $headerclass = ($row['sequence'] == $this->getCurrentSequenceElement()) ? 'bold' : ''; - - if ($row['marked']) { - $tpl->setCurrentBlock("mark_icon"); - $tpl->setVariable("ICON_SRC", ilUtil::getImagePath('object/marked.svg')); - $tpl->setVariable("ICON_TEXT", $this->lng->txt('tst_question_marked')); - $tpl->setVariable("ICON_CLASS", 'ilTestMarkQuestionIcon'); - $tpl->parseCurrentBlock(); - } - - if ($this->isDisabled() || $row['disabled']) { - $tpl->setCurrentBlock('disabled_entry'); - $tpl->setVariable('CLASS', $class); - $tpl->setVariable('HEADERCLASS', $headerclass); - $tpl->setVariable('ITEM', $title); - $tpl->setVariable('DESCRIPTION', $description); - $tpl->parseCurrentBlock(); - } else { - // fau: testNav - show mark icon in side list - // fau. - $tpl->setCurrentBlock('linked_entry'); - $tpl->setVariable('HREF', $this->buildLink($row['sequence'])); - $tpl->setVariable('NEXTCMD', ilTestPlayerCommands::SHOW_QUESTION); - $tpl->setVariable('NEXTSEQ', $row['sequence']); - $tpl->setVariable('HEADERCLASS', $headerclass); - $tpl->setVariable('CLASS', $class); - $tpl->setVariable('ITEM', $title); - $tpl->setVariable("DESCRIPTION", $description); - $tpl->parseCurrentBlock(); - } - - $tpl->setCurrentBlock('item'); - } - - return $tpl->get(); - } - - /** - * @return string - */ - public function getHTML(): string - { - $panel = $this->buildPanel(); - $panel->setBody($this->renderList()); - return $panel->getHTML(); - } - - /** - * @param $row - * @return string - */ - private function buildLink($sequenceElement): string - { - $this->ctrl->setParameter( - $this->getTargetGUI(), - 'pmode', - '' - ); - - $this->ctrl->setParameter( - $this->getTargetGUI(), - 'sequence', - $sequenceElement - ); - - $href = $this->ctrl->getLinkTarget($this->getTargetGUI(), ilTestPlayerCommands::SHOW_QUESTION); - - $this->ctrl->setParameter( - $this->getTargetGUI(), - 'pmode', - $this->getCurrentPresentationMode() - ); - $this->ctrl->setParameter( - $this->getTargetGUI(), - 'sequence', - $this->getCurrentSequenceElement() - ); - return $href; - } -} diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php index 0d6fbbd7db51..71ea800bb033 100644 --- a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php +++ b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php @@ -752,20 +752,20 @@ private function getSourcePoolDefinitionByAvailableQuestionPoolId($poolId): ilTe */ protected function fetchPoolIdsParameter(): array { - $poolIds = []; + $pool_ids = []; if ($this->testrequest->isset('derive_pool_ids') && is_array($this->testrequest->raw('derive_pool_ids'))) { - $poolIds = []; + $pool_ids = []; - foreach ($this->testrequest->raw('derive_pool_ids') as $poolId) { - $poolIds[] = (int) $poolId; + foreach ($this->testrequest->raw('derive_pool_ids') as $pool_id) { + $pool_ids[] = (int) $pool_id; } } elseif ($this->testrequest->isset('derive_pool_ids') && preg_match('/^\d+(\:\d+)*$/', $this->testrequest->raw('derive_pool_ids'))) { - $poolIds = explode(':', $this->testrequest->raw('derive_pool_ids')); + $pool_ids = explode(':', $this->testrequest->raw('derive_pool_ids')); } elseif ($this->testrequest->isset('derive_pool_id') && (int) $this->testrequest->raw('derive_pool_id')) { - $poolIds = [(int) $this->testrequest->raw('derive_pool_id')]; + $pool_ids = [(int) $this->testrequest->raw('derive_pool_id')]; } - return $poolIds; + return $pool_ids; } protected function fetchTargetRefParameter(): ?int @@ -799,29 +799,34 @@ private function selectPoolDerivationTargetCmd(): void private function deriveNewPoolsCmd(): void { - $poolIds = $this->fetchPoolIdsParameter(); - $targetRef = $this->fetchTargetRefParameter(); + $pool_ids = $this->fetchPoolIdsParameter(); + $target_ref = $this->fetchTargetRefParameter(); + if (!$this->access->checkAccess('write', '', $target_ref)) { + $this->tpl->setOnScreenMessage('failure', $this->lng->txt("no_permission"), true); + $this->ctrl->setParameterByClass(ilObjTestGUI::class, 'ref_id', $this->test_obj->getRefId()); + $this->ctrl->redirectByClass(ilObjTestGUI::class); + } - if (count($poolIds)) { - foreach ($poolIds as $poolId) { - $lostPool = $this->sourcePoolDefinitionList->getLostPool($poolId); + if ($pool_ids !== []) { + foreach ($pool_ids as $pool_id) { + $lost_pool = $this->sourcePoolDefinitionList->getLostPool($pool_id); $deriver = new ilTestRandomQuestionSetPoolDeriver($this->db, $this->component_repository, $this->test_obj); $deriver->setSourcePoolDefinitionList($this->sourcePoolDefinitionList); - $deriver->setTargetContainerRef($targetRef); + $deriver->setTargetContainerRef($target_ref); $deriver->setOwnerId($this->user->getId()); - $newPool = $deriver->derive($lostPool); + $new_pool = $deriver->derive($lost_pool); - $srcPoolDefinition = $this->sourcePoolDefinitionList->getDefinitionBySourcePoolId($newPool->getId()); - $srcPoolDefinition->setPoolTitle($newPool->getTitle()); - $srcPoolDefinition->setPoolPath($this->questionSetConfig->getQuestionPoolPathString($newPool->getId())); - $srcPoolDefinition->setPoolRefId($this->questionSetConfig->getFirstQuestionPoolRefIdByObjId($newPool->getId())); + $srcPoolDefinition = $this->sourcePoolDefinitionList->getDefinitionBySourcePoolId($new_pool->getId()); + $srcPoolDefinition->setPoolTitle($new_pool->getTitle()); + $srcPoolDefinition->setPoolPath($this->questionSetConfig->getQuestionPoolPathString($new_pool->getId())); + $srcPoolDefinition->setPoolRefId($this->questionSetConfig->getFirstQuestionPoolRefIdByObjId($new_pool->getId())); $srcPoolDefinition->saveToDb(); ilTestRandomQuestionSetStagingPoolQuestionList::updateSourceQuestionPoolId( $this->test_obj->getTestId(), - $lostPool->getId(), - $newPool->getId() + $lost_pool->getId(), + $new_pool->getId() ); } diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php index ee38fc4d1dda..aae7d17819ee 100644 --- a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php +++ b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php @@ -451,16 +451,10 @@ private function updateDbRecord($testId) 'pool_title' => array('text', $this->getPoolTitle()), 'pool_path' => array('text', $this->getPoolPath()), 'pool_quest_count' => array('integer', $this->getPoolQuestionCount()), - // fau: taxFilter/typeFilter - use new db fields - #'origin_tax_fi' => array('integer', $this->getOriginalFilterTaxId()), - #'origin_node_fi' => array('integer', $this->getOriginalFilterTaxNodeId()), - #'mapped_tax_fi' => array('integer', $this->getMappedFilterTaxId()), - #'mapped_node_fi' => array('integer', $this->getMappedFilterTaxNodeId()), 'origin_tax_filter' => array('text', $this->getOriginalTaxonomyFilterForDbValue()), 'mapped_tax_filter' => array('text', $this->getMappedTaxonomyFilterForDbValue()), 'type_filter' => array('text', $this->getTypeFilterForDbValue()), 'lifecycle_filter' => array('text', $this->getLifecycleFilterForDbValue()), - // fau. 'quest_amount' => array('integer', $this->getQuestionAmount()), 'sequence_pos' => array('integer', $this->getSequencePosition()) ], @@ -485,16 +479,10 @@ private function insertDbRecord(int $test_id): void 'pool_title' => array('text', $this->getPoolTitle()), 'pool_path' => array('text', $this->getPoolPath()), 'pool_quest_count' => array('integer', $this->getPoolQuestionCount()), - // fau: taxFilter/typeFilter - use new db fields - #'origin_tax_fi' => array('integer', $this->getOriginalFilterTaxId()), - #'origin_node_fi' => array('integer', $this->getOriginalFilterTaxNodeId()), - #'mapped_tax_fi' => array('integer', $this->getMappedFilterTaxId()), - #'mapped_node_fi' => array('integer', $this->getMappedFilterTaxNodeId()), 'origin_tax_filter' => array('text', $this->getOriginalTaxonomyFilterForDbValue()), 'mapped_tax_filter' => array('text', $this->getMappedTaxonomyFilterForDbValue()), 'type_filter' => array('text', $this->getTypeFilterForDbValue()), 'lifecycle_filter' => array('text', $this->getLifecycleFilterForDbValue()), - // fau. 'quest_amount' => array('integer', $this->getQuestionAmount()), 'sequence_pos' => array('integer', $this->getSequencePosition()) ]); diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php index c63f78671044..73cbc59a5b5b 100644 --- a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php +++ b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionList.php @@ -176,24 +176,24 @@ public function loadDefinitions() $trashedPools[$trashedPool->getId()] = $trashedPool; } - if (!$this->isLostPool($row['pool_id'])) { - if (!$row['pool_id']) { - $lostPool = new ilTestRandomQuestionSetNonAvailablePool(); - $lostPool->assignDbRow($row); + if (!$this->isLostPool($row['pool_id']) + && !$row['pool_id']) { + $lostPool = new ilTestRandomQuestionSetNonAvailablePool(); + $lostPool->assignDbRow($row); - $lostPool->setUnavailabilityStatus( - ilTestRandomQuestionSetNonAvailablePool::UNAVAILABILITY_STATUS_LOST - ); + $lostPool->setUnavailabilityStatus( + ilTestRandomQuestionSetNonAvailablePool::UNAVAILABILITY_STATUS_LOST + ); - $this->addLostPool($lostPool); + $this->addLostPool($lostPool); - if (isset($trashedPools[$lostPool->getId()])) { - unset($trashedPools[$lostPool->getId()]); - } + if (isset($trashedPools[$lostPool->getId()])) { + unset($trashedPools[$lostPool->getId()]); } } - if ($sourcePoolDefinition->getPoolTitle() !== $row['actual_pool_title']) { + if (isset($row['actual_pool_title']) + && $sourcePoolDefinition->getPoolTitle() !== $row['actual_pool_title']) { $sourcePoolDefinition->setPoolTitle($row['actual_pool_title']); $sourcePoolDefinition->saveToDb(); } diff --git a/Modules/Test/classes/class.ilTestServiceGUI.php b/Modules/Test/classes/class.ilTestServiceGUI.php index bbe7f8f4616f..3dc21286e285 100755 --- a/Modules/Test/classes/class.ilTestServiceGUI.php +++ b/Modules/Test/classes/class.ilTestServiceGUI.php @@ -24,7 +24,6 @@ use ILIAS\GlobalScreen\Services as GlobalScreenServices; use ILIAS\Refinery\Factory as Refinery; use ILIAS\Refinery\Transformation; -use ILIAS\Refinery\Random\Seed\GivenSeed; use ILIAS\Test\InternalRequestService; use ILIAS\HTTP\Wrapper\ArrayBasedRequestWrapper; use ILIAS\DI\LoggingServices; @@ -78,6 +77,9 @@ class ilTestServiceGUI protected UIFactory $ui_factory; protected UIRenderer $ui_renderer; protected SkillService $skills_service; + protected ilTestShuffler $shuffler; + protected ilTestResultsFactory $results_factory; + protected ilTestResultsPresentationFactory $results_presentation_factory; protected ILIAS $ilias; protected ilSetting $settings; @@ -140,19 +142,26 @@ public function __construct( $this->rbac_system = $DIC['rbacsystem']; $this->obj_cache = $DIC['ilObjDataCache']; $this->skills_service = $DIC->skills(); - $this->participant_access_filter = new ilTestParticipantAccessFilterFactory($DIC['ilAccess']); $this->post_wrapper = $DIC->http()->wrapper()->post(); - $this->testrequest = $DIC->test()->internal()->request(); + $this->questioninfo = $DIC->testQuestionPool()->questionInfo(); $this->service = new ilTestService($this->object, $this->db, $this->questioninfo); - $this->lng->loadLanguageModule('cert'); + $this->lng->loadLanguageModule('cert'); $this->ref_id = $this->object->getRefId(); - $this->testrequest = $DIC->test()->internal()->request(); $this->testSessionFactory = new ilTestSessionFactory($this->object, $this->db, $this->user); $this->testSequenceFactory = new ilTestSequenceFactory($this->object, $this->db, $this->questioninfo); - $this->objective_oriented_container = null; + + $this->ui_factory = $DIC['ui.factory']; + $this->ui_renderer = $DIC['ui.renderer']; + + $local_dic = $object->getLocalDIC(); + $this->testrequest = $local_dic['request.internal']; + $this->participant_access_filter = $local_dic['participantAccessFilterFactory']; + $this->shuffler = $local_dic['shuffler']; + $this->results_factory = $local_dic['factory.results']; + $this->results_presentation_factory = $local_dic['factory.results_presentation']; } public function setParticipantData(ilTestParticipantData $participantData): void @@ -358,7 +367,8 @@ public function getPassListOfAnswers( && is_numeric($question_id)) { $maintemplate->setCurrentBlock("printview_question"); $question_gui = $this->object->createQuestionGUI("", $question_id); - $question_gui->object->setShuffler($this->buildQuestionAnswerShuffler( + + $question_gui->object->setShuffler($this->shuffler->getAnswerShuffleFor( (int) $question_id, (int) $active_id, (int) $pass @@ -435,33 +445,6 @@ public function getPassListOfAnswers( return $maintemplate->get(); } - protected function buildQuestionAnswerShuffler( - int $question_id, - int $active_id, - int $pass_id - ): Transformation { - $fixedSeed = $this->buildFixedShufflerSeed($question_id, $pass_id, $active_id); - - return $this->refinery->random()->shuffleArray(new GivenSeed($fixedSeed)); - } - - protected function buildFixedShufflerSeed(int $question_id, int $pass_id, int $active_id): int - { - $seed = ($question_id + $pass_id) * $active_id; - - if (is_float($seed) && is_float($seed = $active_id + $pass_id)) { - $seed = $active_id; - } - - $div = ceil((10 ** (ilTestPlayerAbstractGUI::FIXED_SHUFFLER_SEED_MIN_LENGTH - 1)) / $seed); - - if ($div > 1) { - $seed = $seed * ($div + $seed % 10); - } - - return (int) $seed; - } - /** * Returns the list of answers of a users test pass and offers a scoring option * @@ -675,7 +658,11 @@ public function getAdditionalUsrDataHtmlAndPopulateWindowTitle($testSession, $ac $invited_user = array_pop($this->object->getInvitedUsers($user_id)); $title_client = ''; - if (isset($invited_user['clientip']) && $invited_user["clientip"] !== '') { + if (is_array($invited_user) + && array_key_exists('clientip', $invited_user) + && is_string($invited_user['clientip']) + && trim($invited_user['clientip']) !== '' + ) { $template->setCurrentBlock("client_ip"); $template->setVariable("TXT_CLIENT_IP", $this->lng->txt("client_ip")); $template->setVariable("VALUE_CLIENT_IP", $invited_user["clientip"]); diff --git a/Modules/Test/classes/class.ilTestShuffler.php b/Modules/Test/classes/class.ilTestShuffler.php new file mode 100644 index 000000000000..d0fef441d634 --- /dev/null +++ b/Modules/Test/classes/class.ilTestShuffler.php @@ -0,0 +1,60 @@ +buildFixedShufflerSeed($question_id, $pass_id, $active_id); + return $this->refinery->random()->shuffleArray(new GivenSeed($fixedSeed)); + } + + protected function buildFixedShufflerSeed(int $question_id, int $pass_id, int $active_id): int + { + $seed = ($question_id + $pass_id) * $active_id; + if (is_float($seed) && is_float($seed = $active_id + $pass_id)) { + $seed = $active_id; + } + + $div = ceil((10 ** (self::FIXED_SHUFFLER_SEED_MIN_LENGTH - 1)) / $seed); + if ($div > 1) { + $seed = $seed * ($div + $seed % 10); + } + return (int) $seed; + } +} diff --git a/Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php b/Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php index 275f828c46f8..a63f35c386d3 100644 --- a/Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php +++ b/Modules/Test/classes/tables/class.ilTestPassOverviewTableGUI.php @@ -18,13 +18,16 @@ declare(strict_types=1); +use ILIAS\UI\Factory as UIFactory; +use ILIAS\UI\Renderer as UIRenderer; + /** * Class ilTestPassOverviewTableGUI */ class ilTestPassOverviewTableGUI extends ilTable2GUI { - private \ILIAS\UI\Factory $ui_factory; - private \ILIAS\UI\Renderer $ui_renderer; + private UIFactory $ui_factory; + private UIRenderer $ui_renderer; protected bool $resultPresentationEnabled = false; protected bool $pdfPresentationEnabled = false; @@ -266,12 +269,12 @@ private function buildActionsHtml($actions, $pass): string } $this->ctrl->setParameter($this->parent_obj, 'pass', $pass); - $actions = []; + $action_links = []; if (count($actions) > 1) { foreach ($actions as $cmd => $label) { - $actions[] = $this->ui_factory->link()->standard($label, $this->ctrl->getLinkTarget($this->parent_obj, $cmd)); + $action_links[] = $this->ui_factory->link()->standard($label, $this->ctrl->getLinkTarget($this->parent_obj, $cmd)); } - $dropdown = $this->ui_factory->dropdown()->standard($actions)->withLabel($this->lng->txt('actions')); + $dropdown = $this->ui_factory->dropdown()->standard($action_links)->withLabel($this->lng->txt('actions')); $html = $this->ui_renderer->render($dropdown); } else { $cmd = key($actions); diff --git a/Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php b/Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php index 7ce95036e3a6..5c63aa43375b 100644 --- a/Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php +++ b/Modules/Test/classes/toolbars/class.ilTestResultsToolbarGUI.php @@ -45,7 +45,9 @@ public function build(): void { $this->setId('tst_results_toolbar'); - $this->addButton($this->lng->txt('print'), 'javascript:window.print();'); + $print_button = $this->ui->factory()->button()->standard($this->lng->txt('print'), '') + ->withOnLoadCode(fn($id) => "$('#$id').on('click', ()=>{window.print();})"); + $this->addComponent($print_button); if ($this->getCertificateLinkTarget() !== null && $this->getCertificateLinkTarget() !== '') { diff --git a/Modules/Test/module.xml b/Modules/Test/module.xml index 8341dc429c54..f8a37e633b9f 100644 --- a/Modules/Test/module.xml +++ b/Modules/Test/module.xml @@ -47,4 +47,7 @@ + + +
diff --git a/Modules/Test/templates/default/tpl.il_as_tst_kiosk_head.html b/Modules/Test/templates/default/tpl.il_as_tst_kiosk_head.html deleted file mode 100644 index 39abcfbf3b4e..000000000000 --- a/Modules/Test/templates/default/tpl.il_as_tst_kiosk_head.html +++ /dev/null @@ -1,16 +0,0 @@ -
-
- -{TEST_TITLE} - -
-
- -{PARTICIPANT_NAME} - - -
-{EXAM_ID_TXT} {EXAM_ID} - -
-
\ No newline at end of file diff --git a/Modules/Test/templates/default/tpl.il_as_tst_pass_details_overview_participants.html b/Modules/Test/templates/default/tpl.il_as_tst_pass_details_overview_participants.html index d195f3c6ac2a..1a3108aa34d9 100755 --- a/Modules/Test/templates/default/tpl.il_as_tst_pass_details_overview_participants.html +++ b/Modules/Test/templates/default/tpl.il_as_tst_pass_details_overview_participants.html @@ -12,9 +12,10 @@

{TEXT_HEADING}

{TOTAL_RESULT_TEXT}: {TOTAL_RESULT}

-
+ {LIST_OF_ANSWERS} +

{SIGNATURE} diff --git a/Modules/Test/test/ScoreSettingsTest.php b/Modules/Test/test/ScoreSettingsTest.php index 2d69c04a93b2..8bb2d5f274eb 100644 --- a/Modules/Test/test/ScoreSettingsTest.php +++ b/Modules/Test/test/ScoreSettingsTest.php @@ -76,13 +76,10 @@ public function testScoreSettingsSummary(): void public function testScoreSettingsDetails(): void { $s = new ilObjTestSettingsResultDetails(-666); - $this->assertTrue($s->withPrintBestSolutionWithResult(true)->getPrintBestSolutionWithResult()); $this->assertEquals(192, $s->withResultsPresentation(192)->getResultsPresentation(192)); $this->assertTrue($s->withShowExamIdInTestResults(true)->getShowExamIdInTestResults()); $this->assertTrue($s->withShowPassDetails(true)->getShowPassDetails()); $this->assertFalse($s->withShowPassDetails(false)->getShowPassDetails()); - $this->assertTrue($s->withShowSolutionDetails(true)->getShowSolutionDetails()); - $this->assertFalse($s->withShowSolutionDetails(false)->getShowSolutionDetails()); $this->assertTrue($s->withShowSolutionPrintview(true)->getShowSolutionPrintview()); $this->assertFalse($s->withShowSolutionPrintview(false)->getShowSolutionPrintview()); $this->assertTrue($s->withShowSolutionFeedback(true)->getShowSolutionFeedback()); @@ -367,77 +364,55 @@ public function testScoreSettingsSectionDetails(): void $expected = <<

tst_results_details_options

-
- -
- -
tst_show_solution_details_desc
-
- -
- -
tst_results_print_best_solution_info
-
-
-
-
- +
- -
tst_show_solution_details_singlepage_desc
-
- -
- -
tst_results_print_best_solution_singlepage_info
-
-
+
tst_results_print_best_solution_info
- +
-
tst_show_solution_feedback_desc
+
tst_show_solution_feedback_desc
-
-
tst_show_solution_suggested_desc
+
+
tst_show_solution_suggested_desc
-
-
tst_show_solution_printview_desc
+
+
tst_show_solution_printview_desc
-
-
tst_hide_pagecontents_desc
+
+
tst_hide_pagecontents_desc
-
-
tst_show_solution_signature_desc
+
+
tst_show_solution_signature_desc
-
-
examid_in_test_res_desc
+
+
examid_in_test_res_desc
-
    +
    • 1
    • @@ -587,12 +562,10 @@ public function __construct($s) $this->assertIsInt($t->getPassScoring()); $this->assertNull($t->getReportingDate()); $this->assertIsBool($t->getShowPassDetails()); - $this->assertIsBool($t->getShowSolutionDetails()); $this->assertIsBool($t->getShowSolutionAnswersOnly()); $this->assertIsBool($t->getShowSolutionSignature()); $this->assertIsBool($t->getShowSolutionSuggested()); $this->assertIsBool($t->getShowSolutionListComparison()); - $this->assertIsBool($t->getShowSolutionListOwnAnswers()); $this->assertIsBool($t->isPassDeletionAllowed()); $this->assertIsInt($t->getExportSettings()); $this->assertIsBool($t->getHighscoreEnabled()); diff --git a/Modules/Test/test/TestPassResultsSettingsTest.php b/Modules/Test/test/TestPassResultsSettingsTest.php new file mode 100644 index 000000000000..04b8de9a63c0 --- /dev/null +++ b/Modules/Test/test/TestPassResultsSettingsTest.php @@ -0,0 +1,56 @@ +assertFalse($trs->getShowHiddenQuestions()); + $this->assertFalse($trs->getShowOptionalQuestions()); + $this->assertTrue($trs->getShowBestSolution()); + $this->assertTrue($trs->getShowFeedback()); + $this->assertFalse($trs->getQuestionTextOnly()); + $this->assertFalse($trs->getShowRecapitulation()); + } + + public function testTestResultsSettingsBasicProps(): void + { + $trs = new \ilTestPassResultsSettings(true, true, true, true, true, true); + $this->assertTrue($trs->getShowHiddenQuestions()); + $this->assertTrue($trs->getShowOptionalQuestions()); + $this->assertTrue($trs->getShowBestSolution()); + $this->assertTrue($trs->getShowFeedback()); + $this->assertTrue($trs->getQuestionTextOnly()); + $this->assertTrue($trs->getShowRecapitulation()); + + $trs = new \ilTestPassResultsSettings(false, false, false, false, false, false); + $this->assertFalse($trs->getShowHiddenQuestions()); + $this->assertFalse($trs->getShowOptionalQuestions()); + $this->assertFalse($trs->getShowBestSolution()); + $this->assertFalse($trs->getShowFeedback()); + $this->assertFalse($trs->getQuestionTextOnly()); + $this->assertFalse($trs->getShowRecapitulation()); + } +} diff --git a/Modules/Test/test/TestResultsQuestionResultsTest.php b/Modules/Test/test/TestResultsQuestionResultsTest.php new file mode 100644 index 000000000000..5c5c0a6e9005 --- /dev/null +++ b/Modules/Test/test/TestResultsQuestionResultsTest.php @@ -0,0 +1,55 @@ +assertEquals($id, $qr->getId()); + $this->assertEquals($type, $qr->getType()); + $this->assertEquals($title, $qr->getTitle()); + $this->assertEquals($question_score, $qr->getQuestionScore()); + $this->assertEquals($usr_score, $qr->getUserScore()); + $this->assertEquals(50, $qr->getUserScorePercent()); + $this->assertEquals(\ilQuestionResult::CORRECT_PARTIAL, $qr->getCorrect()); + $this->assertEquals($feedback, $qr->getFeedback()); + $this->assertTrue($qr->isWorkedThrough()); + $this->assertTrue($qr->isAnswered()); + $this->assertEquals($recapitulation, $qr->getContentForRecapitulation()); + } +} diff --git a/Modules/Test/test/ilTestBaseTestCase.php b/Modules/Test/test/ilTestBaseTestCase.php index fd539da1be7d..0fc0f1ac904c 100644 --- a/Modules/Test/test/ilTestBaseTestCase.php +++ b/Modules/Test/test/ilTestBaseTestCase.php @@ -332,4 +332,14 @@ protected function addGlobal_objectService(): void $this->setGlobalVariable("object", $object_mock); } + + protected function getTestObjMock(): ilObjTest + { + $test_mock = $this->createMock(ilObjTest::class); + $test_mock->method('getLocalDIC') + ->willReturn( + ilTestDIC::dic() + ); + return $test_mock; + } } diff --git a/Modules/Test/test/ilTestEvalObjectiveOrientedGUITest.php b/Modules/Test/test/ilTestEvalObjectiveOrientedGUITest.php index 2c0d132e63f1..9afee1881e3f 100644 --- a/Modules/Test/test/ilTestEvalObjectiveOrientedGUITest.php +++ b/Modules/Test/test/ilTestEvalObjectiveOrientedGUITest.php @@ -51,8 +51,7 @@ protected function setUp(): void $this->addGlobal_uiFactory(); $this->addGlobal_uiRenderer(); - $objTest_mock = $this->createMock(ilObjTest::class); - $this->testObj = new ilTestEvalObjectiveOrientedGUI($objTest_mock); + $this->testObj = new ilTestEvalObjectiveOrientedGUI($this->getTestObjMock()); } public function test_instantiateObject_shouldReturnInstance(): void diff --git a/Modules/Test/test/ilTestEvaluationGUITest.php b/Modules/Test/test/ilTestEvaluationGUITest.php index 51205b741482..9082d576a599 100644 --- a/Modules/Test/test/ilTestEvaluationGUITest.php +++ b/Modules/Test/test/ilTestEvaluationGUITest.php @@ -53,7 +53,9 @@ protected function setUp(): void $this->addGlobal_uiFactory(); $this->addGlobal_uiRenderer(); - $this->testObj = new ilTestEvaluationGUI($this->createMock(ilObjTest::class)); + $this->testObj = new ilTestEvaluationGUI( + $this->getTestObjMock() + ); } public function test_instantiateObject_shouldReturnInstance(): void diff --git a/Modules/Test/test/ilTestNavigationToolbarGUITest.php b/Modules/Test/test/ilTestNavigationToolbarGUITest.php index 4712aa1a5913..10baf233d369 100644 --- a/Modules/Test/test/ilTestNavigationToolbarGUITest.php +++ b/Modules/Test/test/ilTestNavigationToolbarGUITest.php @@ -34,7 +34,6 @@ protected function setUp(): void $this->testObj = new ilTestNavigationToolbarGUI( $this->createMock(ilCtrl::class), - $this->createMock(ilLanguage::class), $this->createMock(ilTestPlayerAbstractGUI::class) ); } @@ -53,22 +52,13 @@ public function testSuspendTestButtonEnabled(): void $this->assertTrue($this->testObj->isSuspendTestButtonEnabled()); } - public function testQuestionListButtonEnabled(): void + public function testUserPassOverviewButtonEnabled(): void { - $this->testObj->setQuestionListButtonEnabled(false); - $this->assertFalse($this->testObj->isQuestionListButtonEnabled()); + $this->testObj->setUserPassOverviewEnabled(false); + $this->assertFalse($this->testObj->isUserPassOverviewEnabled()); - $this->testObj->setQuestionListButtonEnabled(true); - $this->assertTrue($this->testObj->isQuestionListButtonEnabled()); - } - - public function testQuestionTreeButtonEnabled(): void - { - $this->testObj->setQuestionTreeButtonEnabled(false); - $this->assertFalse($this->testObj->isQuestionTreeButtonEnabled()); - - $this->testObj->setQuestionTreeButtonEnabled(true); - $this->assertTrue($this->testObj->isQuestionTreeButtonEnabled()); + $this->testObj->setUserPassOverviewEnabled(true); + $this->assertTrue($this->testObj->isUserPassOverviewEnabled()); } public function testQuestionTreeVisible(): void diff --git a/Modules/Test/test/ilTestPlayerFixedQuestionSetGUITest.php b/Modules/Test/test/ilTestPlayerFixedQuestionSetGUITest.php index 6db0e7e38add..dce422243a39 100644 --- a/Modules/Test/test/ilTestPlayerFixedQuestionSetGUITest.php +++ b/Modules/Test/test/ilTestPlayerFixedQuestionSetGUITest.php @@ -53,7 +53,7 @@ protected function setUp(): void $this->addGlobal_uiRenderer(); $this->testObj = new ilTestPlayerFixedQuestionSetGUI( - $this->createMock(ilObjTest::class) + $this->getTestObjMock() ); } diff --git a/Modules/Test/test/ilTestPlayerRandomQuestionSetGUITest.php b/Modules/Test/test/ilTestPlayerRandomQuestionSetGUITest.php index 445a5f8f0b3f..232200115363 100644 --- a/Modules/Test/test/ilTestPlayerRandomQuestionSetGUITest.php +++ b/Modules/Test/test/ilTestPlayerRandomQuestionSetGUITest.php @@ -53,7 +53,7 @@ protected function setUp(): void $this->addGlobal_uiFactory(); $this->addGlobal_uiRenderer(); - $this->testObj = new ilTestPlayerRandomQuestionSetGUI($this->createMock(ilObjTest::class)); + $this->testObj = new ilTestPlayerRandomQuestionSetGUI($this->getTestObjMock()); } public function test_instantiateObject_shouldReturnInstance(): void diff --git a/Modules/Test/test/ilTestQuestionNavigationGUITest.php b/Modules/Test/test/ilTestQuestionNavigationGUITest.php index f821deb94b99..bce57b0c311f 100644 --- a/Modules/Test/test/ilTestQuestionNavigationGUITest.php +++ b/Modules/Test/test/ilTestQuestionNavigationGUITest.php @@ -30,7 +30,15 @@ protected function setUp(): void { parent::setUp(); - $this->testObj = new ilTestQuestionNavigationGUI($this->createMock(ilLanguage::class)); + $test_helper = new UITestHelper(); + $ui_factory = $test_helper->factory(); + $ui_renderer = $test_helper->renderer(); + + $this->testObj = new ilTestQuestionNavigationGUI( + $this->createMock(ilLanguage::class), + $ui_factory, + $ui_renderer + ); } public function test_instantiateObject_shouldReturnInstance(): void diff --git a/Modules/Test/test/ilTestQuestionSideListGUITest.php b/Modules/Test/test/ilTestQuestionSideListGUITest.php deleted file mode 100644 index 01e74cca21f4..000000000000 --- a/Modules/Test/test/ilTestQuestionSideListGUITest.php +++ /dev/null @@ -1,80 +0,0 @@ - - */ -class ilTestQuestionSideListGUITest extends ilTestBaseTestCase -{ - private ilTestQuestionSideListGUI $testObj; - - protected function setUp(): void - { - parent::setUp(); - - $this->testObj = new ilTestQuestionSideListGUI( - $this->createMock(ilCtrl::class), - $this->createMock(ilLanguage::class) - ); - } - - public function test_instantiateObject_shouldReturnInstance(): void - { - $this->assertInstanceOf(ilTestQuestionSideListGUI::class, $this->testObj); - } - - public function testTargetGUI(): void - { - $targetGui_mock = $this->createMock(ilTestPlayerAbstractGUI::class); - $this->testObj->setTargetGUI($targetGui_mock); - $this->assertEquals($targetGui_mock, $this->testObj->getTargetGUI()); - } - - public function testQuestionSummaryData(): void - { - $expected = [ - "test" => "Hello", - ]; - $this->testObj->setQuestionSummaryData($expected); - $this->assertEquals($expected, $this->testObj->getQuestionSummaryData()); - } - - public function testCurrentSequenceElement(): void - { - $this->testObj->setCurrentSequenceElement(125); - $this->assertEquals(125, $this->testObj->getCurrentSequenceElement()); - } - - public function testCurrentPresentationMode(): void - { - $this->testObj->setCurrentPresentationMode("test"); - $this->assertEquals("test", $this->testObj->getCurrentPresentationMode()); - } - - public function testDisabled(): void - { - $this->testObj->setDisabled(false); - $this->assertFalse($this->testObj->isDisabled()); - - $this->testObj->setDisabled(true); - $this->assertTrue($this->testObj->isDisabled()); - } -} diff --git a/Modules/Test/test/ilTestScoringByQuestionsGUITest.php b/Modules/Test/test/ilTestScoringByQuestionsGUITest.php index fe37062aded6..c88a0c53ef31 100644 --- a/Modules/Test/test/ilTestScoringByQuestionsGUITest.php +++ b/Modules/Test/test/ilTestScoringByQuestionsGUITest.php @@ -48,7 +48,7 @@ protected function setUp(): void $this->addGlobal_uiRenderer(); $this->testObj = new ilTestScoringByQuestionsGUI( - $this->createMock(ilObjTest::class) + $this->getTestObjMock() ); } diff --git a/Modules/Test/test/ilTestScoringGUITest.php b/Modules/Test/test/ilTestScoringGUITest.php index 83855b571d5f..ad90f47f1fb1 100644 --- a/Modules/Test/test/ilTestScoringGUITest.php +++ b/Modules/Test/test/ilTestScoringGUITest.php @@ -49,7 +49,7 @@ protected function setUp(): void $this->addGlobal_uiFactory(); $this->addGlobal_uiRenderer(); - $this->testObj = new ilTestScoringGUI($this->createMock(ilObjTest::class)); + $this->testObj = new ilTestScoringGUI($this->getTestObjMock()); } public function test_instantiateObject_shouldReturnInstance(): void diff --git a/Modules/Test/test/ilTestServiceGUITest.php b/Modules/Test/test/ilTestServiceGUITest.php index 64a724e18fb9..c934a4e5dded 100644 --- a/Modules/Test/test/ilTestServiceGUITest.php +++ b/Modules/Test/test/ilTestServiceGUITest.php @@ -16,6 +16,8 @@ * *********************************************************************/ +declare(strict_types=1); + /** * Class ilTestServiceGUITest * @author Marvin Beym @@ -49,7 +51,7 @@ protected function setUp(): void $this->addGlobal_uiFactory(); $this->addGlobal_uiRenderer(); - $this->testObj = new ilTestServiceGUI($this->createMock(ilObjTest::class)); + $this->testObj = new ilTestServiceGUI($this->getTestObjMock()); } public function test_instantiateObject_shouldReturnInstance(): void @@ -114,12 +116,18 @@ public function testBuildFixedShufflerSeedReturnsValidSeed(): void ] ]; - $reflection = new \ReflectionClass(ilTestServiceGUI::class); + $reflection = new \ReflectionClass(ilTestShuffler::class); $method = $reflection->getMethod('buildFixedShufflerSeed'); $method->setAccessible(true); + $refinery = new \ILIAS\Refinery\Factory( + new \ILIAS\Data\Factory(), + $this->getMockBuilder(ilLanguage::class)->disableOriginalConstructor()->getMock() + ); + $shuffler = new ilTestShuffler($refinery); + foreach ($seeds as $seed) { - $fixed_seed = $method->invoke($this->testObj, $seed['question_id'], $seed['pass_id'], $seed['active_id']); + $fixed_seed = $method->invoke($shuffler, $seed['question_id'], $seed['pass_id'], $seed['active_id']); $this->assertEquals($seed['return'], $fixed_seed); } } diff --git a/Modules/Test/test/ilTestSubmissionReviewGUITest.php b/Modules/Test/test/ilTestSubmissionReviewGUITest.php index 862d1f0a8543..84d7ae99cf79 100644 --- a/Modules/Test/test/ilTestSubmissionReviewGUITest.php +++ b/Modules/Test/test/ilTestSubmissionReviewGUITest.php @@ -53,7 +53,7 @@ protected function setUp(): void $this->testObj = new ilTestSubmissionReviewGUI( $this->createMock(ilTestOutputGUI::class), - $this->createMock(ilObjTest::class), + $this->getTestObjMock(), $this->createMock(ilTestSession::class) ); } diff --git a/Modules/TestQuestionPool/classes/Skills/class.TestQuestionPoolSkillDBRepository.php b/Modules/TestQuestionPool/classes/Skills/class.TestQuestionPoolSkillDBRepository.php new file mode 100644 index 000000000000..6d8450775e14 --- /dev/null +++ b/Modules/TestQuestionPool/classes/Skills/class.TestQuestionPoolSkillDBRepository.php @@ -0,0 +1,52 @@ + + */ +class TestQuestionPoolSkillDBRepository +{ + protected \ilDBInterface $db; + + public function __construct( + \ilDBInterface $db = null + ) { + global $DIC; + + $this->db = ($db) ?: $DIC->database(); + } + + public function removeForSkill(int $skill_node_id, bool $is_reference): void + { + if (!$is_reference) { + $this->db->manipulate("DELETE FROM qpl_qst_skl_assigns " . + " WHERE skill_base_fi = " . $this->db->quote($skill_node_id, "integer")); + $this->db->manipulate("DELETE FROM qpl_qst_skl_sol_expr " . + " WHERE skill_base_fi = " . $this->db->quote($skill_node_id, "integer")); + } else { + $this->db->manipulate("DELETE FROM qpl_qst_skl_assigns " . + " WHERE skill_tref_fi = " . $this->db->quote($skill_node_id, "integer")); + $this->db->manipulate("DELETE FROM qpl_qst_skl_sol_expr " . + " WHERE skill_tref_fi = " . $this->db->quote($skill_node_id, "integer")); + } + } +} diff --git a/Modules/TestQuestionPool/classes/class.assMultipleChoiceGUI.php b/Modules/TestQuestionPool/classes/class.assMultipleChoiceGUI.php index 7083a4034c84..95d628f097a8 100755 --- a/Modules/TestQuestionPool/classes/class.assMultipleChoiceGUI.php +++ b/Modules/TestQuestionPool/classes/class.assMultipleChoiceGUI.php @@ -214,11 +214,13 @@ public function getSolutionOutput( $show_feedback = false, $show_correct_solution = false, $show_manual_scoring = false, - $show_question_text = true + $show_question_text = true, + $show_inline_feedback = true ): string { // shuffle output $keys = $this->getChoiceKeys(); + // get the solution of the user for the active pass or from the last pass if allowed $user_solution = array(); if (($active_id > 0) && (!$show_correct_solution)) { @@ -289,7 +291,8 @@ public function getSolutionOutput( $template->parseCurrentBlock(); } - if ($show_feedback) { + + if ($show_inline_feedback) { if ($this->object->getSpecificFeedbackSetting() == 2) { foreach ($user_solution as $mc_solution) { if (strcmp($mc_solution, $answer_id) == 0) { @@ -319,7 +322,8 @@ public function getSolutionOutput( $template->parseCurrentBlock(); } } - + } + if ($show_feedback) { if ($this->object->getSpecificFeedbackSetting() == 3) { $answer = $this->object->getAnswer($answer_id); @@ -337,6 +341,9 @@ public function getSolutionOutput( } } } + + + $template->setCurrentBlock("answer_row"); $template->setVariable("ANSWER_TEXT", ilLegacyFormElementsUtil::prepareTextareaOutput($answer->getAnswertext(), true)); $checked = false; diff --git a/Modules/TestQuestionPool/classes/class.assQuestionGUI.php b/Modules/TestQuestionPool/classes/class.assQuestionGUI.php index fd70db28a51b..e5b0b8efe6cf 100755 --- a/Modules/TestQuestionPool/classes/class.assQuestionGUI.php +++ b/Modules/TestQuestionPool/classes/class.assQuestionGUI.php @@ -710,7 +710,7 @@ public function saveEdit(): void $testQuestionSetConfigFactory = new ilTestQuestionSetConfigFactory( $this->tree, $this->db, - $this->component_repository, + $this->lng, $this->logger, $this->component_repository, $test, @@ -2025,11 +2025,11 @@ protected function generateCorrectnessIconsForCorrectness(int $correctness): str $label = $this->lng->txt("answer_is_wrong"); break; case self::CORRECTNESS_MOSTLY_OK: - $icon_name = 'icon_ok.svg'; + $icon_name = 'standard/icon_ok.svg'; $label = $this->lng->txt("answer_is_not_correct_but_positive"); break; case self::CORRECTNESS_OK: - $icon_name = 'icon_ok.svg'; + $icon_name = 'standard/icon_ok.svg'; $label = $this->lng->txt("answer_is_right"); break; default: diff --git a/Modules/TestQuestionPool/classes/class.assSingleChoiceGUI.php b/Modules/TestQuestionPool/classes/class.assSingleChoiceGUI.php index 2c048636d809..b38e259d524c 100755 --- a/Modules/TestQuestionPool/classes/class.assSingleChoiceGUI.php +++ b/Modules/TestQuestionPool/classes/class.assSingleChoiceGUI.php @@ -240,7 +240,8 @@ public function getSolutionOutput( $show_feedback = false, $show_correct_solution = false, $show_manual_scoring = false, - $show_question_text = true + $show_question_text = true, + bool $show_inline_feedback = true ): string { // shuffle output $keys = $this->getChoiceKeys(); @@ -300,7 +301,8 @@ public function getSolutionOutput( $template->setVariable("ANSWER_IMAGE_TITLE", ilLegacyFormElementsUtil::prepareFormOutput($alt)); $template->parseCurrentBlock(); } - if ($show_feedback) { + + if ($show_inline_feedback) { $this->populateInlineFeedback($template, $answer_id, $user_solution); } $template->setCurrentBlock("answer_row"); @@ -330,8 +332,9 @@ public function getSolutionOutput( } $template->parseCurrentBlock(); } + $questiontext = $this->object->getQuestionForHTMLOutput(); - if ($show_feedback && $this->hasInlineFeedback()) { + if ($show_inline_feedback && $this->hasInlineFeedback()) { $questiontext .= $this->buildFocusAnchorHtml(); } if ($show_question_text == true) { @@ -544,7 +547,7 @@ public function getSpecificFeedbackOutput(array $userSolution): string { // No return value, this question type supports inline specific feedback. $output = ""; - return $ilLegacyFormElementsUtil::prepareTextareaOutput($output, true); + return ilLegacyFormElementsUtil::prepareTextareaOutput($output, true); } public function writeQuestionSpecificPostData(ilPropertyFormGUI $form): void @@ -784,7 +787,7 @@ private function populateInlineFeedback($template, $answer_id, $user_solution): break; case 2: - if (strcmp($user_solution, $answer_id) == 0) { + if (strcmp((string)$user_solution, $answer_id) == 0) { $feedbackOutputRequired = true; } break; diff --git a/Modules/TestQuestionPool/classes/class.ilTestQuestionPoolAppEventListener.php b/Modules/TestQuestionPool/classes/class.ilTestQuestionPoolAppEventListener.php new file mode 100644 index 000000000000..2cecad7639e3 --- /dev/null +++ b/Modules/TestQuestionPool/classes/class.ilTestQuestionPoolAppEventListener.php @@ -0,0 +1,39 @@ + + */ +class ilTestQuestionPoolAppEventListener implements ilAppEventListener +{ + /** + * @inheritDoc + */ + public static function handleEvent(string $a_component, string $a_event, array $a_parameter): void + { + $qpl_skill_repo = new TestQuestionPoolSkillDBRepository(); + + if ($a_component === "Services/Skill" && $a_event === "deleteSkill") { + $qpl_skill_repo->removeForSkill($a_parameter["node_id"], $a_parameter["is_reference"]); + } + } +} diff --git a/Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php b/Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php index c2da7d95ce6c..5ba0fef6a637 100644 --- a/Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php +++ b/Modules/TestQuestionPool/classes/forms/class.ilAssNestedOrderingElementsInputGUI.php @@ -262,7 +262,7 @@ private function getCorrectnessIcon($correctness): string $icon_name = 'standard/icon_not_ok.svg'; $label = $this->lng->txt("answer_is_wrong"); if ($correctness === 'correct') { - $icon_name = 'icon_ok.svg'; + $icon_name = 'standard/icon_ok.svg'; $label = $this->lng->txt("answer_is_right"); } $path = ilUtil::getImagePath($icon_name); diff --git a/Modules/TestQuestionPool/module.xml b/Modules/TestQuestionPool/module.xml index 23a00c43857d..b4c203d4ae7b 100644 --- a/Modules/TestQuestionPool/module.xml +++ b/Modules/TestQuestionPool/module.xml @@ -24,4 +24,7 @@ + + + diff --git a/Services/COPage/test/Compare/PageCompareTest.php b/Services/COPage/test/Compare/PageCompareTest.php index 3f666b25bb1b..de72315fa4d7 100644 --- a/Services/COPage/test/Compare/PageCompareTest.php +++ b/Services/COPage/test/Compare/PageCompareTest.php @@ -46,7 +46,7 @@ public function testCompareEqual(): void $this->insertParagraphAt($r_page, "pg"); $r_page->insertPCIds(); - $res = $compare->compare($l_page, $r_page); + $res = $compare->compare($l_page, $l_page, $r_page); $this->assertEquals( "", @@ -74,7 +74,7 @@ public function testCompareNewDeleted(): void $this->insertParagraphAt($r_page, "pg"); $r_page->insertPCIds(); - $res = $compare->compare($l_page, $r_page); + $res = $compare->compare($l_page, $l_page, $r_page); $this->assertEquals( "Deleted", @@ -101,7 +101,7 @@ public function testCompareChanged(): void $this->insertParagraphAt($r_page, "pg", "Hello little World!"); $r_page->insertPCIds(); - $res = $compare->compare($l_page, $r_page); + $res = $compare->compare($l_page, $l_page, $r_page); $this->assertEquals( "Modified", @@ -128,7 +128,7 @@ public function testCompareTextChanges(): void $this->insertParagraphAt($r_page, "pg", "Hello little World!"); $r_page->insertPCIds(); - $res = $compare->compare($l_page, $r_page); + $res = $compare->compare($l_page, $l_page, $r_page); $expected = <<Hello [ilDiffInsStart]little [ilDiffInsEnd]World! diff --git a/Services/Contact/classes/class.ilMailSearchGUI.php b/Services/Contact/classes/class.ilMailSearchGUI.php index aabb83475b16..f4d7003762c4 100644 --- a/Services/Contact/classes/class.ilMailSearchGUI.php +++ b/Services/Contact/classes/class.ilMailSearchGUI.php @@ -583,13 +583,7 @@ protected function addPermission(array $a_obj_ids): void $a_obj_ids = [$a_obj_ids]; } - $existing = $this->wsp_access_handler->getPermissions($this->wsp_node_id); - $added = false; - foreach ($a_obj_ids as $object_id) { - if (!in_array($object_id, $existing, true)) { - $added = $this->wsp_access_handler->addPermission($this->wsp_node_id, $object_id); - } - } + $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids); if ($added) { $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true); diff --git a/Services/Contact/classes/class.ilMailSearchObjectGUI.php b/Services/Contact/classes/class.ilMailSearchObjectGUI.php index a090a9e026e9..70481fdd2d05 100644 --- a/Services/Contact/classes/class.ilMailSearchObjectGUI.php +++ b/Services/Contact/classes/class.ilMailSearchObjectGUI.php @@ -126,13 +126,7 @@ protected function getRequestValue(string $key, \ILIAS\Refinery\Transformation $ */ protected function addPermission(array $a_obj_ids): void { - $existing = $this->wsp_access_handler->getPermissions($this->wsp_node_id); - $added = false; - foreach ($a_obj_ids as $object_id) { - if (!in_array($object_id, $existing, true)) { - $added = $this->wsp_access_handler->addPermission($this->wsp_node_id, $object_id); - } - } + $added = $this->wsp_access_handler->addMissingPermissionForObjects($this->wsp_node_id, $a_obj_ids); if ($added) { $this->tpl->setOnScreenMessage('success', $this->lng->txt('wsp_share_success'), true); diff --git a/Services/Container/Skills/Service/class.ContainerSkillInternalFactoryService.php b/Services/Container/Skills/Service/class.SkillInternalFactoryService.php similarity index 94% rename from Services/Container/Skills/Service/class.ContainerSkillInternalFactoryService.php rename to Services/Container/Skills/Service/class.SkillInternalFactoryService.php index 5c4fd871dd53..97d488bf1534 100644 --- a/Services/Container/Skills/Service/class.ContainerSkillInternalFactoryService.php +++ b/Services/Container/Skills/Service/class.SkillInternalFactoryService.php @@ -24,7 +24,7 @@ /** * @author Thomas Famula */ -class ContainerSkillInternalFactoryService +class SkillInternalFactoryService { public function containerSkill(): ContainerSkillFactory { diff --git a/Services/Container/Skills/Service/ContainerSkillInternalGUIService.php b/Services/Container/Skills/Service/class.SkillInternalGUIService.php similarity index 97% rename from Services/Container/Skills/Service/ContainerSkillInternalGUIService.php rename to Services/Container/Skills/Service/class.SkillInternalGUIService.php index 87aa4c5ac243..56272fce5b57 100644 --- a/Services/Container/Skills/Service/ContainerSkillInternalGUIService.php +++ b/Services/Container/Skills/Service/class.SkillInternalGUIService.php @@ -27,7 +27,7 @@ /** * @author Thomas Famula */ -class ContainerSkillInternalGUIService +class SkillInternalGUIService { protected HTTP\Services $http; protected Refinery\Factory $refinery; diff --git a/Services/Container/Skills/Service/class.ContainerSkillInternalManagerService.php b/Services/Container/Skills/Service/class.SkillInternalManagerService.php similarity index 82% rename from Services/Container/Skills/Service/class.ContainerSkillInternalManagerService.php rename to Services/Container/Skills/Service/class.SkillInternalManagerService.php index a317cc474aa5..2a6895b3f3d1 100644 --- a/Services/Container/Skills/Service/class.ContainerSkillInternalManagerService.php +++ b/Services/Container/Skills/Service/class.SkillInternalManagerService.php @@ -24,10 +24,15 @@ /** * @author Thomas Famula */ -class ContainerSkillInternalManagerService +class SkillInternalManagerService { public function getSkillManager(int $cont_obj_id, int $cont_ref_id): ContainerSkillManager { return new ContainerSkillManager($cont_obj_id, $cont_ref_id); } + + public function getSkillDeletionManager(): ContainerSkillDeletionManager + { + return new ContainerSkillDeletionManager(); + } } diff --git a/Services/Container/Skills/Service/class.ContainerSkillInternalRepoService.php b/Services/Container/Skills/Service/class.SkillInternalRepoService.php similarity index 95% rename from Services/Container/Skills/Service/class.ContainerSkillInternalRepoService.php rename to Services/Container/Skills/Service/class.SkillInternalRepoService.php index c758c744d4d0..2bb04e9ef765 100644 --- a/Services/Container/Skills/Service/class.ContainerSkillInternalRepoService.php +++ b/Services/Container/Skills/Service/class.SkillInternalRepoService.php @@ -24,7 +24,7 @@ /** * @author famula@leifos.de */ -class ContainerSkillInternalRepoService +class SkillInternalRepoService { public function getContainerSkillRepo(): ContainerSkillDBRepository { diff --git a/Services/Container/Skills/Service/class.ContainerSkillInternalService.php b/Services/Container/Skills/Service/class.SkillInternalService.php similarity index 70% rename from Services/Container/Skills/Service/class.ContainerSkillInternalService.php rename to Services/Container/Skills/Service/class.SkillInternalService.php index 5db323291bf6..3bfe5b203b47 100644 --- a/Services/Container/Skills/Service/class.ContainerSkillInternalService.php +++ b/Services/Container/Skills/Service/class.SkillInternalService.php @@ -27,7 +27,7 @@ /** * @author famula@leifos.de */ -class ContainerSkillInternalService +class SkillInternalService { protected HTTP\Services $http; protected Refinery\Factory $refinery; @@ -40,29 +40,29 @@ public function __construct() $this->refinery = $DIC->refinery(); } - public function repo(): ContainerSkillInternalRepoService + public function repo(): SkillInternalRepoService { - return new ContainerSkillInternalRepoService(); + return new SkillInternalRepoService(); } - public function manager(): ContainerSkillInternalManagerService + public function manager(): SkillInternalManagerService { - return new ContainerSkillInternalManagerService(); + return new SkillInternalManagerService(); } /** * Skill service repos */ - public function factory(): ContainerSkillInternalFactoryService + public function factory(): SkillInternalFactoryService { - return new ContainerSkillInternalFactoryService(); + return new SkillInternalFactoryService(); } public function gui( array $query_params = null, array $post_data = null - ): ContainerSkillInternalGUIService { - return new ContainerSkillInternalGUIService( + ): SkillInternalGUIService { + return new SkillInternalGUIService( $this->http, $this->refinery, $query_params = null, diff --git a/Services/Container/Skills/classes/class.ContainerMemberSkillDBRepository.php b/Services/Container/Skills/classes/class.ContainerMemberSkillDBRepository.php index 2d06320fd16a..d60038297f1a 100644 --- a/Services/Container/Skills/classes/class.ContainerMemberSkillDBRepository.php +++ b/Services/Container/Skills/classes/class.ContainerMemberSkillDBRepository.php @@ -24,11 +24,11 @@ class ContainerMemberSkillDBRepository { protected \ilDBInterface $db; - protected ContainerSkillInternalFactoryService $factory_service; + protected SkillInternalFactoryService $factory_service; public function __construct( \ilDBInterface $db = null, - ContainerSkillInternalFactoryService $factory_service = null, + SkillInternalFactoryService $factory_service = null, ) { global $DIC; @@ -69,6 +69,17 @@ public function removeAll(int $cont_obj_id, int $user_id): void " AND user_id = " . $this->db->quote($user_id, "integer")); } + public function removeForSkill(int $skill_node_id, bool $is_reference): void + { + if (!$is_reference) { + $this->db->manipulate("DELETE FROM cont_member_skills " . + " WHERE skill_id = " . $this->db->quote($skill_node_id, "integer")); + } else { + $this->db->manipulate("DELETE FROM cont_member_skills " . + " WHERE tref_id = " . $this->db->quote($skill_node_id, "integer")); + } + } + public function publish(int $cont_obj_id, int $user_id): void { $this->db->manipulate("UPDATE cont_member_skills SET " . diff --git a/Services/Container/Skills/classes/class.ContainerSkill.php b/Services/Container/Skills/classes/class.ContainerSkill.php index f679f2263ede..54ed7f357026 100644 --- a/Services/Container/Skills/classes/class.ContainerSkill.php +++ b/Services/Container/Skills/classes/class.ContainerSkill.php @@ -29,31 +29,26 @@ */ class ContainerSkill implements GapAnalysisSkill { - protected int $cont_obj_id = 0; protected int $skill_id = 0; protected int $tref_id = 0; + protected int $cont_obj_id = 0; protected string $title = ""; protected ?SkillProfile $profile = null; public function __construct( - int $cont_obj_id, int $skill_id, int $tref_id, + int $cont_obj_id, string $title = "", SkillProfile $profile = null ) { - $this->cont_obj_id = $cont_obj_id; $this->skill_id = $skill_id; $this->tref_id = $tref_id; + $this->cont_obj_id = $cont_obj_id; $this->title = $title; $this->profile = $profile; } - public function getContainerObjectId(): int - { - return $this->cont_obj_id; - } - public function getBaseSkillId(): int { return $this->skill_id; @@ -64,6 +59,11 @@ public function getTrefId(): int return $this->tref_id; } + public function getContainerObjectId(): int + { + return $this->cont_obj_id; + } + public function getTitle(): string { return $this->title; diff --git a/Services/Container/Skills/classes/class.ContainerSkillDBRepository.php b/Services/Container/Skills/classes/class.ContainerSkillDBRepository.php index 16c66e850eed..fccd0e58558e 100644 --- a/Services/Container/Skills/classes/class.ContainerSkillDBRepository.php +++ b/Services/Container/Skills/classes/class.ContainerSkillDBRepository.php @@ -24,11 +24,11 @@ class ContainerSkillDBRepository { protected \ilDBInterface $db; - protected ContainerSkillInternalFactoryService $factory_service; + protected SkillInternalFactoryService $factory_service; public function __construct( \ilDBInterface $db = null, - ContainerSkillInternalFactoryService $factory_service = null, + SkillInternalFactoryService $factory_service = null, ) { global $DIC; @@ -59,6 +59,17 @@ public function remove(int $cont_obj_id, int $skill_id, int $tref_id): void ); } + public function removeForSkill(int $skill_node_id, bool $is_reference): void + { + if (!$is_reference) { + $this->db->manipulate("DELETE FROM cont_skills " . + " WHERE skill_id = " . $this->db->quote($skill_node_id, "integer")); + } else { + $this->db->manipulate("DELETE FROM cont_skills " . + " WHERE tref_id = " . $this->db->quote($skill_node_id, "integer")); + } + } + /** * @return ContainerSkill[] */ @@ -78,14 +89,14 @@ public function getAll(int $cont_obj_id): array protected function getContainerSkillFromRecord(array $rec): ContainerSkill { - $rec["id"] = (int) $rec["id"]; $rec["skill_id"] = (int) $rec["skill_id"]; $rec["tref_id"] = (int) $rec["tref_id"]; + $rec["id"] = (int) $rec["id"]; return $this->factory_service->containerSkill()->skill( - $rec["id"], $rec["skill_id"], - $rec["tref_id"] + $rec["tref_id"], + $rec["id"] ); } } diff --git a/Services/Container/Skills/classes/class.ContainerSkillDeletionManager.php b/Services/Container/Skills/classes/class.ContainerSkillDeletionManager.php new file mode 100644 index 000000000000..43186d24a14d --- /dev/null +++ b/Services/Container/Skills/classes/class.ContainerSkillDeletionManager.php @@ -0,0 +1,53 @@ + + */ +class ContainerSkillDeletionManager +{ + protected ContainerSkillDBRepository $cont_skill_repo; + protected ContainerMemberSkillDBRepository $cont_member_skill_repo; + + public function __construct( + ContainerSkillDBRepository $cont_skill_repo = null, + ContainerMemberSkillDBRepository $cont_member_skill_repo = null + ) { + global $DIC; + + $this->cont_skill_repo = ($cont_skill_repo) + ?: $DIC->skills()->internalContainer()->repo()->getContainerSkillRepo(); + $this->cont_member_skill_repo = ($cont_member_skill_repo) + ?: $DIC->skills()->internalContainer()->repo()->getContainerMemberSkillRepo(); + } + + public function removeContainerSkillsForSkill(int $skill_node_id, bool $is_reference = false): void + { + $this->cont_skill_repo->removeForSkill($skill_node_id, $is_reference); + } + + public function removeContainerMemberSkillsForSkill(int $skill_node_id, bool $is_reference = false): void + { + $this->cont_member_skill_repo->removeForSkill($skill_node_id, $is_reference); + } +} diff --git a/Services/Container/Skills/classes/class.ContainerSkillFactory.php b/Services/Container/Skills/classes/class.ContainerSkillFactory.php index d0b90cb58a63..4d486713b8a6 100644 --- a/Services/Container/Skills/classes/class.ContainerSkillFactory.php +++ b/Services/Container/Skills/classes/class.ContainerSkillFactory.php @@ -30,16 +30,16 @@ class ContainerSkillFactory { public function skill( - int $cont_obj_id, int $skill_id, int $tref_id, + int $cont_obj_id = 0, string $title = "", SkillProfile $profile = null ): ContainerSkill { return new ContainerSkill( - $cont_obj_id, $skill_id, $tref_id, + $cont_obj_id, $title, $profile ); diff --git a/Services/Container/Skills/classes/class.ContainerSkillManager.php b/Services/Container/Skills/classes/class.ContainerSkillManager.php index f6a7a5f07de3..1e5b9b7524b1 100644 --- a/Services/Container/Skills/classes/class.ContainerSkillManager.php +++ b/Services/Container/Skills/classes/class.ContainerSkillManager.php @@ -35,7 +35,7 @@ class ContainerSkillManager protected SkillService\SkillTreeService $tree_service; protected SkillService\SkillProfileService $profile_service; protected SkillService\SkillPersonalService $personal_service; - protected ContainerSkillInternalFactoryService $factory_service; + protected SkillInternalFactoryService $factory_service; protected \ilSkillManagementSettings $skmg_settings; public function __construct( @@ -46,7 +46,7 @@ public function __construct( SkillService\SkillTreeService $tree_service = null, SkillService\SkillProfileService $profile_service = null, SkillService\SkillPersonalService $personal_service = null, - ContainerSkillInternalFactoryService $factory_service = null, + SkillInternalFactoryService $factory_service = null, \ilSkillManagementSettings $skmg_settings = null ) { global $DIC; @@ -97,9 +97,9 @@ public function getSkillsForContainerOrdered(): array $skills_obj_ordered = []; foreach ($skills_ordered as $s) { $skills_obj_ordered[] = $this->factory_service->containerSkill()->skill( - $this->cont_obj_id, $s["skill_id"], - $s["tref_id"] + $s["tref_id"], + $this->cont_obj_id ); } @@ -284,9 +284,9 @@ protected function getSingleSkills(): array { $s_skills = array_map(function (ContainerSkill $v): ContainerSkill { return $this->factory_service->containerSkill()->skill( - $this->cont_obj_id, $v->getBaseSkillId(), $v->getTrefId(), + $this->cont_obj_id, \ilBasicSkill::_lookupTitle($v->getBaseSkillId(), $v->getTrefId()) ); }, $this->getSkillsForContainer()); @@ -307,9 +307,9 @@ protected function getProfileSkills(): array $sklvs = $this->profile_service->getSkillLevels($gp->getId()); foreach ($sklvs as $s) { $p_skills[] = $this->factory_service->containerSkill()->skill( - $this->cont_obj_id, $s->getBaseSkillId(), $s->getTrefId(), + $this->cont_obj_id, \ilBasicSkill::_lookupTitle($s->getBaseSkillId(), $s->getTrefId()), $gp ); @@ -323,9 +323,9 @@ protected function getProfileSkills(): array $sklvs = $this->profile_service->getSkillLevels($lp->getId()); foreach ($sklvs as $s) { $p_skills[] = $this->factory_service->containerSkill()->skill( - $this->cont_obj_id, $s->getBaseSkillId(), $s->getTrefId(), + $this->cont_obj_id, \ilBasicSkill::_lookupTitle($s->getBaseSkillId(), $s->getTrefId()), $lp ); diff --git a/Services/Container/classes/class.ilContainerAppEventListener.php b/Services/Container/classes/class.ilContainerAppEventListener.php new file mode 100644 index 000000000000..6e20d1637079 --- /dev/null +++ b/Services/Container/classes/class.ilContainerAppEventListener.php @@ -0,0 +1,53 @@ + + */ +class ilContainerAppEventListener implements ilAppEventListener +{ + /** + * @inheritDoc + */ + public static function handleEvent(string $a_component, string $a_event, array $a_parameter): void + { + global $DIC; + + $cont_skill_deletion_manager = $DIC->skills()->internalContainer()->manager()->getSkillDeletionManager(); + + switch ($a_component) { + case "Services/Skill": + switch ($a_event) { + case "deleteSkill": + $cont_skill_deletion_manager->removeContainerSkillsForSkill( + $a_parameter["node_id"], + $a_parameter["is_reference"] + ); + $cont_skill_deletion_manager->removeContainerMemberSkillsForSkill( + $a_parameter["node_id"], + $a_parameter["is_reference"] + ); + break; + } + break; + } + } +} diff --git a/Services/Container/service.xml b/Services/Container/service.xml index 66ff2c236522..7410a46a9b0c 100644 --- a/Services/Container/service.xml +++ b/Services/Container/service.xml @@ -9,4 +9,7 @@ + + + diff --git a/Services/Form/js/Form.js b/Services/Form/js/Form.js index 96d05353644c..d0822759fe32 100644 --- a/Services/Form/js/Form.js +++ b/Services/Form/js/Form.js @@ -14,10 +14,6 @@ * ******************************************************************** */ -import terser from '@rollup/plugin-terser'; -import copyright from '../../../../../CI/Copyright-Checker/copyright'; -import preserveCopyright from '../../../../../CI/Copyright-Checker/preserveCopyright'; - il.Form = { duration: 150, @@ -440,6 +436,6 @@ il.Form = { il.Util.addOnLoad(il.Form.init); // see #27281 -$(document).on('dp.show', function(event) { +$(document).on('dp.show', (event) => { il.UI.page.fit($('.bootstrap-datetimepicker-widget')); -}); \ No newline at end of file +}); diff --git a/Services/LTI/classes/Consumer/class.ilObjectConsumerTableGUI.php b/Services/LTI/classes/Consumer/class.ilObjectConsumerTableGUI.php index 3ecd0b272b9e..d6a917761ed0 100644 --- a/Services/LTI/classes/Consumer/class.ilObjectConsumerTableGUI.php +++ b/Services/LTI/classes/Consumer/class.ilObjectConsumerTableGUI.php @@ -110,8 +110,8 @@ protected function fillRow(array $a_set): void $this->tpl->setVariable("TXT_TITLE", $a_set["title"]); $this->tpl->setVariable("TXT_DESCRIPTION", $a_set["description"]); $this->tpl->setVariable("TXT_PREFIX", $a_set["prefix"]); -// $this->tpl->setVariable("TXT_KEY", $a_set["key"]); -// $this->tpl->setVariable("TXT_SECRET", $a_set["secret"]); + // $this->tpl->setVariable("TXT_KEY", $a_set["key"]); + // $this->tpl->setVariable("TXT_SECRET", $a_set["secret"]); $this->tpl->setVariable("TXT_LANGUAGE", $a_set["language"]); $obj_types = ilObjLTIAdministration::getActiveObjectTypes($a_set["id"]); if ($obj_types) { diff --git a/Services/LTI/classes/InternalProvider/class.ilAuthFrontendCredentialsLTI.php b/Services/LTI/classes/InternalProvider/class.ilAuthFrontendCredentialsLTI.php index 68a54604b0b8..fbe2fc263deb 100644 --- a/Services/LTI/classes/InternalProvider/class.ilAuthFrontendCredentialsLTI.php +++ b/Services/LTI/classes/InternalProvider/class.ilAuthFrontendCredentialsLTI.php @@ -30,7 +30,7 @@ public function __construct() { parent::__construct(); // overwrite default lti logger -// $this->setLogger($GLOBALS['DIC']->logger()->lti()); + // $this->setLogger($GLOBALS['DIC']->logger()->lti()); } diff --git a/Services/LTI/classes/InternalProvider/class.ilAuthProviderLTI.php b/Services/LTI/classes/InternalProvider/class.ilAuthProviderLTI.php index 9b1d6a86e93f..acaeedfb01f6 100755 --- a/Services/LTI/classes/InternalProvider/class.ilAuthProviderLTI.php +++ b/Services/LTI/classes/InternalProvider/class.ilAuthProviderLTI.php @@ -224,7 +224,7 @@ public function doAuthentication(\ilAuthStatus $status): bool $DIC->refinery()->kindlyTo()->string() )) { // TODO move to session-variable -// $_POST['launch_presentation_document_target'] = 'window'; + // $_POST['launch_presentation_document_target'] = 'window'; } $this->dataConnector = new ilLTIDataConnector(); @@ -282,7 +282,7 @@ public function doAuthentication(\ilAuthStatus $status): bool } // store POST into Consumer Session -// $post = (array) $DIC->http()->wrapper()->post(); + // $post = (array) $DIC->http()->wrapper()->post(); $post = []; if ($DIC->http()->wrapper()->post()->has('launch_presentation_return_url')) { $post['launch_presentation_return_url'] = $DIC->http()->wrapper()->post()->retrieve('launch_presentation_return_url', $DIC->refinery()->kindlyTo()->string()); @@ -371,14 +371,22 @@ protected function findUserId(string $a_oauth_user, string $a_oauth_id, string $ protected function updateUser(int $a_local_user_id, ilLTIPlatform $consumer): int { global $ilClientIniFile, $DIC; -// if (empty($this->messageParameters)) { -// $status->setReason('empty_lti_message_parameters'); -// $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); -// return false; -// } + // if (empty($this->messageParameters)) { + // $status->setReason('empty_lti_message_parameters'); + // $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); + // return false; + // } $user_obj = new ilObjUser($a_local_user_id); - $user_obj->setFirstname($this->messageParameters['lis_person_name_given']); - $user_obj->setLastname($this->messageParameters['lis_person_name_family']); + if (isset($this->messageParameters['lis_person_name_given'])) { + $user_obj->setFirstname($this->messageParameters['lis_person_name_given']); + } else { + $user_obj->setFirstname('-'); + } + if (isset($this->messageParameters['lis_person_name_family'])) { + $user_obj->setLastname($this->messageParameters['lis_person_name_family']); + } else { + $user_obj->setLastname('-'); + } $user_obj->setEmail($this->messageParameters['lis_person_contact_email_primary']); $user_obj->setActive(true); @@ -410,21 +418,29 @@ protected function updateUser(int $a_local_user_id, ilLTIPlatform $consumer): in protected function createUser(ilLTIPlatform $consumer): int { global $ilClientIniFile, $DIC; -// if (empty($this->messageParameters)) { -// $status->setReason('empty_lti_message_parameters'); -// $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); -// return false; -// } + // if (empty($this->messageParameters)) { + // $status->setReason('empty_lti_message_parameters'); + // $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); + // return false; + // } $userObj = new ilObjUser(); $local_user = ilAuthUtils::_generateLogin($consumer->getPrefix() . '_' . $this->getCredentials()->getUsername()); $newUser["login"] = $local_user; - $newUser["firstname"] = $this->messageParameters['lis_person_name_given']; - $newUser["lastname"] = $this->messageParameters['lis_person_name_family']; + if(isset($this->messageParameters['lis_person_name_given'])) { + $newUser["firstname"] = $this->messageParameters['lis_person_name_given']; + } else { + $newUser["firstname"] = '-'; + } + if(isset($this->messageParameters['lis_person_name_family'])) { + $newUser["lastname"] = $this->messageParameters['lis_person_name_family']; + } else { + $newUser["lastname"] = '-'; + } $newUser['email'] = $this->messageParameters['lis_person_contact_email_primary']; // set "plain md5" password (= no valid password) -// $newUser["passwd"] = ""; + // $newUser["passwd"] = ""; $newUser["passwd_type"] = ilObjUser::PASSWD_CRYPTED; $newUser["auth_mode"] = 'lti_' . $consumer->getExtConsumerId(); @@ -475,7 +491,7 @@ protected function createUser(ilLTIPlatform $consumer): int $newUser["time_limit_unlimited"] = 0; $newUser["time_limit_message"] = 0; $newUser["passwd"] = " "; -// $newUser["last_update"] + // $newUser["last_update"] // system data $userObj->assignData($newUser); @@ -489,14 +505,14 @@ protected function createUser(ilLTIPlatform $consumer): int $userObj->setTimeLimitOwner(7); $userObj->setTimeLimitUnlimited(false); $userObj->setTimeLimitFrom(time() - 5); -// todo ? + // todo ? $userObj->setTimeLimitUntil(time() + (int) $ilClientIniFile->readVariable("session", "expire")); // Create user in DB $userObj->setOwner(6); $userObj->create(); $userObj->setActive(true); -// $userObj->updateOwner(); + // $userObj->updateOwner(); $userObj->setLastPasswordChangeTS(time()); $userObj->saveAsNew(); $userObj->writePrefs(); @@ -510,11 +526,11 @@ protected function createUser(ilLTIPlatform $consumer): int protected function handleLocalRoleAssignments(int $user_id, ilLTIPlatform $consumer): bool { global $DIC; -// if (empty($this->messageParameters)) { -// $status->setReason('empty_lti_message_parameters'); -// $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); -// return false; -// } + // if (empty($this->messageParameters)) { + // $status->setReason('empty_lti_message_parameters'); + // $status->setStatus(ilAuthStatus::STATUS_AUTHENTICATION_FAILED); + // return false; + // } //$target_ref_id = $_SESSION['lti_current_context_id']; $target_ref_id = $this->ref_id; $this->getLogger()->info('$target_ref_id: ' . $target_ref_id); diff --git a/Services/LTI/classes/InternalProvider/class.ilLTIPlatform.php b/Services/LTI/classes/InternalProvider/class.ilLTIPlatform.php index 7f3779919a1c..45f3c1e75b22 100644 --- a/Services/LTI/classes/InternalProvider/class.ilLTIPlatform.php +++ b/Services/LTI/classes/InternalProvider/class.ilLTIPlatform.php @@ -169,10 +169,10 @@ public function getRefId(): int return $this->ref_id; } -// public function getId() : ?int -// { -// return $this->getRecordId(); -// } + // public function getId() : ?int + // { + // return $this->getRecordId(); + // } public function setTitle(string $title): void { @@ -316,7 +316,7 @@ public static function fromConsumerKey(?string $key = null, $dataConnector = nul */ public static function fromRecordId(int $id, ilLTIDataConnector $dataConnector): \ilLTIPlatform { -// $platform = new static($dataConnector); + // $platform = new static($dataConnector); $platform = new ilLTIPlatform($dataConnector); $platform->initialize(); $platform->setRecordId((int) $id); diff --git a/Services/LTI/classes/InternalProvider/class.ilLTIProviderObjectSettingGUI.php b/Services/LTI/classes/InternalProvider/class.ilLTIProviderObjectSettingGUI.php index 2e5b4b7e726f..7925873e07d7 100644 --- a/Services/LTI/classes/InternalProvider/class.ilLTIProviderObjectSettingGUI.php +++ b/Services/LTI/classes/InternalProvider/class.ilLTIProviderObjectSettingGUI.php @@ -131,11 +131,11 @@ public function executeCommand(): void $cmd = $this->ctrl->getCmd('settings'); $next_class = $this->ctrl->getNextClass($this); -// switch ($next_class) { -// default: + // switch ($next_class) { + // default: $this->$cmd(); -// break; -// } + // break; + // } } /** @@ -217,7 +217,7 @@ protected function initObjectSettingsForm(): \ilPropertyFormGUI if (!is_null($active_consumer->ltiVersion)) { $version->setValue($active_consumer->ltiVersion); } -// $version->setInfo($this->lng->txt('lti_obj_version_info')); + // $version->setInfo($this->lng->txt('lti_obj_version_info')); $op1 = new ilRadioOption($this->lng->txt("lti_obj_version_13"), ILIAS\LTI\ToolProvider\Util::LTI_VERSION1P3); $sh = new ilNonEditableValueGUI($this->lng->txt('lti_13_step1'), ''); $sh->setValue($this->lng->txt("lti_13_step1_info")); @@ -225,12 +225,12 @@ protected function initObjectSettingsForm(): \ilPropertyFormGUI $url = new ilNonEditableValueGUI($this->lng->txt('lti_launch_url'), 'url'); $url->setValue(ILIAS_HTTP_PATH . '/lti.php?client_id=' . CLIENT_ID); $op1->addSubItem($url); -// $url = new ilNonEditableValueGUI($this->lng->txt('lti_13_initiate_url'), 'url'); -// $url->setValue(ILIAS_HTTP_PATH . '/lti.php?client_id=' . CLIENT_ID); -// $version->addSubItem($url); -// $url = new ilNonEditableValueGUI($this->lng->txt('lti_13_redirection_url'), 'url'); -// $url->setValue(ILIAS_HTTP_PATH . '/lti.php?client_id=' . CLIENT_ID); -// $active->addSubItem($url); + // $url = new ilNonEditableValueGUI($this->lng->txt('lti_13_initiate_url'), 'url'); + // $url->setValue(ILIAS_HTTP_PATH . '/lti.php?client_id=' . CLIENT_ID); + // $version->addSubItem($url); + // $url = new ilNonEditableValueGUI($this->lng->txt('lti_13_redirection_url'), 'url'); + // $url->setValue(ILIAS_HTTP_PATH . '/lti.php?client_id=' . CLIENT_ID); + // $active->addSubItem($url); $sh = new ilNonEditableValueGUI($this->lng->txt('lti_13_step2'), ''); $sh->setValue($this->lng->txt("lti_13_step2_info")); $op1->addSubItem($sh); diff --git a/Services/LTI/classes/InternalProvider/class.ilLTITool.php b/Services/LTI/classes/InternalProvider/class.ilLTITool.php index c9aa06b3e5fa..8178c6adcb43 100644 --- a/Services/LTI/classes/InternalProvider/class.ilLTITool.php +++ b/Services/LTI/classes/InternalProvider/class.ilLTITool.php @@ -64,12 +64,12 @@ public function __construct(ilLTIDataConnector $dataConnector) { global $DIC; $this->logger = ilLoggerFactory::getLogger('ltis'); -// $this->initialize(); + // $this->initialize(); if (empty($dataConnector)) { $dataConnector = ilLTIDataConnector::getDataConnector(); } $this->dataConnector = $dataConnector; -// parent::__construct($dataConnector); + // parent::__construct($dataConnector); $this->setParameterConstraint('resource_link_id', true, 50, array('basic-lti-launch-request')); $this->setParameterConstraint('user_id', true, 64, array('basic-lti-launch-request')); $this->setParameterConstraint('roles', true, null, array('basic-lti-launch-request')); diff --git a/Services/LTI/classes/Screen/LtiViewLayoutProvider.php b/Services/LTI/classes/Screen/LtiViewLayoutProvider.php index e8809bd87128..c48df8fc59a0 100755 --- a/Services/LTI/classes/Screen/LtiViewLayoutProvider.php +++ b/Services/LTI/classes/Screen/LtiViewLayoutProvider.php @@ -95,7 +95,7 @@ public function getMainBarModification(CalledContexts $screen_context_stack): ?M return $this->globalScreen()->layout()->factory()->mainbar() ->withModification( - function (MainBar $mainbar) use ($is_exit_mode): ?MainBar { + function (?MainBar $mainbar) use ($is_exit_mode): ?MainBar { $tools = $mainbar->getToolEntries(); $mainbar = $mainbar->withClearedEntries(); if ($is_exit_mode) { @@ -120,7 +120,7 @@ public function getMetaBarModification(CalledContexts $screen_context_stack): ?M return $this->globalScreen()->layout()->factory()->metabar() ->withModification( - function (MetaBar $metabar) use ($is_exit_mode, $screen_context_stack): ?Metabar { + function (?MetaBar $metabar) use ($is_exit_mode, $screen_context_stack): ?Metabar { $metabar = $metabar->withClearedEntries(); if ($is_exit_mode) { return $metabar; @@ -146,7 +146,7 @@ public function getTitleModification(CalledContexts $screen_context_stack): ?Tit return $this->globalScreen()->layout()->factory()->title() ->withModification( - function (string $content) use ($is_exit_mode): string { + function (?string $content) use ($is_exit_mode): string { if ($is_exit_mode) { return $this->dic["lti"]->getTitleForExitPage(); } diff --git a/Services/LTI/classes/class.ilGlobalTemplate.php b/Services/LTI/classes/class.ilGlobalTemplate.php index 274e153772c0..67918c3b96e4 100644 --- a/Services/LTI/classes/class.ilGlobalTemplate.php +++ b/Services/LTI/classes/class.ilGlobalTemplate.php @@ -49,9 +49,9 @@ public function __construct( // public function getMainMenu() : void // { - // global $ilMainMenu; - // //$ilMainMenu->setLoginTargetPar($this->getLoginTargetPar()); - // $this->main_menu = $ilMainMenu->getHTML(); - // $this->main_menu_spacer = $ilMainMenu->getSpacerClass(); + // global $ilMainMenu; + // //$ilMainMenu->setLoginTargetPar($this->getLoginTargetPar()); + // $this->main_menu = $ilMainMenu->getHTML(); + // $this->main_menu_spacer = $ilMainMenu->getSpacerClass(); // } } diff --git a/Services/LTI/classes/class.ilLTIDataConnector.php b/Services/LTI/classes/class.ilLTIDataConnector.php index 0de16bfa4579..c0fd444b6fe6 100644 --- a/Services/LTI/classes/class.ilLTIDataConnector.php +++ b/Services/LTI/classes/class.ilLTIDataConnector.php @@ -99,16 +99,16 @@ public function loadPlatform(\ILIAS\LTI\ToolProvider\Platform $platform): bool } else { return false; } -// $ok = $this->executeQuery($sql, $stmt); -// if ($ok) { -// $rsConsumer = $stmt->get_result(); -// $ok = $rsConsumer !== false; -// if ($ok) { -// $row = $rsConsumer->fetch_object(); -// $ok = $row && ($allowMultiple || is_null($rsConsumer->fetch_object())); -// } -// } -// if ($ok) { + // $ok = $this->executeQuery($sql, $stmt); + // if ($ok) { + // $rsConsumer = $stmt->get_result(); + // $ok = $rsConsumer !== false; + // if ($ok) { + // $row = $rsConsumer->fetch_object(); + // $ok = $row && ($allowMultiple || is_null($rsConsumer->fetch_object())); + // } + // } + // if ($ok) { $res = $this->database->queryF($query, $types, $values); while ($row = $this->database->fetchObject($res)) { $platform->setRecordId(intval($row->consumer_pk)); @@ -166,30 +166,30 @@ public function loadPlatform(\ILIAS\LTI\ToolProvider\Platform $platform): bool return $ok; } ####### -// /** -// * Load tool consumer settings -// * @param ilLTIPlatform $platform -// * @return bool -// */ -// public function loadObjectToolConsumerSettings(ilLTIPlatform $platform) : bool -// { -// $this->loadGlobalToolConsumerSettings($platform); -// -// $ilDB = $this->database; -// -// $query = 'SELECT * from lti2_consumer where id = ' . $ilDB->quote($platform->getExtConsumerId(), 'integer'); -// $res = $ilDB->query($query); -// while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { -// $platform->setTitle($row->title); -// $platform->setDescription($row->description); -// $platform->setPrefix($row->prefix); -// $platform->setLanguage($row->user_language); -// $platform->setRole($row->role); -// $platform->setActive((bool) $row->active); -// return true; -// } -// return false; -// } + // /** + // * Load tool consumer settings + // * @param ilLTIPlatform $platform + // * @return bool + // */ + // public function loadObjectToolConsumerSettings(ilLTIPlatform $platform) : bool + // { + // $this->loadGlobalToolConsumerSettings($platform); + // + // $ilDB = $this->database; + // + // $query = 'SELECT * from lti2_consumer where id = ' . $ilDB->quote($platform->getExtConsumerId(), 'integer'); + // $res = $ilDB->query($query); + // while ($row = $res->fetchRow(ilDBConstants::FETCHMODE_OBJECT)) { + // $platform->setTitle($row->title); + // $platform->setDescription($row->description); + // $platform->setPrefix($row->prefix); + // $platform->setLanguage($row->user_language); + // $platform->setRole($row->role); + // $platform->setActive((bool) $row->active); + // return true; + // } + // return false; + // } /** * Load global tool consumer settings in consumer @@ -214,96 +214,96 @@ public function loadGlobalToolConsumerSettings(ilLTIPlatform $platform): bool return false; } -// /** -// * Load extended tool consumer object with ILIAS extension. -// * @param Platform $platform Platform object -// * @return boolean True if the tool consumer object was successfully loaded -// */ -// public function loadToolConsumerILIAS(ilLTIPlatform $platform) : bool -// { -// global $DIC; -// $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor -// -// $ok = false; -// $query = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' . -// 'consumer_name, consumer_version, consumer_guid, ' . -// 'profile, tool_proxy, settings, protected, enabled, ' . -// 'enable_from, enable_until, last_access, created, updated, ' . -// 'ext_consumer_id, ref_id ' . -// #'title, description, prefix, user_language, role, local_role_always_member, default_skin ' . -// 'FROM lti2_consumer ' . -// #'FROM lti2_consumer, lti_ext_consumer ' . -// 'WHERE '; -// #'WHERE lti_ext_consumer.id = consumer_pk AND '; -// if (!empty($platform->getRecordId())) { -// $query .= 'consumer_pk = %s'; -// $types = array('integer'); -// $values = array($platform->getRecordId()); -// } else { -// $query .= 'consumer_key256 = %s'; -// $types = array('text'); -// $key256 = ilLTIDataConnector::getConsumerKey($platform->getKey()); -// $values = array($key256); -// } -// // $rsConsumer = mysql_query($sql); -// $res = $ilDB->queryF($query, $types, $values); -// // if ($rsConsumer) { -// while ($row = $ilDB->fetchObject($res)) { -// // while ($row = mysql_fetch_object($rsConsumer)) { -// if (empty($key256) || empty($row->consumer_key) || ($platform->getKey() === $row->consumer_key)) { -// $platform->setRecordId(intval($row->consumer_pk)); -// $platform->name = $row->name; -// $platform->setkey(empty($row->consumer_key) ? $row->consumer_key256 : $row->consumer_key); -// $platform->secret = $row->secret; -// $platform->ltiVersion = $row->lti_version; -// $platform->consumerName = $row->consumer_name; -// $platform->consumerVersion = $row->consumer_version; -// $platform->consumerGuid = $row->consumer_guid; -// $platform->profile = json_decode((string) $row->profile); // TODO PHP8 Review: Undefined Property -// $platform->toolProxy = $row->tool_proxy; // TODO PHP8 Review: Undefined Property -// $settings = unserialize($row->settings); -// if (!is_array($settings)) { -// $settings = array(); -// } -// $platform->setSettings($settings); -// $platform->protected = (intval($row->protected) === 1); -// $platform->enabled = (intval($row->enabled) === 1); -// $platform->enableFrom = null; -// if (!is_null($row->enable_from)) { -// $platform->enableFrom = strtotime($row->enable_from); -// } -// $platform->enableUntil = null; -// if (!is_null($row->enable_until)) { -// $platform->enableUntil = strtotime($row->enable_until); -// } -// $platform->lastAccess = null; -// if (!is_null($row->last_access)) { -// $platform->lastAccess = strtotime($row->last_access); -// } -// $platform->created = strtotime($row->created); -// $platform->updated = strtotime($row->updated); -// -// //ILIAS specific -// $platform->setExtConsumerId((int) $row->ext_consumer_id); -// $platform->setRefId((int) $row->ref_id); -// #$platform->setTitle($row->title); -// #$platform->setDescription($row->description); -// #$platform->setPrefix($row->prefix); -// #$platform->setLanguage($row->user_language); -// #$platform->setRole($row->role); -// // local_role_always_member -// // default_skin -// -// $ok = true; -// break; -// } -// // } -// // mysql_free_result($rsConsumer); -// } -// -// $this->loadGlobalToolConsumerSettings($platform); -// return $ok; -// } + // /** + // * Load extended tool consumer object with ILIAS extension. + // * @param Platform $platform Platform object + // * @return boolean True if the tool consumer object was successfully loaded + // */ + // public function loadToolConsumerILIAS(ilLTIPlatform $platform) : bool + // { + // global $DIC; + // $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor + // + // $ok = false; + // $query = 'SELECT consumer_pk, name, consumer_key256, consumer_key, secret, lti_version, ' . + // 'consumer_name, consumer_version, consumer_guid, ' . + // 'profile, tool_proxy, settings, protected, enabled, ' . + // 'enable_from, enable_until, last_access, created, updated, ' . + // 'ext_consumer_id, ref_id ' . + // #'title, description, prefix, user_language, role, local_role_always_member, default_skin ' . + // 'FROM lti2_consumer ' . + // #'FROM lti2_consumer, lti_ext_consumer ' . + // 'WHERE '; + // #'WHERE lti_ext_consumer.id = consumer_pk AND '; + // if (!empty($platform->getRecordId())) { + // $query .= 'consumer_pk = %s'; + // $types = array('integer'); + // $values = array($platform->getRecordId()); + // } else { + // $query .= 'consumer_key256 = %s'; + // $types = array('text'); + // $key256 = ilLTIDataConnector::getConsumerKey($platform->getKey()); + // $values = array($key256); + // } + // // $rsConsumer = mysql_query($sql); + // $res = $ilDB->queryF($query, $types, $values); + // // if ($rsConsumer) { + // while ($row = $ilDB->fetchObject($res)) { + // // while ($row = mysql_fetch_object($rsConsumer)) { + // if (empty($key256) || empty($row->consumer_key) || ($platform->getKey() === $row->consumer_key)) { + // $platform->setRecordId(intval($row->consumer_pk)); + // $platform->name = $row->name; + // $platform->setkey(empty($row->consumer_key) ? $row->consumer_key256 : $row->consumer_key); + // $platform->secret = $row->secret; + // $platform->ltiVersion = $row->lti_version; + // $platform->consumerName = $row->consumer_name; + // $platform->consumerVersion = $row->consumer_version; + // $platform->consumerGuid = $row->consumer_guid; + // $platform->profile = json_decode((string) $row->profile); // TODO PHP8 Review: Undefined Property + // $platform->toolProxy = $row->tool_proxy; // TODO PHP8 Review: Undefined Property + // $settings = unserialize($row->settings); + // if (!is_array($settings)) { + // $settings = array(); + // } + // $platform->setSettings($settings); + // $platform->protected = (intval($row->protected) === 1); + // $platform->enabled = (intval($row->enabled) === 1); + // $platform->enableFrom = null; + // if (!is_null($row->enable_from)) { + // $platform->enableFrom = strtotime($row->enable_from); + // } + // $platform->enableUntil = null; + // if (!is_null($row->enable_until)) { + // $platform->enableUntil = strtotime($row->enable_until); + // } + // $platform->lastAccess = null; + // if (!is_null($row->last_access)) { + // $platform->lastAccess = strtotime($row->last_access); + // } + // $platform->created = strtotime($row->created); + // $platform->updated = strtotime($row->updated); + // + // //ILIAS specific + // $platform->setExtConsumerId((int) $row->ext_consumer_id); + // $platform->setRefId((int) $row->ref_id); + // #$platform->setTitle($row->title); + // #$platform->setDescription($row->description); + // #$platform->setPrefix($row->prefix); + // #$platform->setLanguage($row->user_language); + // #$platform->setRole($row->role); + // // local_role_always_member + // // default_skin + // + // $ok = true; + // break; + // } + // // } + // // mysql_free_result($rsConsumer); + // } + // + // $this->loadGlobalToolConsumerSettings($platform); + // return $ok; + // } /** * Lookup record id for global settings and ref_id @@ -324,148 +324,148 @@ public function lookupRecordIdByGlobalSettingsAndRefId(ilLTIPlatform $platform): return null; } -// /** -// * Save platform object. -// * @param Platform $platform Consumer object -// * @return bool True if the tool consumer object was successfully saved -// */ -// public function saveToolConsumer(\ILIAS\LTI\ToolProvider\Platform $platform) : bool -// { -// global $DIC; -// $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor -// -// $id = $platform->getRecordId(); -// $key = $platform->getKey(); -// $key256 = ToolProvider\DataConnector\DataConnector::getConsumerKey($key); -// // $key256 = $this->getConsumerKey($key); -// if ($key === $key256) { -// $key = null; -// } -// $protected = ($platform->protected) ? 1 : 0; -// $enabled = ($platform->enabled) ? 1 : 0; -// $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null; -// $settingsValue = serialize($platform->getSettings()); -// $time = time(); -// $now = date("{$this->dateFormat} {$this->timeFormat}", $time); -// $from = null; -// if (!is_null($platform->enableFrom)) { -// $from = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableFrom); -// } -// $until = null; -// if (!is_null($platform->enableUntil)) { -// $until = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableUntil); -// } -// $last = null; -// if (!is_null($platform->lastAccess)) { -// $last = date($this->dateFormat, $platform->lastAccess); -// } -// -// if (empty($id)) { -// $platform->setRecordId($ilDB->nextId('lti_ext_consumer')); -// $id = $platform->getRecordId(); -// $platform->created = $time; -// $platform->updated = $time; -// if ($key256 == null) { -// $key256 = $id . ToolProvider\DataConnector\DataConnector::getRandomString(10); -// } -// -// // $query = "INSERT INTO {$this->dbTableNamePrefix}" . $this->CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' . -// $query = 'INSERT INTO lti2_consumer (consumer_key256, consumer_key, name, ' . -// 'secret, lti_version, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' . -// 'enable_from, enable_until, last_access, created, updated, consumer_pk) ' . -// 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'; -// $types = array("text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "integer", -// "integer", -// "timestamp", -// "timestamp", -// "timestamp", -// "timestamp", -// "timestamp", -// "integer" -// ); -// $values = array($key256, -// $key, -// $platform->name, -// $platform->secret, -// $platform->ltiVersion, -// $platform->consumerName, -// $platform->consumerVersion, -// $platform->consumerGuid, -// $profile, -// $platform->toolProxy, // TODO PHP8 Review: Undefined Property -// $settingsValue, -// $protected, -// $enabled, -// $from, -// $until, -// $last, -// $now, -// $now, -// $id -// ); -// $ilDB->manipulateF($query, $types, $values); -// } else { -// $platform->updated = $time; -// -// $query = 'UPDATE lti2_consumer SET ' . -// 'consumer_key256 = %s, consumer_key = %s, name = %s, ' . -// 'secret= %s, lti_version = %s, consumer_name = %s, consumer_version = %s, consumer_guid = %s, ' . -// 'profile = %s, tool_proxy = %s, settings = %s, protected = %s, enabled = %s, ' . -// 'enable_from = %s, enable_until = %s, last_access = %s, updated = %s ' . -// 'WHERE consumer_pk = %s'; -// $types = array("text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "text", -// "integer", -// "integer", -// "timestamp", -// "timestamp", -// "timestamp", -// "timestamp", -// "integer" -// ); -// $values = array($key256, -// $key, -// $platform->name, -// $platform->secret, -// $platform->ltiVersion, -// $platform->consumerName, -// $platform->consumerVersion, -// $platform->consumerGuid, -// $profile, -// $platform->toolProxy, // TODO PHP8 Review: Undefined Property -// $settingsValue, -// $protected, -// $enabled, -// $from, -// $until, -// $last, -// $now, -// $id -// ); -// $ilDB->manipulateF($query, $types, $values); -// } -// return true; -// } + // /** + // * Save platform object. + // * @param Platform $platform Consumer object + // * @return bool True if the tool consumer object was successfully saved + // */ + // public function saveToolConsumer(\ILIAS\LTI\ToolProvider\Platform $platform) : bool + // { + // global $DIC; + // $ilDB = $DIC->database(); // TODO PHP8 Review: Move Global Access to Constructor + // + // $id = $platform->getRecordId(); + // $key = $platform->getKey(); + // $key256 = ToolProvider\DataConnector\DataConnector::getConsumerKey($key); + // // $key256 = $this->getConsumerKey($key); + // if ($key === $key256) { + // $key = null; + // } + // $protected = ($platform->protected) ? 1 : 0; + // $enabled = ($platform->enabled) ? 1 : 0; + // $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null; + // $settingsValue = serialize($platform->getSettings()); + // $time = time(); + // $now = date("{$this->dateFormat} {$this->timeFormat}", $time); + // $from = null; + // if (!is_null($platform->enableFrom)) { + // $from = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableFrom); + // } + // $until = null; + // if (!is_null($platform->enableUntil)) { + // $until = date("{$this->dateFormat} {$this->timeFormat}", $platform->enableUntil); + // } + // $last = null; + // if (!is_null($platform->lastAccess)) { + // $last = date($this->dateFormat, $platform->lastAccess); + // } + // + // if (empty($id)) { + // $platform->setRecordId($ilDB->nextId('lti_ext_consumer')); + // $id = $platform->getRecordId(); + // $platform->created = $time; + // $platform->updated = $time; + // if ($key256 == null) { + // $key256 = $id . ToolProvider\DataConnector\DataConnector::getRandomString(10); + // } + // + // // $query = "INSERT INTO {$this->dbTableNamePrefix}" . $this->CONSUMER_TABLE_NAME . ' (consumer_key256, consumer_key, name, ' . + // $query = 'INSERT INTO lti2_consumer (consumer_key256, consumer_key, name, ' . + // 'secret, lti_version, consumer_name, consumer_version, consumer_guid, profile, tool_proxy, settings, protected, enabled, ' . + // 'enable_from, enable_until, last_access, created, updated, consumer_pk) ' . + // 'VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'; + // $types = array("text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "integer", + // "integer", + // "timestamp", + // "timestamp", + // "timestamp", + // "timestamp", + // "timestamp", + // "integer" + // ); + // $values = array($key256, + // $key, + // $platform->name, + // $platform->secret, + // $platform->ltiVersion, + // $platform->consumerName, + // $platform->consumerVersion, + // $platform->consumerGuid, + // $profile, + // $platform->toolProxy, // TODO PHP8 Review: Undefined Property + // $settingsValue, + // $protected, + // $enabled, + // $from, + // $until, + // $last, + // $now, + // $now, + // $id + // ); + // $ilDB->manipulateF($query, $types, $values); + // } else { + // $platform->updated = $time; + // + // $query = 'UPDATE lti2_consumer SET ' . + // 'consumer_key256 = %s, consumer_key = %s, name = %s, ' . + // 'secret= %s, lti_version = %s, consumer_name = %s, consumer_version = %s, consumer_guid = %s, ' . + // 'profile = %s, tool_proxy = %s, settings = %s, protected = %s, enabled = %s, ' . + // 'enable_from = %s, enable_until = %s, last_access = %s, updated = %s ' . + // 'WHERE consumer_pk = %s'; + // $types = array("text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "text", + // "integer", + // "integer", + // "timestamp", + // "timestamp", + // "timestamp", + // "timestamp", + // "integer" + // ); + // $values = array($key256, + // $key, + // $platform->name, + // $platform->secret, + // $platform->ltiVersion, + // $platform->consumerName, + // $platform->consumerVersion, + // $platform->consumerGuid, + // $profile, + // $platform->toolProxy, // TODO PHP8 Review: Undefined Property + // $settingsValue, + // $protected, + // $enabled, + // $from, + // $until, + // $last, + // $now, + // $id + // ); + // $ilDB->manipulateF($query, $types, $values); + // } + // return true; + // } /** * Save lti_ext_consumer @@ -521,7 +521,7 @@ public function saveToolConsumerILIAS(ilLTIPlatform $platform): bool $protected = ($platform->protected) ? 1 : 0; $enabled = ($platform->enabled) ? 1 : 0; $profile = (!empty($platform->profile)) ? json_encode($platform->profile) : null; -// $settingsValue = '{}'; + // $settingsValue = '{}'; $this->fixPlatformSettings($platform, true); $settingsValue = json_encode($platform->getSettings()); $this->fixPlatformSettings($platform, false); @@ -680,6 +680,11 @@ public function deleteGlobalToolConsumerSettings(ilLTIPlatform $platform): bool $values = array($platform->getExtConsumerId()); $ilDB->manipulateF($query, $types, $values); + $query = 'DELETE FROM lti2_consumer WHERE ext_consumer_id = %s'; + $types = array("integer"); + $values = array($platform->getExtConsumerId()); + $ilDB->manipulateF($query, $types, $values); + // delete all assigned lti consumers $platform->initialize(); return true; @@ -790,9 +795,9 @@ public function deleteToolConsumer(\ILIAS\LTI\ToolProvider\Platform $platform): $values = array($platform->getRecordId()); $ilDB->manipulateF($query, $types, $values); -// if ($ok) { + // if ($ok) { $platform->initialize(); -// } + // } return true; } @@ -905,29 +910,29 @@ public function getToolConsumers(): array ### ToolProxy methods ### -// ### -// # Load the tool proxy from the database -// ### -// public function loadToolProxy($toolProxy) : bool -// { -// return false; -// } -// -// ### -// # Save the tool proxy to the database -// ### -// public function saveToolProxy($toolProxy) : bool -// { -// return false; -// } -// -// ### -// # Delete the tool proxy from the database -// ### -// public function deleteToolProxy($toolProxy) : bool -// { -// return false; -// } + // ### + // # Load the tool proxy from the database + // ### + // public function loadToolProxy($toolProxy) : bool + // { + // return false; + // } + // + // ### + // # Save the tool proxy to the database + // ### + // public function saveToolProxy($toolProxy) : bool + // { + // return false; + // } + // + // ### + // # Delete the tool proxy from the database + // ### + // public function deleteToolProxy($toolProxy) : bool + // { + // return false; + // } ### ### Context methods @@ -1146,7 +1151,7 @@ public function loadResourceLink(ResourceLink $resourceLink): bool } $resourceLink->setSettings($settings); if (!is_null($row->primary_resource_link_pk)) { -// $resourceLink->primaryResourceLinkId = intval($row->primary_resource_link_pk); //UK Check + // $resourceLink->primaryResourceLinkId = intval($row->primary_resource_link_pk); //UK Check $resourceLink->primaryResourceLinkId = (string) ($row->primary_resource_link_pk); } else { $resourceLink->primaryResourceLinkId = null; @@ -1189,11 +1194,11 @@ public function saveResourceLink(ResourceLink $resourceLink): bool $now = date("{$this->dateFormat} {$this->timeFormat}", $time); $settingsValue = serialize($resourceLink->getSettings()); if (!is_null($resourceLink->getContext())) { -// $platformId = null; + // $platformId = null; $platformId = strval($resourceLink->getPlatform()->getRecordId()); $contextId = strval($resourceLink->getContext()->getRecordId()); } elseif (!is_null($resourceLink->getContextId())) { -// $platformId = null; + // $platformId = null; $platformId = strval($resourceLink->getPlatform()->getRecordId()); $contextId = strval($resourceLink->getContextId()); } else { @@ -1261,7 +1266,7 @@ public function saveResourceLink(ResourceLink $resourceLink): bool } $ok = (bool) $ilDB->manipulateF($query, $types, $values); $this->logger->debug('Update resource link with query: ' . $query); -// $this->logger->logStack(); + // $this->logger->logStack(); $this->logger->dump($values, ilLogLevel::DEBUG); $this->logger->dump($ok, ilLogLevel::DEBUG); @@ -1376,36 +1381,36 @@ public function getUserResultSourcedIDsResourceLink( return $users; } -// /** -// * Get array of shares defined for this resource link. -// * @param ResourceLink $resourceLink Resource_Link object -// * @return array Array of ResourceLinkShare objects -// */ -// public function getSharesResourceLink(\ILIAS\LTI\Tool\ResourceLink $resourceLink) : array -// { -// global $DIC; -// $ilDB = $DIC->database(); -// -// $shares = array(); -// -// $query = 'SELECT consumer_pk, resource_link_pk, share_approved ' . -// "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' . -// 'WHERE (primary_resource_link_pk = %s) ' . -// 'ORDER BY consumer_pk'; -// $types = array("integer"); -// $values = array($resourceLink->getRecordId()); -// $rsShare = $ilDB->queryF($query, $types, $values); -// if ($rsShare) { -// while ($row = $ilDB->fetchObject($rsShare)) { -// $share = new Tool\ResourceLinkShare(); -// $share->resourceLinkId = intval($row->resource_link_pk); -// $share->approved = (intval($row->share_approved) === 1); -// $shares[] = $share; -// } -// } -// -// return $shares; -// } + // /** + // * Get array of shares defined for this resource link. + // * @param ResourceLink $resourceLink Resource_Link object + // * @return array Array of ResourceLinkShare objects + // */ + // public function getSharesResourceLink(\ILIAS\LTI\Tool\ResourceLink $resourceLink) : array + // { + // global $DIC; + // $ilDB = $DIC->database(); + // + // $shares = array(); + // + // $query = 'SELECT consumer_pk, resource_link_pk, share_approved ' . + // "FROM {$this->dbTableNamePrefix}" . Tool\DataConnector\DataConnector::RESOURCE_LINK_TABLE_NAME . ' ' . + // 'WHERE (primary_resource_link_pk = %s) ' . + // 'ORDER BY consumer_pk'; + // $types = array("integer"); + // $values = array($resourceLink->getRecordId()); + // $rsShare = $ilDB->queryF($query, $types, $values); + // if ($rsShare) { + // while ($row = $ilDB->fetchObject($rsShare)) { + // $share = new Tool\ResourceLinkShare(); + // $share->resourceLinkId = intval($row->resource_link_pk); + // $share->approved = (intval($row->share_approved) === 1); + // $shares[] = $share; + // } + // } + // + // return $shares; + // } ### @@ -1472,7 +1477,7 @@ public function savePlatformNonce(\ILIAS\LTI\ToolProvider\PlatformNonce $nonce): * @param ResourceLinkShareKey $shareKey Resource_Link share key object * @return boolean True if the resource link share key object was successfully loaded */ -// public function loadResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool + // public function loadResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool public function loadResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool { $ilDB = $this->database; @@ -1512,7 +1517,7 @@ public function loadResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool * @param ResourceLinkShareKey $shareKey Resource link share key object * @return boolean True if the resource link share key object was successfully saved */ -// public function saveResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool + // public function saveResourceLinkShareKey(\ILIAS\LTI\Tool\ResourceLinkShareKey $shareKey) : bool public function saveResourceLinkShareKey(ResourceLinkShareKey $shareKey): bool { $ilDB = $this->database; @@ -1616,7 +1621,7 @@ public function saveUserResult(\ILIAS\LTI\ToolProvider\User $userresult): bool $time = time(); $now = date($this->dateFormat . ' ' . $this->timeFormat, $time); if (is_null($userresult->created)) { -// if (is_null($user->getRecordId())) { + // if (is_null($user->getRecordId())) { $userresult->setRecordId($ilDB->nextId($this->dbTableNamePrefix . ToolProvider\DataConnector\DataConnector::USER_RESULT_TABLE_NAME)); $userresult->created = $time; $rid = $userresult->getResourceLink()->getRecordId(); diff --git a/Services/LTI/classes/class.ilLTIRouterGUI.php b/Services/LTI/classes/class.ilLTIRouterGUI.php index 3ddc29a8bbf9..e46e68d2ff90 100755 --- a/Services/LTI/classes/class.ilLTIRouterGUI.php +++ b/Services/LTI/classes/class.ilLTIRouterGUI.php @@ -51,7 +51,7 @@ public function executeCommand(): void if (is_file($class_file)) { //ToDo: check - was $gui = $next_class::getInstance(); // Singleton! $gui = $next_class::getInstance(); -// $gui = call_user_func([$next_class, 'getInstance']); + // $gui = call_user_func([$next_class, 'getInstance']); $this->ilCtrl->forwardCommand($gui); } else { $this->main_tpl->setOnScreenMessage('failure', 'GUI-Class not found! (' . $next_class . ')'); diff --git a/Services/LTI/classes/class.ilLTIViewGUI.php b/Services/LTI/classes/class.ilLTIViewGUI.php index 0001d4677cb7..0a2ca889b860 100755 --- a/Services/LTI/classes/class.ilLTIViewGUI.php +++ b/Services/LTI/classes/class.ilLTIViewGUI.php @@ -173,7 +173,7 @@ protected function getContextId(): ?int // context_id = ref_id in request if (ilSession::has('lti_' . $ref_id . '_post_data')) { $this->log->debug("lti context session exists for " . $ref_id); -// return $ref_id; + // return $ref_id; } // sub item request $this->log->debug("ref_id not exists as context_id, walking tree backwards to find a valid context_id"); @@ -241,7 +241,7 @@ protected function getContextId(): ?int ) { return $context_id; } -// $this->dic->ui()->mainTemplate()->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); + // $this->dic->ui()->mainTemplate()->setOnScreenMessage('failure', $this->lng->txt('permission_denied'), true); $redirect = $this->link_dir . "goto.php?target=" . $obj_type . "_" . $ref_id . "<i_context_id=" . $context_id; $this->log->debug("redirect: " . $redirect); ilUtil::redirect($redirect); @@ -379,7 +379,7 @@ public function logout(bool $force_ilias_logout = false): void //ilSession::setClosingContext(ilSession::SESSION_CLOSE_USER); // needed? $auth = $this->dic['ilAuthSession']; //$auth->logout(); // needed? -// $auth->setExpired($auth::SESSION_AUTH_EXPIRED, ilAuthStatus::STATUS_UNDEFINED); + // $auth->setExpired($auth::SESSION_AUTH_EXPIRED, ilAuthStatus::STATUS_UNDEFINED); $auth->setExpired(true); session_destroy(); ilUtil::setCookie("ilClientId", ""); diff --git a/Services/LTI/classes/class.ilObjLTIAdministrationGUI.php b/Services/LTI/classes/class.ilObjLTIAdministrationGUI.php index 296cd9da07c0..c91d06c34c4c 100755 --- a/Services/LTI/classes/class.ilObjLTIAdministrationGUI.php +++ b/Services/LTI/classes/class.ilObjLTIAdministrationGUI.php @@ -247,9 +247,13 @@ protected function getConsumerForm(string $a_mode = ''): \ilPropertyFormGUI $ti_title = new ilTextInputGUI($this->lng->txt("title"), 'title'); $ti_title->setRequired(true); + $form->addItem($ti_title); $ti_description = new ilTextInputGUI($this->lng->txt("description"), 'description'); + $form->addItem($ti_description); $ti_prefix = new ilTextInputGUI($this->lng->txt("prefix"), 'prefix'); + $ti_prefix->setInfo($this->lng->txt("prefix_info")); $ti_prefix->setRequired(true); + $form->addItem($ti_prefix); #$ti_key = new ilTextInputGUI($this->lng->txt("lti_consumer_key"), 'key'); #$ti_key->setRequired(true); #$ti_secret = new ilTextInputGUI($this->lng->txt("lti_consumer_secret"), 'secret'); @@ -264,15 +268,6 @@ protected function getConsumerForm(string $a_mode = ''): \ilPropertyFormGUI $si_language = new ilSelectInputGUI($this->lng->txt("language"), "language"); $si_language->setOptions($array_lang); - - $cb_active = new ilCheckboxInputGUI($this->lng->txt('active'), 'active'); - - $form->addItem($cb_active); - $form->addItem($ti_title); - $form->addItem($ti_description); - $form->addItem($ti_prefix); - #$form->addItem($ti_key); - #$form->addItem($ti_secret); $form->addItem($si_language); // object types @@ -294,6 +289,9 @@ protected function getConsumerForm(string $a_mode = ''): \ilPropertyFormGUI $si_roles->setOptions($options); $form->addItem($si_roles); + $cb_active = new ilCheckboxInputGUI($this->lng->txt('active'), 'active'); + $form->addItem($cb_active); + if ($a_mode == 'edit') { $form->setFormAction($this->ctrl->getFormAction($this, 'editLTIConsumer')); $form->setTitle($this->lng->txt("lti_edit_consumer")); diff --git a/Services/LTI/src/Firebase/BeforeValidException.php b/Services/LTI/src/Firebase/BeforeValidException.php index c147852b980f..595164bf35db 100755 --- a/Services/LTI/src/Firebase/BeforeValidException.php +++ b/Services/LTI/src/Firebase/BeforeValidException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class BeforeValidException extends \UnexpectedValueException +class BeforeValidException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/Services/LTI/src/Firebase/CHANGELOG.md b/Services/LTI/src/Firebase/CHANGELOG.md new file mode 100644 index 000000000000..4279dfd2331d --- /dev/null +++ b/Services/LTI/src/Firebase/CHANGELOG.md @@ -0,0 +1,163 @@ +# Changelog + +## [6.9.0](https://github.com/firebase/php-jwt/compare/v6.8.1...v6.9.0) (2023-10-04) + + +### Features + +* add payload to jwt exception ([#521](https://github.com/firebase/php-jwt/issues/521)) ([175edf9](https://github.com/firebase/php-jwt/commit/175edf958bb61922ec135b2333acf5622f2238a2)) + +## [6.8.1](https://github.com/firebase/php-jwt/compare/v6.8.0...v6.8.1) (2023-07-14) + + +### Bug Fixes + +* accept float claims but round down to ignore them ([#492](https://github.com/firebase/php-jwt/issues/492)) ([3936842](https://github.com/firebase/php-jwt/commit/39368423beeaacb3002afa7dcb75baebf204fe7e)) +* different BeforeValidException messages for nbf and iat ([#526](https://github.com/firebase/php-jwt/issues/526)) ([0a53cf2](https://github.com/firebase/php-jwt/commit/0a53cf2986e45c2bcbf1a269f313ebf56a154ee4)) + +## [6.8.0](https://github.com/firebase/php-jwt/compare/v6.7.0...v6.8.0) (2023-06-14) + + +### Features + +* add support for P-384 curve ([#515](https://github.com/firebase/php-jwt/issues/515)) ([5de4323](https://github.com/firebase/php-jwt/commit/5de4323f4baf4d70bca8663bd87682a69c656c3d)) + + +### Bug Fixes + +* handle invalid http responses ([#508](https://github.com/firebase/php-jwt/issues/508)) ([91c39c7](https://github.com/firebase/php-jwt/commit/91c39c72b22fc3e1191e574089552c1f2041c718)) + +## [6.7.0](https://github.com/firebase/php-jwt/compare/v6.6.0...v6.7.0) (2023-06-14) + + +### Features + +* add ed25519 support to JWK (public keys) ([#452](https://github.com/firebase/php-jwt/issues/452)) ([e53979a](https://github.com/firebase/php-jwt/commit/e53979abae927de916a75b9d239cfda8ce32be2a)) + +## [6.6.0](https://github.com/firebase/php-jwt/compare/v6.5.0...v6.6.0) (2023-06-13) + + +### Features + +* allow get headers when decoding token ([#442](https://github.com/firebase/php-jwt/issues/442)) ([fb85f47](https://github.com/firebase/php-jwt/commit/fb85f47cfaeffdd94faf8defdf07164abcdad6c3)) + + +### Bug Fixes + +* only check iat if nbf is not used ([#493](https://github.com/firebase/php-jwt/issues/493)) ([398ccd2](https://github.com/firebase/php-jwt/commit/398ccd25ea12fa84b9e4f1085d5ff448c21ec797)) + +## [6.5.0](https://github.com/firebase/php-jwt/compare/v6.4.0...v6.5.0) (2023-05-12) + + +### Bug Fixes + +* allow KID of '0' ([#505](https://github.com/firebase/php-jwt/issues/505)) ([9dc46a9](https://github.com/firebase/php-jwt/commit/9dc46a9c3e5801294249cfd2554c5363c9f9326a)) + + +### Miscellaneous Chores + +* drop support for PHP 7.3 ([#495](https://github.com/firebase/php-jwt/issues/495)) + +## [6.4.0](https://github.com/firebase/php-jwt/compare/v6.3.2...v6.4.0) (2023-02-08) + + +### Features + +* add support for W3C ES256K ([#462](https://github.com/firebase/php-jwt/issues/462)) ([213924f](https://github.com/firebase/php-jwt/commit/213924f51936291fbbca99158b11bd4ae56c2c95)) +* improve caching by only decoding jwks when necessary ([#486](https://github.com/firebase/php-jwt/issues/486)) ([78d3ed1](https://github.com/firebase/php-jwt/commit/78d3ed1073553f7d0bbffa6c2010009a0d483d5c)) + +## [6.3.2](https://github.com/firebase/php-jwt/compare/v6.3.1...v6.3.2) (2022-11-01) + + +### Bug Fixes + +* check kid before using as array index ([bad1b04](https://github.com/firebase/php-jwt/commit/bad1b040d0c736bbf86814c6b5ae614f517cf7bd)) + +## [6.3.1](https://github.com/firebase/php-jwt/compare/v6.3.0...v6.3.1) (2022-11-01) + + +### Bug Fixes + +* casing of GET for PSR compat ([#451](https://github.com/firebase/php-jwt/issues/451)) ([60b52b7](https://github.com/firebase/php-jwt/commit/60b52b71978790eafcf3b95cfbd83db0439e8d22)) +* string interpolation format for php 8.2 ([#446](https://github.com/firebase/php-jwt/issues/446)) ([2e07d8a](https://github.com/firebase/php-jwt/commit/2e07d8a1524d12b69b110ad649f17461d068b8f2)) + +## 6.3.0 / 2022-07-15 + + - Added ES256 support to JWK parsing ([#399](https://github.com/firebase/php-jwt/pull/399)) + - Fixed potential caching error in `CachedKeySet` by caching jwks as strings ([#435](https://github.com/firebase/php-jwt/pull/435)) + +## 6.2.0 / 2022-05-14 + + - Added `CachedKeySet` ([#397](https://github.com/firebase/php-jwt/pull/397)) + - Added `$defaultAlg` parameter to `JWT::parseKey` and `JWT::parseKeySet` ([#426](https://github.com/firebase/php-jwt/pull/426)). + +## 6.1.0 / 2022-03-23 + + - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0 + - Add parameter typing and return types where possible + +## 6.0.0 / 2022-01-24 + + - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information. + - New Key object to prevent key/algorithm type confusion (#365) + - Add JWK support (#273) + - Add ES256 support (#256) + - Add ES384 support (#324) + - Add Ed25519 support (#343) + +## 5.0.0 / 2017-06-26 +- Support RS384 and RS512. + See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! +- Add an example for RS256 openssl. + See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! +- Detect invalid Base64 encoding in signature. + See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! +- Update `JWT::verify` to handle OpenSSL errors. + See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! +- Add `array` type hinting to `decode` method + See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! +- Add all JSON error types. + See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! +- Bugfix 'kid' not in given key list. + See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! +- Miscellaneous cleanup, documentation and test fixes. + See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), + [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and + [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), + [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! + +## 4.0.0 / 2016-07-17 +- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! +- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! +- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! +- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! + +## 3.0.0 / 2015-07-22 +- Minimum PHP version updated from `5.2.0` to `5.3.0`. +- Add `\Firebase\JWT` namespace. See +[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to +[@Dashron](https://github.com/Dashron)! +- Require a non-empty key to decode and verify a JWT. See +[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to +[@sjones608](https://github.com/sjones608)! +- Cleaner documentation blocks in the code. See +[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to +[@johanderuijter](https://github.com/johanderuijter)! + +## 2.2.0 / 2015-06-22 +- Add support for adding custom, optional JWT headers to `JWT::encode()`. See +[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to +[@mcocaro](https://github.com/mcocaro)! + +## 2.1.0 / 2015-05-20 +- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew +between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! +- Add support for passing an object implementing the `ArrayAccess` interface for +`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! + +## 2.0.0 / 2015-04-01 +- **Note**: It is strongly recommended that you update to > v2.0.0 to address + known security vulnerabilities in prior versions when both symmetric and + asymmetric keys are used together. +- Update signature for `JWT::decode(...)` to require an array of supported + algorithms to use when verifying token signatures. diff --git a/Services/LTI/src/Firebase/CachedKeySet.php b/Services/LTI/src/Firebase/CachedKeySet.php index f80a7b7f608c..ebdf757f10ff 100755 --- a/Services/LTI/src/Firebase/CachedKeySet.php +++ b/Services/LTI/src/Firebase/CachedKeySet.php @@ -3,6 +3,7 @@ namespace Firebase\JWT; use ArrayAccess; +use InvalidArgumentException; use LogicException; use OutOfBoundsException; use Psr\Cache\CacheItemInterface; @@ -10,6 +11,7 @@ use Psr\Http\Client\ClientInterface; use Psr\Http\Message\RequestFactoryInterface; use RuntimeException; +use UnexpectedValueException; /** * @implements ArrayAccess @@ -41,7 +43,7 @@ class CachedKeySet implements ArrayAccess */ private ?CacheItemInterface $cacheItem; /** - * @var array + * @var array> */ private array $keySet; /** @@ -68,6 +70,10 @@ class CachedKeySet implements ArrayAccess * @var int */ private int $maxCallsPerMinute = 10; + /** + * @var string|null + */ + private ?string $defaultAlg; public function __construct( string $jwksUri, @@ -75,7 +81,8 @@ public function __construct( RequestFactoryInterface $httpFactory, CacheItemPoolInterface $cache, int $expiresAfter = null, - bool $rateLimit = false + bool $rateLimit = false, + string $defaultAlg = null ) { $this->jwksUri = $jwksUri; $this->httpClient = $httpClient; @@ -83,6 +90,7 @@ public function __construct( $this->cache = $cache; $this->expiresAfter = $expiresAfter; $this->rateLimit = $rateLimit; + $this->defaultAlg = $defaultAlg; $this->setCacheKeys(); } @@ -95,7 +103,7 @@ public function offsetGet($keyId): Key if (!$this->keyIdExists($keyId)) { throw new OutOfBoundsException('Key ID not found'); } - return $this->keySet[$keyId]; + return JWK::parseKey($this->keySet[$keyId], $this->defaultAlg); } /** @@ -124,15 +132,43 @@ public function offsetUnset($offset): void throw new LogicException('Method not implemented'); } + /** + * @return array + */ + private function formatJwksForCache(string $jwks): array + { + $jwks = json_decode($jwks, true); + + if (!isset($jwks['keys'])) { + throw new UnexpectedValueException('"keys" member must exist in the JWK Set'); + } + + if (empty($jwks['keys'])) { + throw new InvalidArgumentException('JWK Set did not contain any keys'); + } + + $keys = []; + foreach ($jwks['keys'] as $k => $v) { + $kid = isset($v['kid']) ? $v['kid'] : $k; + $keys[(string) $kid] = $v; + } + + return $keys; + } + private function keyIdExists(string $keyId): bool { - $keySetToCache = null; if (null === $this->keySet) { $item = $this->getCacheItem(); // Try to load keys from cache if ($item->isHit()) { - // item found! Return it + // item found! retrieve it $this->keySet = $item->get(); + // If the cached item is a string, the JWKS response was cached (previous behavior). + // Parse this into expected format array instead. + if (\is_string($this->keySet)) { + $this->keySet = $this->formatJwksForCache($this->keySet); + } } } @@ -140,19 +176,27 @@ private function keyIdExists(string $keyId): bool if ($this->rateLimitExceeded()) { return false; } - $request = $this->httpFactory->createRequest('get', $this->jwksUri); + $request = $this->httpFactory->createRequest('GET', $this->jwksUri); $jwksResponse = $this->httpClient->sendRequest($request); - $jwks = json_decode((string) $jwksResponse->getBody(), true); - $this->keySet = $keySetToCache = JWK::parseKeySet($jwks); + if ($jwksResponse->getStatusCode() !== 200) { + throw new UnexpectedValueException( + sprintf( + 'HTTP Error: %d %s for URI "%s"', + $jwksResponse->getStatusCode(), + $jwksResponse->getReasonPhrase(), + $this->jwksUri, + ), + $jwksResponse->getStatusCode() + ); + } + $this->keySet = $this->formatJwksForCache((string) $jwksResponse->getBody()); if (!isset($this->keySet[$keyId])) { return false; } - } - if ($keySetToCache) { $item = $this->getCacheItem(); - $item->set($keySetToCache); + $item->set($this->keySet); if ($this->expiresAfter) { $item->expiresAfter($this->expiresAfter); } diff --git a/Services/LTI/src/Firebase/ExpiredException.php b/Services/LTI/src/Firebase/ExpiredException.php index 81ba52d43f60..12fef0944868 100755 --- a/Services/LTI/src/Firebase/ExpiredException.php +++ b/Services/LTI/src/Firebase/ExpiredException.php @@ -2,6 +2,17 @@ namespace Firebase\JWT; -class ExpiredException extends \UnexpectedValueException +class ExpiredException extends \UnexpectedValueException implements JWTExceptionWithPayloadInterface { + private object $payload; + + public function setPayload(object $payload): void + { + $this->payload = $payload; + } + + public function getPayload(): object + { + return $this->payload; + } } diff --git a/Services/LTI/src/Firebase/JWK.php b/Services/LTI/src/Firebase/JWK.php index 766a766eb2ad..63fb2484b320 100755 --- a/Services/LTI/src/Firebase/JWK.php +++ b/Services/LTI/src/Firebase/JWK.php @@ -20,10 +20,29 @@ */ class JWK { + private const OID = '1.2.840.10045.2.1'; + private const ASN1_OBJECT_IDENTIFIER = 0x06; + private const ASN1_SEQUENCE = 0x10; // also defined in JWT + private const ASN1_BIT_STRING = 0x03; + private const EC_CURVES = [ + 'P-256' => '1.2.840.10045.3.1.7', // Len: 64 + 'secp256k1' => '1.3.132.0.10', // Len: 64 + 'P-384' => '1.3.132.0.34', // Len: 96 + // 'P-521' => '1.3.132.0.35', // Len: 132 (not supported) + ]; + + // For keys with "kty" equal to "OKP" (Octet Key Pair), the "crv" parameter must contain the key subtype. + // This library supports the following subtypes: + private const OKP_SUBTYPES = [ + 'Ed25519' => true, // RFC 8037 + ]; + /** * Parse a set of JWK keys * * @param array $jwks The JSON Web Key Set as an associative array + * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * JSON Web Key Set * * @return array An associative array of key IDs (kid) to Key objects * @@ -33,7 +52,7 @@ class JWK * * @uses parseKey */ - public static function parseKeySet(array $jwks): array + public static function parseKeySet(array $jwks, string $defaultAlg = null): array { $keys = []; @@ -47,7 +66,7 @@ public static function parseKeySet(array $jwks): array foreach ($jwks['keys'] as $k => $v) { $kid = isset($v['kid']) ? $v['kid'] : $k; - if ($key = self::parseKey($v)) { + if ($key = self::parseKey($v, $defaultAlg)) { $keys[(string) $kid] = $key; } } @@ -63,8 +82,10 @@ public static function parseKeySet(array $jwks): array * Parse a JWK key * * @param array $jwk An individual JWK + * @param string $defaultAlg The algorithm for the Key object if "alg" is not set in the + * JSON Web Key Set * - * @return Key|string The key object for the JWK //UK: added |string + * @return Key The key object for the JWK * * @throws InvalidArgumentException Provided JWK is empty * @throws UnexpectedValueException Provided JWK was invalid @@ -72,7 +93,7 @@ public static function parseKeySet(array $jwks): array * * @uses createPemFromModulusAndExponent */ - public static function parseKey(array $jwk) + public static function parseKey(array $jwk, string $defaultAlg = null): ?Key { if (empty($jwk)) { throw new InvalidArgumentException('JWK must not be empty'); @@ -83,10 +104,14 @@ public static function parseKey(array $jwk) } if (!isset($jwk['alg'])) { - // The "alg" parameter is optional in a KTY, but is required for parsing in - // this library. Add it manually to your JWK array if it doesn't already exist. - // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4 - throw new UnexpectedValueException('JWK must contain an "alg" parameter'); + if (\is_null($defaultAlg)) { + // The "alg" parameter is optional in a KTY, but an algorithm is required + // for parsing in this library. Use the $defaultAlg parameter when parsing the + // key set in order to prevent this error. + // @see https://datatracker.ietf.org/doc/html/rfc7517#section-4.4 + throw new UnexpectedValueException('JWK must contain an "alg" parameter'); + } + $jwk['alg'] = $defaultAlg; } switch ($jwk['kty']) { @@ -106,14 +131,93 @@ public static function parseKey(array $jwk) ); } return new Key($publicKey, $jwk['alg']); + case 'EC': + if (isset($jwk['d'])) { + // The key is actually a private key + throw new UnexpectedValueException('Key data must be for a public key'); + } + + if (empty($jwk['crv'])) { + throw new UnexpectedValueException('crv not set'); + } + + if (!isset(self::EC_CURVES[$jwk['crv']])) { + throw new DomainException('Unrecognised or unsupported EC curve'); + } + + if (empty($jwk['x']) || empty($jwk['y'])) { + throw new UnexpectedValueException('x and y not set'); + } + + $publicKey = self::createPemFromCrvAndXYCoordinates($jwk['crv'], $jwk['x'], $jwk['y']); + return new Key($publicKey, $jwk['alg']); + case 'OKP': + if (isset($jwk['d'])) { + // The key is actually a private key + throw new UnexpectedValueException('Key data must be for a public key'); + } + + if (!isset($jwk['crv'])) { + throw new UnexpectedValueException('crv not set'); + } + + if (empty(self::OKP_SUBTYPES[$jwk['crv']])) { + throw new DomainException('Unrecognised or unsupported OKP key subtype'); + } + + if (empty($jwk['x'])) { + throw new UnexpectedValueException('x not set'); + } + + // This library works internally with EdDSA keys (Ed25519) encoded in standard base64. + $publicKey = JWT::convertBase64urlToBase64($jwk['x']); + return new Key($publicKey, $jwk['alg']); default: - // Currently only RSA is supported break; } return null; } + /** + * Converts the EC JWK values to pem format. + * + * @param string $crv The EC curve (only P-256 & P-384 is supported) + * @param string $x The EC x-coordinate + * @param string $y The EC y-coordinate + * + * @return string + */ + private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, string $y): string + { + $pem = + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_SEQUENCE, + self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID(self::OID) + ) + . self::encodeDER( + self::ASN1_OBJECT_IDENTIFIER, + self::encodeOID(self::EC_CURVES[$crv]) + ) + ) . + self::encodeDER( + self::ASN1_BIT_STRING, + \chr(0x00) . \chr(0x04) + . JWT::urlsafeB64Decode($x) + . JWT::urlsafeB64Decode($y) + ) + ); + + return sprintf( + "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", + wordwrap(base64_encode($pem), 64, "\n", true) + ); + } + /** * Create a public key represented in PEM format from RSA modulus and exponent information * @@ -154,11 +258,9 @@ private static function createPemFromModulusAndExponent( $rsaOID . $rsaPublicKey ); - $rsaPublicKey = "-----BEGIN PUBLIC KEY-----\r\n" . + return "-----BEGIN PUBLIC KEY-----\r\n" . \chunk_split(\base64_encode($rsaPublicKey), 64) . '-----END PUBLIC KEY-----'; - - return $rsaPublicKey; } /** @@ -180,4 +282,68 @@ private static function encodeLength(int $length): string return \pack('Ca*', 0x80 | \strlen($temp), $temp); } + + /** + * Encodes a value into a DER object. + * Also defined in Firebase\JWT\JWT + * + * @param int $type DER tag + * @param string $value the value to encode + * @return string the encoded object + */ + private static function encodeDER(int $type, string $value): string + { + $tag_header = 0; + if ($type === self::ASN1_SEQUENCE) { + $tag_header |= 0x20; + } + + // Type + $der = \chr($tag_header | $type); + + // Length + $der .= \chr(\strlen($value)); + + return $der . $value; + } + + /** + * Encodes a string into a DER-encoded OID. + * + * @param string $oid the OID string + * @return string the binary DER-encoded OID + */ + private static function encodeOID(string $oid): string + { + $octets = explode('.', $oid); + + // Get the first octet + $first = (int) array_shift($octets); + $second = (int) array_shift($octets); + $oid = \chr($first * 40 + $second); + + // Iterate over subsequent octets + foreach ($octets as $octet) { + if ($octet == 0) { + $oid .= \chr(0x00); + continue; + } + $bin = ''; + + while ($octet) { + $bin .= \chr(0x80 | ($octet & 0x7f)); + $octet >>= 7; + } + $bin[0] = $bin[0] & \chr(0x7f); + + // Convert to big endian if necessary + if (pack('V', 65534) == pack('L', 65534)) { + $oid .= strrev($bin); + } else { + $oid .= $bin; + } + } + + return $oid; + } } diff --git a/Services/LTI/src/Firebase/JWT.php b/Services/LTI/src/Firebase/JWT.php index 6e8d08b7bfb5..f7296bc07e2c 100755 --- a/Services/LTI/src/Firebase/JWT.php +++ b/Services/LTI/src/Firebase/JWT.php @@ -55,6 +55,7 @@ class JWT public static array $supported_algs = [ 'ES384' => ['openssl', 'SHA384'], 'ES256' => ['openssl', 'SHA256'], + 'ES256K' => ['openssl', 'SHA256'], 'HS256' => ['hash_hmac', 'SHA256'], 'HS384' => ['hash_hmac', 'SHA384'], 'HS512' => ['hash_hmac', 'SHA512'], @@ -68,15 +69,20 @@ class JWT * Decodes a JWT string into a PHP object. * * @param string $jwt The JWT - * @param Key|array $keyOrKeyArray The Key or associative array of key IDs (kid) to Key objects. - * If the algorithm used is asymmetric, this is the public key - * Each Key object contains an algorithm and matching key. - * Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' + * @param Key|ArrayAccess|array $keyOrKeyArray The Key or associative array of key IDs + * (kid) to Key objects. + * If the algorithm used is asymmetric, this is + * the public key. + * Each Key object contains an algorithm and + * matching key. + * Supported algorithms are 'ES384','ES256', + * 'HS256', 'HS384', 'HS512', 'RS256', 'RS384' + * and 'RS512'. + * @param stdClass $headers Optional. Populates stdClass with headers. * * @return stdClass The JWT's payload as a PHP object * - * @throws InvalidArgumentException Provided key/key-array was empty + * @throws InvalidArgumentException Provided key/key-array was empty or malformed * @throws DomainException Provided JWT is malformed * @throws UnexpectedValueException Provided JWT was invalid * @throws SignatureInvalidException Provided JWT was invalid because the signature verification failed @@ -89,7 +95,8 @@ class JWT */ public static function decode( string $jwt, - $keyOrKeyArray + $keyOrKeyArray, + stdClass &$headers = null ): stdClass { // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; @@ -98,7 +105,7 @@ public static function decode( throw new InvalidArgumentException('Key may not be empty'); } $tks = \explode('.', $jwt); - if (\count($tks) != 3) { + if (\count($tks) !== 3) { throw new UnexpectedValueException('Wrong number of segments'); } list($headb64, $bodyb64, $cryptob64) = $tks; @@ -106,6 +113,9 @@ public static function decode( if (null === ($header = static::jsonDecode($headerRaw))) { throw new UnexpectedValueException('Invalid header encoding'); } + if ($headers !== null) { + $headers = $header; + } $payloadRaw = static::urlsafeB64Decode($bodyb64); if (null === ($payload = static::jsonDecode($payloadRaw))) { throw new UnexpectedValueException('Invalid claims encoding'); @@ -132,46 +142,52 @@ public static function decode( // See issue #351 throw new UnexpectedValueException('Incorrect key for this algorithm'); } - if ($header->alg === 'ES256' || $header->alg === 'ES384') { - // OpenSSL expects an ASN.1 DER sequence for ES256/ES384 signatures + if (\in_array($header->alg, ['ES256', 'ES256K', 'ES384'], true)) { + // OpenSSL expects an ASN.1 DER sequence for ES256/ES256K/ES384 signatures $sig = self::signatureToDER($sig); } - if (!self::verify("$headb64.$bodyb64", $sig, $key->getKeyMaterial(), $header->alg)) { + if (!self::verify("{$headb64}.{$bodyb64}", $sig, $key->getKeyMaterial(), $header->alg)) { throw new SignatureInvalidException('Signature verification failed'); } // Check the nbf if it is defined. This is the time that the // token can actually be used. If it's not yet that time, abort. - if (isset($payload->nbf) && $payload->nbf > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->nbf) + if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { + $ex = new BeforeValidException( + 'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf) ); + $ex->setPayload($payload); + throw $ex; } // Check that this token has been created before 'now'. This prevents // using tokens that have been created for later use (and haven't // correctly used the nbf claim). - if (isset($payload->iat) && $payload->iat > ($timestamp + static::$leeway)) { - throw new BeforeValidException( - 'Cannot handle token prior to ' . \date(DateTime::ISO8601, $payload->iat) + if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { + $ex = new BeforeValidException( + 'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat) ); + $ex->setPayload($payload); + throw $ex; } // Check if this token has expired. if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { - throw new ExpiredException('Expired token'); + $ex = new ExpiredException('Expired token'); + $ex->setPayload($payload); + throw $ex; } return $payload; } /** - * Converts and signs a PHP object or array into a JWT string. + * Converts and signs a PHP array into a JWT string. * * @param array $payload PHP array * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. - * @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' + * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', + * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * @param string $keyId * @param array $head An array with header elements to attach * @@ -210,8 +226,8 @@ public static function encode( * * @param string $msg The message to sign * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. - * @param string $alg Supported algorithms are 'ES384','ES256', 'HS256', 'HS384', - * 'HS512', 'RS256', 'RS384', and 'RS512' + * @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256', + * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * * @return string An encrypted message * @@ -238,7 +254,7 @@ public static function sign( if (!$success) { throw new DomainException('OpenSSL unable to sign data'); } - if ($alg === 'ES256') { + if ($alg === 'ES256' || $alg === 'ES256K') { $signature = self::signatureFromDER($signature, 256); } elseif ($alg === 'ES384') { $signature = self::signatureFromDER($signature, 384); @@ -255,6 +271,9 @@ public static function sign( // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $key)); $key = base64_decode((string) end($lines)); + if (\strlen($key) === 0) { + throw new DomainException('Key cannot be empty string'); + } return sodium_crypto_sign_detached($msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); @@ -270,7 +289,7 @@ public static function sign( * * @param string $msg The original message (header and body) * @param string $signature The original signature - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey + * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey * @param string $alg The algorithm * * @return bool @@ -293,7 +312,8 @@ private static function verify( $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line if ($success === 1) { return true; - } elseif ($success === 0) { + } + if ($success === 0) { return false; } // returns 1 on success, 0 on failure, -1 on error. @@ -311,6 +331,12 @@ private static function verify( // The last non-empty line is used as the key. $lines = array_filter(explode("\n", $keyMaterial)); $key = base64_decode((string) end($lines)); + if (\strlen($key) === 0) { + throw new DomainException('Key cannot be empty string'); + } + if (\strlen($signature) === 0) { + throw new DomainException('Signature cannot be empty string'); + } return sodium_crypto_sign_verify_detached($signature, $msg, $key); } catch (Exception $e) { throw new DomainException($e->getMessage(), 0, $e); @@ -365,7 +391,7 @@ public static function jsonEncode(array $input): string } if ($errno = \json_last_error()) { self::handleJsonError($errno); - } elseif ($json === 'null' && $input !== null) { + } elseif ($json === 'null') { throw new DomainException('Null result with non-null input'); } if ($json === false) { @@ -384,13 +410,28 @@ public static function jsonEncode(array $input): string * @throws InvalidArgumentException invalid base64 characters */ public static function urlsafeB64Decode(string $input): string + { + return \base64_decode(self::convertBase64UrlToBase64($input)); + } + + /** + * Convert a string in the base64url (URL-safe Base64) encoding to standard base64. + * + * @param string $input A Base64 encoded string with URL-safe characters (-_ and no padding) + * + * @return string A Base64 encoded string with standard characters (+/) and padding (=), when + * needed. + * + * @see https://www.rfc-editor.org/rfc/rfc4648 + */ + public static function convertBase64UrlToBase64(string $input): string { $remainder = \strlen($input) % 4; if ($remainder) { $padlen = 4 - $remainder; $input .= \str_repeat('=', $padlen); } - return \base64_decode(\strtr($input, '-_', '+/')); + return \strtr($input, '-_', '+/'); } /** @@ -424,14 +465,15 @@ private static function getKey( return $keyOrKeyArray; } + if (empty($kid) && $kid !== '0') { + throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); + } + if ($keyOrKeyArray instanceof CachedKeySet) { // Skip "isset" check, as this will automatically refresh if not set return $keyOrKeyArray[$kid]; } - if (empty($kid)) { - throw new UnexpectedValueException('"kid" empty, unable to lookup correct key'); - } if (!isset($keyOrKeyArray[$kid])) { throw new UnexpectedValueException('"kid" invalid, unable to lookup correct key'); } @@ -510,7 +552,7 @@ private static function signatureToDER(string $sig): string { // Separate the signature into r-value and s-value $length = max(1, (int) (\strlen($sig) / 2)); - list($r, $s) = \str_split($sig, $length > 0 ? $length : 1); + list($r, $s) = \str_split($sig, $length); // Trim leading zeros $r = \ltrim($r, "\x00"); @@ -610,7 +652,7 @@ private static function readDER(string $der, int $offset = 0): array } // Value - if ($type == self::ASN1_BIT_STRING) { + if ($type === self::ASN1_BIT_STRING) { $pos++; // Skip the first contents octet (padding indicator) $data = \substr($der, $pos, $len - 1); $pos += $len - 1; diff --git a/Services/LTI/src/Firebase/JWTExceptionWithPayloadInterface.php b/Services/LTI/src/Firebase/JWTExceptionWithPayloadInterface.php new file mode 100644 index 000000000000..7b5e94ba0515 --- /dev/null +++ b/Services/LTI/src/Firebase/JWTExceptionWithPayloadInterface.php @@ -0,0 +1,21 @@ + 'http://example.org', + 'aud' => 'http://example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; + +$headers = [ + 'x-forwarded-for' => 'www.google.com' +]; + +// Encode headers in the JWT string +$jwt = JWT::encode($payload, $key, 'HS256', null, $headers); + +// Decode headers from the JWT string WITHOUT validation +// **IMPORTANT**: This operation is vulnerable to attacks, as the JWT has not yet been verified. +// These headers could be any value sent by an attacker. +list($headersB64, $payloadB64, $sig) = explode('.', $jwt); +$decoded = json_decode(base64_decode($headersB64), true); + +print_r($decoded); +``` Example with RS256 (openssl) ---------------------------- ```php @@ -73,28 +110,43 @@ use Firebase\JWT\Key; $privateKey = << 'example.org', + 'aud' => 'example.com', + 'iat' => 1356999524, + 'nbf' => 1357000000 +]; + +$jwt1 = JWT::encode($payload, $privateKey1, 'RS256', 'kid1'); +$jwt2 = JWT::encode($payload, $privateKey2, 'EdDSA', 'kid2'); +echo "Encode 1:\n" . print_r($jwt1, true) . "\n"; +echo "Encode 2:\n" . print_r($jwt2, true) . "\n"; + +$keys = [ + 'kid1' => new Key($publicKey1, 'RS256'), + 'kid2' => new Key($publicKey2, 'EdDSA'), +]; + +$decoded1 = JWT::decode($jwt1, $keys); +$decoded2 = JWT::decode($jwt2, $keys); + +echo "Decode 1:\n" . print_r((array) $decoded1, true) . "\n"; +echo "Decode 2:\n" . print_r((array) $decoded2, true) . "\n"; +``` + Using JWKs ---------- @@ -245,6 +335,58 @@ $decoded = JWT::decode($jwt, $keySet); Miscellaneous ------------- +#### Exception Handling + +When a call to `JWT::decode` is invalid, it will throw one of the following exceptions: + +```php +use Firebase\JWT\JWT; +use Firebase\JWT\SignatureInvalidException; +use Firebase\JWT\BeforeValidException; +use Firebase\JWT\ExpiredException; +use DomainException; +use InvalidArgumentException; +use UnexpectedValueException; + +try { + $decoded = JWT::decode($payload, $keys); +} catch (InvalidArgumentException $e) { + // provided key/key-array is empty or malformed. +} catch (DomainException $e) { + // provided algorithm is unsupported OR + // provided key is invalid OR + // unknown error thrown in openSSL or libsodium OR + // libsodium is required but not available. +} catch (SignatureInvalidException $e) { + // provided JWT signature verification failed. +} catch (BeforeValidException $e) { + // provided JWT is trying to be used before "nbf" claim OR + // provided JWT is trying to be used before "iat" claim. +} catch (ExpiredException $e) { + // provided JWT is trying to be used after "exp" claim. +} catch (UnexpectedValueException $e) { + // provided JWT is malformed OR + // provided JWT is missing an algorithm / using an unsupported algorithm OR + // provided JWT algorithm does not match provided key OR + // provided key ID in key/key-array is empty or invalid. +} +``` + +All exceptions in the `Firebase\JWT` namespace extend `UnexpectedValueException`, and can be simplified +like this: + +```php +use Firebase\JWT\JWT; +use UnexpectedValueException; +try { + $decoded = JWT::decode($payload, $keys); +} catch (LogicException $e) { + // errors having to do with environmental setup or malformed JWT Keys +} catch (UnexpectedValueException $e) { + // errors having to do with JWT signature and claims +} +``` + #### Casting to array The return value of `JWT::decode` is the generic PHP object `stdClass`. If you'd like to handle with arrays @@ -258,81 +400,6 @@ $decoded = JWT::decode($payload, $keys); $decoded = json_decode(json_encode($decoded), true); ``` -Changelog ---------- - -#### 6.1.0 / 2022-03-23 - - - Drop support for PHP 5.3, 5.4, 5.5, 5.6, and 7.0 - - Add parameter typing and return types where possible - -#### 6.0.0 / 2022-01-24 - - - **Backwards-Compatibility Breaking Changes**: See the [Release Notes](https://github.com/firebase/php-jwt/releases/tag/v6.0.0) for more information. - - New Key object to prevent key/algorithm type confusion (#365) - - Add JWK support (#273) - - Add ES256 support (#256) - - Add ES384 support (#324) - - Add Ed25519 support (#343) - -#### 5.0.0 / 2017-06-26 -- Support RS384 and RS512. - See [#117](https://github.com/firebase/php-jwt/pull/117). Thanks [@joostfaassen](https://github.com/joostfaassen)! -- Add an example for RS256 openssl. - See [#125](https://github.com/firebase/php-jwt/pull/125). Thanks [@akeeman](https://github.com/akeeman)! -- Detect invalid Base64 encoding in signature. - See [#162](https://github.com/firebase/php-jwt/pull/162). Thanks [@psignoret](https://github.com/psignoret)! -- Update `JWT::verify` to handle OpenSSL errors. - See [#159](https://github.com/firebase/php-jwt/pull/159). Thanks [@bshaffer](https://github.com/bshaffer)! -- Add `array` type hinting to `decode` method - See [#101](https://github.com/firebase/php-jwt/pull/101). Thanks [@hywak](https://github.com/hywak)! -- Add all JSON error types. - See [#110](https://github.com/firebase/php-jwt/pull/110). Thanks [@gbalduzzi](https://github.com/gbalduzzi)! -- Bugfix 'kid' not in given key list. - See [#129](https://github.com/firebase/php-jwt/pull/129). Thanks [@stampycode](https://github.com/stampycode)! -- Miscellaneous cleanup, documentation and test fixes. - See [#107](https://github.com/firebase/php-jwt/pull/107), [#115](https://github.com/firebase/php-jwt/pull/115), - [#160](https://github.com/firebase/php-jwt/pull/160), [#161](https://github.com/firebase/php-jwt/pull/161), and - [#165](https://github.com/firebase/php-jwt/pull/165). Thanks [@akeeman](https://github.com/akeeman), - [@chinedufn](https://github.com/chinedufn), and [@bshaffer](https://github.com/bshaffer)! - -#### 4.0.0 / 2016-07-17 -- Add support for late static binding. See [#88](https://github.com/firebase/php-jwt/pull/88) for details. Thanks to [@chappy84](https://github.com/chappy84)! -- Use static `$timestamp` instead of `time()` to improve unit testing. See [#93](https://github.com/firebase/php-jwt/pull/93) for details. Thanks to [@josephmcdermott](https://github.com/josephmcdermott)! -- Fixes to exceptions classes. See [#81](https://github.com/firebase/php-jwt/pull/81) for details. Thanks to [@Maks3w](https://github.com/Maks3w)! -- Fixes to PHPDoc. See [#76](https://github.com/firebase/php-jwt/pull/76) for details. Thanks to [@akeeman](https://github.com/akeeman)! - -#### 3.0.0 / 2015-07-22 -- Minimum PHP version updated from `5.2.0` to `5.3.0`. -- Add `\Firebase\JWT` namespace. See -[#59](https://github.com/firebase/php-jwt/pull/59) for details. Thanks to -[@Dashron](https://github.com/Dashron)! -- Require a non-empty key to decode and verify a JWT. See -[#60](https://github.com/firebase/php-jwt/pull/60) for details. Thanks to -[@sjones608](https://github.com/sjones608)! -- Cleaner documentation blocks in the code. See -[#62](https://github.com/firebase/php-jwt/pull/62) for details. Thanks to -[@johanderuijter](https://github.com/johanderuijter)! - -#### 2.2.0 / 2015-06-22 -- Add support for adding custom, optional JWT headers to `JWT::encode()`. See -[#53](https://github.com/firebase/php-jwt/pull/53/files) for details. Thanks to -[@mcocaro](https://github.com/mcocaro)! - -#### 2.1.0 / 2015-05-20 -- Add support for adding a leeway to `JWT:decode()` that accounts for clock skew -between signing and verifying entities. Thanks to [@lcabral](https://github.com/lcabral)! -- Add support for passing an object implementing the `ArrayAccess` interface for -`$keys` argument in `JWT::decode()`. Thanks to [@aztech-dev](https://github.com/aztech-dev)! - -#### 2.0.0 / 2015-04-01 -- **Note**: It is strongly recommended that you update to > v2.0.0 to address - known security vulnerabilities in prior versions when both symmetric and - asymmetric keys are used together. -- Update signature for `JWT::decode(...)` to require an array of supported - algorithms to use when verifying token signatures. - - Tests ----- Run the tests using phpunit: diff --git a/Services/Object/classes/CommonSettings/class.ilObjectCommonSettingFormAdapter.php b/Services/Object/classes/CommonSettings/class.ilObjectCommonSettingFormAdapter.php index 1c7e02ac9522..a5ea1d0e9bfd 100644 --- a/Services/Object/classes/CommonSettings/class.ilObjectCommonSettingFormAdapter.php +++ b/Services/Object/classes/CommonSettings/class.ilObjectCommonSettingFormAdapter.php @@ -19,6 +19,10 @@ declare(strict_types=1); use ILIAS\FileUpload\FileUpload; +use ILIAS\FileUpload\DTO\UploadResult; +use ILIAS\ResourceStorage\Services as ResourceStorageServices; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectTileImageStakeholder; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectTileImageFlavourDefinition; /** * @@ -30,6 +34,9 @@ class ilObjectCommonSettingFormAdapter implements ilObjectCommonSettingFormAdapt public function __construct( private ilLanguage $language, private FileUpload $upload, + private ResourceStorageServices $storage, + private ilObjectTileImageStakeholder $stakeholder, + private ilObjectTileImageFlavourDefinition $flavour, private ilObjectCommonSettings $common_settings, private ?ilPropertyFormGUI $legacy_form = null ) { @@ -53,7 +60,6 @@ public function saveIcon(): void return; } - $item = $this->legacy_form->getItemByPostVar('icon'); if ($item && $item->getDeletionFlag()) { $this->common_settings->storePropertyIcon( @@ -101,19 +107,28 @@ public function saveTileImage(): void return; } - $file_data = $this->legacy_form->getInput('tile_image'); - if (isset($file_data['tmp_name']) && $file_data['tmp_name'] - && isset($file_data['size']) && $file_data['size'] > 0) { - $file_name_parts = explode('.', $file_data['name']); - $extension = '.' . array_pop($file_name_parts); - $tempfile = ilFileUtils::ilTempnam() . strtolower($extension); - if (!$this->upload->hasBeenProcessed()) { - $this->upload->process(); - } + $this->upload->process(); + $result_array = $this->upload->getResults(); + $result = end($result_array); - rename($file_data['tmp_name'], $tempfile); + if (!($result instanceof UploadResult) || !$result->isOK()) { + return; + } + + if ($item->getValue() === null || $item->getValue() === '') { + $i = $this->storage->manage()->upload($result, $this->stakeholder); + $this->storage->flavours()->ensure($i, $this->flavour); + $new_tile_image = $this->common_settings->getPropertyTileImage() + ->getTileImage()->withRid($i->serialize()); $this->common_settings->storePropertyTileImage( - $this->common_settings->getPropertyTileImage()->withTempFileName(basename($tempfile)) + $this->common_settings->getPropertyTileImage()->withTileImage($new_tile_image) + ); + } else { + $i = $this->storage->manage()->find($item->getValue()); + $this->storage->manage()->replaceWithUpload( + $i, + $result, + $this->stakeholder ); } } diff --git a/Services/Object/classes/CommonSettings/class.ilObjectCommonSettings.php b/Services/Object/classes/CommonSettings/class.ilObjectCommonSettings.php index 4954931f6c1e..4491c140fc8f 100644 --- a/Services/Object/classes/CommonSettings/class.ilObjectCommonSettings.php +++ b/Services/Object/classes/CommonSettings/class.ilObjectCommonSettings.php @@ -19,6 +19,10 @@ declare(strict_types=1); use ILIAS\FileUpload\FileUpload; +use ILIAS\ResourceStorage\Services as ResourceStorageServices; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectPropertyTileImage; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectTileImageStakeholder; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectTileImageFlavourDefinition; /** * @deprecated 11 This class will be removed with ILIAS 11. Please use @@ -27,10 +31,15 @@ class ilObjectCommonSettings { private ilObjectAdditionalProperties $additional_properties; + private ilObjectCoreProperties $core_properties; public function __construct( private ilLanguage $language, private FileUpload $upload, + private ResourceStorageServices $storage, + private ilObjectTileImageStakeholder $stakeholder, + private ilObjectTileImageFlavourDefinition $flavour, + private ilObjectCorePropertiesRepository $core_properties_repository, private ilObjectAdditionalPropertiesRepository $additional_properties_repository ) { } @@ -63,15 +72,15 @@ public function storePropertyHeaderActionVisibility( public function getPropertyTileImage(): ilObjectPropertyTileImage { - return $this->additional_properties->getPropertyTileImage(); + return $this->core_properties->getPropertyTileImage(); } public function storePropertyTileImage( ilObjectPropertyTileImage $property_tile_image ): void { - $this->additional_properties = $this->additional_properties + $this->core_properties = $this->core_properties ->withPropertyTileImage($property_tile_image); - $this->additional_properties_repository->store($this->additional_properties); + $this->core_properties_repository->store($this->core_properties); } public function getPropertyIcon(): ilObjectPropertyIcon @@ -96,6 +105,16 @@ public function storePropertyIcon( public function legacyForm(ilPropertyFormGUI $form, ilObject $object): ilObjectCommonSettingFormAdapter { $this->additional_properties = $this->additional_properties_repository->getFor($object->getId()); - return new ilObjectCommonSettingFormAdapter($this->language, $this->upload, $this, $form); + $this->core_properties = $this->core_properties_repository->getFor($object->getId()); + + return new ilObjectCommonSettingFormAdapter( + $this->language, + $this->upload, + $this->storage, + $this->stakeholder, + $this->flavour, + $this, + $form + ); } } diff --git a/Services/Object/classes/Properties/AdditionalProperties/Icon/ilObjectPropertyIcon.php b/Services/Object/classes/Properties/AdditionalProperties/Icon/ilObjectPropertyIcon.php index 83f2f7da80bb..d792f86b892e 100644 --- a/Services/Object/classes/Properties/AdditionalProperties/Icon/ilObjectPropertyIcon.php +++ b/Services/Object/classes/Properties/AdditionalProperties/Icon/ilObjectPropertyIcon.php @@ -18,6 +18,7 @@ declare(strict_types=1); +use ILIAS\Object\Properties\ObjectTypeSpecificProperties\ilObjectTypeSpecificPropertyProviders; use ILIAS\UI\Component\Input\Field\Factory as FieldFactory; use ILIAS\UI\Component\Input\Field\File; use ILIAS\Refinery\Factory as Refinery; @@ -36,7 +37,8 @@ class ilObjectPropertyIcon implements ilObjectProperty public function __construct( private bool $custom_icons_enabled, - private ?ilObjectCustomIcon $custom_icon = null + private ?ilObjectCustomIcon $custom_icon = null, + private ?ilObjectTypeSpecificPropertyProviders $object_type_specific_property_providers = null ) { } diff --git a/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImage.php b/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImage.php deleted file mode 100644 index 56f547efbdf0..000000000000 --- a/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImage.php +++ /dev/null @@ -1,212 +0,0 @@ -image_converter = $DIC->fileConverters()->legacyImages(); - } - - public function getExtension(): string - { - if ($this->ext === '') { - $this->ext = ilContainer::_lookupContainerSetting($this->object_id, 'tile_image'); - } - return $this->ext; - } - - public function copy(int $target_obj_id): void - { - if (!$this->exists()) { - ilContainer::_deleteContainerSettings($target_obj_id, 'tile_image'); - return; - } - - try { - $this->filesystem->copy( - $this->getRelativePath(), - preg_replace( - '/(' . "tile_image_" . ')(\d*)\/(.*)$/', - '${1}' . $target_obj_id . '/${3}', - $this->getRelativePath() - ) - ); - - ilContainer::_writeContainerSetting($target_obj_id, 'tile_image', $this->getExtension()); - } catch (Exception $e) { - ilContainer::_deleteContainerSettings($target_obj_id, 'tile_image'); - } - } - - public function delete(): void - { - if ($this->filesystem->hasDir($this->getRelativeDirectory())) { - try { - $this->filesystem->deleteDir($this->getRelativeDirectory()); - } catch (Exception $e) { - } - } - - ilContainer::_deleteContainerSettings($this->object_id, 'tile_image'); - } - - public function saveFromTempFileName(string $tempfile_name): void - { - $this->createDirectory(); - - $relative_path = $this->getRelativePath(); - if ($this->filesystem->has($relative_path)) { - $this->filesystem->delete($relative_path); - } - - $this->ext = pathinfo($tempfile_name, PATHINFO_EXTENSION); - - rename(ilFileUtils::getDataDir() . '/temp/' . $tempfile_name, $this->getFullPath()); - - $this->image_converter->croppedSquare( - $this->getFullPath(), - $this->getFullPath(), - self::TILE_IMAGE_SIZE, // I suggest to use a constant here, in the old code it was the min length of either height or width of the original image which can be huge... - ImageOutputOptions::FORMAT_KEEP, - 70 - ); - - $this->persistImageState(); - } - - protected function persistImageState(): void - { - if ($this->filesystem->has($this->getRelativePath())) { - ilContainer::_writeContainerSetting($this->object_id, 'tile_image', $this->ext); - } else { - ilContainer::_deleteContainerSettings($this->object_id, 'tile_image'); - } - } - - /** - * @throws IOException - */ - protected function createDirectory(): void - { - $this->filesystem->createDir($this->getRelativeDirectory()); - } - - public function getRelativeDirectory(): string - { - return implode( - DIRECTORY_SEPARATOR, - [ - 'obj_data', - 'tile_image', - 'tile_image_' . $this->object_id - ] - ); - } - - protected function getFileName(): string - { - return 'tile_image.' . $this->getExtension(); - } - - protected function getRelativePath(): string - { - return implode( - DIRECTORY_SEPARATOR, - [ - $this->getRelativeDirectory(), - $this->getFileName() - ] - ); - } - - public function exists(): bool - { - if (!ilContainer::_lookupContainerSetting($this->object_id, 'tile_image', '0')) { - return false; - } - - return $this->filesystem->has($this->getRelativePath()); - } - - public function getFullPath(): string - { - // TODO: Currently there is no option to get the relative base directory of a filesystem - return implode( - DIRECTORY_SEPARATOR, - [ - ilFileUtils::getWebspaceDir(), - $this->getRelativePath() - ] - ); - } - - public function createFromImportDir(string $source_dir, string $ext): void - { - $target_dir = implode( - DIRECTORY_SEPARATOR, - [ - ilFileUtils::getWebspaceDir(), - $this->getRelativeDirectory() - ] - ); - $sourceFS = LegacyPathHelper::deriveFilesystemFrom($source_dir); - $targetFS = LegacyPathHelper::deriveFilesystemFrom($target_dir); - - $sourceDir = LegacyPathHelper::createRelativePath($source_dir); - $targetDir = LegacyPathHelper::createRelativePath($target_dir); - - - $sourceList = $sourceFS->listContents($sourceDir, true); - - foreach ($sourceList as $item) { - if ($item->isDir()) { - continue; - } - try { - $itemPath = $targetDir . '/' . substr($item->getPath(), strlen($sourceDir)); - $stream = $sourceFS->readStream($item->getPath()); - $targetFS->writeStream($itemPath, $stream); - } catch (FileAlreadyExistsException $e) { - // Do nothing with that type of exception - } - } - - ilContainer::_writeContainerSetting($this->object_id, 'tile_image', $ext); - } -} diff --git a/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php b/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php deleted file mode 100644 index 05f0ce11dc65..000000000000 --- a/Services/Object/classes/Properties/AdditionalProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php +++ /dev/null @@ -1,153 +0,0 @@ - - */ -class ilObjectTileImageUploadHandlerGUI extends AbstractCtrlAwareUploadHandler implements ilCtrlBaseClassInterface -{ - use ilObjectPropertiesUploadSecurityFunctionsTrait; - - protected ilLanguage $language; - protected bool $has_access = false; - - public function __construct( - protected ?ilObjectTileImage $tile_image = null - ) { - /** @var ILIAS\DI\Container $DIC */ - global $DIC; - $this->language = $DIC->language(); - - $ref_id = null; - if ($DIC->http()->wrapper()->query()->has('ref_id')) { - $transformation = $DIC->refinery()->kindlyTo()->int(); - $ref_id = $DIC->http()->wrapper()->query()->retrieve('ref_id', $transformation); - } - - $this->has_access = $this->getAccess( - $ref_id, - $DIC->access() - ); - - $DIC->ctrl()->setParameterByClass(self::class, 'ref_id', $ref_id); - - parent::__construct(); - } - - /** - * @inheritDoc - */ - protected function getUploadResult(): HandlerResult - { - $tempfile = ''; - if ($this->has_access === false) { - return $this->getAccessFailureResult( - $this->getFileIdentifierParameterName(), - $tempfile, - $this->language - ); - } - - $this->upload->process(); - - $result_array = $this->upload->getResults(); - $result = end($result_array); - - if ($result instanceof UploadResult - && in_array($result->getMimeType(), ilObjectPropertyTileImage::SUPPORTED_MIME_TYPES) - && $result->isOK()) { - $status = HandlerResult::STATUS_OK; - $message = 'Upload ok'; - $tempfile = $this->getTempFileWithExtension($result->getName()); - rename($result->getPath(), $tempfile); - } else { - $status = HandlerResult::STATUS_FAILED; - $message = $result->getStatus()->getMessage(); - } - - return new BasicHandlerResult( - $this->getFileIdentifierParameterName(), - $status, - basename($tempfile), - $message - ); - } - - protected function getRemoveResult(string $file_name): HandlerResult - { - if ($this->has_access === false) { - return $this->getAccessFailureResult( - $this->getFileIdentifierParameterName(), - $file_name, - $this->language - ); - } - - return new BasicHandlerResult( - $this->getFileIdentifierParameterName(), - HandlerResult::STATUS_OK, - $file_name, - 'There is nothing to do here.' - ); - } - - public function getInfoResult(string $file_name): ?FileInfoResult - { - if ($this->has_access === false) { - return null; - } - $file_path = $this->tile_image->getFullPath(); - - $extension = '.' . strtolower($this->tile_image->getExtension()); - $mimetype_map = MimeType::getExt2MimeMap(); - - return new BasicFileInfoResult( - $this->getFileIdentifierParameterName(), - 'tile_image', - $this->language->txt('obj_tile_image'), - filesize($file_path), - $mimetype_map[$extension] - ); - } - - /** - * @return \ILIAS\FileUpload\Handler\BasicFileInfoResult[] - */ - public function getInfoForExistingFiles(array $file_names): array - { - return [$this->getInfoResult('tile_image')]; - } - - protected function getTempFileWithExtension($upload_file_name): string - { - $file_name_parts = explode('.', $upload_file_name); - $extension = '.' . array_pop($file_name_parts); - return ilFileUtils::ilTempnam() . strtolower($extension); - } -} diff --git a/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditionalPropertiesLegacyRepository.php b/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditionalPropertiesLegacyRepository.php index c63fb72beb7b..c768f28b07dc 100644 --- a/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditionalPropertiesLegacyRepository.php +++ b/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditionalPropertiesLegacyRepository.php @@ -1,4 +1,5 @@ getDefaultAdditionalProperties(); } + $type = ilObject::_lookupType($object_id); + $object_type_specific_properties = $this->object_type_specific_properties_factory->getForObjectTypeString($type); + $providers = null; + if ($object_type_specific_properties !== null) { + $providers = $object_type_specific_properties->getProviders(); + } + return new ilObjectAdditionalProperties( new ilObjectPropertyTitleAndIconVisibility($this->getTitleAndIconVisibility($object_id)), new ilObjectPropertyHeaderActionVisibility($this->getHeaderActionVisibility($object_id)), new ilObjectPropertyInfoTabVisibility($this->getInfoTabVisibility($object_id)), - new ilObjectPropertyTileImage( - new ilObjectTileImage( - $this->filesystem, - $this->upload, - $object_id - ) - ), new ilObjectPropertyIcon( $this->areCustomIconsEnabled(), $this->custom_icon_factory->getByObjId($object_id), - $this->areCustomIconsEnabled() + $providers ), $object_id ); @@ -88,10 +87,6 @@ public function store(ilObjectAdditionalProperties $properties): ilObjectAdditio ); } - if ($properties->wasPropertyTileImageUpdated()) { - $this->storeTileImage($properties->getPropertyTileImage()); - } - if ($properties->wasPropertyIconUpdated()) { $this->storeIcon($properties->getPropertyIcon()); } @@ -105,7 +100,6 @@ private function getDefaultAdditionalProperties(): ilObjectAdditionalProperties new ilObjectPropertyTitleAndIconVisibility(), new ilObjectPropertyHeaderActionVisibility(), new ilObjectPropertyInfoTabVisibility(), - new ilObjectPropertyTileImage(), new ilObjectPropertyIcon( $this->areCustomIconsEnabled() ) @@ -157,18 +151,6 @@ private function storeInfoTabVisibility(int $object_id, bool $visibility): void ); } - private function storeTileImage(ilObjectPropertyTileImage $property_tile_image): void - { - if ($property_tile_image->getDeletedFlag() === true) { - $property_tile_image->getTileImage()->delete(); - } - if ($property_tile_image->getTempFileName() !== null) { - $property_tile_image->getTileImage()->saveFromTempFileName( - $property_tile_image->getTempFileName() - ); - } - } - private function areCustomIconsEnabled(): bool { return (bool) ilSetting::_lookupValue('common', 'custom_icons'); diff --git a/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditonalProperties.php b/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditonalProperties.php index cc8b0abe74a6..5e5c6f522938 100644 --- a/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditonalProperties.php +++ b/Services/Object/classes/Properties/AdditionalProperties/ilObjectAdditonalProperties.php @@ -26,14 +26,12 @@ class ilObjectAdditionalProperties private bool $property_title_and_icon_visibility_updated = false; private bool $property_header_action_visibility_updated = false; private bool $property_info_tab_visibility_updated = false; - private bool $property_tile_image_updated = false; private bool $property_icon_updated = false; public function __construct( private ilObjectPropertyTitleAndIconVisibility $property_title_and_icon_visibility, private ilObjectPropertyHeaderActionVisibility $property_header_action_visibility, private ilObjectPropertyInfoTabVisibility $property_info_tab_visibility, - private ilObjectPropertyTileImage $property_tile_image, private ilObjectPropertyIcon $property_icon, private ?int $object_id = null ) { @@ -98,24 +96,6 @@ public function withPropertyInfoTabVisibility(ilObjectPropertyInfoTabVisibility return $clone; } - public function getPropertyTileImage(): ilObjectProperty - { - return $this->property_tile_image; - } - - public function wasPropertyTileImageUpdated(): bool - { - return $this->property_tile_image_updated; - } - - public function withPropertyTileImage(ilObjectPropertyTileImage $property_tile_image): self - { - $clone = clone $this; - $clone->property_tile_image = $property_tile_image; - $clone->property_tile_image_updated = true; - return $clone; - } - public function getPropertyIcon(): ilObjectProperty { return $this->property_icon; @@ -141,7 +121,6 @@ public function withResetUpdatedFlags(): self $clone->property_header_action_visibility_updated = false; $clone->property_info_tab_visibility_updated = false; $clone->property_icon_updated = false; - $clone->property_tile_image_updated = false; return $clone; } } diff --git a/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImage.php b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImage.php new file mode 100644 index 000000000000..9b554269b549 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImage.php @@ -0,0 +1,204 @@ +rid; + } + + public function withRid(?string $rid): self + { + $clone = clone $this; + $clone->rid = $rid; + return $clone; + } + + public function getImage(): Image + { + if ($this->object_type_specific_property_providers !== null && + ( + $specific_tile_image = $this->object_type_specific_property_providers->getObjectTypeSpecificTileImage( + $this->object_id, + $this->image_factory, + $this->storage_services + ) + ) !== null) { + return $specific_tile_image; + } + + if ($this->rid !== null + && $this->rid !== '' + && ($resource = $this->storage_services->manage()->find($this->rid)) !== null + ) { + return $this->getImageFromIRSS($resource); + } + + if ($this->exists()) { + return $this->image_factory->responsive($this->getFullPath(), ''); + } + + $path = \ilUtil::getImagePath('cont_tile/cont_tile_default_' . $this->obj_type . '.svg'); + if (is_file($path)) { + return $this->image_factory->responsive($path, ''); + } + return $this->image_factory->responsive(\ilUtil::getImagePath('cont_tile/cont_tile_default.svg'), ''); + } + + private function getImageFromIRSS(ResourceIdentification $resource): Image + { + $flavour = $this->storage_services->flavours()->get($resource, $this->flavour_definition); + $urls = $this->storage_services->consume()->flavourUrls($flavour)->getURLsAsArray(); + + $available_sizes = $this->flavour_definition->getSizes(); + array_pop($available_sizes); + + $image = $this->image_factory->responsive($urls[count($available_sizes)], ''); + return array_reduce( + $available_sizes, + function ($carry, $size) use ($urls) { + $image = $carry['image']->withAdditionalHighResSource($urls[$carry['counter']], $size / 2); + $counter = ++$carry['counter']; + return [ + 'image' => $image, + 'counter' => $counter + ]; + }, + ['image' => $image, 'counter' => 0] + )['image']; + } + + /** + * + * @deprecated 11: This is only here for the Legacy Input and will be removed + * with ILIAS 11. + */ + public function getSrcUrlForLegacyForm(): string + { + if ($this->rid !== null && $this->rid !== '') { + $resource = $this->storage_services->manage()->find($this->rid); + if ($resource === null) { + return ''; + } + + $flavour = $this->storage_services->flavours()->get($resource, $this->flavour_definition); + $urls = $this->storage_services->consume()->flavourUrls($flavour)->getURLsAsArray(false); + + return array_pop($urls); + } + + if (!$this->exists()) { + return ''; + } + return $this->getFullPath(); + } + + public function deleteLegacyTileImage(): void + { + if ($this->exists()) { + unlink(ILIAS_ABSOLUTE_PATH . DIRECTORY_SEPARATOR . $this->getFullPath()); + rmdir(dirname(ILIAS_ABSOLUTE_PATH . DIRECTORY_SEPARATOR . $this->getFullPath())); + \ilContainer::_deleteContainerSettings($this->object_id, 'tile_image'); + } + } + + public function cloneFor(int $new_object_id): self + { + $clone = clone $this; + $clone->object_id = $new_object_id; + + if ($this->rid !== null) { + $i = $this->storage_services->manage()->clone($this->rid); + $clone->rid = $i->serialize(); + } + + return $clone; + } + + private function exists(): bool + { + if (!\ilContainer::_lookupContainerSetting($this->object_id, 'tile_image', '0')) { + return false; + } + + return is_file($this->getFullPath()); + } + + private function getFullPath(): string + { + if ($this->ext === '') { + $this->ext = \ilContainer::_lookupContainerSetting($this->object_id, 'tile_image'); + } + + return implode( + DIRECTORY_SEPARATOR, + [ + \ilFileUtils::getWebspaceDir(), + 'obj_data', + 'tile_image', + 'tile_image_' . $this->object_id, + 'tile_image.' . $this->ext + ] + ); + } + + public function createFromImportDir(string $source_dir): void + { + $sourceFS = LegacyPathHelper::deriveFilesystemFrom($source_dir); + $sourceDir = LegacyPathHelper::createRelativePath($source_dir); + $sourceList = $sourceFS->listContents($sourceDir, true); + + foreach ($sourceList as $item) { + if ($item->isDir()) { + continue; + } + + $path = $source_dir . DIRECTORY_SEPARATOR . basename($item->getPath()); + $stream = new Stream(fopen($path, 'r')); + $i = $this->storage_services->manage()->stream($stream, $this->storage_stakeholder, 'Tile Image'); + $this->rid = $i->serialize(); + } + } +} diff --git a/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourDefinition.php b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourDefinition.php new file mode 100644 index 000000000000..ff92083db7f2 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourDefinition.php @@ -0,0 +1,80 @@ + 1920, + 'l' => 960, + 'm' => 480, + 's' => 240, + 'xs' => 120 + ]; + + public function __construct( + ) { + } + + public function getId(): string + { + return self::ID; + } + + public function getFlavourMachineId(): string + { + return ilObjectTileImageFlavourMachine::ID; + } + + public function getInternalName(): string + { + return 'object_tile_image'; + } + + public function getVariantName(): ?string + { + return json_encode([ + 'quality' => $this->quality, + 'sizes' => $this->sizes + ]); + } + + public function persist(): bool + { + return true; + } + + public function getSizes(): array + { + return $this->sizes; + } + + public function getQuality(): int + { + return $this->quality; + } +} diff --git a/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourMachine.php b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourMachine.php new file mode 100644 index 000000000000..7fc16df474a2 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageFlavourMachine.php @@ -0,0 +1,104 @@ +crop = new CropSquare(); + } + + + public function getId(): string + { + return self::ID; + } + + public function canHandleDefinition(FlavourDefinition $definition): bool + { + return $definition instanceof ilObjectTileImageFlavourDefinition; + } + + public function dependsOnEngine(): ?string + { + return GDEngine::class; + } + + public function processStream( + FileInformation $information, + FileStream $stream, + FlavourDefinition $for_definition + ): \Generator { + /** @var ilObjectTileImageFlavourDefinition $for_definition */ + $this->definition = $for_definition; + $this->information = $information; + + $i = 0; + foreach ($for_definition->getSizes() as $size) { + yield new Result( + $for_definition, + $this->cropImage($stream, $size), + $i, + true + ); + $i++; + } + } + + protected function cropImage( + FileStream $stream, + int $size + ) { + $quality = $size <= self::FULL_QUALITY_SIZE_THRESHOLD + ? 100 // we take 100% jpeg quality for small resultions + : $this->definition->getQuality(); + + + return $this->crop->processStream( + $this->information, + $stream, + new CropToSquare( + false, + $size, + $quality + ) + )->current()->getStream(); + } +} diff --git a/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageStakeholder.php b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageStakeholder.php new file mode 100644 index 000000000000..e317ee6fbed4 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageStakeholder.php @@ -0,0 +1,54 @@ + + */ +class ilObjectTileImageStakeholder extends AbstractResourceStakeholder +{ + private int $default_owner; + + public function __construct() + { + global $DIC; + $this->default_owner = $DIC->isDependencyAvailable('user') + ? $DIC->user()->getId() + : (defined('SYSTEM_USER_ID') ? (int) SYSTEM_USER_ID : 6); + } + + public function setOwner(int $user_id_of_owner): void + { + $this->default_owner = $user_id_of_owner; + } + + public function getId(): string + { + return 'object_tile_image'; + } + + public function getOwnerOfNewResources(): int + { + return $this->default_owner; + } +} diff --git a/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php new file mode 100644 index 000000000000..46cf10879b63 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/class.ilObjectTileImageUploadHandlerGUI.php @@ -0,0 +1,177 @@ + + */ +class ilObjectTileImageUploadHandlerGUI extends AbstractCtrlAwareUploadHandler implements \ilCtrlBaseClassInterface +{ + use \ilObjectPropertiesUploadSecurityFunctionsTrait; + + protected \ilLanguage $language; + protected ResourceStorageServices $storage; + protected ilObjectTileImageStakeholder $stakeholder; + protected ilObjectTileImageFlavourDefinition $flavour; + + protected ?ResourceIdentification $rid = null; + protected bool $has_access = false; + + public function __construct( + protected ?ilObjectTileImage $tile_image = null + ) { + /** @var \ILIAS\DI\Container $DIC */ + global $DIC; + $this->language = $DIC->language(); + + $ref_id = null; + if ($DIC->http()->wrapper()->query()->has('ref_id')) { + $transformation = $DIC->refinery()->kindlyTo()->int(); + $ref_id = $DIC->http()->wrapper()->query()->retrieve('ref_id', $transformation); + } + + $this->has_access = $this->getAccess( + $ref_id, + $DIC->access() + ); + + if ($DIC->http()->wrapper()->post()->has('rid')) { + $id = $DIC->http()->wrapper()->post()->retrieve( + 'rid', + $DIC->refinery()->to()->string() + ); + $this->rid = $DIC->resourceStorage()->manage()->find($id); + } + + $DIC->ctrl()->setParameterByClass(self::class, 'ref_id', $ref_id); + + $this->storage = $DIC->resourceStorage(); + $this->stakeholder = new ilObjectTileImageStakeholder(); + $this->flavour = new ilObjectTileImageFlavourDefinition(); + + parent::__construct(); + } + + /** + * @inheritDoc + */ + protected function getUploadResult(): HandlerResult + { + $this->upload->process(); + + $result_array = $this->upload->getResults(); + $result = end($result_array); + + if (!($result instanceof UploadResult) || !$result->isOK()) { + return new BasicHandlerResult( + $this->getFileIdentifierParameterName(), + HandlerResult::STATUS_FAILED, + '', + $result->getStatus()->getMessage() + ); + } + + $status = HandlerResult::STATUS_OK; + $message = "file upload OK"; + if ($this->rid === null) { + $i = $this->storage->manage()->upload($result, $this->stakeholder); + } else { + $i = $this->rid; + $this->storage->manage()->replaceWithUpload( + $i, + $result, + $this->stakeholder + ); + } + + $this->storage->flavours()->ensure($i, $this->flavour); + + return new BasicHandlerResult( + $this->getFileIdentifierParameterName(), + $status, + $i->serialize(), + $message + ); + } + + protected function getRemoveResult(string $identifier): HandlerResult + { + if ($this->has_access === false) { + return $this->getAccessFailureResult( + $this->getFileIdentifierParameterName(), + $identifier, + $this->language + ); + } + + return new BasicHandlerResult( + $this->getFileIdentifierParameterName(), + HandlerResult::STATUS_OK, + $identifier, + "We just don't do anything here." + ); + } + + public function getInfoResult(string $identifier): ?FileInfoResult + { + if (null !== ($id = $this->storage->manage()->find($identifier))) { + $revision = $this->storage->manage()->getCurrentRevision($id)->getInformation(); + $title = $revision->getTitle(); + $size = $revision->getSize(); + $mime = $revision->getMimeType(); + } else { + $title = $mime = 'unknown'; + $size = 0; + } + + return new BasicFileInfoResult( + $this->getFileIdentifierParameterName(), + $identifier, + $title, + $size, + $mime + ); + } + + /** + * @return \ILIAS\FileUpload\Handler\BasicFileInfoResult[] + */ + public function getInfoForExistingFiles(array $file_ids): array + { + $info_results = []; + foreach ($file_ids as $identifier) { + $info_results[] = $this->getInfoResult($identifier); + } + + return $info_results; + } +} diff --git a/Services/Object/classes/Properties/AdditionalProperties/TileImage/ilObjectPropertyTileImage.php b/Services/Object/classes/Properties/CoreProperties/TileImage/ilObjectPropertyTileImage.php similarity index 61% rename from Services/Object/classes/Properties/AdditionalProperties/TileImage/ilObjectPropertyTileImage.php rename to Services/Object/classes/Properties/CoreProperties/TileImage/ilObjectPropertyTileImage.php index b43b2eb159d5..7b6dd123ed72 100644 --- a/Services/Object/classes/Properties/AdditionalProperties/TileImage/ilObjectPropertyTileImage.php +++ b/Services/Object/classes/Properties/CoreProperties/TileImage/ilObjectPropertyTileImage.php @@ -18,6 +18,8 @@ declare(strict_types=1); +namespace ILIAS\Object\Properties\CoreProperties\TileImage; + use ILIAS\UI\Component\Input\Field\File; use ILIAS\UI\Component\Input\Field\Factory as FieldFactory; use ILIAS\Refinery\Factory as Refinery; @@ -26,7 +28,7 @@ /** * @author Stephan Kergomard */ -class ilObjectPropertyTileImage implements ilObjectProperty +class ilObjectPropertyTileImage implements \ilObjectProperty { public const SUPPORTED_MIME_TYPES = [MimeType::IMAGE__PNG, MimeType::IMAGE__JPEG]; private const SUPPORTED_FILE_EXTENSIONS = ['png', 'jpg', 'jpeg']; @@ -35,7 +37,6 @@ class ilObjectPropertyTileImage implements ilObjectProperty protected const INPUT_BYLINE = 'obj_tile_image_info'; private bool $deleted_flag = false; - private ?string $temp_file_name = null; public function __construct( private ?ilObjectTileImage $tile_image = null @@ -47,27 +48,22 @@ public function getTileImage(): ?ilObjectTileImage return $this->tile_image; } - public function getDeletedFlag(): bool - { - return $this->deleted_flag; - } - - public function withDeletedFlag(): self + public function withTileImage(ilObjectTileImage $tile_image): self { $clone = clone $this; - $clone->deleted_flag = true; + $clone->tile_image = $tile_image; return $clone; } - public function getTempFileName(): ?string + public function getDeletedFlag(): bool { - return $this->temp_file_name; + return $this->deleted_flag; } - public function withTempFileName(string $name): self + public function withDeletedFlag(): self { $clone = clone $this; - $clone->temp_file_name = $name; + $clone->deleted_flag = true; return $clone; } @@ -77,50 +73,44 @@ public function toForm( Refinery $refinery ): File { $trafo = $refinery->custom()->transformation( - function ($v): ?ilObjectProperty { - $property_tile_image = new ilObjectPropertyTileImage( - $this->tile_image - ); - - if (count($v) > 0 && $v[0] !== 'tile_image') { - return $property_tile_image - ->withTempFileName($v[0]); + function ($v): ?\ilObjectProperty { + if ($v === null || $v === []) { + return $this->withDeletedFlag(); } - if (count($v) === 0 && $this->tile_image->exists()) { - return $property_tile_image - ->withDeletedFlag(); + if (count($v) > 0 && $v[0] === 'tile_image') { + return $this; } - return $property_tile_image; + return $this->withTileImage( + $this->tile_image->withRid($v[0]) + ); } ); $tile_image = $field_factory - ->file(new ilObjectTileImageUploadHandlerGUI($this->tile_image), $language->txt(self::INPUT_LABEL), $language->txt(self::INPUT_BYLINE)) + ->file(new \ilObjectTileImageUploadHandlerGUI($this->tile_image), $language->txt(self::INPUT_LABEL), $language->txt(self::INPUT_BYLINE)) ->withAcceptedMimeTypes(self::SUPPORTED_MIME_TYPES) - ->withMaxFileSize((int) ilFileUtils::getUploadSizeLimitBytes()) + ->withMaxFileSize((int) \ilFileUtils::getUploadSizeLimitBytes()) ->withAdditionalTransformation($trafo); - if (!$this->tile_image->exists()) { + if ($this->tile_image->getRid() === null + || $this->tile_image->getRid() === '') { return $tile_image; } - return $tile_image->withValue(['tile_image']); + return $tile_image->withValue([$this->tile_image->getRid()]); } public function toLegacyForm( \ilLanguage $language - ): ilImageFileInputGUI { - $timg = new ilImageFileInputGUI($language->txt(self::INPUT_LABEL), 'tile_image'); + ): \ilImageFileInputGUI { + $timg = new \ilImageFileInputGUI($language->txt(self::INPUT_LABEL), 'tile_image'); $timg->setInfo($language->txt(self::INPUT_BYLINE)); $timg->setSuffixes(self::SUPPORTED_FILE_EXTENSIONS); $timg->setUseCache(false); - if ($this->tile_image?->exists()) { - $timg->setImage($this->tile_image->getFullPath()); - } else { - $timg->setImage(''); - } + $timg->setImage($this->tile_image->getSrcUrlForLegacyForm()); + $timg->setValue($this->tile_image->getRid() ?? ''); return $timg; } } diff --git a/Services/Object/classes/Properties/CoreProperties/ilObjectCoreProperties.php b/Services/Object/classes/Properties/CoreProperties/ilObjectCoreProperties.php index 14070722b326..56b74e92b313 100644 --- a/Services/Object/classes/Properties/CoreProperties/ilObjectCoreProperties.php +++ b/Services/Object/classes/Properties/CoreProperties/ilObjectCoreProperties.php @@ -18,6 +18,8 @@ declare(strict_types=1); +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectPropertyTileImage; + /** * @author Stephan Kergomard */ @@ -45,6 +47,7 @@ class ilObjectCoreProperties public function __construct( private ilObjectPropertyTitleAndDescription $property_title_and_description, private ilObjectPropertyIsOnline $property_is_online, + private ilObjectPropertyTileImage $property_tile_image, array $data = null ) { if ($this->checkDataArray($data)) { @@ -120,6 +123,18 @@ public function withPropertyIsOnline(ilObjectPropertyIsOnline $property_is_onlin return $clone; } + public function getPropertyTileImage(): ilObjectPropertyTileImage + { + return $this->property_tile_image; + } + + public function withPropertyTileImage(ilObjectPropertyTileImage $property_tile_image): self + { + $clone = clone $this; + $clone->property_tile_image = $property_tile_image; + return $clone; + } + /** * diff --git a/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesCachedRepository.php b/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesCachedRepository.php new file mode 100644 index 000000000000..657eaa7e7038 --- /dev/null +++ b/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesCachedRepository.php @@ -0,0 +1,245 @@ +data_cache += $this->retrieveDataForObjectIds($object_ids); + } + + public function resetPreloadedData(): void + { + $this->data_cache = []; + } + + public function getFor(?int $object_id): ilObjectCoreProperties + { + if ($object_id === null + || $object_id === 0) { + return $this->getDefaultCoreProperties(); + } + + if (!isset($this->data_cache[$object_id])) { + $this->data_cache[$object_id] = $this->retrieveDataForObjectId($object_id); + } + + $data = $this->data_cache[$object_id]; + + $object_type_specific_properties = $this->object_type_specific_properties_factory->getForObjectTypeString($data['type']); + $providers = null; + $modifications = null; + if ($object_type_specific_properties !== null) { + $providers = $object_type_specific_properties->getProviders(); + $modifications = $object_type_specific_properties->getModifications(); + } + return new ilObjectCoreProperties( + new ilObjectPropertyTitleAndDescription( + array_shift($data), + array_shift($data), + $modifications + ), + new ilObjectPropertyIsOnline(array_shift($data)), + new ilObjectPropertyTileImage( + new ilObjectTileImage( + $object_id, + $data['type'], + array_shift($data), + $this->ui->factory()->image(), + $this->storage_services, + $this->storage_stakeholder, + $this->flavour_definition, + $providers + ) + ), + $data + ); + } + + public function store(ilObjectCoreProperties $properties): ilObjectCoreProperties + { + if ($properties->getObjectId() === null || $properties->getOwner() === null) { + throw new \Exception('The current configuration cannot be saved.'); + } + + if ($properties->getPropertyTileImage()->getDeletedFlag()) { + $this->deleteOldTileImage($properties->getPropertyTileImage()->getTileImage()); + $properties = $properties->withPropertyTileImage( + $properties->getPropertyTileImage()->withTileImage( + $properties->getPropertyTileImage()->getTileImage()->withRid(null) + ) + ); + /** + * Remove with ILIAS10 + */ + $properties->getPropertyTileImage()->getTileImage()->deleteLegacyTileImage(); + } + + /** + * Remove with ILIAS10 + */ + if ($properties->getPropertyTileImage()->getTileImage()->getRid() !== null) { + $properties->getPropertyTileImage()->getTileImage()->deleteLegacyTileImage(); + } + + $where = [ + 'obj_id' => [ilDBConstants::T_INTEGER, $properties->getObjectId()] + ]; + + $storage_array = [ + 'type' => [ilDBConstants::T_TEXT, $properties->getType()], + 'title' => [ilDBConstants::T_TEXT, $properties->getPropertyTitleAndDescription()->getTitle()], + 'description' => [ilDBConstants::T_TEXT, $properties->getPropertyTitleAndDescription()->getDescription()], + 'owner' => [ilDBConstants::T_INTEGER, $properties->getOwner()], + 'create_date' => [ilDBConstants::T_DATETIME, $properties->getCreateDate()->format('Y-m-d H:i:s')], + 'last_update' => [ilDBConstants::T_DATETIME, $properties->getLastUpdateDate()->format('Y-m-d H:i:s')], + 'import_id' => [ilDBConstants::T_TEXT, $properties->getImportId()], + 'offline' => [ilDBConstants::T_INTEGER, (int) !$properties->getPropertyIsOnline()->getIsOnline()], + 'tile_image_rid' => [ilDBConstants::T_TEXT, $properties->getPropertyTileImage()->getTileImage()->getRid()] + ]; + $this->database->update(self::CORE_PROPERTIES_TABLE, $storage_array, $where); + + $this->storeLongDescription($properties->getPropertyTitleAndDescription()->getLongDescription(), $where); + + return $properties; + } + + private function deleteOldTileImage(ilObjectTileImage $tile_image): void + { + if ($tile_image->getRid() === null) { + return; + } + + $i = $this->storage_services->manage()->find($tile_image->getRid()); + if ($i === null) { + return; + } + + $this->storage_services->manage()->remove( + $i, + $this->storage_stakeholder + ); + } + + private function getDefaultCoreProperties(): ilObjectCoreProperties + { + return new ilObjectCoreProperties( + new ilObjectPropertyTitleAndDescription(), + new ilObjectPropertyIsOnline() + ); + } + + /** + * @return array + */ + protected function retrieveDataForObjectId(int $object_id): array + { + $where = 'WHERE obj.obj_id=' . $this->database->quote($object_id, 'integer'); + $data = $this->retrieveDataForWhereClause($where); + + if ($data === []) { + throw new \Exception('The object with the following id does not exist: ' + . (string) $object_id); + } + + return $data[$object_id]; + } + + /** + * @param array $object_ids + */ + protected function retrieveDataForObjectIds(array $object_ids): array + { + $where = 'WHERE ' . $this->database->in('obj.obj_id', $object_ids, false, ilDBConstants::T_INTEGER); + return $this->retrieveDataForWhereClause($where); + } + + protected function retrieveDataForWhereClause(string $where): array + { + $query = 'SELECT ' + . 'obj.obj_id, obj.type, obj.title, obj.description, obj.owner,' . PHP_EOL + . 'obj.create_date, obj.last_update, obj.import_id, obj.offline,' . PHP_EOL + . 'obj.tile_image_rid, descr.description' . PHP_EOL + . 'FROM ' . self::CORE_PROPERTIES_TABLE . ' AS obj' . PHP_EOL + . 'LEFT JOIN ' . self::DESCRIPTION_TABLE . ' AS descr' . PHP_EOL + . 'ON obj.obj_id = descr.obj_id' . PHP_EOL + . $where; + + $statement = $this->database->query($query); + $num_rows = $this->database->numRows($statement); + + if ($num_rows === 0) { + return []; + } + + $data = []; + while ($row = $this->database->fetchAssoc($statement)) { + $data[$row['obj_id']] = [ + 'title' => $row['title'], + 'long_description' => $row['description'] ?? '', + 'is_online' => !((bool) $row['offline']), + 'tile_image_rid' => $row['tile_image_rid'], + 'object_id' => $row['obj_id'], + 'type' => $row['type'], + 'owner' => $row['owner'], + 'import_id' => $row['import_id'], + 'create_date' => new DateTimeImmutable($row['create_date']), + 'update_date' => new DateTimeImmutable($row['last_update']) + ]; + } + + return $data; + } + + protected function storeLongDescription(string $long_description, array $where): void + { + $description_array = [ + 'description' => [ilDBConstants::T_TEXT, $long_description] + ]; + $this->database->update(self::DESCRIPTION_TABLE, $description_array, $where); + } +} diff --git a/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesDatabaseRepository.php b/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesDatabaseRepository.php deleted file mode 100644 index 195c7b5cfdad..000000000000 --- a/Services/Object/classes/Properties/CoreProperties/ilObjectCorePropertiesDatabaseRepository.php +++ /dev/null @@ -1,147 +0,0 @@ -getDefaultCoreProperties(); - } - - $data = $this->retrieveDataForObjectId($object_id); - return new ilObjectCoreProperties( - new ilObjectPropertyTitleAndDescription(array_shift($data), array_shift($data)), - new ilObjectPropertyIsOnline(array_shift($data)), - $data - ); - } - - public function store(ilObjectCoreProperties $properties): ilObjectCoreProperties - { - if ($properties->getObjectId() === null || $properties->getOwner() === null) { - throw new \Exception('The current configuration cannot be saved.'); - } - - $where = [ - 'obj_id' => [ilDBConstants::T_INTEGER, $properties->getObjectId()] - ]; - - $storage_array = [ - 'type' => [ilDBConstants::T_TEXT, $properties->getType()], - 'title' => [ilDBConstants::T_TEXT, $properties->getPropertyTitleAndDescription()->getTitle()], - 'description' => [ilDBConstants::T_TEXT, $properties->getPropertyTitleAndDescription()->getDescription()], - 'owner' => [ilDBConstants::T_INTEGER, $properties->getOwner()], - 'create_date' => [ilDBConstants::T_DATETIME, $properties->getCreateDate()->format('Y-m-d H:i:s')], - 'last_update' => [ilDBConstants::T_DATETIME, $properties->getLastUpdateDate()->format('Y-m-d H:i:s')], - 'import_id' => [ilDBConstants::T_TEXT, $properties->getImportId()], - 'offline' => [ilDBConstants::T_INTEGER, (int) !$properties->getPropertyIsOnline()->getIsOnline()] - ]; - $this->database->update(self::CORE_PROPERTIES_TABLE, $storage_array, $where); - - $this->storeLongDescription($properties->getPropertyTitleAndDescription()->getLongDescription(), $where); - - return $properties; - } - - private function getDefaultCoreProperties(): ilObjectCoreProperties - { - return new ilObjectCoreProperties( - new ilObjectPropertyTitleAndDescription(), - new ilObjectPropertyIsOnline() - ); - } - - /** - * @return array - */ - protected function retrieveDataForObjectId(int $object_id): array - { - $query = 'SELECT ' - . 'type, title, description, owner, create_date, last_update, import_id, offline' . PHP_EOL - . 'FROM ' . self::CORE_PROPERTIES_TABLE . PHP_EOL - . 'WHERE obj_id=' . $this->database->quote($object_id, 'integer'); - - $statement = $this->database->query($query); - $num_rows = $this->database->numRows($statement); - - if ($num_rows === 0) { - throw new \Exception('The object with the following id does not exist: ' - . (string) $object_id); - } - - if ($num_rows > 1) { - throw new \Exception('There is more than one object with the following id.' - . 'This should very definitely never happen: ' - . (string) $object_id); - } - - $row = $this->database->fetchAssoc($statement); - - $data = [ - 'title' => $row['title'], - 'long_description' => $this->retrieveLongDescriptionForObjectId($object_id), - 'is_online' => !((bool) $row['offline']), - 'object_id' => $object_id, - 'type' => $row['type'], - 'owner' => $row['owner'], - 'import_id' => $row['import_id'], - 'create_date' => new DateTimeImmutable($row['create_date']), - 'update_date' => new DateTimeImmutable($row['last_update']) - ]; - - return $data; - } - - protected function retrieveLongDescriptionForObjectId(int $object_id): string - { - $query = 'SELECT ' - . 'description FROM ' . self::DESCRIPTION_TABLE . PHP_EOL - . 'WHERE obj_id=' . $this->database->quote($object_id, 'integer'); - - $statement = $this->database->query($query); - $num_rows = $this->database->numRows($statement); - - if ($num_rows === 0) { - return ''; - } - - return $this->database->fetchAssoc($statement)['description'] ?? ''; - } - - protected function storeLongDescription(string $long_description, array $where): void - { - $description_array = [ - 'description' => [ilDBConstants::T_TEXT, $long_description] - ]; - $this->database->update(self::DESCRIPTION_TABLE, $description_array, $where); - } -} diff --git a/Services/Object/classes/Properties/CoreProperties/ilObjectPropertyTitleAndDescription.php b/Services/Object/classes/Properties/CoreProperties/ilObjectPropertyTitleAndDescription.php index cb9f3b762ace..aa2556c69d65 100644 --- a/Services/Object/classes/Properties/CoreProperties/ilObjectPropertyTitleAndDescription.php +++ b/Services/Object/classes/Properties/CoreProperties/ilObjectPropertyTitleAndDescription.php @@ -19,6 +19,7 @@ declare(strict_types=1); use ILIAS\UI\Component\Input\Container\Form\FormInput; +use ILIAS\Object\Properties\ObjectTypeSpecificProperties\ilObjectTypeSpecificPropertyModifications; use ILIAS\UI\Component\Input\Field\Factory as FieldFactory; use ILIAS\Refinery\Factory as Refinery; @@ -33,22 +34,30 @@ class ilObjectPropertyTitleAndDescription implements ilObjectProperty public function __construct( private string $title = '', - private string $long_description = '' + private string $long_description = '', + private ?ilObjectTypeSpecificPropertyModifications $object_type_specific_property_modifications = null ) { } public function getTitle(): string { + if ($this->object_type_specific_property_modifications !== null) { + return $this->object_type_specific_property_modifications->modifyTitle($this->title); + } + return $this->title; } public function getDescription(): string { - return substr($this->long_description, 0, ilObject::DESC_LENGTH); + return substr($this->getLongDescription(), 0, ilObject::DESC_LENGTH); } - public function getLongDescription(): string + public function getLongDescription(): ?string { + if ($this->object_type_specific_property_modifications !== null) { + return $this->object_type_specific_property_modifications->modifyDescription($this->long_description); + } return $this->long_description; } diff --git a/Services/Object/classes/Properties/ObjectTypeSpecificProperties/AbstractObjectTypeSpecificProperties.php b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/AbstractObjectTypeSpecificProperties.php new file mode 100644 index 000000000000..cd1fea72c46c --- /dev/null +++ b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/AbstractObjectTypeSpecificProperties.php @@ -0,0 +1,49 @@ +db = $db; + } + + abstract public function getObjectTypeString(): string; + + public function getModifications(): ?ilObjectTypeSpecificPropertyModifications + { + return null; + } + + public function getProviders(): ?ilObjectTypeSpecificPropertyProviders + { + return null; + } + + abstract public function preload(array $object_ids): void; +} diff --git a/Services/Object/classes/Properties/ObjectTypeSpecificProperties/Factory.php b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/Factory.php new file mode 100644 index 000000000000..05b5d0cc9f4f --- /dev/null +++ b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/Factory.php @@ -0,0 +1,42 @@ +properties_array)) { + $class = $this->properties_array[$type]; + $instance = new $class(); + $instance->init($this->db); + return $instance; + } + + return null; + } +} diff --git a/Services/Object/classes/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertiesArtifactObjective.php b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertiesArtifactObjective.php new file mode 100644 index 000000000000..561ce26cbfc0 --- /dev/null +++ b/Services/Object/classes/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertiesArtifactObjective.php @@ -0,0 +1,54 @@ +getMatchingClassNames(ilObjectTypeSpecificProperties::class) as $object_properties_class) { + /** @var $properties \ILIAS\Object\Properties\ObjectTypeSpecificProperties */ + $properties = new $object_properties_class(); + $object_type = $properties->getObjectTypeString(); + + $object_properties[$object_type] = $object_properties_class; + } + return new ArrayArtifact($object_properties); + } +} diff --git a/Services/Object/classes/Properties/class.ilObjectProperties.php b/Services/Object/classes/Properties/class.ilObjectProperties.php index 56d7596c82b7..dec122a72f8f 100644 --- a/Services/Object/classes/Properties/class.ilObjectProperties.php +++ b/Services/Object/classes/Properties/class.ilObjectProperties.php @@ -18,13 +18,16 @@ declare(strict_types=1); +use ILIAS\Object\Properties\ObjectTypeSpecificProperties\Factory as ObjectTypeSpecificPropertiesFactory; +use ILIAS\Object\Properties\CoreProperties\TileImage\ilObjectPropertyTileImage; + class ilObjectProperties { public function __construct( private ilObjectCoreProperties $core_properties, private ilObjectCorePropertiesRepository $core_properties_repository, private ilObjectAdditionalProperties $additional_properties, - private ilObjectAdditionalPropertiesRepository $additional_properties_repository + private ilObjectAdditionalPropertiesRepository $additional_properties_repository, ) { } @@ -105,16 +108,16 @@ public function storePropertyInfoTabVisibility( ); } - public function getPropertyTileImage(): ilObjectProperty + public function getPropertyTileImage(): ilObjectPropertyTileImage { - return $this->additional_properties->getPropertyTileImage(); + return $this->core_properties->getPropertyTileImage(); } public function storePropertyTileImage( ilObjectPropertyTileImage $property_tile_image ): void { - $this->additional_properties = $this->additional_properties_repository->store( - $this->additional_properties + $this->core_properties = $this->core_properties_repository->store( + $this->core_properties ->withPropertyTileImage($property_tile_image) ); } diff --git a/Services/Object/classes/Properties/class.ilObjectPropertiesAgregator.php b/Services/Object/classes/Properties/class.ilObjectPropertiesAgregator.php index 9686a9cb8375..47ffe6fc0377 100644 --- a/Services/Object/classes/Properties/class.ilObjectPropertiesAgregator.php +++ b/Services/Object/classes/Properties/class.ilObjectPropertiesAgregator.php @@ -1,4 +1,5 @@ additional_properties_repository ); } + + public function preload(array $object_ids): void + { + $this->core_properties_repository->preload($object_ids); + $objects_by_type = []; + foreach($object_ids as $obj_id) { + $type = ilObject::_lookupType($obj_id); + + if (!array_key_exists($type, $objects_by_type)) { + $objects_by_type[$type] = []; + } + $objects_by_type[$type][] = $obj_id; + } + + foreach ($objects_by_type as $type => $obj_ids) { + $this->object_type_specific_properties_factory->getForObjectTypeString($type)->preload($obj_ids); + } + } } diff --git a/Services/Object/classes/Service/class.ilObjectService.php b/Services/Object/classes/Service/ilObjectService.php similarity index 51% rename from Services/Object/classes/Service/class.ilObjectService.php rename to Services/Object/classes/Service/ilObjectService.php index 51424137b74c..32936cc0d7a5 100644 --- a/Services/Object/classes/Service/class.ilObjectService.php +++ b/Services/Object/classes/Service/ilObjectService.php @@ -18,35 +18,18 @@ declare(strict_types=1); -use ILIAS\Filesystem\Filesystem; -use ILIAS\FileUpload\FileUpload; +use ILIAS\Object\ilObjectDIC; class ilObjectService { - public function __construct( - private ilDBInterface $database, - private ilLanguage $language, - private Filesystem $filesystem, - private FileUpload $upload, - private ilObjectCustomIconFactory $custom_icon_factory - ) { - } - /** * * @deprecated 11: This Settings Instance will be removed with ILIAS 11. * Please use ObjectProperties in ilObject. */ - public function commonSettings(): ilObjectCommonSettings + public function commonSettings(): \ilObjectCommonSettings { - return new ilObjectCommonSettings( - $this->language, - $this->upload, - new ilObjectAdditionalPropertiesLegacyRepository( - $this->custom_icon_factory, - $this->filesystem, - $this->upload - ) - ); + $object_dic = ilObjectDIC::dic(); + return $object_dic['common_settings']; } } diff --git a/Services/Object/classes/Setup/class.ilObject9DBUpdateSteps.php b/Services/Object/classes/Setup/class.ilObject9DBUpdateSteps.php new file mode 100644 index 000000000000..da318c8f3332 --- /dev/null +++ b/Services/Object/classes/Setup/class.ilObject9DBUpdateSteps.php @@ -0,0 +1,45 @@ +db = $db; + } + + public function step_1(): void + { + if (!$this->db->tableColumnExists('object_data', 'tile_image_rid')) { + $this->db->addTableColumn( + 'object_data', + 'tile_image_rid', + [ + 'type' => 'text', + 'notnull' => false, + 'length' => 64, + 'default' => '' + ] + ); + } + } +} diff --git a/Services/Object/classes/Setup/class.ilObjectSetupAgent.php b/Services/Object/classes/Setup/class.ilObjectSetupAgent.php new file mode 100644 index 000000000000..c53669b3034c --- /dev/null +++ b/Services/Object/classes/Setup/class.ilObjectSetupAgent.php @@ -0,0 +1,71 @@ + + */ +class ilObjectTileImageMigration implements Migration +{ + protected \ilResourceStorageMigrationHelper $helper; + protected FlavourBuilder $flavour_builder; + protected ilObjectTileImageFlavourDefinition $flavour_definition; + + public function getLabel(): string + { + return "Migration of Tile Images to the Resource Storage Service."; + } + + public function getDefaultAmountOfStepsPerRun(): int + { + return 10000; + } + + public function getPreconditions(Environment $environment): array + { + return \ilResourceStorageMigrationHelper::getPreconditions(); + } + + public function prepare(Environment $environment): void + { + $this->helper = new \ilResourceStorageMigrationHelper( + new ilObjectTileImageStakeholder(), + $environment + ); + $this->flavour_builder = $this->helper->getFlavourBuilder(); + $this->flavour_definition = new ilObjectTileImageFlavourDefinition(); + } + + public function step(Environment $environment): void + { + $query_select = $this->helper->getDatabase()->query(' + SELECT + cs.id, + cs.value AS extension, + o.owner + FROM container_settings AS cs + INNER JOIN object_data AS o + ON cs.id = o.obj_id + WHERE cs.keyword = "tile_image" + LIMIT 1; + '); + $next_record = $this->helper->getDatabase()->fetchObject($query_select); + + $path = $this->getFullPath($next_record->id, $next_record->extension); + + if (is_readable(dirname(dirname($path))) + && (!file_exists(dirname($path)) + || is_readable(dirname($path)) && !file_exists($path))) { + $this->deleteTileImageInfoFromContainerSettings($next_record->id); + return; + } + + $rid = $this->helper->movePathToStorage( + $path, + $next_record->owner + ); + + $this->flavour_builder->get($rid, $this->flavour_definition, true); + + $this->helper->getDatabase()->update( + 'object_data', + ['tile_image_rid' => ['text', $rid->serialize()]], + ['obj_id' => ['integer', $next_record->id],] + ); + + rmdir(dirname($path)); + $this->deleteTileImageInfoFromContainerSettings($next_record->id); + } + + private function getFullPath(int $object_id, string $extension): string + { + return implode( + DIRECTORY_SEPARATOR, + [ + CLIENT_WEB_DIR, + 'obj_data', + 'tile_image', + 'tile_image_' . $object_id, + 'tile_image.' . $extension + ] + ); + } + + private function deleteTileImageInfoFromContainerSettings(int $id): void + { + $query_delete = $this->helper->getDatabase()->queryF(' + DELETE FROM container_settings + WHERE keyword = "tile_image" AND id = %s + ', ['integer'], [$id]); + $this->helper->getDatabase()->execute($query_delete); + } + + public function getRemainingAmountOfSteps(): int + { + $query = $this->helper->getDatabase()->query(' + SELECT + count(container_settings.id) AS amount + FROM container_settings + WHERE container_settings.keyword = "tile_image" + '); + $r = $this->helper->getDatabase()->fetchObject($query); + + return (int) $r->amount; + } +} diff --git a/Services/Object/classes/class.ilObject.php b/Services/Object/classes/class.ilObject.php index 8e24ca07f681..1dd40f7e840b 100755 --- a/Services/Object/classes/class.ilObject.php +++ b/Services/Object/classes/class.ilObject.php @@ -18,6 +18,9 @@ declare(strict_types=1); +use ILIAS\Object\ilObjectDIC; +use ILIAS\DI\UIServices; +use ILIAS\ResourceStorage\Services as ResourceStorageServices; use ILIAS\Filesystem\Filesystem; use ILIAS\FileUpload\FileUpload; @@ -50,6 +53,7 @@ class ilObject protected ilRbacReview $rbac_review; protected ilObjUser $user; protected ilLanguage $lng; + private ilObjectDIC $object_dic; protected bool $call_by_reference; protected int $max_title = self::TITLE_LENGTH; @@ -98,6 +102,7 @@ public function __construct( $this->error = $DIC["ilErr"]; $this->tree = $DIC["tree"]; $this->app_event_handler = $DIC["ilAppEventHandler"]; + $this->object_dic = ilObjectDIC::dic(); $this->call_by_reference = $this->referenced; @@ -132,30 +137,10 @@ public function __construct( } } - private function initializeObjectProperties( - Filesystem $filesystem, - FileUpload $upload, - ilObjectCustomIconFactory $custom_icon_factory - ): ilObjectProperties { - return (new ilObjectPropertiesAgregator( - new ilObjectCorePropertiesDatabaseRepository($this->db), - new ilObjectAdditionalPropertiesLegacyRepository( - $custom_icon_factory, - $filesystem, - $upload - ) - ))->getFor($this->getId()); - } - public function getObjectProperties(): ilObjectProperties { if ($this->object_properties === null) { - global $DIC; - $this->object_properties = $this->initializeObjectProperties( - $DIC->filesystem()->web(), - $DIC->upload(), - $DIC['object.customicons.factory'] - ); + $this->object_properties = $this->object_dic['object_properties']->getFor($this->getId()); } return $this->object_properties; } @@ -422,6 +407,9 @@ final public static function _lookupObjIdByImportId(string $import_id): int return (int) $row->obj_id; } + /** + * @deprecated 11 + */ public function setOfflineStatus(bool $status): void { $property_is_online = $this->getObjectProperties()->getPropertyIsOnline()->withOnline(); diff --git a/Services/Object/classes/class.ilObject2GUI.php b/Services/Object/classes/class.ilObject2GUI.php index f0081d10e427..7eff311cdf15 100644 --- a/Services/Object/classes/class.ilObject2GUI.php +++ b/Services/Object/classes/class.ilObject2GUI.php @@ -54,7 +54,6 @@ abstract class ilObject2GUI extends ilObjectGUI protected ilCtrl $ctrl; protected ilLanguage $lng; protected ilTabsGUI $tabs_gui; - protected ilObjectService $object_service; protected ilFavouritesManager $favourites; protected ilErrorHandling $error; protected ilLocatorGUI $locator; diff --git a/Services/Object/classes/class.ilObjectCopySelectionTableGUI.php b/Services/Object/classes/class.ilObjectCopySelectionTableGUI.php index 6a18970b1d5d..0bcce9c4e46b 100644 --- a/Services/Object/classes/class.ilObjectCopySelectionTableGUI.php +++ b/Services/Object/classes/class.ilObjectCopySelectionTableGUI.php @@ -45,6 +45,7 @@ public function __construct(?object $parent_class, string $parent_cmd, string $t $this->type = $type; $this->setTitle($this->lng->txt($this->type . '_wizard_page')); + $this->addColumn($this->lng->txt('title'), '', '55%'); $this->addColumn($this->lng->txt('copy'), '', '15%'); $this->addColumn($this->lng->txt('link'), '', '15%'); @@ -60,7 +61,11 @@ public function __construct(?object $parent_class, string $parent_cmd, string $t $this->setFormName('cmd'); - $this->addCommandButton('copyContainerToTargets', $this->lng->txt('obj_' . $this->type . '_duplicate')); + $submit_button_label = $this->lng->txt('obj_' . $this->type . '_duplicate'); + if ($this->parent_obj->getSubMode() === ilObjectCopyGUI::SUBMODE_CONTENT_ONLY) { + $submit_button_label = $this->lng->txt('cntr_adopt_content'); + } + $this->addCommandButton('copyContainerToTargets', $submit_button_label); } public function getType(): string diff --git a/Services/Object/classes/class.ilObjectDataSet.php b/Services/Object/classes/class.ilObjectDataSet.php index c9e1aa549c75..7a13ca2a6da1 100644 --- a/Services/Object/classes/class.ilObjectDataSet.php +++ b/Services/Object/classes/class.ilObjectDataSet.php @@ -1,7 +1,5 @@ storage = $DIC->resourceStorage(); + + $obj_dic = ilObjectDIC::dic(); + $this->object_properties_agregator = $obj_dic['object_properties']; + + parent::__construct(); + } public function getSupportedVersions(): array { return array("4.4.0", "5.1.0", "5.2.0", "5.4.0"); @@ -103,7 +121,6 @@ protected function getTypes(string $entity, string $version): array if ($version == "5.4.0") { return [ "ObjId" => "integer", - "Extension" => "text", "Dir" => "directory" ]; } @@ -193,19 +210,17 @@ public function readData(string $entity, string $version, array $ids): void if ($entity == "tile") { $this->data = []; foreach ($ids as $id) { - $ti = new ilObjectTileImage( - $DIC->filesystem()->web(), - $DIC->upload(), - (int) $id - ); - - if ($ti->exists()) { - $this->data[] = [ - "ObjId" => $id, - "Extension" => $ti->getExtension(), - "Dir" => dirname($ti->getFullPath()) - ]; + $rid = $this->object_properties_agregator->getFor((int) $id)->getPropertyTileImage()->getTileImage()->getRid(); + if ($rid === null) { + continue; } + + $temp_dir = $this->copyTileToTempFolderForExport($rid); + + $this->data[] = [ + "ObjId" => $id, + "Dir" => $temp_dir + ]; } } @@ -227,6 +242,22 @@ public function readData(string $entity, string $version, array $ids): void } } + private function copyTileToTempFolderForExport(string $rid): string + { + $i = $this->storage->manage()->find($rid); + $stream = $this->storage->consume()->stream( + $i + ); + $title = $this->storage->manage()->getCurrentRevision($i)->getTitle(); + + $temp_dir = implode( + DIRECTORY_SEPARATOR, + [ILIAS_DATA_DIR, CLIENT_ID, 'temp', uniqid('tmp')] + ); + mkdir($temp_dir); + file_put_contents($temp_dir . DIRECTORY_SEPARATOR . $title, $stream->getStream()->getContents()); + return $temp_dir; + } /** * Determine the dependent sets of data */ @@ -323,12 +354,12 @@ public function importRecord( $dir = str_replace("..", "", $rec["Dir"]); if ($new_id > 0 && $dir != "" && $this->getImportDirectory() != "") { $source_dir = $this->getImportDirectory() . "/" . $dir; - $ti = new ilObjectTileImage( - $DIC->filesystem()->web(), - $DIC->upload(), - $new_id + $object_properties = $this->object_properties_agregator->getFor($new_id); + $ti = $object_properties->getPropertyTileImage()->getTileImage(); + $ti->createFromImportDir($source_dir); + $object_properties->storePropertyTileImage( + $object_properties->getPropertyTileImage()->withTileImage($ti) ); - $ti->createFromImportDir($source_dir, $rec["Extension"]); } break; } diff --git a/Services/Object/classes/class.ilObjectExporter.php b/Services/Object/classes/class.ilObjectExporter.php index 4af80fb00a44..200977c3b768 100644 --- a/Services/Object/classes/class.ilObjectExporter.php +++ b/Services/Object/classes/class.ilObjectExporter.php @@ -42,7 +42,7 @@ public function init(): void */ public function getXmlExportTailDependencies(string $entity, string $target_release, array $ids): array { - return array(); + return []; } public function getXmlRepresentation(string $entity, string $schema_version, string $id): string diff --git a/Services/Object/classes/class.ilObjectListGUI.php b/Services/Object/classes/class.ilObjectListGUI.php index a4ad3b476f27..deee1f646fb3 100644 --- a/Services/Object/classes/class.ilObjectListGUI.php +++ b/Services/Object/classes/class.ilObjectListGUI.php @@ -24,8 +24,10 @@ use ILIAS\UI\Component\Modal\Modal; use ILIAS\UI\Component\Card\RepositoryObject; use ILIAS\UI\Component\Item\Item; +use ILIAS\UI\Component\Image\Image; use ILIAS\Notes\Note; use ILIAS\HTTP\Services as HTTPServices; +use ILIAS\Object\ilObjectDIC; /** * Important note: @@ -71,6 +73,8 @@ class ilObjectListGUI protected array $access_cache; protected ilAccessHandler $access; protected ilObjUser $user; + protected ilObjectDIC $object_dic; + protected ilObjectProperties $object_properties; protected ilObjectDefinition $obj_definition; protected ilTree $tree; protected ilSetting $settings; @@ -83,7 +87,6 @@ class ilObjectListGUI protected string $mode; protected bool $path_enabled; protected int $context; - protected ilObjectService $object_service; protected ILIAS\HTTP\Wrapper\RequestWrapper $request_wrapper; protected ILIAS\Refinery\Factory $refinery; @@ -193,6 +196,7 @@ public function __construct(int $context = self::CONTEXT_REPOSITORY) $this->access = $DIC['ilAccess']; $this->user = $DIC['ilUser']; + $this->object_dic = ilObjectDIC::dic(); $this->obj_definition = $DIC['objDefinition']; $this->tree = $DIC['tree']; $this->settings = $DIC['ilSetting']; @@ -205,7 +209,6 @@ public function __construct(int $context = self::CONTEXT_REPOSITORY) $this->mode = self::IL_LIST_FULL; $this->path_enabled = false; $this->context = $context; - $this->object_service = $DIC->object(); $this->request_wrapper = $DIC->http()->wrapper()->query(); $this->refinery = $DIC['refinery']; @@ -718,6 +721,7 @@ public function initItem( $this->access_cache = []; $this->ref_id = $ref_id; $this->obj_id = $obj_id; + $this->object_properties = $this->object_dic['object_properties']->getFor($obj_id); $this->setTitle($title); $this->setDescription($description); @@ -1953,7 +1957,11 @@ public function insertCommands( string $async_url = '', bool $header_actions = false ): string { - if (!$this->getCommandsStatus()) { + if (!$this->getCommandsStatus() || $this->commandsNeedToBeHidden( + $use_async, + $get_async_commands, + $header_actions + )) { return ''; } @@ -2119,20 +2127,6 @@ public function insertCommands( $this->ctrl->clearParametersByClass($this->gui_class_name); } - // fix bug #12417 - // there is one case, where no action menu should be displayed: - // public area, category, no info tab - // todo: make this faster and remove type specific implementation if possible - if ($use_async && !$get_async_commands && !$header_actions) { - if ($this->user->getId() === ANONYMOUS_USER_ID && $this->checkInfoPageOnAsynchronousRendering()) { - if ( - !ilContainer::_lookupContainerSetting($this->obj_id, ilObjectServiceSettingsGUI::INFO_TAB_VISIBILITY) - ) { - return ''; - } - } - } - if ($use_async && $get_async_commands) { return $this->current_selection_list->getHTML(true); } @@ -2140,6 +2134,25 @@ public function insertCommands( return $this->current_selection_list->getHTML(); } + /** + * Fix bug #12417: We hide the action menu when we are in the public area + */ + // there is one case, where no action menu should be displayed: + // public area, category, no info tab + // todo: make this faster and remove type specific implementation if possible + private function commandsNeedToBeHidden( + bool $use_async, + bool $get_async_commands, + bool $header_actions + ): bool { + if ($use_async && !$get_async_commands && !$header_actions + && $this->user->getId() === ANONYMOUS_USER_ID && $this->checkInfoPageOnAsynchronousRendering() + && $this->object_properties->getPropertyInfoTabVisibility()) { + return true; + } + return false; + } + public function enableComments(bool $value, bool $enable_comments_settings = true): void { if ($this->settings->get('disable_comments')) { @@ -3208,8 +3221,6 @@ public function getAsCard( htmlspecialchars(addslashes($title)) )); - $path = $this->getTileImagePath(); - // workaround for #26205 // we should get rid of _top links completely and gifure our how // to manage scorm links better @@ -3223,9 +3234,7 @@ public function getAsCard( $modified_link = $this->modifySAHSlaunch($def_cmd_link, $def_cmd_frame); - $image = $this->ui->factory() - ->image() - ->responsive($path, ''); + $image = $this->getTileImage(); if ($def_cmd_link != '') { // #24256 if ($def_cmd_frame != '' && ($modified_link == $def_cmd_link)) { $image = $image->withAdditionalOnLoadCode(function ($id) use ( @@ -3347,24 +3356,10 @@ public function checkInfoPageOnAsynchronousRendering(): bool return false; } - protected function getTileImagePath(): string + private function getTileImage(): Image { - $object = ilObjectFactory::getInstanceByObjId($this->obj_id); - if ($object === null) { - return ''; - } - - $img = $object->getObjectProperties()->getPropertyTileImage()->getTileImage(); - if ($img->exists()) { - return $img->getFullPath(); - } - - $path = ilUtil::getImagePath('cont_tile/cont_tile_default_' . $this->type . '.svg'); - if (is_file($path)) { - return $path; - } - - return ilUtil::getImagePath('cont_tile/cont_tile_default.svg'); + return $this->object_properties->getPropertyTileImage() + ->getTileImage()->getImage(); } /** diff --git a/Services/Object/classes/ilObjectDIC.php b/Services/Object/classes/ilObjectDIC.php new file mode 100644 index 000000000000..cb70fe1d8b5e --- /dev/null +++ b/Services/Object/classes/ilObjectDIC.php @@ -0,0 +1,93 @@ +init($DIC); + } + + return self::$dic; + } + + private function init(ILIASContainer $DIC): void + { + $this['common_settings'] = fn($c): \ilObjectCommonSettings => new \ilObjectCommonSettings( + $DIC->language(), + $DIC->upload(), + $DIC->resourceStorage(), + $c['tile_image_stackholder'], + $c['tile_image_flavour'], + $c['core_properties_repository'], + $c['additional_properties_repository'] + ); + + $this['object_properties'] = fn($c): \ilObjectPropertiesAgregator => new \ilObjectPropertiesAgregator( + $c['core_properties_repository'], + $c['additional_properties_repository'], + $c['object_type_specific_properties_factory'] + ); + + $this['core_properties_repository'] = fn($c): \ilObjectCorePropertiesRepository + => new \ilObjectCorePropertiesCachedRepository( + $DIC['ilDB'], + $DIC->ui(), + $DIC['resource_storage'], + $c['tile_image_stackholder'], + new ilObjectTileImageFlavourDefinition(), + $c['object_type_specific_properties_factory'] + ); + + $this['additional_properties_repository'] = fn($c): \ilObjectAdditionalPropertiesRepository + => new \ilObjectAdditionalPropertiesLegacyRepository( + $DIC['object.customicons.factory'], + $c['object_type_specific_properties_factory'] + ); + + $this['tile_image_stackholder'] = static fn($c): ilObjectTileImageStakeholder + => new ilObjectTileImageStakeholder(); + + $this['tile_image_flavour'] = static fn($c): ilObjectTileImageFlavourDefinition + => new ilObjectTileImageFlavourDefinition(); + + $this['object_type_specific_properties_factory'] = fn($c): ObjectTypeSpecificPropertiesFactory + => new ObjectTypeSpecificPropertiesFactory( + is_readable(ilObjectTypeSpecificPropertiesArtifactObjective::PATH) ? + include ilObjectTypeSpecificPropertiesArtifactObjective::PATH + : [], + $DIC['ilDB'] + ); + } +} diff --git a/Services/Object/interfaces/Properties/CoreProperties/ilObjectCorePropertiesRepository.php b/Services/Object/interfaces/Properties/CoreProperties/ilObjectCorePropertiesRepository.php index 0608441d962d..54121a1f45ce 100644 --- a/Services/Object/interfaces/Properties/CoreProperties/ilObjectCorePropertiesRepository.php +++ b/Services/Object/interfaces/Properties/CoreProperties/ilObjectCorePropertiesRepository.php @@ -1,7 +1,5 @@ $ids + */ + public function preload(array $ids): void; + public function resetPreloadedData(): void; public function getFor(int $object_id): ilObjectCoreProperties; public function store(ilObjectCoreProperties $properties): ilObjectCoreProperties; } diff --git a/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificProperties.php b/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificProperties.php new file mode 100644 index 000000000000..799a0083e114 --- /dev/null +++ b/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificProperties.php @@ -0,0 +1,40 @@ + $object_ids + */ + public function preload(array $object_ids): void; +} diff --git a/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertyModifications.php b/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertyModifications.php new file mode 100644 index 000000000000..0f6d0fbd6562 --- /dev/null +++ b/Services/Object/interfaces/Properties/ObjectTypeSpecificProperties/ilObjectTypeSpecificPropertyModifications.php @@ -0,0 +1,25 @@ +getAccessHandler()->addPermission($this->node_id, self::PERMISSION_REGISTERED); - $this->tpl->setOnScreenMessage('success', $this->lng->txt("wsp_permission_registered_info"), true); + $this->getAccessHandler()->addMissingPermissionForObjects($this->node_id, [self::PERMISSION_REGISTERED]); + $this->tpl->setOnScreenMessage('success', $this->lng->txt("wsp_share_success"), true); $this->ctrl->redirect($this, "share"); break; @@ -283,7 +283,7 @@ public function addPermissionHandler(): void break; case "all": - $this->getAccessHandler()->addPermission($this->node_id, self::PERMISSION_ALL); + $this->getAccessHandler()->addMissingPermissionForObjects($this->node_id, [self::PERMISSION_ALL]); $this->tpl->setOnScreenMessage('success', $this->lng->txt("wsp_permission_all_info"), true); $this->ctrl->redirect($this, "share"); } diff --git a/Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php b/Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php index 29c7fedd8585..e03b7189801e 100644 --- a/Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php +++ b/Services/PersonalWorkspace/classes/class.ilWorkspaceAccessHandler.php @@ -421,10 +421,10 @@ public function findSharedObjects(// PHP8-Review: Method return type and paramet if ($a_filter["obj_type"] ?? false) { $sql .= " AND obj.type = " . $ilDB->quote($a_filter["obj_type"], "text"); } - if (($a_filter["title"] ?? false) && strlen($a_filter["title"]) >= 3) { + if (($a_filter["title"] ?? false) && strlen($a_filter["title"]) >= 3) { $sql .= " AND " . $ilDB->like("obj.title", "text", "%" . $a_filter["title"] . "%"); } - if (($a_filter["user"] ?? false) && strlen($a_filter["user"]) >= 3) { + if (($a_filter["user"] ?? false) && strlen($a_filter["user"]) >= 3) { $usr_ids = array(); $set = $ilDB->query("SELECT usr_id FROM usr_data" . " WHERE (" . $ilDB->like("login", "text", "%" . $a_filter["user"] . "%") . " " . @@ -534,4 +534,18 @@ public static function getObjectDataFromNode(int $a_node_id): ?array // PHP8-Re " WHERE ref.wsp_id = " . $ilDB->quote($a_node_id, "integer")); return $ilDB->fetchAssoc($set); } + + public function addMissingPermissionForObjects(int $node_id, array $objects): bool + { + $existing = $this->getPermissions($node_id); + $added = false; + foreach ($objects as $object_id) { + if (!in_array($object_id, $existing, true)) { + $this->addPermission($node_id, $object_id); + $added = true; + } + } + return $added; + } + } diff --git a/Services/PersonalWorkspace/classes/class.ilWorkspaceShareTableGUI.php b/Services/PersonalWorkspace/classes/class.ilWorkspaceShareTableGUI.php index 6c5bed03f210..a2c4c680c980 100644 --- a/Services/PersonalWorkspace/classes/class.ilWorkspaceShareTableGUI.php +++ b/Services/PersonalWorkspace/classes/class.ilWorkspaceShareTableGUI.php @@ -90,9 +90,9 @@ public function __construct( $this->addColumn($this->lng->txt("wsp_shared_title"), "title"); $this->addColumn($this->lng->txt("wsp_shared_type")); - if (!$this->portfolio_mode) { - $this->addColumn($this->lng->txt("action")); - } + //if (!$this->portfolio_mode) { + $this->addColumn($this->lng->txt("action")); + //} $this->setDefaultOrderField("acl_date"); $this->setDefaultOrderDirection("desc"); @@ -112,6 +112,14 @@ public function __construct( $this->filter["obj_type"] = "prtf"; } + // see #38253 + if ((isset($this->filter["user"]) && $this->filter["user"] !== "") || + (isset($this->filter["title"]) && $this->filter["title"] !== "") || + (isset($this->filter["acl_type"]) && $this->filter["acl_type"] !== "") || + (isset($this->filter["acl_date"]) && $this->filter["acl_date"] !== "")) { + $a_load_data = true; + } + // incoming request: check for validity if ($a_load_data) { /* @@ -128,7 +136,7 @@ public function __construct( $this->importData(); return; } else { - $main_tpl->setOnScreenMessage('info', $lng->txt("wsp_shared_mandatory_filter_info")); + //$main_tpl->setOnScreenMessage('info', $lng->txt("wsp_shared_mandatory_filter_info")); } // initial state: show filters only @@ -280,7 +288,6 @@ protected function fillRow(array $a_set): void { $ilCtrl = $this->ctrl; $lng = $this->lng; - $this->tpl->setVariable("LASTNAME", $a_set["lastname"]); $this->tpl->setVariable("FIRSTNAME", $a_set["firstname"]); $this->tpl->setVariable("LOGIN", $a_set["login"]); @@ -358,6 +365,17 @@ protected function fillRow(array $a_set): void } else { $this->tpl->touchBlock("action_col_bl"); } + } else { + $ilCtrl->setParameter($this->parent_obj, "owner_id", $a_set["owner_id"]); + $ilCtrl->setParameter($this->parent_obj, "prt_id", $a_set["obj_id"]); + $b = $this->ui_factory->button()->shy( + $this->lng->txt("wsp_send_mail"), + $ilCtrl->getLinkTarget($this->parent_obj, "redirectSendMailToSharer") + ); + $dd = $this->ui_factory->dropdown()->standard([$b]); + $this->tpl->setCurrentBlock("action_bl"); + $this->tpl->setVariable("ACTION_DD", $this->renderer->render($dd)); + $this->tpl->parseCurrentBlock(); } } } diff --git a/Services/PersonalWorkspace/templates/default/tpl.shared_row.html b/Services/PersonalWorkspace/templates/default/tpl.shared_row.html index 0d7f84da85b6..f1ff49136b0a 100644 --- a/Services/PersonalWorkspace/templates/default/tpl.shared_row.html +++ b/Services/PersonalWorkspace/templates/default/tpl.shared_row.html @@ -29,6 +29,7 @@ {ACTION} + {ACTION_DD} \ No newline at end of file diff --git a/Services/Skill/Level/class.ilSkillUserLevelDBRepository.php b/Services/Skill/Level/class.ilSkillUserLevelDBRepository.php index 970fd8a97193..bda51e4ca80d 100644 --- a/Services/Skill/Level/class.ilSkillUserLevelDBRepository.php +++ b/Services/Skill/Level/class.ilSkillUserLevelDBRepository.php @@ -31,14 +31,29 @@ public function __construct(ilDBInterface $db = null) ?: $DIC->database(); } - public function deleteUserLevelsOfSkill(int $skill_id): void + public function deleteUserLevelsOfSkill(int $skill_id, bool $is_referenece = false): void { $ilDB = $this->db; - $ilDB->manipulate( - "DELETE FROM skl_user_has_level WHERE " - . " skill_id = " . $ilDB->quote($skill_id, "integer") - ); + if (!$is_referenece) { + $ilDB->manipulate( + "DELETE FROM skl_user_has_level WHERE " + . " skill_id = " . $ilDB->quote($skill_id, "integer") + ); + $ilDB->manipulate( + "DELETE FROM skl_user_skill_level WHERE " + . " skill_id = " . $ilDB->quote($skill_id, "integer") + ); + } else { + $ilDB->manipulate( + "DELETE FROM skl_user_has_level WHERE " + . " tref_id = " . $ilDB->quote($skill_id, "integer") + ); + $ilDB->manipulate( + "DELETE FROM skl_user_skill_level WHERE " + . " tref_id = " . $ilDB->quote($skill_id, "integer") + ); + } } /** diff --git a/Services/Skill/Node/class.SkillDeletionManager.php b/Services/Skill/Node/class.SkillDeletionManager.php new file mode 100644 index 000000000000..43b1bc257dfc --- /dev/null +++ b/Services/Skill/Node/class.SkillDeletionManager.php @@ -0,0 +1,214 @@ + + */ +class SkillDeletionManager +{ + protected SkillTreeManager $tree_manager; + protected PersonalSkillManager $personal_manager; + protected AssignedMaterialManager $material_manager; + protected SkillProfileManager $profile_manager; + protected SkillProfileCompletionManager $profile_completion_manager; + protected SkillResourcesManager $resources_manager; + protected \ilSkillTreeRepository $tree_repo; + protected \ilSkillLevelRepository $level_repo; + protected \ilSkillUserLevelRepository $user_level_repo; + protected \ilAppEventHandler $event_handler; + + public function __construct( + SkillTreeManager $tree_manager = null, + PersonalSkillManager $personal_manager = null, + AssignedMaterialManager $material_manager = null, + SkillProfileManager $profile_manager = null, + SkillProfileCompletionManager $profile_completion_manager = null, + SkillResourcesManager $resources_manager = null, + \ilSkillTreeRepository $tree_repo = null, + \ilSkillLevelRepository $level_repo = null, + \ilSkillUserLevelRepository $user_level_repo = null, + \ilAppEventHandler $event_handler = null, + ) { + global $DIC; + + $this->tree_manager = ($tree_manager) ?: $DIC->skills()->internal()->manager()->getTreeManager(); + $this->personal_manager = ($personal_manager) ?: $DIC->skills()->internal()->manager()->getPersonalSkillManager(); + $this->material_manager = ($material_manager) ?: $DIC->skills()->internal()->manager()->getAssignedMaterialManager(); + $this->profile_manager = ($profile_manager) ?: $DIC->skills()->internal()->manager()->getProfileManager(); + $this->profile_completion_manager = ($profile_completion_manager) ?: $DIC->skills()->internal()->manager()->getProfileCompletionManager(); + $this->resources_manager = ($resources_manager) ?: $DIC->skills()->internal()->manager()->getResourceManager(); + $this->tree_repo = ($tree_repo) ?: $DIC->skills()->internal()->repo()->getTreeRepo(); + $this->level_repo = ($level_repo) ?: $DIC->skills()->internal()->repo()->getLevelRepo(); + $this->user_level_repo = ($user_level_repo) ?: $DIC->skills()->internal()->repo()->getUserLevelRepo(); + $this->event_handler = ($event_handler) ?: $DIC->event(); + } + + public function deleteTree(int $node_id): void + { + if ($node_id != \ilTree::POS_FIRST_NODE) { + $tree = $this->tree_repo->getTreeForNodeId($node_id); + $tree_obj = $this->tree_manager->getTree($tree->getTreeId()); + + // delete competence profiles of tree + $tree_profiles = $this->profile_manager->getProfilesForSkillTree($tree->getTreeId()); + foreach ($tree_profiles as $profile) { + $this->profile_manager->delete($profile->getId()); + $this->profile_completion_manager->deleteEntriesForProfile($profile->getId()); + } + + $this->deleteNode($node_id, $tree); + $this->tree_manager->deleteTree($tree_obj); + } + } + + public function deleteNode(int $node_id, \ilSkillTree $tree = null): void + { + if ($node_id != \ilTree::POS_FIRST_NODE) { + if (!$tree) { + $tree = $this->tree_repo->getTreeForNodeId($node_id); + } + $obj = \ilSkillTreeNodeFactory::getInstance($node_id); + $node_data = $tree->getNodeData($node_id); + if (is_object($obj)) { + $obj_type = $obj->getType(); + switch ($obj_type) { + case "skrt": + $this->deleteSkillRoot($obj->getId(), $tree); + break; + case "skll": + $this->deleteSkill($obj->getId()); + break; + case "scat": + $this->deleteSkillCategory($obj->getId(), $tree); + break; + case "sktr": + $this->deleteSkillTemplateReference($obj->getId()); + break; + case "sktp": + $this->deleteSkillTemplate($obj->getId()); + break; + case "sctp": + $this->deleteSkillCategoryTemplate($obj->getId(), $tree); + break; + } + $obj->delete(); + } + if ($tree->isInTree($node_id)) { + $tree->deleteTree($node_data); + } + } + } + + protected function deleteSkillRoot(int $skrt_id, \ilSkillTree $tree): void + { + $childs = $tree->getChildsByTypeFilter( + $skrt_id, + ["skll", "scat", "sktp", "sctp", "sktr"] + ); + foreach ($childs as $node) { + $this->deleteNode((int) $node["obj_id"], $tree); + } + } + + protected function deleteSkill(int $skll_id): void + { + $this->level_repo->deleteLevelsOfSkill($skll_id); + $this->user_level_repo->deleteUserLevelsOfSkill($skll_id); + \ilSkillUsage::removeUsagesForSkill($skll_id); + $this->personal_manager->removePersonalSkillsForSkill($skll_id); + $this->material_manager->removeAssignedMaterialsForSkill($skll_id); + $this->profile_manager->deleteProfileLevelsForSkill($skll_id); + $this->resources_manager->removeResourcesForSkill($skll_id); + $this->event_handler->raise("Services/Skill", "deleteSkill", ["node_id" => $skll_id, "is_reference" => false]); + } + + protected function deleteSkillCategory(int $scat_id, \ilSkillTree $tree): void + { + $childs = $tree->getChildsByTypeFilter( + $scat_id, + ["skll", "scat", "sktr"] + ); + foreach ($childs as $node) { + $this->deleteNode((int) $node["obj_id"], $tree); + } + + $this->personal_manager->removePersonalSkillsForSkill($scat_id); + } + + protected function deleteSkillTemplateReference(int $sktr_id): void + { + $this->user_level_repo->deleteUserLevelsOfSkill($sktr_id, true); + \ilSkillUsage::removeUsagesForSkill($sktr_id, true); + $this->personal_manager->removePersonalSkillsForSkill($sktr_id); + $this->material_manager->removeAssignedMaterialsForSkill($sktr_id, true); + $this->profile_manager->deleteProfileLevelsForSkill($sktr_id, true); + $this->resources_manager->removeResourcesForSkill($sktr_id, true); + $this->event_handler->raise("Services/Skill", "deleteSkill", ["node_id" => $sktr_id, "is_reference" => true]); + } + + protected function deleteSkillTemplate(int $sktp_id): void + { + $this->level_repo->deleteLevelsOfSkill($sktp_id); + $this->user_level_repo->deleteUserLevelsOfSkill($sktp_id); + \ilSkillUsage::removeUsagesForSkill($sktp_id); + $this->material_manager->removeAssignedMaterialsForSkill($sktp_id); + $this->profile_manager->deleteProfileLevelsForSkill($sktp_id); + $this->resources_manager->removeResourcesForSkill($sktp_id); + $this->event_handler->raise("Services/Skill", "deleteSkill", ["node_id" => $sktp_id, "is_reference" => false]); + + foreach (\ilSkillTemplateReference::_lookupTrefIdsForTemplateId($sktp_id) as $tref_id) { + $this->deleteNode($tref_id); + } + } + + protected function deleteSkillCategoryTemplate(int $sctp_id, \ilSkillTree $tree): void + { + $childs = $tree->getChildsByTypeFilter( + $sctp_id, + ["sktp", "sctp"] + ); + foreach ($childs as $node) { + $this->deleteNode((int) $node["obj_id"], $tree); + } + + foreach (\ilSkillTemplateReference::_lookupTrefIdsForTemplateId($sctp_id) as $tref_id) { + $this->deleteNode($tref_id); + } + } + + public function updateProfileCompletions(\ilSkillTree $tree): void + { + $tree_profiles = $this->profile_manager->getProfilesForSkillTree($tree->getTreeId()); + foreach ($tree_profiles as $profile) { + $this->profile_completion_manager->writeCompletionEntryForAllAssignedUsersOfProfile($profile->getId()); + } + } +} diff --git a/Services/Skill/Node/class.ilBasicSkill.php b/Services/Skill/Node/class.ilBasicSkill.php index 60555f483968..0bd85dedc340 100644 --- a/Services/Skill/Node/class.ilBasicSkill.php +++ b/Services/Skill/Node/class.ilBasicSkill.php @@ -86,18 +86,6 @@ public function create(): void parent::create(); } - /** - * Delete skill - */ - public function delete(): void - { - $skill_id = $this->getId(); - $this->bsc_skl_lvl_db_rep->deleteLevelsOfSkill($skill_id); - $this->bsc_skl_usr_lvl_db_rep->deleteUserLevelsOfSkill($skill_id); - - parent::delete(); - } - /** * Copy basic skill */ diff --git a/Services/Skill/Node/class.ilBasicSkillTemplate.php b/Services/Skill/Node/class.ilBasicSkillTemplate.php index 9943f2d362ff..f19519f68b6c 100644 --- a/Services/Skill/Node/class.ilBasicSkillTemplate.php +++ b/Services/Skill/Node/class.ilBasicSkillTemplate.php @@ -59,18 +59,6 @@ public function delete(): void { $ilDB = $this->db; - foreach (\ilSkillTemplateReference::_lookupTrefIdsForTemplateId($this->getId()) as $tref_id) { - $obj = ilSkillTreeNodeFactory::getInstance($tref_id); - $skill_tree = $this->skill_service->internal()->repo()->getTreeRepo()->getTreeForNodeId($tref_id); - $node_data = $skill_tree->getNodeData($tref_id); - if (is_object($obj)) { - $obj->delete(); - } - if ($skill_tree->isInTree($tref_id)) { - $skill_tree->deleteTree($node_data); - } - } - $ilDB->manipulate( "DELETE FROM skl_templ_ref WHERE " . " templ_id = " . $ilDB->quote($this->getId(), "integer") diff --git a/Services/Skill/Node/class.ilSkillCategory.php b/Services/Skill/Node/class.ilSkillCategory.php index 7deecdc8559b..c1e9b44c7593 100644 --- a/Services/Skill/Node/class.ilSkillCategory.php +++ b/Services/Skill/Node/class.ilSkillCategory.php @@ -44,34 +44,4 @@ public function copy(): ilSkillCategory return $scat; } - - public function delete(): void - { - $scat_id = $this->getId(); - $skill_tree = $this->skill_service->internal()->repo()->getTreeRepo()->getTreeForNodeId($scat_id); - $childs = $skill_tree->getChildsByTypeFilter( - $scat_id, - ["skll", "scat", "sktr"] - ); - foreach ($childs as $node) { - switch ($node["type"]) { - case "skll": - $obj = new ilBasicSkill((int) $node["obj_id"]); - $obj->delete(); - break; - - case "scat": - $obj = new ilSkillCategory((int) $node["obj_id"]); - $obj->delete(); - break; - - case "sktr": - $obj = new ilSkillTemplateReference((int) $node["obj_id"]); - $obj->delete(); - break; - } - } - - parent::delete(); - } } diff --git a/Services/Skill/Node/class.ilSkillRoot.php b/Services/Skill/Node/class.ilSkillRoot.php index ed90b6f75bce..f0516fbccb9d 100644 --- a/Services/Skill/Node/class.ilSkillRoot.php +++ b/Services/Skill/Node/class.ilSkillRoot.php @@ -31,44 +31,4 @@ public function __construct(int $a_id = 0) parent::__construct($a_id); $this->setType("skrt"); } - - public function delete(): void - { - $skrt_id = $this->getId(); - $skill_tree = $this->skill_service->internal()->repo()->getTreeRepo()->getTreeForNodeId($skrt_id); - $childs = $skill_tree->getChildsByTypeFilter( - $skrt_id, - ["skll", "scat", "sktp", "sctp", "sktr"] - ); - foreach ($childs as $node) { - switch ($node["type"]) { - case "skll": - $obj = new ilBasicSkill((int) $node["obj_id"]); - $obj->delete(); - break; - - case "scat": - $obj = new ilSkillCategory((int) $node["obj_id"]); - $obj->delete(); - break; - - case "sktp": - $obj = new ilBasicSkillTemplate((int) $node["obj_id"]); - $obj->delete(); - break; - - case "sctp": - $obj = new ilSkillTemplateCategory((int) $node["obj_id"]); - $obj->delete(); - break; - - case "sktr": - $obj = new ilSkillTemplateReference((int) $node["obj_id"]); - $obj->delete(); - break; - } - } - - parent::delete(); - } } diff --git a/Services/Skill/Node/class.ilSkillTemplateCategory.php b/Services/Skill/Node/class.ilSkillTemplateCategory.php index dadb0d7e70be..d4a24251a95b 100644 --- a/Services/Skill/Node/class.ilSkillTemplateCategory.php +++ b/Services/Skill/Node/class.ilSkillTemplateCategory.php @@ -48,38 +48,6 @@ public function delete(): void { $ilDB = $this->db; - $sctp_id = $this->getId(); - $skill_tree = $this->skill_service->internal()->repo()->getTreeRepo()->getTreeForNodeId($sctp_id); - $childs = $skill_tree->getChildsByTypeFilter( - $sctp_id, - ["sktp", "sctp"] - ); - foreach ($childs as $node) { - switch ($node["type"]) { - case "sktp": - $obj = new ilBasicSkillTemplate((int) $node["obj_id"]); - $obj->delete(); - break; - - case "sctp": - $obj = new ilSkillTemplateCategory((int) $node["obj_id"]); - $obj->delete(); - break; - } - } - - foreach (\ilSkillTemplateReference::_lookupTrefIdsForTemplateId($sctp_id) as $tref_id) { - $obj = ilSkillTreeNodeFactory::getInstance($tref_id); - $skill_tree = $this->skill_service->internal()->repo()->getTreeRepo()->getTreeForNodeId($tref_id); - $node_data = $skill_tree->getNodeData($tref_id); - if (is_object($obj)) { - $obj->delete(); - } - if ($skill_tree->isInTree($tref_id)) { - $skill_tree->deleteTree($node_data); - } - } - $ilDB->manipulate( "DELETE FROM skl_templ_ref WHERE " . " templ_id = " . $ilDB->quote($this->getId(), "integer") diff --git a/Services/Skill/Personal/class.AssignedMaterialDBRepository.php b/Services/Skill/Personal/class.AssignedMaterialDBRepository.php index f772fd695a65..f49c7d8e8d37 100644 --- a/Services/Skill/Personal/class.AssignedMaterialDBRepository.php +++ b/Services/Skill/Personal/class.AssignedMaterialDBRepository.php @@ -174,7 +174,7 @@ public function remove(int $user_id, int $tref_id, int $level_id, int $wsp_id): $ilDB->manipulate($t); } - public function removeAll(int $user_id): void + public function removeAllForUser(int $user_id): void { $ilDB = $this->db; @@ -182,4 +182,18 @@ public function removeAll(int $user_id): void " user_id = " . $ilDB->quote($user_id, "integer"); $ilDB->manipulate($t); } + + public function removeAllForSkill(int $skill_node_id, bool $is_reference): void + { + $ilDB = $this->db; + + if (!$is_reference) { + $t = "DELETE FROM skl_assigned_material WHERE " . + " skill_id = " . $ilDB->quote($skill_node_id, "integer"); + } else { + $t = "DELETE FROM skl_assigned_material WHERE " . + " tref_id = " . $ilDB->quote($skill_node_id, "integer"); + } + $ilDB->manipulate($t); + } } diff --git a/Services/Skill/Personal/class.AssignedMaterialManager.php b/Services/Skill/Personal/class.AssignedMaterialManager.php index 6cd7841dbc97..812f20c8901c 100644 --- a/Services/Skill/Personal/class.AssignedMaterialManager.php +++ b/Services/Skill/Personal/class.AssignedMaterialManager.php @@ -91,9 +91,14 @@ public function removeAssignedMaterial(int $user_id, int $tref_id, int $level_id $this->ass_mat_repo->remove($user_id, $tref_id, $level_id, $wsp_id); } - public function removeAssignedMaterials(int $user_id): void + public function removeAssignedMaterialsForUser(int $user_id): void { - $this->ass_mat_repo->removeAll($user_id); + $this->ass_mat_repo->removeAllForUser($user_id); + } + + public function removeAssignedMaterialsForSkill(int $skill_node_id, bool $is_reference = false): void + { + $this->ass_mat_repo->removeAllForSkill($skill_node_id, $is_reference); } /** diff --git a/Services/Skill/Personal/class.PersonalSkillDBRepository.php b/Services/Skill/Personal/class.PersonalSkillDBRepository.php index 0dc7907d7996..257567c50dfd 100644 --- a/Services/Skill/Personal/class.PersonalSkillDBRepository.php +++ b/Services/Skill/Personal/class.PersonalSkillDBRepository.php @@ -104,7 +104,7 @@ public function remove(int $user_id, int $skill_node_id): void ); } - public function removeAll(int $user_id): void + public function removeAllForUser(int $user_id): void { $ilDB = $this->db; @@ -114,6 +114,16 @@ public function removeAll(int $user_id): void ); } + public function removeAllForSkill(int $skill_node_id): void + { + $ilDB = $this->db; + + $ilDB->manipulate( + "DELETE FROM skl_personal_skill WHERE " . + " skill_node_id = " . $ilDB->quote($skill_node_id, "integer") + ); + } + /** * @param array> $usages * @param int[] $pskill_ids diff --git a/Services/Skill/Personal/class.PersonalSkillManager.php b/Services/Skill/Personal/class.PersonalSkillManager.php index 35425e47479f..6e121af354d9 100644 --- a/Services/Skill/Personal/class.PersonalSkillManager.php +++ b/Services/Skill/Personal/class.PersonalSkillManager.php @@ -54,8 +54,13 @@ public function removePersonalSkill(int $user_id, int $skill_node_id): void $this->personal_repo->remove($user_id, $skill_node_id); } - public function removePersonalSkills(int $user_id): void + public function removePersonalSkillsForUser(int $user_id): void { - $this->personal_repo->removeAll($user_id); + $this->personal_repo->removeAllForUser($user_id); + } + + public function removePersonalSkillsForSkill(int $skill_node_id): void + { + $this->personal_repo->removeAllForSkill($skill_node_id); } } diff --git a/Services/Skill/Personal/class.ilPersonalSkillsGUI.php b/Services/Skill/Personal/class.ilPersonalSkillsGUI.php index a666a134b074..9a9ef5b28790 100644 --- a/Services/Skill/Personal/class.ilPersonalSkillsGUI.php +++ b/Services/Skill/Personal/class.ilPersonalSkillsGUI.php @@ -131,7 +131,7 @@ class ilPersonalSkillsGUI protected Personal\SelfEvaluationManager $self_evaluation_manager; protected Resource\SkillResourcesManager $resource_manager; protected Table\SkillTableManager $table_manager; - protected ContainerSkills\ContainerSkillInternalFactoryService $cont_factory_service; + protected ContainerSkills\SkillInternalFactoryService $cont_factory_service; protected string $requested_list_mode = self::LIST_PROFILES; protected int $requested_node_id = 0; protected int $requested_profile_id = 0; @@ -1368,10 +1368,8 @@ public function getGapAnalysisHTML(int $a_user_id = 0, ?array $a_skills = null): if ($a_skills == null) { foreach ($this->getObjectSkills() as $s) { $a_skills[] = array( - "cont_obj_id" => $s->getContainerObjectId(), "base_skill_id" => $s->getBaseSkillId(), - "tref_id" => $s->getTrefId(), - "title" => $s->getTitle() + "tref_id" => $s->getTrefId() ); } } @@ -1404,10 +1402,8 @@ public function getGapAnalysisHTML(int $a_user_id = 0, ?array $a_skills = null): foreach ($a_skills as $s) { /** @var XAxis $x_axis */ $skills[] = $this->cont_factory_service->containerSkill()->skill( - (int) $s["cont_obj_id"], (int) $s["base_skill_id"], - (int) $s["tref_id"], - $s["title"] + (int) $s["tref_id"] ); } } diff --git a/Services/Skill/Profile/class.SkillProfileLevelsDBRepository.php b/Services/Skill/Profile/class.SkillProfileLevelsDBRepository.php index 0f0633b428d5..a115630f97d4 100644 --- a/Services/Skill/Profile/class.SkillProfileLevelsDBRepository.php +++ b/Services/Skill/Profile/class.SkillProfileLevelsDBRepository.php @@ -123,7 +123,7 @@ public function delete(SkillProfileLevel $skill_level_obj): void ); } - public function deleteAll(int $profile_id): void + public function deleteAllForProfile(int $profile_id): void { $ilDB = $this->db; @@ -133,6 +133,23 @@ public function deleteAll(int $profile_id): void ); } + public function deleteAllForSkill(int $skill_node_id, bool $is_reference): void + { + $ilDB = $this->db; + + if (!$is_reference) { + $ilDB->manipulate( + "DELETE FROM skl_profile_level WHERE " . + " base_skill_id = " . $ilDB->quote($skill_node_id, "integer") + ); + } else { + $ilDB->manipulate( + "DELETE FROM skl_profile_level WHERE " . + " tref_id = " . $ilDB->quote($skill_node_id, "integer") + ); + } + } + public function updateSkillOrder(int $profile_id, array $order): void { $ilDB = $this->db; diff --git a/Services/Skill/Profile/class.SkillProfileManager.php b/Services/Skill/Profile/class.SkillProfileManager.php index 87c49cc4077d..10eaa7803184 100644 --- a/Services/Skill/Profile/class.SkillProfileManager.php +++ b/Services/Skill/Profile/class.SkillProfileManager.php @@ -88,7 +88,12 @@ protected function deleteProfile(int $profile_id): void protected function deleteProfileLevels(int $profile_id): void { - $this->profile_levels_repo->deleteAll($profile_id); + $this->profile_levels_repo->deleteAllForProfile($profile_id); + } + + public function deleteProfileLevelsForSkill(int $skill_node_id, bool $is_reference = false): void + { + $this->profile_levels_repo->deleteAllForSkill($skill_node_id, $is_reference); } protected function deleteProfileUsers(int $profile_id): void diff --git a/Services/Skill/README.md b/Services/Skill/README.md index 7e5f6650db05..65199e92acec 100644 --- a/Services/Skill/README.md +++ b/Services/Skill/README.md @@ -156,7 +156,7 @@ Skills are organised in a hierarchical structure called the [Skill Tree](#skill- * **Code**: `class ilSkillRoot` -The root node of the tree. There is only one. +The root node of a skill tree. There can be more than one. ## Basic Skill @@ -194,9 +194,10 @@ A skill template reference is the link between the main category tree and a skil * **Node ID**: Node ID (`skl_templ_ref.skl_node_id` referencing a `skl_tree_node.obj_id` of type "sktr") * **Template Node ID**: Template Node ID (`skl_templ_ref.templ_id` referencing a `skl_tree_node.obj_id` of type "sktp" or "sctp") -**Business Rule** +**Business Rules** * A Skill Template Reference can only reference Templates or Template Category Nodes which are on the top level (directly underneath the root node). +* When a Template or Template Category is deleted, all related Skill Template References will also be deleted. ## Skill Tree @@ -419,9 +420,12 @@ There are three different types of user skill levels: * Features that reference skills (e.g. local skill profiles) can re-instantiate these references on import by retrieving the new IDs through the methods `ilBasicSkill::getCommonSkillIdForImportId()` and/or `ilBasicSkill::getLevelIdForImportIdMatchSkill`. -##Deleting Competences +## Deleting Competences -* Competences cannot be deleted, if: +* Up to ILIAS 8, Competences could not be deleted, if there were in use. Since ILIAS 9, it is possible to delete + Competences, Competence Templates and whole Competence Trees, even when they are in use. Before the deletion is done, + there is still a warning message to inform the user about the impact of the deletion. The message contains information + about the following usages: * Competence is used in a repository object * Competence is selected by users as Personal Competence * Users assigned material from their personal resources to a competence @@ -437,7 +441,7 @@ There are three different types of user skill levels: * If an entry is written for a user, all Competence Profiles of the user are checked * If a user is assigned to a Competence Profile manually or by a role, the Competence Profile for the one user or all users of a role are checked (in future: OrgUnits, too) * If a Competence Profile is edited, i.e. a skill level is removed or added, the Competence Profile is checked for all assigned users/roles - * The deletion of competences is intercepted by the general prevention of competence deletion when they are assigned to a Competence Profile. This may change in the future and therefore should be mentioned here. + * If a competence is fully deleted, the Competence Profile is checked for all assigned users/roles * For every time a user fulfills a Competence Profile, an entry in the Learning History is written * The fulfillment of a Competence Profile is given, when the completion status changes from <100% to 100%. This can happen multiple times, because Competence Profiles can be edited, and the fulfillment of a Skill Profile for a user can vanish later on. diff --git a/Services/Skill/Resource/class.SkillResourceDBRepository.php b/Services/Skill/Resource/class.SkillResourceDBRepository.php index a10d00fdf771..1131a97fb747 100644 --- a/Services/Skill/Resource/class.SkillResourceDBRepository.php +++ b/Services/Skill/Resource/class.SkillResourceDBRepository.php @@ -163,6 +163,21 @@ public function remove(int $skill_id, int $tref_id, int $level_id, int $rep_ref_ ); } + public function removeForSkill(int $skill_node_id, bool $is_reference): void + { + if (!$is_reference) { + $this->db->manipulate( + "DELETE FROM skl_skill_resource WHERE " . + " base_skill_id = " . $this->db->quote($skill_node_id, "integer") + ); + } else { + $this->db->manipulate( + "DELETE FROM skl_skill_resource WHERE " . + " tref_id = " . $this->db->quote($skill_node_id, "integer") + ); + } + } + /** * @return SkillResourceLevel[] */ diff --git a/Services/Skill/Resource/class.SkillResourcesManager.php b/Services/Skill/Resource/class.SkillResourcesManager.php index 68669c83e16c..ae808cd1d900 100644 --- a/Services/Skill/Resource/class.SkillResourcesManager.php +++ b/Services/Skill/Resource/class.SkillResourcesManager.php @@ -136,6 +136,11 @@ public function removeResource( $this->skill_res_repo->remove($skill_id, $tref_id, $level_id, $rep_ref_id); } + public function removeResourcesForSkill(int $skill_node_id, bool $is_reference = false): void + { + $this->skill_res_repo->removeForSkill($skill_node_id, $is_reference); + } + public function isLevelTooLow(int $tref_id, array $skill_levels, array $profile_levels, array $actual_levels): bool { $too_low = true; diff --git a/Services/Skill/Service/classes/class.SkillInternalManagerService.php b/Services/Skill/Service/classes/class.SkillInternalManagerService.php index a93a62cf3b5e..9ca318c562ac 100644 --- a/Services/Skill/Service/classes/class.SkillInternalManagerService.php +++ b/Services/Skill/Service/classes/class.SkillInternalManagerService.php @@ -133,4 +133,9 @@ public function getTableManager(): Table\SkillTableManager { return new Table\SkillTableManager(); } + + public function getDeletionManager(): Node\SkillDeletionManager + { + return new Node\SkillDeletionManager(); + } } diff --git a/Services/Skill/Service/classes/class.SkillService.php b/Services/Skill/Service/classes/class.SkillService.php index 33ad6fcf5081..cc569cee31cd 100644 --- a/Services/Skill/Service/classes/class.SkillService.php +++ b/Services/Skill/Service/classes/class.SkillService.php @@ -1,7 +1,5 @@ skill_tree_manager->getSkillManagementRefId() ); $this->skill_table_manager = $skill_manager->getTableManager(); + $this->skill_deletion_manager = $skill_manager->getDeletionManager(); } public function executeCommand(): void @@ -634,7 +636,6 @@ public function deleteNodes(object $a_gui): void $tpl = $this->tpl; $ilCtrl = $this->ctrl; $ilTabs = $this->tabs; - $ilToolbar = $this->toolbar; if (empty($this->requested_node_ids)) { $this->ilias->raiseError($this->lng->txt("no_checkbox"), $this->ilias->error_obj->MESSAGE); @@ -692,20 +693,13 @@ public function deleteNodes(object $a_gui): void $this->ilias->raiseError("Skill Deletion - type mismatch.", $this->ilias->error_obj->MESSAGE); } + $usage_html = ""; if (count($usages) > 0) { - $html = ""; foreach ($usages as $k => $usage) { $table = $this->skill_table_manager->getSkillUsageTable($k, $usage, $mode)->getComponent(); - $html .= $this->ui->renderer()->render($table) . "

      "; + $usage_html .= $this->ui->renderer()->render($table) . "

      "; } - $tpl->setContent($html); $ilCtrl->saveParameter($a_gui, "tmpmode"); - $ilToolbar->addButton( - $lng->txt("back"), - $ilCtrl->getLinkTarget($a_gui, "cancelDelete") - ); - $this->main_tpl->setOnScreenMessage('failure', $lng->txt("skmg_cannot_delete_nodes_in_use")); - return; } // SAVE POST VALUES @@ -716,7 +710,12 @@ public function deleteNodes(object $a_gui): void $ilCtrl->setParameter($a_gui, "tmpmode", (int) $this->requested_tmpmode); $a_form_action = $this->ctrl->getFormAction($a_gui); $confirmation_gui->setFormAction($a_form_action); - $confirmation_gui->setHeaderText($this->lng->txt("info_delete_sure")); + if (count($usages) > 0) { + $confirmation_text = $this->lng->txt("skmg_delete_warning"); + } else { + $confirmation_text = $this->lng->txt("info_delete_sure"); + } + $confirmation_gui->setHeaderText($confirmation_text); // Add items to delete foreach ($this->requested_node_ids as $id) { @@ -751,7 +750,7 @@ public function deleteNodes(object $a_gui): void $confirmation_gui->setConfirm($lng->txt("confirm"), "confirmedDelete"); } - $tpl->setContent($confirmation_gui->getHTML()); + $tpl->setContent($confirmation_gui->getHTML() . $usage_html); } public function cancelDelete(): void @@ -765,19 +764,7 @@ public function confirmedDeleteTrees(): void // delete all selected trees foreach ($this->requested_node_ids as $id) { - if ($id != ilTree::POS_FIRST_NODE) { - $obj = ilSkillTreeNodeFactory::getInstance($id); - $tree = $this->skill_tree_repo->getTreeForNodeId($id); - $tree_obj = $this->skill_tree_manager->getTree($tree->getTreeId()); - $node_data = $tree->getNodeData($id); - if (is_object($obj)) { - $obj->delete(); - } - if ($tree->isInTree($id)) { - $tree->deleteTree($node_data); - } - $this->skill_tree_manager->deleteTree($tree_obj); - } + $this->skill_deletion_manager->deleteTree($id); } // feedback @@ -789,17 +776,9 @@ public function confirmedDelete(): void { // delete all selected objects foreach ($this->requested_node_ids as $id) { - if ($id != ilTree::POS_FIRST_NODE) { - $obj = ilSkillTreeNodeFactory::getInstance($id); - $node_data = $this->skill_tree->getNodeData($id); - if (is_object($obj)) { - $obj->delete(); - } - if ($this->skill_tree->isInTree($id)) { - $this->skill_tree->deleteTree($node_data); - } - } + $this->skill_deletion_manager->deleteNode($id, $this->skill_tree); } + $this->skill_deletion_manager->updateProfileCompletions($this->skill_tree); // feedback $this->main_tpl->setOnScreenMessage('info', $this->lng->txt("info_deleted"), true); diff --git a/Services/Skill/classes/class.ilSkillObjDeletionHandler.php b/Services/Skill/classes/class.ilSkillObjDeletionHandler.php index fc5deb3baa5a..0893a8784180 100644 --- a/Services/Skill/classes/class.ilSkillObjDeletionHandler.php +++ b/Services/Skill/classes/class.ilSkillObjDeletionHandler.php @@ -52,8 +52,8 @@ public function __construct(int $obj_id, string $obj_type) public function processDeletion(): void { if ($this->obj_type == "usr" && ilObject::_lookupType($this->obj_id) == "usr") { - $this->personal_manager->removePersonalSkills($this->obj_id); - $this->assigned_material_manager->removeAssignedMaterials($this->obj_id); + $this->personal_manager->removePersonalSkillsForUser($this->obj_id); + $this->assigned_material_manager->removeAssignedMaterialsForUser($this->obj_id); $this->profile_manager->removeUserFromAllProfiles($this->obj_id); $this->profile_completion_manager->deleteEntriesForUser($this->obj_id); ilBasicSkill::removeAllUserData($this->obj_id); diff --git a/Services/Skill/classes/class.ilSkillUsage.php b/Services/Skill/classes/class.ilSkillUsage.php index 4c3d776f9cd6..c0171b52e422 100644 --- a/Services/Skill/classes/class.ilSkillUsage.php +++ b/Services/Skill/classes/class.ilSkillUsage.php @@ -108,6 +108,25 @@ public static function removeUsagesFromObject(int $a_obj_id): void ); } + public static function removeUsagesForSkill(int $node_id, bool $is_referenece = false): void + { + global $DIC; + + $ilDB = $DIC->database(); + + if (!$is_referenece) { + $ilDB->manipulate( + $q = "DELETE FROM skl_usage WHERE " . + " skill_id = " . $ilDB->quote($node_id, "integer") + ); + } else { + $ilDB->manipulate( + $q = "DELETE FROM skl_usage WHERE " . + " tref_id = " . $ilDB->quote($node_id, "integer") + ); + } + } + /** * @return int[] */ diff --git a/Services/Skill/service.xml b/Services/Skill/service.xml index 56e6c18c8900..11a085fb2b50 100644 --- a/Services/Skill/service.xml +++ b/Services/Skill/service.xml @@ -17,6 +17,7 @@ + diff --git a/Services/User/classes/class.ilUserXMLWriter.php b/Services/User/classes/class.ilUserXMLWriter.php index 6328809e4db0..492656e73c1e 100644 --- a/Services/User/classes/class.ilUserXMLWriter.php +++ b/Services/User/classes/class.ilUserXMLWriter.php @@ -27,34 +27,38 @@ */ class ilUserXMLWriter extends ilXmlWriter { - public ILIAS $ilias; - public array $users; // Missing array type. - public int $user_id = 0; - public bool $attachRoles = false; - public bool $attachPreferences = false; + private ILIAS $ilias; + private ilDBInterface $db; + private ilLanguage $lng; + private array $users; // Missing array type. + private int $user_id = 0; + private bool $attach_roles = false; + private bool $attach_preferences = false; /** * fields to be exported + * */ - private array $settings; // Missing array type. + private array $settings = []; public function __construct() { + /** @var ILIAS\DI\Container $DIC */ global $DIC; - $ilias = $DIC['ilias']; - $ilUser = $DIC->user(); + $this->ilias = $DIC['ilias']; + $this->db = $DIC['ilDB']; + $this->lng = $DIC['lng']; + $this->user_id = $DIC['ilUser']->getId(); - parent::__construct(); + $this->attach_roles = false; - $this->ilias = $ilias; - $this->user_id = $ilUser->getId(); - $this->attachRoles = false; + parent::__construct(); } public function setAttachRoles(bool $value): void { - $this->attachRoles = $value; + $this->attach_roles = $value; } public function setObjects(array $users): void // Missing array type. @@ -91,8 +95,8 @@ public function getXML(): string public function __buildHeader(): void { - $this->xmlSetDtdDef(""); - $this->xmlSetGenCmt("User of ilias system"); + $this->xmlSetDtdDef(''); + $this->xmlSetGenCmt('User of ilias system'); $this->xmlHeader(); $this->xmlStartTag('Users'); @@ -105,114 +109,109 @@ public function __buildFooter(): void public function __handleUser(array $row): void // Missing array type. { - global $DIC; - - $ilDB = $DIC['ilDB']; - $lng = $DIC['lng']; - if (!is_array($this->settings)) { + if ($this->settings === []) { $this->setSettings(ilObjUserFolder::getExportSettings()); } - $prefs = ilObjUser::_getPreferences($row["usr_id"]); + $prefs = ilObjUser::_getPreferences($row['usr_id']); - if (strlen($row["language"]) == 0) { - $row["language"] = $lng->getDefaultLanguage(); + if (strlen($row['language']) == 0) { + $row['language'] = $this->lng->getDefaultLanguage(); } $attrs = [ - 'Id' => "il_" . IL_INST_ID . "_usr_" . $row["usr_id"], - 'Language' => $row["language"], - 'Action' => "Update" + 'Id' => 'il_' . IL_INST_ID . '_usr_' . $row['usr_id'], + 'Language' => $row['language'], + 'Action' => 'Update' ]; - $this->xmlStartTag("User", $attrs); + $this->xmlStartTag('User', $attrs); - $this->xmlElement("Login", null, $row["login"]); + $this->xmlElement('Login', null, $row['login']); - if ($this->attachRoles == true) { + if ($this->attach_roles == true) { $query = sprintf( - "SELECT object_data.title, object_data.description, rbac_fa.* " . - "FROM object_data, rbac_ua, rbac_fa WHERE rbac_ua.usr_id = %s " . - "AND rbac_ua.rol_id = rbac_fa.rol_id AND object_data.obj_id = rbac_fa.rol_id", - $ilDB->quote($row["usr_id"], 'integer') + 'SELECT object_data.title, object_data.description, rbac_fa.* ' . + 'FROM object_data, rbac_ua, rbac_fa WHERE rbac_ua.usr_id = %s ' . + 'AND rbac_ua.rol_id = rbac_fa.rol_id AND object_data.obj_id = rbac_fa.rol_id', + $this->db->quote($row['usr_id'], 'integer') ); - $rbacresult = $ilDB->query($query); + $rbacresult = $this->db->query($query); while ($rbacrow = $rbacresult->fetchRow(ilDBConstants::FETCHMODE_ASSOC)) { - if ($rbacrow["assign"] != "y") { + if ($rbacrow['assign'] != 'y') { continue; } - $type = ""; + $type = ''; - if ($rbacrow["parent"] == ROLE_FOLDER_ID) { - $type = "Global"; + if ($rbacrow['parent'] == ROLE_FOLDER_ID) { + $type = 'Global'; } else { - $type = "Local"; + $type = 'Local'; } if (strlen($type)) { $this->xmlElement( - "Role", - array("Id" => - "il_" . IL_INST_ID . "_role_" . $rbacrow["rol_id"], "Type" => $type), - $rbacrow["title"] + 'Role', + ['Id' => 'il_' . IL_INST_ID . '_role_' . $rbacrow['rol_id'], 'Type' => $type], + $rbacrow['title'] ); } } } - $this->__addElement("Firstname", $row["firstname"]); - $this->__addElement("Lastname", $row["lastname"]); - $this->__addElement("Title", $row["title"]); + $this->__addElement('Firstname', $row['firstname']); + $this->__addElement('Lastname', $row['lastname']); + $this->__addElement('Title', $row['title']); - if ($this->canExport("PersonalPicture", "upload")) { - $imageData = $this->getPictureValue($row["usr_id"]); + if ($this->canExport('PersonalPicture', 'upload')) { + $imageData = $this->getPictureValue($row['usr_id']); if ($imageData) { - $value = array_shift($imageData); //$imageData["value"]; - $this->__addElement("PersonalPicture", $value, $imageData, "upload"); + $value = array_shift($imageData); //$imageData['value']; + $this->__addElement('PersonalPicture', $value, $imageData, 'upload'); } } - $this->__addElement("Gender", $row["gender"]); - $this->__addElement("Email", $row["email"]); - $this->__addElement("SecondEmail", $row["second_email"], null, "second_email"); - $this->__addElement("Birthday", $row["birthday"]); - $this->__addElement("Institution", $row["institution"]); - $this->__addElement("Street", $row["street"]); - $this->__addElement("City", $row["city"]); - $this->__addElement("PostalCode", $row["zipcode"], null, "zipcode"); - $this->__addElement("Country", $row["country"]); - $this->__addElement("SelCountry", $row["sel_country"], null, "sel_country"); - $this->__addElement("PhoneOffice", $row["phone_office"], null, "phone_office"); - $this->__addElement("PhoneHome", $row["phone_home"], null, "phone_home"); - $this->__addElement("PhoneMobile", $row["phone_mobile"], null, "phone_mobile"); - $this->__addElement("Fax", $row["fax"]); - $this->__addElement("Hobby", $row["hobby"]); - - $this->__addElementMulti("GeneralInterest", $row["interests_general"] ?? [], null, "interests_general"); - $this->__addElementMulti("OfferingHelp", $row["interests_help_offered"] ?? [], null, "interests_help_offered"); - $this->__addElementMulti("LookingForHelp", $row["interests_help_looking"] ?? [], null, "interests_help_looking"); - - $this->__addElement("Department", $row["department"]); - $this->__addElement("Comment", $row["referral_comment"], null, "referral_comment"); - $this->__addElement("Matriculation", $row["matriculation"]); - $this->__addElement("Active", $row["active"] ? "true" : "false"); - $this->__addElement("ClientIP", $row["client_ip"], null, "client_ip"); - $this->__addElement("TimeLimitOwner", $row["time_limit_owner"], null, "time_limit_owner"); - $this->__addElement("TimeLimitUnlimited", $row["time_limit_unlimited"], null, "time_limit_unlimited"); - $this->__addElement("TimeLimitFrom", $row["time_limit_from"], null, "time_limit_from"); - $this->__addElement("TimeLimitUntil", $row["time_limit_until"], null, "time_limit_until"); - $this->__addElement("TimeLimitMessage", $row["time_limit_message"], null, "time_limit_message"); - $this->__addElement("ApproveDate", $row["approve_date"], null, "approve_date"); - $this->__addElement("AgreeDate", $row["agree_date"], null, "agree_date"); - - if (strlen($row["auth_mode"]) > 0) { - $this->__addElement("AuthMode", null, array("type" => $row["auth_mode"]), "auth_mode", true); + $this->__addElement('Gender', $row['gender']); + $this->__addElement('Email', $row['email']); + $this->__addElement('SecondEmail', $row['second_email'], null, 'second_email'); + $this->__addElement('Birthday', $row['birthday']); + $this->__addElement('Institution', $row['institution']); + $this->__addElement('Street', $row['street']); + $this->__addElement('City', $row['city']); + $this->__addElement('PostalCode', $row['zipcode'], null, 'zipcode'); + $this->__addElement('Country', $row['country']); + $this->__addElement('SelCountry', $row['sel_country'], null, 'sel_country'); + $this->__addElement('PhoneOffice', $row['phone_office'], null, 'phone_office'); + $this->__addElement('PhoneHome', $row['phone_home'], null, 'phone_home'); + $this->__addElement('PhoneMobile', $row['phone_mobile'], null, 'phone_mobile'); + $this->__addElement('Fax', $row['fax']); + $this->__addElement('Hobby', $row['hobby']); + + $this->__addElementMulti('GeneralInterest', $row['interests_general'] ?? [], null, 'interests_general'); + $this->__addElementMulti('OfferingHelp', $row['interests_help_offered'] ?? [], null, 'interests_help_offered'); + $this->__addElementMulti('LookingForHelp', $row['interests_help_looking'] ?? [], null, 'interests_help_looking'); + + $this->__addElement('Department', $row['department']); + $this->__addElement('Comment', $row['referral_comment'], null, 'referral_comment'); + $this->__addElement('Matriculation', $row['matriculation']); + $this->__addElement('Active', $row['active'] ? 'true' : 'false'); + $this->__addElement('ClientIP', $row['client_ip'], null, 'client_ip'); + $this->__addElement('TimeLimitOwner', $row['time_limit_owner'], null, 'time_limit_owner'); + $this->__addElement('TimeLimitUnlimited', $row['time_limit_unlimited'], null, 'time_limit_unlimited'); + $this->__addElement('TimeLimitFrom', $row['time_limit_from'], null, 'time_limit_from'); + $this->__addElement('TimeLimitUntil', $row['time_limit_until'], null, 'time_limit_until'); + $this->__addElement('TimeLimitMessage', $row['time_limit_message'], null, 'time_limit_message'); + $this->__addElement('ApproveDate', $row['approve_date'], null, 'approve_date'); + $this->__addElement('AgreeDate', $row['agree_date'], null, 'agree_date'); + + if (strlen($row['auth_mode']) > 0) { + $this->__addElement('AuthMode', null, ['type' => $row['auth_mode']], 'auth_mode', true); } - if (strlen($row["ext_account"]) > 0) { - $this->__addElement("ExternalAccount", $row["ext_account"], null, "ext_account", true); + if (strlen($row['ext_account']) > 0) { + $this->__addElement('ExternalAccount', $row['ext_account'], null, 'ext_account', true); } if (isset($prefs['skin']) @@ -230,22 +229,22 @@ public function __handleUser(array $row): void // Missing array type. } - $this->__addElement("LastUpdate", $row["last_update"], null, "last_update"); - $this->__addElement("LastLogin", $row["last_login"], null, "last_login"); + $this->__addElement('LastUpdate', $row['last_update'], null, 'last_update'); + $this->__addElement('LastLogin', $row['last_login'], null, 'last_login'); $udf_data = new ilUserDefinedData($row['usr_id']); $udf_data->addToXML($this); - $this->__addElement("AccountInfo", $row["ext_account"], array("Type" => "external")); + $this->__addElement('AccountInfo', $row['ext_account'], ['Type' => 'external']); - $this->__addElement("GMapsInfo", null, array( - "longitude" => $row["longitude"], - "latitude" => $row["latitude"], - "zoom" => $row["loc_zoom"])); + $this->__addElement('GMapsInfo', null, [ + 'longitude' => $row['longitude'], + 'latitude' => $row['latitude'], + 'zoom' => $row['loc_zoom']]); - $this->__addElement("Feedhash", $row["feed_hash"]); + $this->__addElement('Feedhash', $row['feed_hash']); - if ($this->attachPreferences || $this->canExport("prefs", "preferences")) { + if ($this->attach_preferences || $this->canExport('prefs', 'preferences')) { $this->__handlePreferences($prefs, $row); } @@ -256,18 +255,18 @@ public function __handleUser(array $row): void // Missing array type. private function __handlePreferences(array $prefs, array $row): void // Missing array type. { //todo nadia: test mail_address_option - $mailOptions = new ilMailOptions($row["usr_id"]); - $prefs["mail_incoming_type"] = $mailOptions->getIncomingType(); - $prefs["mail_address_option"] = $mailOptions->getEmailAddressMode(); - $prefs["mail_signature"] = $mailOptions->getSignature(); - if (count($prefs)) { - $this->xmlStartTag("Prefs"); + $mailOptions = new ilMailOptions($row['usr_id']); + $prefs['mail_incoming_type'] = $mailOptions->getIncomingType(); + $prefs['mail_address_option'] = $mailOptions->getEmailAddressMode(); + $prefs['mail_signature'] = $mailOptions->getSignature(); + if ($prefs !== []) { + $this->xmlStartTag('Prefs'); foreach ($prefs as $key => $value) { if (self::isPrefExportable($key)) { - $this->xmlElement("Pref", array("key" => $key), $value); + $this->xmlElement('Pref', ['key' => $key], $value); } } - $this->xmlEndTag("Prefs"); + $this->xmlEndTag('Prefs'); } } @@ -278,10 +277,8 @@ public function __addElementMulti( ?string $settingsname = null, bool $requiredTag = false ): void { - if (is_array($value) && count($value)) { - foreach ($value as $item) { - $this->__addElement($tagname, $item, $attrs, $settingsname, $requiredTag); - } + foreach ($value as $item) { + $this->__addElement($tagname, $item, $attrs, $settingsname, $requiredTag); } } @@ -292,10 +289,11 @@ public function __addElement( ?string $settingsname = null, bool $requiredTag = false ): void { - if ($this->canExport($tagname, $settingsname)) { - if (strlen($value) > 0 || $requiredTag || (is_array($attrs) && count($attrs) > 0)) { - $this->xmlElement($tagname, $attrs, (string) $value); - } + if ($this->canExport($tagname, $settingsname) + && ($value !== null + || $requiredTag + || is_array($attrs) && count($attrs) > 0)) { + $this->xmlElement($tagname, $attrs, (string) $value); } } @@ -303,9 +301,9 @@ private function canExport( string $tagname, ?string $settingsname = null ): bool { - return !is_array($this->settings) || - in_array(strtolower($tagname), $this->settings) !== false || - in_array($settingsname, $this->settings) !== false; + return $this->settings === [] + || in_array(strtolower($tagname), $this->settings) !== false + || in_array($settingsname, $this->settings) !== false; } public function setSettings(array $settings): void // Missing array type. @@ -319,36 +317,33 @@ public function setSettings(array $settings): void // Missing array type. */ private function getPictureValue(int $usr_id): ?array { - global $DIC; - - $ilDB = $DIC['ilDB']; // personal picture $q = sprintf( - "SELECT value FROM usr_pref WHERE usr_id = %s AND keyword = %s", - $ilDB->quote($usr_id, "integer"), - $ilDB->quote('profile_image', "text") + 'SELECT value FROM usr_pref WHERE usr_id = %s AND keyword = %s', + $this->db->quote($usr_id, 'integer'), + $this->db->quote('profile_image', 'text') ); - $r = $ilDB->query($q); - if ($ilDB->numRows($r) == 1) { + $r = $this->db->query($q); + if ($this->db->numRows($r) == 1) { $personal_picture_data = $r->fetchRow(ilDBConstants::FETCHMODE_ASSOC); - $personal_picture = $personal_picture_data["value"]; + $personal_picture = $personal_picture_data['value']; $webspace_dir = ilFileUtils::getWebspaceDir(); - $image_file = $webspace_dir . "/usr_images/" . $personal_picture; + $image_file = $webspace_dir . '/usr_images/' . $personal_picture; if (is_file($image_file)) { - $fh = fopen($image_file, "rb"); + $fh = fopen($image_file, 'rb'); if ($fh) { $image_data = fread($fh, filesize($image_file)); fclose($fh); $base64 = base64_encode($image_data); - $imagetype = "image/jpeg"; - if (preg_match("/.*\.(png|gif)$/", $personal_picture, $matches)) { - $imagetype = "image/" . $matches[1]; + $imagetype = 'image/jpeg'; + if (preg_match('/.*\.(png|gif)$/', $personal_picture, $matches)) { + $imagetype = 'image/' . $matches[1]; } - return array( - "value" => $base64, - "encoding" => "Base64", - "imagetype" => $imagetype - ); + return [ + 'value' => $base64, + 'encoding' => 'Base64', + 'imagetype' => $imagetype + ]; } } } @@ -359,9 +354,9 @@ private function getPictureValue(int $usr_id): ?array /** * if set to true, all preferences of a user will be set */ - public function setAttachPreferences(bool $attachPrefs): void + public function setAttachPreferences(bool $attach_preferences): void { - $this->attachPreferences = $attachPrefs; + $this->attach_preferences = $attach_preferences; } /** @@ -369,7 +364,7 @@ public function setAttachPreferences(bool $attachPrefs): void */ public static function getExportablePreferences(): array // Missing array type. { - return array( + return [ 'hits_per_page', 'public_city', 'public_country', @@ -402,7 +397,7 @@ public static function getExportablePreferences(): array // Missing array type. 'public_interests_general', 'public_interests_help_offered', 'public_interests_help_looking' - ); + ]; } /** diff --git a/Services/WebServices/RPC/lib/README.md b/Services/WebServices/RPC/lib/README.md index 6aae6699de53..4a9a0dadae6e 100644 --- a/Services/WebServices/RPC/lib/README.md +++ b/Services/WebServices/RPC/lib/README.md @@ -19,14 +19,14 @@ # Apache Lucene -Apache Lucene is a high-performance, full-featured text search engine library -written entirely in Java. It is a technology suitable for nearly any application +Apache Lucene is a high-performance, full-featured text search engine library +written entirely in Java. It is a technology suitable for nearly any application that requires full-text search, especially cross-platform. ## Requirements -This Java server has been tested with Open JDK Java Runtime 1.8. +This Java server has been tested with Open JDK Java Runtime 11. To be able to index and search for non-ASCII characters your system should support UTF-8 encodings. @@ -34,67 +34,74 @@ PHP curl and xmlrpc are required for using the Java server features. On Debian based systems try: -``` -bash$ apt-get install php5-curl curl php5-xmlrpc +````shell +> apt-get install php-curl php-xmlrpc +```` +Dependencies and the build process is managed via maven +```shell +> apt-get install maven ``` # Installation - -## Create a Server Configuration File - -Open the java server configuration in ```Administration -> General Setting -Java-Server``` and click the button ```Create Configuration File```. - -Fill the form and download the configuration file. -Save the newly created file (ilServer.ini) on your ILIAS server, the file location doesn't matter. - - -## Start the server: - -**MySQL backends:** - -``` -bash$ java -Dfile.encoding=UTF-8 -jar /ilServer.jar start & -``` - -**Oracle Backends:** - -The Oracle licence is very restrictive. Thus it is not possible to release an all-in-one package -including an Oracle-JDBC-Driver. - -Download an appropriate JDBC-Thin-Client from: - -http://www.oracle.com/technology/software/tech/java/sqlj_jdbc/htdocs/jdbc_10201.html - -The following packages are required: - + +## Build the Java RPC Server +```shell +> cd Services/WebServervices/RPC/lib +> mvn install +``` +The newly generated ilServer.jar has been created in the target-directory. + +## Configure the Java RPC Server +Create a config file readable by the webserver user/group with following contents. E.g in the external data directory +```shell +> vi {PATH_TO_EXTERNAL_DATA}/ilServer.ini +[Server] +IpAddress = localhost +Port = 11111 +IndexPath = /var/www/html/ilias/data/ +LogFile = /var/www/files/ilServer.log +LogLevel = INFO +NumThreads = 1 +RamBufferSize = 256 +IndexMaxFileSizeMB = 500 + +[Client1] +ClientId = ACMECorp +NicId = 0 +IliasIniPath = /var/www/html/ilias/ilias.ini.php +``` +## Manage Startup using systemd +```shell +> vi /etc/systemd/system/ilserver.service +[Unit] +Description=ILIAS Java-Server +After=network.target + +[Service] +User=www-data +Group=www-data +ExecStart=/usr/bin/java -jar /var/www/html/ilias/Services/WebServices/RPC/lib/ilServer.jar /var/www/html/ilias/ilias.ini.php start +ExecStop=/usr/bin/java -jar /var/www/html/ilias/Services/WebServices/RPC/lib/ilServer.jar /var/www/html/ilias/ilias.ini.php stop +TimeoutStopSec=10 + +[Install] +WantedBy=multi-user.target +> systemctl enable ilserver.service ``` -ojdbc14.jar -orai18n.jar -``` - -**Start the Java-Server including these packages to your CLASSPATH:** - -``` -bash$java -Dfile.encoding=UTF-8 -cp "::ilServer.jar" de.ilias.ilServer start & -``` - -**To stop the server simply type:** - -``` -bash$ java -jar /ilServer.jar stop -``` - -**Show the server status:** + +## Start the Server +```shell +> systemctl start ilserver.service ``` -bash$ java -jar /ilServer.jar status +## Show Additional Status Info +```shell +> java -jar /ilServer.jar status ``` -**Possible return values are:** - +Possible return values are: ``` Running Stopped @@ -104,138 +111,43 @@ Indexing ## Creating a new Lucene index: -``` -bash$ java -jar /ilServer.jar createIndex & +```shell +> java -jar /ilServer.jar createIndex ``` The `````` is a combination of the client id and the installation id. -You find these values in the table "Administration -> Server Data". - -**Example:** - +You find these values with the setup status command: +```shell +> cd +> php setup/cli.php status +... +config: + common: + client_id: default + inst_id: 12345678 +... +``` + +Example: +```shell +> java -jar /ilServer.jar createIndex default_12345678 ``` -bash$ java -jar /ilServer.jar createIndex ilias40_4000 & -``` - or - -``` -bash$ java -jar /ilServer.jar createIndex ilias40_0 & +```shell +> java -jar /ilServer.jar createIndex default_0 ``` if no installation id is given. ## Updating an existing index: -``` -bash$ java -jar ilServer.jar updateIndex & +```shell +> java -jar ilServer.jar updateIndex ``` ## Performing a query -``` -bash$ java -jar /ilServer.jar search "ilias" -``` - - -# Preparing ILIAS - - * Log in to ILIAS - * Setup up the Lucene Host and Port in ```Administration -> General settings -> Java-Server``` - * Enable Lucene Search - * Enable the option ```Lucene search``` in ```Administration -> Search -> Settings```. - - -# Starting Lucene server at boot time - - -## SysV-Init - -To start the Lucene RPC server automatically at boottime, follow these instructions: - -Change the working directory to ```/etc/init.d/``` and create a file named ```ilserver``` - -``` -bash$ cd /etc/init.d # Adjust this path according to your distribution -bash$ vi ilserver -``` - -with this content - -``` -#!/bin/bash -### BEGIN INIT INFO -# Provides: ilServer -# Required-Start: $remote_fs $network -# Required-Stop: $remote_fs $network -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start ilServer instances -# Description: Debian init script for starting ilServer instances -### END INIT INFO - -JAVABIN=/usr/bin/java -ILIASDIR=/var/www/ilias # Type in the root directory of your ILIAS installation -IL_SERVER_INI=/path_to_server_ini # Type in the path to your ilserver.ini - -case "$1" in - start) - echo "Starting ILIAS Java-Server" - $JAVABIN -Dfile.encoding=UTF-8 -jar $ILIASDIR/Services/WebServices/RPC/lib/ilServer.jar $IL_SERVER_INI start & - ;; - - stop) - echo "Shutting down ILIAS Java-Server" - $JAVABIN -jar $ILIASDIR/Services/WebServices/RPC/lib/ilServer.jar $IL_SERVER_INI stop - ;; - - status) - $JAVABIN -jar $ILIASDIR/Services/WebServices/RPC/lib/ilServer.jar $IL_SERVER_INI status - ;; - - restart) - $0 stop - sleep 2 - $0 start - ;; - - *) - echo "Usage: $0 {start|stop|status|restart}" - exit 1 -esac - -exit 0 -``` - -Change the file permissions by typing - -``` -bash$ chmod 750 ilserver -``` - -**You can start the ILIAS Java-Server by typing:** - -``` -bash$ /etc/init.d/ilserver start -``` - -**stop it:** - -``` -bash$ /etc/init.d/ilserver stop -``` - -**restart it:** - -``` -bash$ /etc/init.d/ilserver restart -``` - -**or receive the status:** - -``` -bash$ /etc/init.d/ilserver status -``` - -You can start the ILIAS Java-Server automatically at boottime by executing ```update-rc.d ilserver enable``` or linking ```/etc/init.d/ilserver``` to ```/etc/rc.X``` (where ```X``` is the desired runlevel). +```shell +> java -jar /ilServer.jar search "ilias" +``` \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/build.xml b/Services/WebServices/RPC/lib/build.xml deleted file mode 100644 index 68657a1eaf2f..000000000000 --- a/Services/WebServices/RPC/lib/build.xml +++ /dev/null @@ -1,75 +0,0 @@ - - - - Compile and create ilServer.jar, ilServer.source.jar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      - -
      -
      -
      -
      -
      diff --git a/Services/WebServices/RPC/lib/ilServer.jar b/Services/WebServices/RPC/lib/ilServer.jar deleted file mode 100644 index 954ab8a6dc64..000000000000 Binary files a/Services/WebServices/RPC/lib/ilServer.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/ilServer.properties b/Services/WebServices/RPC/lib/ilServer.properties deleted file mode 100755 index 8cc2a73e53ef..000000000000 --- a/Services/WebServices/RPC/lib/ilServer.properties +++ /dev/null @@ -1,4 +0,0 @@ -IpAddress = 127.0.0.1 -Port = 11111 -IndexPath = /tmp -LogFile = /tmp/ilServer.log diff --git a/Services/WebServices/RPC/lib/jars/META-INF/MANIFEST.MF b/Services/WebServices/RPC/lib/jars/META-INF/MANIFEST.MF deleted file mode 100644 index 45ca4181d5b1..000000000000 --- a/Services/WebServices/RPC/lib/jars/META-INF/MANIFEST.MF +++ /dev/null @@ -1,11 +0,0 @@ -Manifest-Version: 1.0 -Archiver-Version: Plexus Archiver -Created-By: Apache Maven -Built-By: ubuntu -Build-Jdk: 1.6.0 - -Name: org.apache.log4j -Implementation-Title: log4j -Implementation-Vendor: "Apache Software Foundation" -Implementation-Version: 1.2.15 - diff --git a/Services/WebServices/RPC/lib/jars/META-INF/NOTICE b/Services/WebServices/RPC/lib/jars/META-INF/NOTICE deleted file mode 100644 index 037573236004..000000000000 --- a/Services/WebServices/RPC/lib/jars/META-INF/NOTICE +++ /dev/null @@ -1,5 +0,0 @@ -Apache log4j -Copyright 2007 The Apache Software Foundation - -This product includes software developed at -The Apache Software Foundation (http://www.apache.org/). \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.properties b/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.properties deleted file mode 100644 index 3e6235a79da8..000000000000 --- a/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.properties +++ /dev/null @@ -1,5 +0,0 @@ -#Generated by Maven -#Sat Aug 25 00:29:44 EDT 2007 -version=1.2.15 -groupId=log4j -artifactId=log4j diff --git a/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.xml b/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.xml deleted file mode 100644 index b3f7fd27e755..000000000000 --- a/Services/WebServices/RPC/lib/jars/META-INF/maven/log4j/log4j/pom.xml +++ /dev/null @@ -1,478 +0,0 @@ - - - 4.0.0 - log4j - log4j - jar - Apache Log4j - 1.2.15 - - 1.2.15 - - Apache Log4j 1.2 - http://logging.apache.org:80/log4j/1.2/ - - Bugzilla - http://issues.apache.org/bugzilla/ - - - Gump - http://vmgump.apache.org/gump/public/logging-log4j-12/logging-log4j-12/index.html - - 1999 - - - log4j-user - log4j-user-subscribe@logging.apache.org - log4j-user-unsubscribe@logging.apache.org - log4j-user@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/ - - http://marc.info/?l=log4j-user - http://dir.gmane.org/gmane.comp.jakarta.log4j.user - - - - log4j-dev - log4j-dev-subscribe@logging.apache.org - log4j-dev-unsubscribe@logging.apache.org - log4j-dev@logging.apache.org - http://mail-archives.apache.org/mod_mbox/logging-log4j-dev/ - - http://marc.info/?l=log4j-dev - http://dir.gmane.org/gmane.comp.jakarta.log4j.devel - - - - - - The Apache Software License, Version 2.0 - http://www.apache.org/licenses/LICENSE-2.0.txt - repo - - - - scm:svn:http://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_15_rc6 - scm:svn:https://svn.apache.org/repos/asf/logging/log4j/tags/v1_2_15_rc6 - http://svn.apache.org/viewcvs.cgi/logging/log4j/tags/v1_2_15_rc6 - - - Apache Software Foundation - http://www.apache.org - - - - - maven-surefire-plugin - - tests - plain - pertest - true - - org/apache/log4j/LevelTest.java - org/apache/log4j/PriorityTest.java - org/apache/log4j/CategoryTest.java - org/apache/log4j/FileAppenderTest.java - org/apache/log4j/LogManagerTest.java - org/apache/log4j/helpers.LogLogTest.java - org/apache/log4j/LayoutTest.java - org/apache/log4j/helpers.DateLayoutTest.java - org/apache/log4j/TTCCLayoutTest.java - org/apache/log4j/xml.XMLLayoutTest.java - org/apache/log4j/HTMLLayoutTest.java - org/apache/log4j/PatternLayoutTest.java - org/apache/log4j/spi.LoggingEventTest.java - org/apache/log4j/spi.ThrowableInformationTest.java - org/apache/log4j/spi.LocationInfoTest.java - org/apache/log4j/PropertyConfiguratorTest.java - org/apache/log4j/MinimumTestCase.java - org/apache/log4j/LoggerTestCase.java - org/apache/log4j/PatternLayoutTestCase.java - org/apache/log4j/HierarchyThresholdTestCase.java - org/apache/log4j/xml/DOMTestCase.java - org/apache/log4j/xml/CustomLevelTestCase.java - org/apache/log4j/customLogger/XLoggerTestCase.java - - - org/apache/log4j/xml/XMLLayoutTestCase.java - org/apache/log4j/xml/AsyncAppenderTestCase.java - org/apache/log4j/varia/LevelMatchFilterTestCase.java - - - - org/apache/log4j/helpers/BoundedFIFOTestCase.java - org/apache/log4j/helpers/CyclicBufferTestCase.java - org/apache/log4j/helpers/PatternParserTestCase.java - org/apache/log4j/or/ORTestCase.java - org/apache/log4j/DRFATestCase.java - org/apache/log4j/RFATestCase.java - org/apache/log4j/varia/ERFATestCase.java - org/apache/log4j/net/SyslogAppenderTest - org/apache/log4j/nt/NTEventLogAppenderTest - org/apache/log4j/net/SocketAppenderTest - - - - - maven-compiler-plugin - - 1.2 - 1.1 - - - - maven-jar-plugin - - - - - org.apache.log4j - - log4j - ${project.version} - "Apache Software Foundation" - - - - - - - - maven-antrun-plugin - - - - process-classes - ntdll - - - - - - - - - - - - run - - - - - test-compile - mkdir_tests_output - - - - - - - run - - - - clean - rmdir_tests_output - - - - - - - run - - - - test - runAll - - - - - - - - - - - - - - run - - - - - site - untag-site - - - - - - - - - - - run - - - - post-site - post-site - - - - - - - run - - - - site-deploy - site-deploy - - - - - - - run - - - - - - ant - ant-nodeps - 1.6.5 - - - ant-contrib - ant-contrib - 1.0b2 - - - ant - ant-junit - 1.6.5 - - - junit - junit - 3.8.1 - test - - - sun.jdk - tools - 1.4.2 - system - ${tools.jar} - - - - - maven-assembly-plugin - - - src/assembly/bin.xml - - false - - - - - assembly - - - - - - maven-javadoc-plugin - - - - jar - javadoc - - - - - - maven-source-plugin - - - - jar - - - - - - - org.codehaus.mojo - clirr-maven-plugin - - 1.2.14 - - - - org.codehaus.mojo - rat-maven-plugin - - - tests/src/java - - - tests/resources - - - - - - mac - - mac - - - ${java.home}/../Classes/classes.jar - - - - default - - true - - - ${java.home}/../lib/tools.jar - - - - - - java.net - https://maven-repository.dev.java.net/nonav/repository - legacy - - - - - javax.mail - mail - 1.4 - - - javax.jms - jms - 1.1 - - - com.sun.jdmk - jmxtools - 1.2.1 - - - com.sun.jmx - jmxri - 1.2.1 - - - oro - oro - 2.0.8 - test - - - junit - junit - 3.8.1 - test - - - - true - - - maven-project-info-reports-plugin - - - - scm - dependencies - cim - issue-tracking - mailing-list - license - - - - - - org.codehaus.mojo - jxr-maven-plugin - - - maven-release-plugin - - - test site-deploy assembly:attached deploy - - - - maven-changes-plugin - - - - changes-report - - - - - %URL%/show_bug.cgi?id=%ISSUE% - - - - - - - logging.repo - scp://people.apache.org/www/people.apache.org/builds/logging/repo/ - - - logging.site - scp://localhost/${user.dir}/target/site-deploy - - - diff --git a/Services/WebServices/RPC/lib/jars/Tidy.jar b/Services/WebServices/RPC/lib/jars/Tidy.jar deleted file mode 100644 index af4eed0506b5..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/Tidy.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/commons-codec-1.3.jar b/Services/WebServices/RPC/lib/jars/commons-codec-1.3.jar deleted file mode 100644 index 957b6752af9a..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/commons-codec-1.3.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/commons-httpclient31/LICENSE.txt b/Services/WebServices/RPC/lib/jars/commons-httpclient31/LICENSE.txt deleted file mode 100644 index d9a10c0d8e86..000000000000 --- a/Services/WebServices/RPC/lib/jars/commons-httpclient31/LICENSE.txt +++ /dev/null @@ -1,176 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS diff --git a/Services/WebServices/RPC/lib/jars/commons-httpclient31/commons-httpclient-3.1.jar b/Services/WebServices/RPC/lib/jars/commons-httpclient31/commons-httpclient-3.1.jar deleted file mode 100644 index 7c59774aed4f..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/commons-httpclient31/commons-httpclient-3.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/dom4j-1.6.1.jar b/Services/WebServices/RPC/lib/jars/dom4j-1.6.1.jar deleted file mode 100644 index c8c4dbb92d6c..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/dom4j-1.6.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/avalon-framework-4.2.0.jar b/Services/WebServices/RPC/lib/jars/fop/avalon-framework-4.2.0.jar deleted file mode 100644 index 22a7ab341694..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/avalon-framework-4.2.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/avalon-framework.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/avalon-framework.LICENSE.txt deleted file mode 100644 index 67db8588217f..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/avalon-framework.LICENSE.txt +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/Services/WebServices/RPC/lib/jars/fop/batik-all-1.7.jar b/Services/WebServices/RPC/lib/jars/fop/batik-all-1.7.jar deleted file mode 100644 index 589328581963..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/batik-all-1.7.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/batik.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/batik.LICENSE.txt deleted file mode 100644 index 3e4e3d004084..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/batik.LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/jars/fop/commons-io-1.3.1.jar b/Services/WebServices/RPC/lib/jars/fop/commons-io-1.3.1.jar deleted file mode 100644 index 7affdefcd274..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/commons-io-1.3.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/commons-io.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/commons-io.LICENSE.txt deleted file mode 100644 index 6b0b1270ff0c..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/commons-io.LICENSE.txt +++ /dev/null @@ -1,203 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/Services/WebServices/RPC/lib/jars/fop/commons-logging-1.0.4.jar b/Services/WebServices/RPC/lib/jars/fop/commons-logging-1.0.4.jar deleted file mode 100644 index b73a80fab641..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/commons-logging-1.0.4.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/commons-logging.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/commons-logging.LICENSE.txt deleted file mode 100644 index d64569567334..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/commons-logging.LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/fop/fop.jar b/Services/WebServices/RPC/lib/jars/fop/fop.jar deleted file mode 100644 index 5113064bb638..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/fop.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/serializer-2.7.0.jar b/Services/WebServices/RPC/lib/jars/fop/serializer-2.7.0.jar deleted file mode 100644 index 7cd80696427f..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/serializer-2.7.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/serializer.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/serializer.LICENSE.txt deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/serializer.LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/fop/xalan-2.7.0.jar b/Services/WebServices/RPC/lib/jars/fop/xalan-2.7.0.jar deleted file mode 100644 index 979ee761ccfe..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/xalan-2.7.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/xalan.BCEL.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xalan.BCEL.LICENSE.txt deleted file mode 100644 index 58940a049732..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xalan.BCEL.LICENSE.txt +++ /dev/null @@ -1,52 +0,0 @@ -Apache Software License, Version 1.1 -* -* Copyright (c) 2001 The Apache Software Foundation. All rights -* reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* -* 3. The end-user documentation included with the redistribution, -* if any, must include the following acknowledgment: -* "This product includes software developed by the -* Apache Software Foundation (http://www.apache.org/)." -* Alternately, this acknowledgment may appear in the software itself, -* if and wherever such third-party acknowledgments normally appear. -* -* 4. The names "Apache" and "Apache Software Foundation" and -* "Apache BCEL" must not be used to endorse or promote products -* derived from this software without prior written permission. For -* written permission, please contact apache@apache.org. -* -* 5. Products derived from this software may not be called "Apache", -* "Apache BCEL", nor may "Apache" appear in their name, without -* prior written permission of the Apache Software Foundation. -* -* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* ==================================================================== -* -* This software consists of voluntary contributions made by many -* individuals on behalf of the Apache Software Foundation. For more -* information on the Apache Software Foundation, please see -* . -*/ diff --git a/Services/WebServices/RPC/lib/jars/fop/xalan.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xalan.LICENSE.txt deleted file mode 100644 index 57bc88a15a0e..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xalan.LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - diff --git a/Services/WebServices/RPC/lib/jars/fop/xalan.regexp.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xalan.regexp.LICENSE.txt deleted file mode 100644 index 58940a049732..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xalan.regexp.LICENSE.txt +++ /dev/null @@ -1,52 +0,0 @@ -Apache Software License, Version 1.1 -* -* Copyright (c) 2001 The Apache Software Foundation. All rights -* reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in -* the documentation and/or other materials provided with the -* distribution. -* -* 3. The end-user documentation included with the redistribution, -* if any, must include the following acknowledgment: -* "This product includes software developed by the -* Apache Software Foundation (http://www.apache.org/)." -* Alternately, this acknowledgment may appear in the software itself, -* if and wherever such third-party acknowledgments normally appear. -* -* 4. The names "Apache" and "Apache Software Foundation" and -* "Apache BCEL" must not be used to endorse or promote products -* derived from this software without prior written permission. For -* written permission, please contact apache@apache.org. -* -* 5. Products derived from this software may not be called "Apache", -* "Apache BCEL", nor may "Apache" appear in their name, without -* prior written permission of the Apache Software Foundation. -* -* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED -* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -* DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR -* ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -* SUCH DAMAGE. -* ==================================================================== -* -* This software consists of voluntary contributions made by many -* individuals on behalf of the Apache Software Foundation. For more -* information on the Apache Software Foundation, please see -* . -*/ diff --git a/Services/WebServices/RPC/lib/jars/fop/xalan.runtime.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xalan.runtime.LICENSE.txt deleted file mode 100644 index 374d49849b18..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xalan.runtime.LICENSE.txt +++ /dev/null @@ -1,20 +0,0 @@ -CUP Parser Generator Copyright Notice, License, and Disclaimer -(runtime.jar component) - -Copyright 1996-1999 by Scott Hudson, Frank Flannery, C. Scott Ananian - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both -the copyright notice and this permission notice and warranty disclaimer -appear in supporting documentation, and that the names of the authors -or their employers not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior permission. - -The authors and their employers disclaim all warranties with regard to -this software, including all implied warranties of merchantability -and fitness. In no event shall the authors or their employers be liable -for any special, indirect or consequential damages or any damages -whatsoever resulting from loss of use, data or profits, whether in an action -of contract, negligence or other tortious action, arising out of or -in connection with the use or performance of this software. diff --git a/Services/WebServices/RPC/lib/jars/fop/xerces.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xerces.LICENSE.txt deleted file mode 100644 index b37087c56987..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xerces.LICENSE.txt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * The Apache Software License, Version 1.1 - * - * - * Copyright (c) 1999 The Apache Software Foundation. All rights - * reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The end-user documentation included with the redistribution, - * if any, must include the following acknowledgment: - * "This product includes software developed by the - * Apache Software Foundation (http://www.apache.org/)." - * Alternately, this acknowledgment may appear in the software itself, - * if and wherever such third-party acknowledgments normally appear. - * - * 4. The names "Xerces" and "Apache Software Foundation" must - * not be used to endorse or promote products derived from this - * software without prior written permission. For written - * permission, please contact apache@apache.org. - * - * 5. Products derived from this software may not be called "Apache", - * nor may "Apache" appear in their name, without prior written - * permission of the Apache Software Foundation. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR - * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT - * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF - * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND - * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, - * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT - * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * ==================================================================== - * - * This software consists of voluntary contributions made by many - * individuals on behalf of the Apache Software Foundation and was - * originally based on software copyright (c) 1999, International - * Business Machines, Inc., http://www.ibm.com. For more - * information on the Apache Software Foundation, please see - * . - */ diff --git a/Services/WebServices/RPC/lib/jars/fop/xercesImpl-2.7.1.jar b/Services/WebServices/RPC/lib/jars/fop/xercesImpl-2.7.1.jar deleted file mode 100644 index eac75ae8ef63..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/xercesImpl-2.7.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/xercesImpl.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xercesImpl.LICENSE.txt deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xercesImpl.LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis-1.3.04.jar b/Services/WebServices/RPC/lib/jars/fop/xml-apis-1.3.04.jar deleted file mode 100644 index d42c0ea6cfd1..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/xml-apis-1.3.04.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext-1.3.04.jar b/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext-1.3.04.jar deleted file mode 100644 index a7869d68aacd..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext-1.3.04.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-documentation.txt b/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-documentation.txt deleted file mode 100644 index 3d84b5d6ceb2..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-documentation.txt +++ /dev/null @@ -1,73 +0,0 @@ -xml-commons/java/external/LICENSE.dom-documentation.txt $Id: LICENSE.dom-documentation.txt 226215 2005-06-03 22:49:13Z mrglavas $ - - -This license came from: http://www.w3.org/Consortium/Legal/copyright-documents-20021231 - - -W3C® DOCUMENT LICENSE -http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231 - -Public documents on the W3C site are provided by the copyright holders under -the following license. By using and/or copying this document, or the W3C -document from which this statement is linked, you (the licensee) agree that -you have read, understood, and will comply with the following terms and -conditions: - -Permission to copy, and distribute the contents of this document, or the W3C -document from which this statement is linked, in any medium for any purpose -and without fee or royalty is hereby granted, provided that you include the -following on ALL copies of the document, or portions thereof, that you use: - - 1. A link or URL to the original W3C document. - 2. The pre-existing copyright notice of the original author, or if it - doesn't exist, a notice (hypertext is preferred, but a textual - representation is permitted) of the form: "Copyright © [$date-of-document] - World Wide Web Consortium, (Massachusetts Institute of Technology, - European Research Consortium for Informatics and Mathematics, Keio - University). All Rights Reserved. - http://www.w3.org/Consortium/Legal/2002/copyright-documents-20021231" - 3. If it exists, the STATUS of the W3C document. - -When space permits, inclusion of the full text of this NOTICE should be -provided. We request that authorship attribution be provided in any software, -documents, or other items or products that you create pursuant to the -implementation of the contents of this document, or any portion thereof. - -No right to create modifications or derivatives of W3C documents is granted -pursuant to this license. However, if additional requirements (documented in -the Copyright FAQ) are satisfied, the right to create modifications or -derivatives is sometimes granted by the W3C to individuals complying with -those requirements. - -THIS DOCUMENT IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE NO -REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT -LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, -NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE -FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT -INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - -COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE -PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF. - -The name and trademarks of copyright holders may NOT be used in advertising -or publicity pertaining to this document or its contents without specific, -written prior permission. Title to copyright in this document will at all -times remain with copyright holders. - ----------------------------------------------------------------------------- - -This formulation of W3C's notice and license became active on December 31 2002. -This version removes the copyright ownership notice such that this license can -be used with materials other than those owned by the W3C, moves information on -style sheets, DTDs, and schemas to the Copyright FAQ, reflects that ERCIM is -now a host of the W3C, includes references to this specific dated version of -the license, and removes the ambiguous grant of "use". See the older -formulation for the policy prior to this date. Please see our Copyright FAQ for -common questions about using materials from our site, such as the translating -or annotating specifications. Other questions about this notice can be directed -to site-policy@w3.org. - -Joseph Reagle - -Last revised by Reagle $Date: 2005-06-03 18:49:13 -0400 (Fri, 03 Jun 2005) $ diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-software.txt b/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-software.txt deleted file mode 100644 index c5fe5a48a0dc..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.dom-software.txt +++ /dev/null @@ -1,61 +0,0 @@ -xml-commons/java/external/LICENSE.dom-software.txt $Id: LICENSE.dom-software.txt 226215 2005-06-03 22:49:13Z mrglavas $ - - -This license came from: http://www.w3.org/Consortium/Legal/copyright-software-20021231 - - -W3C® SOFTWARE NOTICE AND LICENSE -http://www.w3.org/Consortium/Legal/2002/copyright-software-20021231 - -This work (and included software, documentation such as READMEs, or other -related items) is being provided by the copyright holders under the following -license. By obtaining, using and/or copying this work, you (the licensee) agree -that you have read, understood, and will comply with the following terms and -conditions. - -Permission to copy, modify, and distribute this software and its documentation, -with or without modification, for any purpose and without fee or royalty is -hereby granted, provided that you include the following on ALL copies of the -software and documentation or portions thereof, including modifications: - - 1. The full text of this NOTICE in a location viewable to users of the - redistributed or derivative work. - 2. Any pre-existing intellectual property disclaimers, notices, or terms - and conditions. If none exist, the W3C Software Short Notice should be - included (hypertext is preferred, text is permitted) within the body - of any redistributed or derivative code. - 3. Notice of any changes or modifications to the files, including the date - changes were made. (We recommend you provide URIs to the location from - which the code is derived.) - -THIS SOFTWARE AND DOCUMENTATION IS PROVIDED "AS IS," AND COPYRIGHT HOLDERS MAKE -NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO, WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT -THE USE OF THE SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY THIRD PARTY -PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - -COPYRIGHT HOLDERS WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE OR DOCUMENTATION. - -The name and trademarks of copyright holders may NOT be used in advertising or -publicity pertaining to the software without specific, written prior permission. -Title to copyright in this software and any associated documentation will at -all times remain with copyright holders. - -____________________________________ - -This formulation of W3C's notice and license became active on December 31 2002. -This version removes the copyright ownership notice such that this license can -be used with materials other than those owned by the W3C, reflects that ERCIM -is now a host of the W3C, includes references to this specific dated version of -the license, and removes the ambiguous grant of "use". Otherwise, this version -is the same as the previous version and is written so as to preserve the Free -Software Foundation's assessment of GPL compatibility and OSI's certification -under the Open Source Definition. Please see our Copyright FAQ for common -questions about using materials from our site, including specific terms and -conditions for packages like libwww, Amaya, and Jigsaw. Other questions about -this notice can be directed to site-policy@w3.org. - -Joseph Reagle - -Last revised by Reagle $Date: 2005-06-03 18:49:13 -0400 (Fri, 03 Jun 2005) $ diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.txt deleted file mode 100644 index d64569567334..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xml-apis-ext.LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/fop/xml-apis.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xml-apis.LICENSE.txt deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xml-apis.LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons-1.5.jar b/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons-1.5.jar deleted file mode 100644 index 0ff3b4f46d7e..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons-1.5.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons.LICENSE.txt b/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons.LICENSE.txt deleted file mode 100644 index d64569567334..000000000000 --- a/Services/WebServices/RPC/lib/jars/fop/xmlgraphics-commons.LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/ini4j051/LICENSE.txt b/Services/WebServices/RPC/lib/jars/ini4j051/LICENSE.txt deleted file mode 100644 index 261eeb9e9f8b..000000000000 --- a/Services/WebServices/RPC/lib/jars/ini4j051/LICENSE.txt +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/ini4j051/ini4j-0.5.1.jar b/Services/WebServices/RPC/lib/jars/ini4j051/ini4j-0.5.1.jar deleted file mode 100644 index 66045bb94b37..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/ini4j051/ini4j-0.5.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/jaxen-core.jar b/Services/WebServices/RPC/lib/jars/jaxen-core.jar deleted file mode 100644 index e52bf679cc04..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/jaxen-core.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/jaxen-jdom.jar b/Services/WebServices/RPC/lib/jars/jaxen-jdom.jar deleted file mode 100644 index 978bd0269190..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/jaxen-jdom.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/jdom-1.1.jar b/Services/WebServices/RPC/lib/jars/jdom-1.1.jar deleted file mode 100644 index 97c85f564e3f..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/jdom-1.1.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/jsr173_1.0_api.jar b/Services/WebServices/RPC/lib/jars/jsr173_1.0_api.jar deleted file mode 100644 index 987db0f5817a..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/jsr173_1.0_api.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/log4j-api-2.17.2.jar b/Services/WebServices/RPC/lib/jars/log4j-api-2.17.2.jar deleted file mode 100644 index a03f31516554..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/log4j-api-2.17.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/log4j-core-2.17.2.jar b/Services/WebServices/RPC/lib/jars/log4j-core-2.17.2.jar deleted file mode 100644 index fbc0641dc4fc..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/log4j-core-2.17.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/log4j-jcl-2.17.2.jar b/Services/WebServices/RPC/lib/jars/log4j-jcl-2.17.2.jar deleted file mode 100644 index 86dc767d0f6a..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/log4j-jcl-2.17.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-core-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-core-7.3.0.jar deleted file mode 100644 index 07e07a4a7264..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-core-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-highlighter-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-highlighter-7.3.0.jar deleted file mode 100644 index 606516dd8d1d..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-highlighter-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-join-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-join-7.3.0.jar deleted file mode 100644 index 370c4da190fa..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-join-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-memory-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-memory-7.3.0.jar deleted file mode 100644 index 2c508be4325b..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-memory-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-queries-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-queries-7.3.0.jar deleted file mode 100644 index 47d2387b20fe..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-queries-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/lucene730/lucene-queryparser-7.3.0.jar b/Services/WebServices/RPC/lib/jars/lucene730/lucene-queryparser-7.3.0.jar deleted file mode 100644 index 2ed2401a083c..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/lucene730/lucene-queryparser-7.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/mariadb-connector/mariadb-java-client-1.7.3.jar b/Services/WebServices/RPC/lib/jars/mariadb-connector/mariadb-java-client-1.7.3.jar deleted file mode 100644 index 8726062eb648..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/mariadb-connector/mariadb-java-client-1.7.3.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/ojdbc14.jar b/Services/WebServices/RPC/lib/jars/ojdbc14.jar deleted file mode 100644 index d228a8ed1f34..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/ojdbc14.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/LICENSE.txt b/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/LICENSE.txt deleted file mode 100644 index 329a3112a744..000000000000 --- a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/LICENSE.txt +++ /dev/null @@ -1,587 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -EXTERNAL COMPONENTS - -Apache PDFBox includes a number of components with separate copyright notices -and license terms. Your use of these components is subject to the terms and -conditions of the following licenses. - -Contributions made to the original PDFBox, JempBox and FontBox projects: - - Copyright (c) 2002-2007, www.pdfbox.org - Copyright (c) 2006-2007, www.jempbox.org - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - 1. Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - - 2. Redistributions in binary form must reproduce the above copyright - notice, this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. - - 3. Neither the name of pdfbox; nor the names of its contributors may be - used to endorse or promote products derived from this software without - specific prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - -Bouncy Castle encryption libraries - - Copyright (c) 2000-2006 The Legion Of The Bouncy Castle - (http://www.bouncycastle.org) - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files - (the "Software"), to deal in the Software without restriction, - including without limitation the rights to use, copy, modify, merge, - publish, distribute, sublicense, and/or sell copies of the Software, - and to permit persons to whom the Software is furnished to do so, - subject to the following conditions: - - The above copyright notice and this permission notice shall be included - in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - OTHER DEALINGS IN THE SOFTWARE. - -Adobe Font Metrics (AFM) for PDF Core 14 Fonts - - This file and the 14 PostScript(R) AFM files it accompanies may be used, - copied, and distributed for any purpose and without charge, with or without - modification, provided that all copyright notices are retained; that the - AFM files are not distributed without this file; that all modifications - to this file or any of the AFM files are prominently noted in the modified - file(s); and that this paragraph is not modified. Adobe Systems has no - responsibility or obligation to support the use of the AFM files. - -CMaps for PDF Fonts (http://www.adobe.com/devnet/font/#pcfi and -ftp://ftp.oreilly.com/pub/examples/nutshell/cjkv/adobe/) - - Copyright 1990-2001 Adobe Systems Incorporated. - All Rights Reserved. - - Patents Pending - - NOTICE: All information contained herein is the property - of Adobe Systems Incorporated. - - Permission is granted for redistribution of this file - provided this copyright notice is maintained intact and - that the contents of this file are not altered in any - way from its original form. - - PostScript and Display PostScript are trademarks of - Adobe Systems Incorporated which may be registered in - certain jurisdictions. - -Glyphlist (http://www.adobe.com/devnet/opentype/archives/glyph.html) - - Copyright (c) 1997,1998,2002,2007 Adobe Systems Incorporated - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this documentation file to use, copy, publish, distribute, - sublicense, and/or sell copies of the documentation, and to permit - others to do the same, provided that: - - No modification, editing or other alteration of this document is - allowed; and - - The above copyright notice and this permission notice shall be - included in all copies of the documentation. - - Permission is hereby granted, free of charge, to any person obtaining a - copy of this documentation file, to create their own derivative works - from the content of this document to use, copy, publish, distribute, - sublicense, and/or sell the derivative works, and to permit others to do - the same, provided that the derived work is not represented as being a - copy or version of this document. - - Adobe shall not be liable to any party for any loss of revenue or profit - or for indirect, incidental, special, consequential, or other similar - damages, whether based on tort (including without limitation negligence - or strict liability), contract or other legal or equitable grounds even - if Adobe has been advised or had reason to know of the possibility of - such damages. The Adobe materials are provided on an "AS IS" basis. - Adobe specifically disclaims all express, statutory, or implied - warranties relating to the Adobe materials, including but not limited to - those concerning merchantability or fitness for a particular purpose or - non-infringement of any third party rights regarding the Adobe - materials. - -The JUnit test framework (http://junit.org/) - - Common Public License - v 1.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS COMMON PUBLIC - LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM - CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - - 1. DEFINITIONS - - "Contribution" means: - - a) in the case of the initial Contributor, the initial code and - documentation distributed under this Agreement, and - - b) in the case of each subsequent Contributor: - - i) changes to the Program, and - - ii) additions to the Program; - - where such changes and/or additions to the Program originate from and - are distributed by that particular Contributor. A Contribution - 'originates' from a Contributor if it was added to the Program by such - Contributor itself or anyone acting on such Contributor's behalf. - Contributions do not include additions to the Program which: - (i) are separate modules of software distributed in conjunction with - the Program under their own license agreement, and (ii) are not - derivative works of the Program. - - "Contributor" means any person or entity that distributes the Program. - - "Licensed Patents " mean patent claims licensable by a Contributor which - are necessarily infringed by the use or sale of its Contribution alone or - when combined with the Program. - - "Program" means the Contributions distributed in accordance with this - Agreement. - - "Recipient" means anyone who receives the Program under this Agreement, - including all Contributors. - - 2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free copyright license to - reproduce, prepare derivative works of, publicly display, publicly - perform, distribute and sublicense the Contribution of such Contributor, - if any, and such derivative works, in source code and object code form. - - b) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free patent license under - Licensed Patents to make, use, sell, offer to sell, import and otherwise - transfer the Contribution of such Contributor, if any, in source code - and object code form. This patent license shall apply to the combination - of the Contribution and the Program if, at the time the Contribution is - added by the Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent license - shall not apply to any other combinations which include the - Contribution. No hardware per se is licensed hereunder. - - c) Recipient understands that although each Contributor grants the licenses - to its Contributions set forth herein, no assurances are provided by any - Contributor that the Program does not infringe the patent or other - intellectual property rights of any other entity. Each Contributor - disclaims any liability to Recipient for claims brought by any other - entity based on infringement of intellectual property rights or - otherwise. As a condition to exercising the rights and licenses granted - hereunder, each Recipient hereby assumes sole responsibility to secure - any other intellectual property rights needed, if any. For example, if - a third party patent license is required to allow Recipient to - distribute the Program, it is Recipient's responsibility to acquire that - license before distributing the Program. - - d) Each Contributor represents that to its knowledge it has sufficient - copyright rights in its Contribution, if any, to grant the copyright - license set forth in this Agreement. - - 3. REQUIREMENTS - - A Contributor may choose to distribute the Program in object code form - under its own license agreement, provided that: - - a) it complies with the terms and conditions of this Agreement; and - - b) its license agreement: - - i) effectively disclaims on behalf of all Contributors all warranties - and conditions, express and implied, including warranties or - conditions of title and non-infringement, and implied warranties or - conditions of merchantability and fitness for a particular purpose; - - ii) effectively excludes on behalf of all Contributors all liability for - damages, including direct, indirect, special, incidental and - consequential damages, such as lost profits; - - iii) states that any provisions which differ from this Agreement are - offered by that Contributor alone and not by any other party; and - - iv) states that source code for the Program is available from such - Contributor, and informs licensees how to obtain it in a reasonable - manner on or through a medium customarily used for software - exchange. - - When the Program is made available in source code form: - - a) it must be made available under this Agreement; and - - b) a copy of this Agreement must be included with each copy of the Program. - - Contributors may not remove or alter any copyright notices contained within - the Program. - - Each Contributor must identify itself as the originator of its - Contribution, if any, in a manner that reasonably allows subsequent - Recipients to identify the originator of the Contribution. - - 4. COMMERCIAL DISTRIBUTION - - Commercial distributors of software may accept certain responsibilities - with respect to end users, business partners and the like. While this - license is intended to facilitate the commercial use of the Program, the - Contributor who includes the Program in a commercial product offering - should do so in a manner which does not create potential liability for - other Contributors. Therefore, if a Contributor includes the Program in - a commercial product offering, such Contributor ("Commercial Contributor") - hereby agrees to defend and indemnify every other Contributor ("Indemnified - Contributor") against any losses, damages and costs (collectively "Losses") - arising from claims, lawsuits and other legal actions brought by a third - party against the Indemnified Contributor to the extent caused by the acts - or omissions of such Commercial Contributor in connection with its - distribution of the Program in a commercial product offering. The - obligations in this section do not apply to any claims or Losses relating - to any actual or alleged intellectual property infringement. In order to - qualify, an Indemnified Contributor must: a) promptly notify the Commercial - Contributor in writing of such claim, and b) allow the Commercial - Contributor to control, and cooperate with the Commercial Contributor in, - the defense and any related settlement negotiations. The Indemnified - Contributor may participate in any such claim at its own expense. - - For example, a Contributor might include the Program in a commercial - product offering, Product X. That Contributor is then a Commercial - Contributor. If that Commercial Contributor then makes performance claims, - or offers warranties related to Product X, those performance claims and - warranties are such Commercial Contributor's responsibility alone. Under - this section, the Commercial Contributor would have to defend claims - against the other Contributors related to those performance claims and - warranties, and if a court requires any other Contributor to pay any - damages as a result, the Commercial Contributor must pay those damages. - - 5. NO WARRANTY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED - ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER - EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR - CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A - PARTICULAR PURPOSE. Each Recipient is solely responsible for determining - the appropriateness of using and distributing the Program and assumes all - risks associated with its exercise of rights under this Agreement, - including but not limited to the risks and costs of program errors, - compliance with applicable laws, damage to or loss of data, programs or - equipment, and unavailability or interruption of operations. - - 6. DISCLAIMER OF LIABILITY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY - CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION - LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE - EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGES. - - 7. GENERAL - - If any provision of this Agreement is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of the - remainder of the terms of this Agreement, and without further action by - the parties hereto, such provision shall be reformed to the minimum extent - necessary to make such provision valid and enforceable. - - If Recipient institutes patent litigation against a Contributor with - respect to a patent applicable to software (including a cross-claim or - counterclaim in a lawsuit), then any patent licenses granted by that - Contributor to such Recipient under this Agreement shall terminate as of - the date such litigation is filed. In addition, if Recipient institutes - patent litigation against any entity (including a cross-claim or - counterclaim in a lawsuit) alleging that the Program itself (excluding - combinations of the Program with other software or hardware) infringes - such Recipient's patent(s), then such Recipient's rights granted under - Section 2(b) shall terminate as of the date such litigation is filed. - - All Recipient's rights under this Agreement shall terminate if it fails - to comply with any of the material terms or conditions of this Agreement - and does not cure such failure in a reasonable period of time after - becoming aware of such noncompliance. If all Recipient's rights under this - Agreement terminate, Recipient agrees to cease use and distribution of the - Program as soon as reasonably practicable. However, Recipient's obligations - under this Agreement and any licenses granted by Recipient relating to the - Program shall continue and survive. - - Everyone is permitted to copy and distribute copies of this Agreement, but - in order to avoid inconsistency the Agreement is copyrighted and may only - be modified in the following manner. The Agreement Steward reserves the - right to publish new versions (including revisions) of this Agreement from - time to time. No one other than the Agreement Steward has the right to - modify this Agreement. IBM is the initial Agreement Steward. IBM may assign - the responsibility to serve as the Agreement Steward to a suitable separate - entity. Each new version of the Agreement will be given a distinguishing - version number. The Program (including Contributions) may always be - distributed subject to the version of the Agreement under which it was - received. In addition, after a new version of the Agreement is published, - Contributor may elect to distribute the Program (including its - Contributions) under the new version. Except as expressly stated in - Sections 2(a) and 2(b) above, Recipient receives no rights or licenses to - the intellectual property of any Contributor under this Agreement, whether - expressly, by implication, estoppel or otherwise. All rights in the Program - not expressly granted under this Agreement are reserved. - - This Agreement is governed by the laws of the State of New York and the - intellectual property laws of the United States of America. No party to - this Agreement will bring a legal action under this Agreement more than - one year after the cause of action arose. Each party waives its rights to - a jury trial in any resulting litigation. - -The International Components for Unicode library (http://site.icu-project.org/) - - ICU License - ICU 1.8.1 and later - - COPYRIGHT AND PERMISSION NOTICE - - Copyright (c) 1995-2009 International Business Machines Corporation and others - - All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the "Software"), - to deal in the Software without restriction, including without limitation - the rights to use, copy, modify, merge, publish, distribute, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, provided that the above copyright notice(s) and this - permission notice appear in all copies of the Software and that both the - above copyright notice(s) and this permission notice appear in supporting - documentation. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS. - IN NO EVENT SHALL THE COPYRIGHT HOLDER OR HOLDERS INCLUDED IN THIS NOTICE - BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, - OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, - WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, - ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - - Except as contained in this notice, the name of a copyright holder shall - not be used in advertising or otherwise to promote the sale, use or other - dealings in this Software without prior written authorization of the - copyright holder. - diff --git a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/fontbox-1.6.0.jar b/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/fontbox-1.6.0.jar deleted file mode 100644 index c3492fc29b75..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/fontbox-1.6.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/jempbox-1.6.0.jar b/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/jempbox-1.6.0.jar deleted file mode 100644 index 5ca6d7a58b95..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/jempbox-1.6.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/pdfbox-1.6.0.jar b/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/pdfbox-1.6.0.jar deleted file mode 100644 index 75efe034f1b1..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/pdfbox-1.6.0/pdfbox-1.6.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/LICENSE b/Services/WebServices/RPC/lib/jars/poi/LICENSE deleted file mode 100644 index 19246db04cbb..000000000000 --- a/Services/WebServices/RPC/lib/jars/poi/LICENSE +++ /dev/null @@ -1,513 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - - -APACHE POI SUBCOMPONENTS: - -Apache POI includes subcomponents with separate copyright notices and -license terms. Your use of these subcomponents is subject to the terms -and conditions of the following licenses: - - -Office Open XML schemas (ooxml-schemas-1.*.jar) - - The Office Open XML schema definitions used by Apache POI are - a part of the Office Open XML ECMA Specification (ECMA-376, [1]). - As defined in section 9.4 of the ECMA bylaws [2], this specification - is available to all interested parties without restriction: - - 9.4 All documents when approved shall be made available to - all interested parties without restriction. - - Furthermore, both Microsoft and Adobe have granted patent licenses - to this work [3,4,5]. - - [1] http://www.ecma-international.org/publications/standards/Ecma-376.htm - [2] http://www.ecma-international.org/memento/Ecmabylaws.htm - [3] http://www.microsoft.com/openspecifications/en/us/programs/osp/default.aspx - [4] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ - Patent%20statements%20ok/ECMA-376%20Edition%202%20Microsoft%20Patent%20Declaration.pdf - [5] http://www.ecma-international.org/publications/files/ECMA-ST/Ecma%20PATENT/ - Patent%20statements%20ok/ECMA-376%20Adobe%20Patent%20Declaration.pdf - - -Bouncy Castle library (bcprov-*.jar, bcpg-*.jar, bcpkix-*.jar) - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - The above copyright notice and this permission notice shall be included in - all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - IN THE SOFTWARE. - -JUnit test library (junit-4.*.jar) & JaCoCo (*jacoco*) - - Eclipse Public License - v 1.0 - - THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC - LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM - CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT. - - 1. DEFINITIONS - - "Contribution" means: - - a) in the case of the initial Contributor, the initial code and documentation - distributed under this Agreement, and - b) in the case of each subsequent Contributor: - i) changes to the Program, and - ii) additions to the Program; - where such changes and/or additions to the Program originate from and are - distributed by that particular Contributor. A Contribution 'originates' from - a Contributor if it was added to the Program by such Contributor itself or - anyone acting on such Contributor's behalf. Contributions do not include - additions to the Program which: (i) are separate modules of software - distributed in conjunction with the Program under their own license agreement, - and (ii) are not derivative works of the Program. - - "Contributor" means any person or entity that distributes the Program. - - "Licensed Patents" mean patent claims licensable by a Contributor which are - necessarily infringed by the use or sale of its Contribution alone or when - combined with the Program. - - "Program" means the Contributions distributed in accordance with this Agreement. - - "Recipient" means anyone who receives the Program under this Agreement, - including all Contributors. - - 2. GRANT OF RIGHTS - - a) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free copyright license to - reproduce, prepare derivative works of, publicly display, publicly - perform, distribute and sublicense the Contribution of such Contributor, - if any, and such derivative works, in source code and object code form. - b) Subject to the terms of this Agreement, each Contributor hereby grants - Recipient a non-exclusive, worldwide, royalty-free patent license under - Licensed Patents to make, use, sell, offer to sell, import and otherwise - transfer the Contribution of such Contributor, if any, in source code - and object code form. This patent license shall apply to the combination - of the Contribution and the Program if, at the time the Contribution is - added by the Contributor, such addition of the Contribution causes such - combination to be covered by the Licensed Patents. The patent license - shall not apply to any other combinations which include the Contribution. - No hardware per se is licensed hereunder. - c) Recipient understands that although each Contributor grants the licenses - to its Contributions set forth herein, no assurances are provided by any - Contributor that the Program does not infringe the patent or other - intellectual property rights of any other entity. Each Contributor - disclaims any liability to Recipient for claims brought by any other - entity based on infringement of intellectual property rights or - otherwise. As a condition to exercising the rights and licenses granted - hereunder, each Recipient hereby assumes sole responsibility to secure - any other intellectual property rights needed, if any. For example, if - a third party patent license is required to allow Recipient to distribute - the Program, it is Recipient's responsibility to acquire that license - before distributing the Program. - d) Each Contributor represents that to its knowledge it has sufficient - copyright rights in its Contribution, if any, to grant the copyright - license set forth in this Agreement. - - 3. REQUIREMENTS - - A Contributor may choose to distribute the Program in object code form under - its own license agreement, provided that: - - a) it complies with the terms and conditions of this Agreement; and - b) its license agreement: - i) effectively disclaims on behalf of all Contributors all warranties and - conditions, express and implied, including warranties or conditions of - title and non-infringement, and implied warranties or conditions of - merchantability and fitness for a particular purpose; - ii) effectively excludes on behalf of all Contributors all liability for - damages, including direct, indirect, special, incidental and - consequential damages, such as lost profits; - iii) states that any provisions which differ from this Agreement are - offered by that Contributor alone and not by any other party; and - iv) states that source code for the Program is available from such - Contributor, and informs licensees how to obtain it in a reasonable - manner on or through a medium customarily used for software exchange. - - When the Program is made available in source code form: - - a) it must be made available under this Agreement; and - b) a copy of this Agreement must be included with each copy of the Program. - Contributors may not remove or alter any copyright notices contained - within the Program. - - Each Contributor must identify itself as the originator of its Contribution, - if any, in a manner that reasonably allows subsequent Recipients to identify - the originator of the Contribution. - - 4. COMMERCIAL DISTRIBUTION - - Commercial distributors of software may accept certain responsibilities with - respect to end users, business partners and the like. While this license is - intended to facilitate the commercial use of the Program, the Contributor - who includes the Program in a commercial product offering should do so in a - manner which does not create potential liability for other Contributors. - Therefore, if a Contributor includes the Program in a commercial product - offering, such Contributor ("Commercial Contributor") hereby agrees to - defend and indemnify every other Contributor ("Indemnified Contributor") - against any losses, damages and costs (collectively "Losses") arising from - claims, lawsuits and other legal actions brought by a third party against - the Indemnified Contributor to the extent caused by the acts or omissions - of such Commercial Contributor in connection with its distribution of the - Program in a commercial product offering. The obligations in this section - do not apply to any claims or Losses relating to any actual or alleged - intellectual property infringement. In order to qualify, an Indemnified - Contributor must: a) promptly notify the Commercial Contributor in writing - of such claim, and b) allow the Commercial Contributor to control, and - cooperate with the Commercial Contributor in, the defense and any related - settlement negotiations. The Indemnified Contributor may participate in any - such claim at its own expense. - - For example, a Contributor might include the Program in a commercial product - offering, Product X. That Contributor is then a Commercial Contributor. If - that Commercial Contributor then makes performance claims, or offers - warranties related to Product X, those performance claims and warranties are - such Commercial Contributor's responsibility alone. Under this section, the - Commercial Contributor would have to defend claims against the other - Contributors related to those performance claims and warranties, and if a - court requires any other Contributor to pay any damages as a result, the - Commercial Contributor must pay those damages. - - 5. NO WARRANTY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON - AN "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER - EXPRESS OR IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR - CONDITIONS OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A - PARTICULAR PURPOSE. Each Recipient is solely responsible for determining the - appropriateness of using and distributing the Program and assumes all risks - associated with its exercise of rights under this Agreement , including but - not limited to the risks and costs of program errors, compliance with - applicable laws, damage to or loss of data, programs or equipment, and - unavailability or interruption of operations. - - 6. DISCLAIMER OF LIABILITY - - EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY - CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL, - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION - LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE - EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY - OF SUCH DAMAGES. - - 7. GENERAL - - If any provision of this Agreement is invalid or unenforceable under - applicable law, it shall not affect the validity or enforceability of the - remainder of the terms of this Agreement, and without further action by the - parties hereto, such provision shall be reformed to the minimum extent - necessary to make such provision valid and enforceable. - - If Recipient institutes patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Program itself - (excluding combinations of the Program with other software or hardware) - infringes such Recipient's patent(s), then such Recipient's rights granted - under Section 2(b) shall terminate as of the date such litigation is filed. - - All Recipient's rights under this Agreement shall terminate if it fails to - comply with any of the material terms or conditions of this Agreement and - does not cure such failure in a reasonable period of time after becoming - aware of such noncompliance. If all Recipient's rights under this Agreement - terminate, Recipient agrees to cease use and distribution of the Program as - soon as reasonably practicable. However, Recipient's obligations under this - Agreement and any licenses granted by Recipient relating to the Program - shall continue and survive. - - Everyone is permitted to copy and distribute copies of this Agreement, but - in order to avoid inconsistency the Agreement is copyrighted and may only - be modified in the following manner. The Agreement Steward reserves the - right to publish new versions (including revisions) of this Agreement from - time to time. No one other than the Agreement Steward has the right to - modify this Agreement. The Eclipse Foundation is the initial Agreement - Steward. The Eclipse Foundation may assign the responsibility to serve as - the Agreement Steward to a suitable separate entity. Each new version of - the Agreement will be given a distinguishing version number. The Program - (including Contributions) may always be distributed subject to the version - of the Agreement under which it was received. In addition, after a new - version of the Agreement is published, Contributor may elect to distribute - the Program (including its Contributions) under the new version. Except as - expressly stated in Sections 2(a) and 2(b) above, Recipient receives no - rights or licenses to the intellectual property of any Contributor under - this Agreement, whether expressly, by implication, estoppel or otherwise. - All rights in the Program not expressly granted under this Agreement are - reserved. - - This Agreement is governed by the laws of the State of New York and the - intellectual property laws of the United States of America. No party to this - Agreement will bring a legal action under this Agreement more than one year - after the cause of action arose. Each party waives its rights to a jury - trial in any resulting litigation. - -Hamcrest library (hamcrest-*.jar) & CuvesAPI / Curve API - - BSD License - - Copyright (c) 2000-2006, www.hamcrest.org - All rights reserved. - - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions are met: - - Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. Redistributions in binary - form must reproduce the above copyright notice, this list of conditions and - the following disclaimer in the documentation and/or other materials - provided with the distribution. - - Neither the name of Hamcrest nor the names of its contributors may be used - to endorse or promote products derived from this software without specific - prior written permission. - - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - POSSIBILITY OF SUCH DAMAGE. - -SLF4J library (slf4j-api-*.jar) - - Copyright (c) 2004-2013 QOS.ch - All rights reserved. - - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: - - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-3.15.jar deleted file mode 100644 index ab368bd61a46..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-examples-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-examples-3.15.jar deleted file mode 100644 index 093946c48058..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-examples-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-excelant-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-excelant-3.15.jar deleted file mode 100644 index 65a5ad022335..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-excelant-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-3.15.jar deleted file mode 100644 index 6de995605459..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-schemas-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-schemas-3.15.jar deleted file mode 100644 index f3ed2053bdce..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-ooxml-schemas-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/poi/poi-scratchpad-3.15.jar b/Services/WebServices/RPC/lib/jars/poi/poi-scratchpad-3.15.jar deleted file mode 100644 index f68ae818d016..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/poi/poi-scratchpad-3.15.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/saxpath.jar b/Services/WebServices/RPC/lib/jars/saxpath.jar deleted file mode 100644 index 2b43955babc5..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/saxpath.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/xmlbeans-2.3.0.jar b/Services/WebServices/RPC/lib/jars/xmlbeans-2.3.0.jar deleted file mode 100644 index ccd8163421ba..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/xmlbeans-2.3.0.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/xmlrpc312/LICENSE.txt b/Services/WebServices/RPC/lib/jars/xmlrpc312/LICENSE.txt deleted file mode 100644 index d64569567334..000000000000 --- a/Services/WebServices/RPC/lib/jars/xmlrpc312/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/Services/WebServices/RPC/lib/jars/xmlrpc312/ws-commons-util-1.0.2.jar b/Services/WebServices/RPC/lib/jars/xmlrpc312/ws-commons-util-1.0.2.jar deleted file mode 100644 index 3fc364e7f605..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/xmlrpc312/ws-commons-util-1.0.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-client-3.1.2.jar b/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-client-3.1.2.jar deleted file mode 100644 index 9c33bb4f925f..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-client-3.1.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-common-3.1.2.jar b/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-common-3.1.2.jar deleted file mode 100644 index 707d1b3c5bf9..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-common-3.1.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-server-3.1.2.jar b/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-server-3.1.2.jar deleted file mode 100644 index 79ef4bb464dd..000000000000 Binary files a/Services/WebServices/RPC/lib/jars/xmlrpc312/xmlrpc-server-3.1.2.jar and /dev/null differ diff --git a/Services/WebServices/RPC/lib/pom.xml b/Services/WebServices/RPC/lib/pom.xml new file mode 100644 index 000000000000..e58f688c0c42 --- /dev/null +++ b/Services/WebServices/RPC/lib/pom.xml @@ -0,0 +1,227 @@ + + + 4.0.0 + de.ilias.ilserver + ilServer + 9.0.1 + + ilServer + + + org.apache.maven.plugins + maven-resources-plugin + 3.3.1 + + UTF-8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.4.1 + + + package + + shade + + + false + false + + + *:* + + module-info.class + META-INF/maven/** + META-INF/DEPENDENCIES + META-INF/NOTICE* + META-INF/*.SF + META-INF/*.DSA + META-INF/*.RSA + META-INF/*.MF + META-INF/AL2.0 + META-INF/LGPL2.1 + META-INF/versions/9/module-info.class + license/** + + + + + + + + + + de.ilias.ilServer + true + + + + + + + + + + + + + commons-httpclient + commons-httpclient + 3.1 + + + + org.apache.logging.log4j + log4j-core + 2.21.0 + + + + org.apache.logging.log4j + log4j-api + 2.21.0 + + + + org.apache.logging.log4j + log4j-jcl + 2.21.0 + + + + org.apache.logging.log4j + log4j-slf4j-impl + 2.21.0 + + + + org.apache.logging.log4j + log4j-1.2-api + 2.21.0 + + + + org.apache.commons + commons-configuration2 + 2.9.0 + + + org.apache.lucene + lucene-core + 9.8.0 + + + org.apache.lucene + lucene-highlighter + 9.8.0 + + + org.apache.lucene + lucene-join + 9.8.0 + + + org.apache.lucene + lucene-memory + 9.8.0 + + + org.apache.lucene + lucene-queries + 9.8.0 + + + org.apache.lucene + lucene-queryparser + 9.8.0 + + + + org.mariadb.jdbc + mariadb-java-client + 3.2.0 + compile + + + org.apache.xmlrpc + xmlrpc-server + 3.1.3 + + + org.apache.xmlrpc + xmlrpc-common + 3.1.3 + + + org.apache.xmlrpc + xmlrpc-client + 3.1.3 + + + org.jdom + jdom2 + 2.0.6.1 + compile + + + + org.apache.tika + tika-core + 2.9.0 + + + org.apache.tika + tika-parser-html-module + 2.9.0 + + + org.apache.tika + tika-parser-microsoft-module + 2.9.0 + + + org.apache.tika + tika-parser-miscoffice-module + 2.9.0 + + + org.apache.tika + tika-parser-pdf-module + 2.9.0 + + + org.apache.tika + tika-parser-text-module + 2.9.0 + + + org.apache.tika + tika-parser-xml-module + 2.9.0 + + + + org.apache.xmlgraphics + fop-core + 2.9 + + + org.apache.xmlgraphics + fop-util + 2.9 + + + jar + ilServer + https://www.ilias.de + + true + UTF-8 + 17 + 17 + + diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ExtensionFileHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ExtensionFileHandler.java deleted file mode 100644 index 2cd616c6d087..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ExtensionFileHandler.java +++ /dev/null @@ -1,441 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.file; - - -import de.ilias.services.settings.ConfigurationException; -import de.ilias.services.settings.ServerSettings; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.poi.POITextExtractor; -import org.apache.poi.extractor.ExtractorFactory; -import org.apache.poi.openxml4j.exceptions.InvalidFormatException; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class ExtensionFileHandler { - - protected static Logger logger = LogManager.getLogger(ExtensionFileHandler.class); - - - public ExtensionFileHandler() { - // Do nothing here - } - - /** - * - * @param file - * @return - * @throws FileHandlerException - */ - public String getContent(File file, String extension) throws FileHandlerException { - - // Stop here if no read permission is given - if(!file.canRead()) { - throw new FileHandlerException("No permission to read file: " + file.getAbsolutePath()); - } - - // Check file size - if(!checkFileSizeLimit(file)) { - throw new FileHandlerException("File size limit exceeded. Ignoring file " + file.getAbsolutePath()); - } - - logger.info("Current file is: " + file.getAbsolutePath()); - try { - String fname = file.getName(); - int dotIndex = fname.lastIndexOf("."); - if ((extension.length() == 0) - && (dotIndex > 0) - && (dotIndex < fname.length())) { - extension = fname.substring(dotIndex + 1, fname.length()); - } - if (extension.equalsIgnoreCase("")) { - logger.warn("no valid extension found for: " + file.getName()); - return ""; - } - // Do not index xslx - if (extension.equalsIgnoreCase("xlsx")) { - logger.info("Ignoring xslx: " + file.getName()); - return ""; - } - // Handled extensions are: html,pdf,txt - if (extension.equalsIgnoreCase("pdf")) { - logger.info("Using getPDFDocument() for " + file.getName()); - return getPDFDocument(file); - } - // HTML - if (extension.equalsIgnoreCase("html") || extension.equalsIgnoreCase("htm")) { - logger.info("Using getHTMLDocument() for " + file.getName()); - return getHTMLDocument(file); - } - if (extension.equalsIgnoreCase("txt") || extension.length() == 0) { - logger.info("Using getTextDocument() for: " + file.getName()); - return getTextDocument(file); - } - // Open office - if (extension.equalsIgnoreCase("odt")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("ott")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("stw")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("sxw")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("odg")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("odp")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("sti")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("sxd")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("sxw")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getOpenOfficeDocument(file); - } - // Flat XML OO documents - if (extension.equalsIgnoreCase("fodt")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getFlatOpenOfficeDocument(file); - } - if (extension.equalsIgnoreCase("fodp")) { - logger.info("Using getOpenOfficeDocument() for " + file.getName()); - return getFlatOpenOfficeDocument(file); - } - - // RTF - if (extension.equalsIgnoreCase("rtf")) { - logger.info("Using getRTFDocument() for " + file.getName()); - return getRTFDocument(file); - } - } - catch (FileHandlerException e) { - logger.warn("Parsing failed with message: " + e); - return ""; - } - - catch(Exception e) { - logger.warn("Parsing failed with message: " + e); - return ""; - } - - return tryPOIDocument(file); - } - - /** - * Try to extract POI content - * @param file - */ - private String tryPOIDocument(File file) { - - FileInputStream fis = null; - - try { - StringBuilder content = new StringBuilder(); - POITextExtractor extractor = null; - - extractor = ExtractorFactory.createExtractor(fis = new FileInputStream(file)); - content.append(extractor.getText()); - - if(content.length() > 0) { - logger.info("Parsed file: " + file.getName()); - } - else { - logger.warn("No content found for" + file.getName()); - } - //logger.debug("Parsed content is: " + content.toString()); - return content.toString(); - } - catch (InvalidFormatException e) { - logger.info("File is not a compatible POI file."); - logger.info("Current file is: " + file.getAbsolutePath()); - } - catch(IllegalArgumentException e) { - logger.info("No handler found."); - logger.info("Current file is: " + file.getAbsolutePath()); - } - catch (Exception e) { - logger.warn("Parsing failed with message: " + e); - logger.info("Current file is: " + file.getAbsolutePath()); - } - finally { - try { - if(fis != null) { - fis.close(); - } - } - catch(IOException e) { - // Nothing - } - } - - return ""; - } - - - /** - * - * @param file - * @return - * @throws ilFileHandlerException - */ - private String getTextDocument(File file) throws FileHandlerException { - - FileInputStream fis = null; - FileHandler doch = (FileHandler) new PlainTextHandler(); - - try { - return doch.getContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(FileNotFoundException e) { - throw new FileHandlerException("Cannot find file: " + file.getAbsolutePath()); - } - catch(FileHandlerException e) { - throw e; - } - catch (IOException e) { - throw new FileHandlerException(e); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * - * @param file - * @return - * @throws FileHandlerException - */ - private String getPDFDocument(File file) throws FileHandlerException { - - FileHandler doch = (FileHandler) new PDFBoxPDFHandler(); - FileInputStream fis = null; - logger.debug("Start PDFBoxPDFHandler..."); - - try { - - logger.debug(file.getAbsolutePath()); - return doch.getContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(IOException e) { - throw new FileHandlerException("Caught unknown exception " + e.getMessage()); - } - catch(FileHandlerException e) { - throw e; - } - catch(Exception e) { - throw new FileHandlerException("Caught unknown exception " + e.getMessage()); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * - * @param file - * @return - * @throws FileHandlerException - */ - private String getHTMLDocument(File file) throws FileHandlerException { - - FileInputStream fis = null; - FileHandler doch = (FileHandler) new JTidyHTMLHandler(); - - try { - return doch.getContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(FileHandlerException e) { - throw e; - } - catch(IOException e) { - throw new FileHandlerException(e); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * @param file - * @return - */ - private String getOpenOfficeDocument(File file) throws FileHandlerException { - - FileInputStream fis = null; - FileHandler doch = (FileHandler) new OpenOfficeDefaultHandler(); - - try { - return doch.getContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(IOException e) { - throw new FileHandlerException(e); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * Get - * @param file - * @return - */ - private String getFlatOpenOfficeDocument(File file) throws FileHandlerException { - - FileInputStream fis = null; - OpenOfficeDefaultHandler doch = new OpenOfficeDefaultHandler(); - - try { - return doch.extractContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(IOException e) { - throw new FileHandlerException(e); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * Get rtf document - * @param file - * @return - */ - private String getRTFDocument(File file) throws FileHandlerException { - - FileInputStream fis = null; - FileHandler doch = (FileHandler) new RTFHandler(); - - try { - return doch.getContent(fis = new FileInputStream(file.getAbsolutePath())); - } - catch(IOException e) { - throw new FileHandlerException(e); - } - finally { - try { - if(fis != null) - fis.close(); - } - catch (IOException e) { - } - } - } - - /** - * Check file size limit - * @param file - * @return bool - */ - private boolean checkFileSizeLimit(File file) - { - long maxFileSize = 0; - - try { - maxFileSize = ServerSettings.getInstance().getMaxFileSize(); - } - catch(ConfigurationException e) { - maxFileSize = ServerSettings.DEFAULT_MAX_FILE_SIZE; - } - - if(file.length() > maxFileSize) { - logger.info("File size is " + file.length() + " bytes."); - return false; - } - return true; - } - - - /* - private Document getFlashDocument(File file) - throws ilFileHandlerException { - - Document doc = null; - ilDocumentHandler doch = (ilDocumentHandler) new ilFlashHandler(); - - try { - doc = doch.getDocument(new FileInputStream(file.getAbsolutePath())); - } - catch(FileNotFoundException e) { - throw new ilFileHandlerException("Cannot find file: " + file.getAbsolutePath()); - } - catch(ilDocumentHandlerException e) { - throw new ilFileHandlerException(e.getMessage()); - } - return doc; - - } - */ -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/JTidyHTMLHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/JTidyHTMLHandler.java deleted file mode 100644 index 11400738d964..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/JTidyHTMLHandler.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ - */ - -package de.ilias.services.lucene.index.file; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.PrintWriter; -import java.io.StringWriter; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.w3c.dom.Element; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; -import org.w3c.tidy.Tidy; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class JTidyHTMLHandler implements FileHandler { - - protected Logger logger = LogManager.getLogger(JTidyHTMLHandler.class); - - private Tidy tidy; - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#getContent(java.io.InputStream) - */ - public String getContent(InputStream is) throws FileHandlerException, - IOException { - - StringBuilder builder = new StringBuilder(); - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - - tidy = new Tidy(); - tidy.setErrout(new PrintWriter(new ByteArrayOutputStream())); - tidy.setQuiet(true); - tidy.setShowWarnings(false); - - org.w3c.dom.Document root = tidy.parseDOM(is, bout); - Element rawDoc = root.getDocumentElement(); - - String title = getTitle(rawDoc); - String body = getBody(rawDoc); - - if (title != null && !title.equals("")) { - builder.append(title); - } - if (body != null && !body.equals("")) { - builder.append(body); - } - - if(bout != null) { - try { - bout.close(); - } - catch(IOException e) { - // Nothing - } - } - - - return builder.toString(); - - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#transformStream(java.io.InputStream) - */ - public InputStream transformStream(InputStream is) { - - return null; - } - - private String getTitle(Element rawDoc) { - if (rawDoc == null) { - return null; - } - - String title = ""; - NodeList children = rawDoc.getElementsByTagName("title"); - if (children.getLength() > 0) { - Element titleElement = (Element) children.item(0); - Text text = (Text) titleElement.getFirstChild(); - if (text != null) { - title = text.getData(); - } - } - return title; - } - - private String getBody(Element rawDoc) { - if (rawDoc == null) { - return null; - } - String body = ""; - NodeList children = rawDoc.getElementsByTagName("body"); - if (children.getLength() > 0) { - body = getText(children.item(0)); - } - return body; - } - - private String getText(Node node) { - NodeList children = node.getChildNodes(); - StringBuilder sb = new StringBuilder(); - - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - switch (child.getNodeType()) { - case Node.ELEMENT_NODE: - sb.append(getText(child)); - sb.append(" "); - break; - case Node.TEXT_NODE: - sb.append(((Text) child).getData()); - break; - } - } - return sb.toString(); - } -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/OpenOfficeDefaultHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/OpenOfficeDefaultHandler.java deleted file mode 100644 index 95f9df5e38d3..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/OpenOfficeDefaultHandler.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.file; - -import java.io.IOException; -import java.io.InputStream; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class OpenOfficeDefaultHandler extends ZipBasedOfficeHandler implements FileHandler { - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#getContent(java.io.InputStream) - */ - public String getContent(InputStream is) throws FileHandlerException, IOException { - - InputStream contentStream = extractContentStream(is); - StringBuilder content = new StringBuilder(); - content.append(extractContent(contentStream)); - logger.debug(content.toString()); - - if(contentStream != null) { - try { - contentStream.close(); - } - catch(IOException e) { - // Nothing - } - } - - return content.toString(); - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#transformStream(java.io.InputStream) - */ - public InputStream transformStream(InputStream is) { - return null; - } - - /** - * @see de.ilias.services.lucene.index.file.ZipBasedOfficeHandler#getContentFileName() - */ - protected String getContentFileName() { - - return "content.xml"; - } - - /** - * @see de.ilias.services.lucene.index.file.ZipBasedOfficeHandler#getXPath() - */ - protected String getXPath() { - - return "//text:p"; - } - - - - - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PDFBoxPDFHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PDFBoxPDFHandler.java deleted file mode 100644 index 59bff53ed540..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PDFBoxPDFHandler.java +++ /dev/null @@ -1,98 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.file; - -import java.io.IOException; -import java.io.InputStream; -import java.io.StringWriter; -import java.util.logging.Level; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.apache.pdfbox.pdmodel.PDDocument; -import org.apache.pdfbox.util.PDFTextStripper; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class PDFBoxPDFHandler implements FileHandler { - - protected Logger logger = LogManager.getLogger(PDFBoxPDFHandler.class); - - - /** - * @throws IOException - * @see de.ilias.services.lucene.index.file.FileHandler#getContent(java.io.InputStream) - */ - public String getContent(InputStream is) throws FileHandlerException { - - PDDocument pddo = null; - PDFTextStripper stripper = null; - String str = new String(""); - - try { - - pddo = PDDocument.load(is); - - if(pddo.isEncrypted()) { - logger.warn("PDF Document is encrypted. Trying empty password..."); - return ""; - } - stripper = new PDFTextStripper(); - str = stripper.getText(pddo); - } - catch (NumberFormatException e) { - logger.warn("Invalid PDF version number given. Aborting"); - } - catch (IOException e) { - logger.warn(e.getMessage()); - throw new FileHandlerException(e); - } - catch (Exception e) { - logger.error(e.getMessage()); - throw new FileHandlerException(e); - } - finally { - try { - if(pddo != null) - pddo.close(); - } - catch (IOException e) { - ; - } - } - return str; - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#transformStream(java.io.InputStream) - */ - public InputStream transformStream(InputStream is) { - // TODO Auto-generated method stub - return null; - } - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PlainTextHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PlainTextHandler.java deleted file mode 100644 index 7895c12730d7..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/PlainTextHandler.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.file; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -/** - * Handle plain text files - * - * @author Stefan Meyer - * @version $Id$ - */ -public class PlainTextHandler implements FileHandler { - - /** - * - */ - public PlainTextHandler() { - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#getContent(java.io.InputStream) - */ - public String getContent(InputStream is) throws FileHandlerException { - - StringBuilder content = new StringBuilder(); - BufferedReader br = new BufferedReader(new InputStreamReader(is)); - - is = transformStream(is); - try { - String line = null; - while((line = br.readLine()) != null) { - content.append(' '); - content.append(line); - } - return content.toString(); - } - catch (IOException e) { - throw new FileHandlerException("Cannot read plain text file: " + e); - } - finally { - if(br != null) { - try { - br.close(); - } - catch (IOException e) { - } - } - } - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#transformStream(java.io.InputStream) - */ - public InputStream transformStream(InputStream is) { - - return is; - } -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/RTFHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/RTFHandler.java deleted file mode 100644 index 1389c7b1ca4e..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/RTFHandler.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ - */ - -package de.ilias.services.lucene.index.file; - -import java.io.IOException; -import java.io.InputStream; - -import javax.swing.text.BadLocationException; -import javax.swing.text.DefaultStyledDocument; -import javax.swing.text.rtf.RTFEditorKit; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class RTFHandler implements FileHandler { - - /** - * From Lucene in Action - * Use Swing lib - * - * @seede.ilias.services.lucene.index.file.FileHandler#getContent(java.io. - * InputStream) - */ - public String getContent(InputStream is) throws FileHandlerException, - IOException { - - String bodyText = null; - DefaultStyledDocument styledDoc = new DefaultStyledDocument(); - - try { - - new RTFEditorKit().read(is, styledDoc, 0); - bodyText = styledDoc.getText(0, styledDoc.getLength()); - } - catch (IOException e) { - throw new FileHandlerException( - "Cannot extract text from a RTF document", e); - - } - catch (BadLocationException e) { - throw new FileHandlerException( - "Cannot extract text from a RTF document", e); - } - - return bodyText; - } - - /** - * @see de.ilias.services.lucene.index.file.FileHandler#transformStream(java.io.InputStream) - */ - public InputStream transformStream(InputStream is) { - return null; - } - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ZipBasedOfficeHandler.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ZipBasedOfficeHandler.java deleted file mode 100644 index 017243b90d27..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/ZipBasedOfficeHandler.java +++ /dev/null @@ -1,129 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.file; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.util.zip.ZipEntry; -import java.util.zip.ZipException; -import java.util.zip.ZipInputStream; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.jdom.Element; -import org.jdom.JDOMException; -import org.jdom.input.SAXBuilder; -import org.jdom.xpath.XPath; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public abstract class ZipBasedOfficeHandler { - - protected static Logger logger = LogManager.getLogger(ZipBasedOfficeHandler.class); - protected static final int BUFFER = 2048; - - /** - * get name of content file - * E.g content.xml for .odt files - * @return - */ - abstract protected String getContentFileName(); - abstract protected String getXPath(); - - protected InputStream extractContentStream(InputStream is) throws FileHandlerException { - - ByteArrayOutputStream bout = new ByteArrayOutputStream(); - try { - ZipInputStream zip = new ZipInputStream(is); - ZipEntry entry; - - while((entry = zip.getNextEntry()) != null) { - - if(entry.getName().equalsIgnoreCase(getContentFileName())) { - int count; - byte data[] = new byte[BUFFER]; - while((count = zip.read(data,0,BUFFER)) != -1) { - bout.write(data, 0, count); - } - break; - } - } - is.close(); - return new ByteArrayInputStream(bout.toByteArray()); - } - catch(ZipException e) { - logger.info("Cannot extract " + getContentFileName() + " " + e.getMessage()); - throw new FileHandlerException(e); - } - catch (IOException e) { - logger.info("Cannot extract " + getContentFileName() + " " + e.getMessage()); - throw new FileHandlerException(e); - } - finally { - try { - bout.close(); - } - catch (IOException e) { - // Yepp - } - } - } - - public String extractContent(InputStream is) { - - SAXBuilder builder = new SAXBuilder(); - StringBuilder content = new StringBuilder(); - - try { - org.jdom.Document doc = builder.build(is); - XPath xpath = XPath.newInstance(getXPath()); - List res = xpath.selectNodes(doc); - - for(Object element : res) { - Element el = (Element) element; - content.append(" "); - content.append(el.getTextTrim()); - } - return content.toString(); - - } - catch (NullPointerException e) { - logger.warn("Caught NullPointerException: " + e); - } - catch (JDOMException e) { - logger.info("Cannot parse OO content: " + e); - } - catch (IOException e) { - logger.info("Cannot parse OO content: " + e); - } - return ""; - } - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java b/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java deleted file mode 100644 index e414d7b90598..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.lucene.index.transform; - -import java.io.IOException; -import java.io.StringReader; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.xml.sax.InputSource; -import org.xml.sax.SAXException; -import org.xml.sax.XMLReader; -import org.xml.sax.helpers.XMLReaderFactory; - -/** - * - * - * @author Stefan Meyer - * @version $Id$ - */ -public class ContentObjectTransformer implements ContentTransformer { - - protected Logger logger = LogManager.getLogger(ContentObjectTransformer.class); - - - - /** - * Extract text from page_objects - * @see de.ilias.services.lucene.index.transform.ContentTransformer#transform(java.lang.String) - */ - public String transform(String content) { - - XMLReader reader = null; - PageObjectHandler handler = null; - StringReader stringReader = new StringReader(content); - - try { - reader = XMLReaderFactory.createXMLReader(); - handler = new PageObjectHandler(); - - reader.setContentHandler(handler); - reader.parse(new InputSource(stringReader)); - - return handler.getContent(); - - } - catch (SAXException e) { - logger.warn("Cannot parse page_object content." + e); - } - catch (IOException e) { - logger.warn("Found invalid content." + e); - } - - return ""; - } - - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/IniFileParser.java b/Services/WebServices/RPC/lib/src/de/ilias/services/settings/IniFileParser.java deleted file mode 100644 index 7f36e90c14df..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/IniFileParser.java +++ /dev/null @@ -1,238 +0,0 @@ -/* - +-----------------------------------------------------------------------------+ - | ILIAS open source | - +-----------------------------------------------------------------------------+ - | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | - | | - | This program is free software; you can redistribute it and/or | - | modify it under the terms of the GNU General Public License | - | as published by the Free Software Foundation; either version 2 | - | of the License, or (at your option) any later version. | - | | - | This program is distributed in the hope that it will be useful, | - | but WITHOUT ANY WARRANTY; without even the implied warranty of | - | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | - | GNU General Public License for more details. | - | | - | You should have received a copy of the GNU General Public License | - | along with this program; if not, write to the Free Software | - | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | - +-----------------------------------------------------------------------------+ -*/ - -package de.ilias.services.settings; - -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.io.StringReader; -import java.util.prefs.Preferences; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.ini4j.Ini; -import org.ini4j.IniPreferences; - -/** - * Parser for ini files. - * Stores ini values in ServerSettings and ClientSettings - * - * @author Stefan Meyer - * @version $Id$ - */ -public class IniFileParser { - - Logger logger = LogManager.getLogger(IniFileParser.class); - - /** - * - */ - public IniFileParser() { - - } - - /** - * - * @param path - * @throws ConfigurationException - */ - public void parseServerSettings(String path, boolean parseClientSettings) throws ConfigurationException { - - Ini prefs; - ServerSettings serverSettings = ServerSettings.getInstance(); - ClientSettings clientSettings; - try { - - prefs = new Ini(new FileReader(path)); - for(Ini.Section section : prefs.values()) { - - if(section.getName().equals("Server")) { - if(section.containsKey("IpAddress")) - serverSettings.setHost(purgeString(section.get("IpAddress"))); - if(section.containsKey("Port")) - serverSettings.setPort(purgeString(section.get("Port"))); - if(section.containsKey("IndexPath")) - serverSettings.setIndexPath(purgeString(section.get("IndexPath"))); - if(section.containsKey("LogFile")) - serverSettings.setLogFile(purgeString(section.get("LogFile"))); - if(section.containsKey("LogLevel")) - serverSettings.setLogLevel(purgeString(section.get("LogLevel"))); - //serverSettings.initLogManager(); - if(section.containsKey("NumThreads")) - serverSettings.setThreadNumber(purgeString(section.get("NumThreads"))); - if(section.containsKey("RAMBufferSize")) - serverSettings.setRAMSize(purgeString(section.get("RAMBufferSize"))); - if(section.containsKey("IndexMaxFileSizeMB")) - serverSettings.setMaxFileSizeMB(purgeString(section.get("IndexMaxFileSizeMB"))); - } - if(section.getName().startsWith("Client") && parseClientSettings) { - if(section.containsKey("ClientId")) { - String client = purgeString(section.get("ClientId")); - String nic; - if(section.containsKey("NicId")) - nic = purgeString(section.get("NicId")); - else - nic = "0"; - clientSettings = ClientSettings.getInstance(client, nic); - if(section.containsKey("IliasIniPath")) { - clientSettings.setIliasIniFile(purgeString(section.get("IliasIniPath"))); - - // Now parse the ilias.ini file - parseClientData(clientSettings); - } - } - else { - logger.error("No ClientId given for section: " + section.getName()); - throw new ConfigurationException("No ClientId given for section: " + section.getName()); - } - } - } - - } - catch (ConfigurationException e) { - logger.error("Cannot parse server settings: " + e.getMessage()); - throw new ConfigurationException(e); - } - catch (IOException e) { - logger.error("Cannot parse server settings: " + e.getMessage()); - throw new ConfigurationException(e); - } - } - - /** - * @param clientSettings - * @throws ConfigurationException - */ - public void parseClientData(ClientSettings clientSettings) throws ConfigurationException { - - Preferences prefs; - try { - // parse ilias.ini.php - prefs = new IniPreferences(convertIniFile(clientSettings.getIliasIniFile())); - clientSettings.setDataDirectory(purgeString(prefs.node("clients").get("datadir",""),true)); - clientSettings.setAbsolutePath(purgeString(prefs.node("server").get("absolute_path",""),true)); - - String dataName = purgeString(prefs.node("clients").get("path", ""),true); - String iniFileName = purgeString(prefs.node("clients").get("inifile",""),true); - - clientSettings.setClientIniFile(clientSettings.getAbsolutePath().getCanonicalPath() + - System.getProperty("file.separator") + - dataName + System.getProperty("file.separator") + - clientSettings.getClient() + System.getProperty("file.separator") + - iniFileName); - clientSettings.setIndexPath(ServerSettings.getInstance().getIndexPath() + - System.getProperty("file.separator") + - clientSettings.getClientKey()); - // now parse client.ini.php - prefs = new IniPreferences(convertIniFile(clientSettings.getClientIniFile())); - - clientSettings.setDbType(purgeString(prefs.node("db").get("type",""),true)); - clientSettings.setDbHost(purgeString(prefs.node("db").get("host",""),true)); - clientSettings.setDbPort(purgeString(prefs.node("db").get("port",""),true)); - clientSettings.setDbUser(purgeString(prefs.node("db").get("user",""),true)); - clientSettings.setDbPass(purgeString(prefs.node("db").get("pass",""),true)); - clientSettings.setDbName(purgeString(prefs.node("db").get("name",""),true)); - - logger.debug("Client ID: " + clientSettings.getClient()); - logger.debug("DB Type: " + clientSettings.getDbType()); - logger.debug("DB Host: " +clientSettings.getDbHost()); - logger.debug("DB Port: " + clientSettings.getDbPort()); - logger.debug("DB Name: " +clientSettings.getDbName()); - logger.debug("DB User: " +clientSettings.getDbUser()); - logger.debug("DB Pass: " +clientSettings.getDbPass()); - - } - catch (IOException e) { - logger.error("Caught IOException when trying to parse client data: " + e.getMessage()); - throw new ConfigurationException(e); - } - catch (ConfigurationException e) { - logger.error("Caught ConfigurationException when trying to parse client data."); - throw e; - } - - } - - /** - * - * @param dirty - * @param replaceQuotes - * @return - */ - public String purgeString(String dirty,boolean replaceQuotes) { - - if(replaceQuotes) { - return dirty.replace('"',' ').trim(); - } - else { - return dirty.trim(); - } - } - - /** - * - * @param dirty - * @return - */ - public String purgeString(String dirty) { - - return purgeString(dirty,false); - } - - /** - * - * @return - * @throws ConfigurationException - */ - private StringReader convertIniFile(File iniFile) throws ConfigurationException { - - try { - String output; - InputStreamReader reader = new InputStreamReader(new FileInputStream(iniFile)); - - int c; - StringBuilder builder = new StringBuilder(); - - while((c = reader.read())!=-1){ - builder.append((char)c); - } - output = builder.toString(); - output = output.replaceFirst("<\\?php /\\*",""); - output = output.replaceFirst("\\*/ \\?>",""); - return new StringReader(output); - } - catch (FileNotFoundException e) { - logger.fatal("Cannot find ini file: " + e.getMessage()); - throw new ConfigurationException(e); - } - catch (IOException e) { - logger.error("Caught IOException when trying to convert ini file: " + e.getMessage()); - throw new ConfigurationException(e); - } - } - - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/LogConfigParser.java b/Services/WebServices/RPC/lib/src/de/ilias/services/settings/LogConfigParser.java deleted file mode 100644 index 82d7486d5d99..000000000000 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/LogConfigParser.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ -package de.ilias.services.settings; - -import java.io.FileReader; -import java.io.IOException; -import org.ini4j.Ini; - -/** - * - * @author stefan - */ -public class LogConfigParser { - - String file; - String level; - - - public String getLogLevel() - { - return this.level; - } - - public String getLogFile() - { - return this.file; - } - - - public void parse(String path) throws ConfigurationException { - - Ini prefs; - try { - - prefs = new Ini(new FileReader(path)); - for(Ini.Section section : prefs.values()) { - - if(section.getName().equals("Server")) { - if(section.containsKey("LogFile")) - this.file = purgeString(section.get("LogFile")); - if(section.containsKey("LogLevel")) - this.level = purgeString(section.get("LogLevel")); - } - } - } catch (IOException e) { - throw new ConfigurationException(e); - } - } - - /** - * @param dirty - * @param replaceQuotes - * @return - */ - public String purgeString(String dirty,boolean replaceQuotes) { - - if(replaceQuotes) { - return dirty.replace('"',' ').trim(); - } - else { - return dirty.trim(); - } - } - - /** - * - * @param dirty - * @return - */ - public String purgeString(String dirty) { - - return purgeString(dirty,false); - } - -} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/ilServer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServer.java similarity index 75% rename from Services/WebServices/RPC/lib/src/de/ilias/ilServer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServer.java index 9316a1db0a72..f70b90c4806c 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/ilServer.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServer.java @@ -22,97 +22,66 @@ package de.ilias; -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.util.Vector; - +import de.ilias.services.rpc.RPCServer; +import de.ilias.services.settings.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.client.XmlRpcClient; import org.apache.xmlrpc.client.XmlRpcClientConfigImpl; import org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory; -import de.ilias.services.rpc.RPCServer; -import de.ilias.services.settings.ClientSettings; -import de.ilias.services.settings.ConfigurationException; -import de.ilias.services.settings.IniFileParser; -import de.ilias.services.settings.LogConfigParser; -import de.ilias.services.settings.ServerSettings; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Vector; /** - * + * Main class * * @author Stefan Meyer - * @version $Id$ */ public class ilServer { - private String version = "4.4.0.1"; + private static final Logger logger = LogManager.getLogger(ilServer.class ); + private final String version = "4.4.0.1"; - private String[] arguments; + private final String[] arguments; private String command; - private static Logger logger = null; - - /** - * @param args - */ + public ilServer(String[] args) { arguments = args; } - /** - * @param args - */ - public static void main(String[] args) { - + public static void main(String[] args) + { ilServer server = null; server = new ilServer(args); boolean success = server.handleRequest(); System.exit(success ? 0 : 1); } - - - private boolean initLogging() + + private boolean handleRequest() { - LogConfigParser parser; - ServerSettings settings; - parser = new LogConfigParser(); - try { - parser.parse(arguments[0]); - settings = ServerSettings.getInstance(); - settings.setLogFile(parser.getLogFile()); - settings.setLogLevel(parser.getLogLevel()); - settings.initLogManager(); - // init after configuration - logger = LogManager.getLogger(ilServer.class); - return true; - - } catch (ConfigurationException | IOException ex) { - System.err.println("Failed to initialize logging: " + ex.getMessage()); - } - return false; - } - + Boolean status; - /** - * @return success status - */ - private boolean handleRequest() { - if(arguments.length < 1) { - System.err.println(this.getUsage()); + logger.error(this.getUsage()); return false; } - - if(!this.initLogging()) { - return false; + if (arguments.length >= 1) { + LogConfigManager logConfigManager = new LogConfigManager(); + try { + logConfigManager.parse(arguments[0]); + logConfigManager.initLogManager(); + } catch (ConfigurationException e) { + logger.error("Logging to ?"); + } } - + if(arguments.length == 1) { command = arguments[0]; if(command.compareTo("version") == 0) { @@ -130,28 +99,30 @@ private boolean handleRequest() { } else if(command.compareTo("stop") == 0) { if(arguments.length != 2) { - logger.error("Usage: java -jar ilServer.jar PATH_TO_SERVER_INI stop"); + System.err.println("Usage: java -jar ilServer.jar PATH_TO_SERVER_INI stop"); return false; } return stopServer(); } else if(command.compareTo("createIndex") == 0) { if(arguments.length != 3) { - logger.error("Usage java -jar ilServer.jar PATH_TO_SERVER_INI createIndex CLIENT_KEY"); + System.err.println("Usage java -jar ilServer.jar PATH_TO_SERVER_INI createIndex CLIENT_KEY"); return false; } - return createIndexer(); + status = createIndexer(); + logger.info("Finished creation of new index for client {}", arguments[2]); + return status; } else if(command.compareTo("updateIndex") == 0) { if(arguments.length < 3) { - logger.error("Usage java -jar ilServer.jar PATH_TO_SERVER_INI updateIndex CLIENT_KEY"); + System.err.println("Usage java -jar ilServer.jar PATH_TO_SERVER_INI updateIndex CLIENT_KEY"); return false; } return updateIndexer(); } else if(command.compareTo("search") == 0) { if(arguments.length != 4) { - logger.error("Usage java -jar ilServer.jar PATH_TO_SERVER_INI CLIENT_KEY search QUERY_STRING"); + System.err.println("Usage java -jar ilServer.jar PATH_TO_SERVER_INI CLIENT_KEY search QUERY_STRING"); return false; } return startSearch(); @@ -159,29 +130,25 @@ else if(command.compareTo("search") == 0) { } else if(command.compareTo("status") == 0) { if(arguments.length != 2) { - logger.error("Usage java -jar ilServer.jar PATH_TO_SERVER_INI status"); + System.err.println("Usage java -jar ilServer.jar PATH_TO_SERVER_INI status"); return false; } return getStatus(); } else { - logger.error(getUsage()); + System.err.println(getUsage()); return false; } } - /** - * @return - */ - @SuppressWarnings("unchecked") private boolean createIndexer() { XmlRpcClient client; - IniFileParser parser; + CommonsIniFileParser parser; try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],true); + parser = new CommonsIniFileParser(); + parser.parseSettings(arguments[0],true); if(!ClientSettings.exists(arguments[2])) { throw new ConfigurationException("Unknown client given: " + arguments[2]); @@ -192,29 +159,23 @@ private boolean createIndexer() { params.add(arguments[2]); params.add(false); client.execute("RPCIndexHandler.index",params); - return true; - } + logger.info("Finished indexing"); + } catch (Exception e) { - System.err.println(e); - logger.fatal(e.getMessage()); + logger.error(e.getMessage()); System.exit(1); } return false; } - /** - * @return - */ - @SuppressWarnings("unchecked") private boolean updateIndexer() { XmlRpcClient client; - IniFileParser parser; - - + CommonsIniFileParser parser; + try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],true); + parser = new CommonsIniFileParser(); + parser.parseSettings(arguments[0],true); if(!ClientSettings.exists(arguments[2])) { throw new ConfigurationException("Unknown client given: " + arguments[2]); @@ -225,11 +186,11 @@ private boolean updateIndexer() { params.add(arguments[2]); params.add(true); client.execute("RPCIndexHandler.index",params); + logger.info("Finished indexing"); return true; } catch (Exception e) { - System.err.println(e); - logger.fatal(e.getMessage()); + logger.error(e.getMessage()); System.exit(1); } return false; @@ -242,12 +203,11 @@ private boolean updateIndexer() { private boolean startSearch() { XmlRpcClient client; - IniFileParser parser; - - + CommonsIniFileParser parser; + try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],true); + parser = new CommonsIniFileParser(); + parser.parseSettings(arguments[0],true); if(!ClientSettings.exists(arguments[2])) { throw new ConfigurationException("Unknown client given: " + arguments[2]); @@ -263,8 +223,7 @@ private boolean startSearch() { return true; } catch (Exception e) { - System.err.println(e); - logger.fatal(e.getMessage()); + logger.error(e.getMessage()); System.exit(1); } return false; @@ -279,16 +238,18 @@ private boolean startServer() { ServerSettings settings; RPCServer rpc; XmlRpcClient client; - IniFileParser parser; + CommonsIniFileParser parser; String status; - - try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],true); - + try { + logger.debug("Start parsing"); + parser = new CommonsIniFileParser(); + logger.debug("Parser created"); + parser.parseSettings(arguments[0], true); + logger.debug("Parser parsed"); + settings = ServerSettings.getInstance(); client = initRpcClient(); - + // Check if server is already running try { status = (String) client.execute("RPCAdministration.status",new Vector()); @@ -299,15 +260,18 @@ private boolean startServer() { logger.info("No server running. Starting new instance..."); } - settings = ServerSettings.getInstance(); - logger.info("New rpc server"); + logger.info("Listening on {}:{}", settings.getHost(), settings.getPort()); rpc = RPCServer.getInstance(settings.getHost(),settings.getPort()); - logger.info("Server start"); + logger.info("Server started"); rpc.start(); client = initRpcClient(); client.execute("RPCAdministration.start",new Vector()); + //Vector params = new Vector(); + //params.add(arguments[0]); + //client.execute("RPCAdministration.initLogManager", params); + // Check if webserver is alive // otherwise stop execution while(true) { @@ -320,7 +284,7 @@ private boolean startServer() { logger.info("WebServer shutdown. Aborting..."); return true; - } + } catch (ConfigurationException e) { System.exit(1); return false; @@ -353,15 +317,16 @@ private boolean startServer() { private boolean stopServer() { XmlRpcClient client; - IniFileParser parser; + CommonsIniFileParser parser; try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],false); + parser = new CommonsIniFileParser(); + parser.parseSettings(arguments[0],false); client = initRpcClient(); logger.debug("Client execute"); client.execute("RPCAdministration.stop",new Vector()); + logger.info("Server stopped"); return true; } catch (ConfigurationException e) { @@ -376,23 +341,25 @@ private boolean stopServer() { return false; } - @SuppressWarnings("unchecked") private boolean getStatus() { XmlRpcClient client; - IniFileParser parser; + CommonsIniFileParser parser; ServerSettings settings; String status; try { - parser = new IniFileParser(); - parser.parseServerSettings(arguments[0],false); - + parser = new CommonsIniFileParser(); + parser.parseSettings(arguments[0],false); + settings = ServerSettings.getInstance(); client = initRpcClient(); status = (String) client.execute("RPCAdministration.status",new Vector()); System.out.println(status); + logger.info("RPC Status is {}", status); + status = ilServerStatus.getStatus(); + logger.info("Main Status is {}", status); return true; } catch (ConfigurationException e) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/ilServerStatus.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServerStatus.java similarity index 91% rename from Services/WebServices/RPC/lib/src/de/ilias/ilServerStatus.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServerStatus.java index 75cf7eb97c34..1a8f21e22b88 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/ilServerStatus.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/ilServerStatus.java @@ -22,20 +22,20 @@ package de.ilias; -import java.util.HashMap; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.util.HashMap; + public class ilServerStatus { public static final String RUNNING = "Runnning"; public static final String STOPPED = "Stopped"; public static final String INDEXING = "Indexing"; - private static Logger logger = LogManager.getLogger(ilServerStatus.class); + private static final Logger logger = LogManager.getLogger(ilServerStatus.class); - private static HashMap indexer = new HashMap(); + private static final HashMap indexer = new HashMap(); private static boolean active = false; @@ -75,11 +75,8 @@ public static boolean isIndexerActive(String clientKey) { * @param clientKey */ public static void removeIndexer(String clientKey) { - - if(indexer.containsKey(clientKey)) { - - indexer.remove(clientKey); - } + + indexer.remove(clientKey); } /** @@ -92,7 +89,8 @@ public static int getCountActiveIndexer() { } public static String getStatus() { - + + logger.warn("Get status called with status {}", isActive() ? RUNNING : STOPPED); if(getCountActiveIndexer() != 0) { return INDEXING + " (" + getCountActiveIndexer() + ")"; diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/db/DBFactory.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/db/DBFactory.java similarity index 72% rename from Services/WebServices/RPC/lib/src/de/ilias/services/db/DBFactory.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/db/DBFactory.java index f1efebf4d4ee..11d3c04aabfc 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/db/DBFactory.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/db/DBFactory.java @@ -22,36 +22,32 @@ package de.ilias.services.db; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.HashMap; - - -import org.apache.logging.log4j.LogManager; - import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; import de.ilias.services.settings.ServerSettings; -import oracle.jdbc.OraclePreparedStatement; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.sql.*; +import java.util.HashMap; + /** * A thread local singleton for db connections - * * @author Stefan Meyer - * @version $Id$ */ public class DBFactory { - private static Logger logger = LogManager.getLogger(DBFactory.class); + private static final Logger logger = LogManager.getLogger(DBFactory.class); - private static String MARIA_DB_CONNECTOR = "jdbc:mariadb://"; + private static final String MARIA_DB_CONNECTOR = "jdbc:mariadb://"; + + // valid db types + private static final String DB_TYPE_MYSQL = "mysql"; + private static final String DB_TYPE_INNODB = "innodb"; + - private static ThreadLocal> ps = new ThreadLocal>() { + private static final ThreadLocal> ps = new ThreadLocal>() { protected HashMap initialValue() { return new HashMap(); @@ -62,7 +58,7 @@ public void remove() { } }; - private static ThreadLocal connection = new ThreadLocal() { + private static final ThreadLocal connection = new ThreadLocal() { protected Connection initialValue() { try { @@ -71,73 +67,38 @@ protected Connection initialValue() { logger.info("+++++++++++++++++++++++++++++++++++++++++++ New Thread local " + LocalSettings.getClientKey()); - // MySQL - if(client.getDbType().equalsIgnoreCase("mysql")) { - - logger.info("Loading maria db driver..."); - logger.info("Using jdbc url: " + - client.getDbUrl() + "/" + - client.getDbUser() + "/" + - "******" + "?autoReconnect=true" - ); - - return DriverManager.getConnection( - DBFactory.MARIA_DB_CONNECTOR + - client.getDbUrl() + "?autoReconnect=true", - client.getDbUser(), - client.getDbPass() - ); - } - // Oracle - else if(client.getDbType().equalsIgnoreCase("oracle")) { - - logger.info("Loading Oracle driver..."); - Class.forName("oracle.jdbc.driver.OracleDriver"); - - if(client.getDbName().length() == 0) { - - String url = "jdbc:oracle:thin:" + client.getDbUser() + "/" + client.getDbPass() + "@" + client.getDbHost(); - String log = "jdbc:oracle:thin:" + client.getDbUser() + "/" + "******" + "@" + client.getDbHost(); - logger.info("Using tnsname.ora: " + log); - - try { - System.setProperty("oracle.net.tns_admin",server.lookupTnsAdmin()); - } - catch(SecurityException e) { - logger.error("Cannot connect to database: " + e); - return null; - } - catch(NullPointerException e) { - logger.error("No TNS_ADMIN given: " + e); - return null; - } - return DriverManager.getConnection(url); - } - - logger.info("Using URL: " + - client.getDbUrl() - ); - return DriverManager.getConnection(client.getDbUrl()); - } - else { + if (!isValidDatabaseType(client.getDbType())) { logger.error("Unsupported db type given." + client.getDbType()); throw new ConfigurationException("Unsupported db type given." + client.getDbType()); } + logger.info("Loading maria db driver..."); + logger.info("Using jdbc url: " + + client.getDbUrl() + "/" + + client.getDbUser() + "/" + + "******" + "?autoReconnect=true" + ); + + return DriverManager.getConnection( + DBFactory.MARIA_DB_CONNECTOR + + client.getDbUrl() + "?autoReconnect=true", + client.getDbUser(), + client.getDbPass() + ); } - catch (SQLException e) { - logger.error("Cannot connect to database: " + e); - } - catch (ConfigurationException e) { + catch (SQLException | ConfigurationException e) { logger.error("Cannot connect to database: " + e); - } - catch (ClassNotFoundException e) { - // no oracle driver! - logger.error(e); - logger.error("Could not load the JDBC driver."); } return null; } + protected boolean isValidDatabaseType(String dbType) + { + if (dbType.equalsIgnoreCase(DBFactory.DB_TYPE_MYSQL) || dbType.equalsIgnoreCase(DBFactory.DB_TYPE_INNODB)) { + return true; + } + return false; + } + /** * @see java.lang.ThreadLocal#remove() */ @@ -148,20 +109,17 @@ public void remove() { }; - + /** * get singleton db connection for each url - * @param url - * @param user - * @param pass * @return Connection * @throws SQLException */ public static Connection factory() throws SQLException { logger.debug("====================================== Used cached DB connector."); - return (Connection) connection.get(); + return connection.get(); } public static void init() { @@ -226,7 +184,7 @@ public static void closeAll() { // Close connection } catch (SQLException e) { - logger.warn("Cannot close prepared statement: " + pst.toString()); + logger.warn("Cannot close prepared statement: " + pst); logger.warn(e); } catch (Throwable t) { @@ -261,24 +219,18 @@ public static PreparedStatement setString(PreparedStatement ps,int index,String ClientSettings client; try { - client = ClientSettings.getInstance(LocalSettings.getClientKey()); if(client.getDbType().equals("mysql")) { ps.setString(index, str); return ps; } - else { - - ((OraclePreparedStatement) ps).setFixedCHAR(index, str); - return (PreparedStatement) ps; - } } catch (ConfigurationException e) { // shouldn't happen here logger.error(e); } - return (PreparedStatement) ps; + return ps; } /** diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/io/ilNullPrintStream.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/io/ilNullPrintStream.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/io/ilNullPrintStream.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/io/ilNullPrintStream.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandController.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandController.java similarity index 89% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandController.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandController.java index 3ce0da110e05..e5bdcc674d55 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandController.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandController.java @@ -52,7 +52,7 @@ */ public class CommandController { - private static ThreadLocal instance = new ThreadLocal() { + private static final ThreadLocal instance = new ThreadLocal() { /** * Init value @@ -75,16 +75,11 @@ protected CommandController initialValue() { private Vector finished = new Vector(); private CommandQueue queue; - private ObjectDefinitions objDefinitions; - private IndexHolder holder; + private final ObjectDefinitions objDefinitions; + private final IndexHolder holder; /** - * @throws SQLException - * @throws ConfigurationException - * @throws IOException - * @throws LockObtainFailedException - * @throws CorruptIndexException - * + * */ private CommandController(ObjectDefinitions objDefinitions) throws SQLException, @@ -104,12 +99,7 @@ private CommandController(ObjectDefinitions objDefinitions) throws } /** - * @throws ConfigurationException - * @throws IOException - * @throws SQLException - * @throws LockObtainFailedException - * @throws CorruptIndexException - * + * */ public CommandController() throws CorruptIndexException, LockObtainFailedException, SQLException, IOException, ConfigurationException { @@ -120,14 +110,8 @@ public CommandController() } /** - * - * @return - * @throws CorruptIndexException - * @throws LockObtainFailedException - * @throws SQLException - * @throws IOException - * @throws ConfigurationException - */ + * + */ public static CommandController getInstance() { try { @@ -158,8 +142,7 @@ public Vector getFinished() { /** * Init command queue for new index - * @throws SQLException - */ + */ public void initCreate() throws SQLException { queue.deleteAll(); @@ -177,9 +160,7 @@ public void initRefresh() throws SQLException, ConfigurationException { /** * Load queue elements from given obj ids list - * @param objIds - * @throws SQLException - */ + */ public void initObjects(Vector objIds) throws SQLException { queue.loadFromObjectList(objIds); @@ -269,8 +250,7 @@ else if(command.equals("delete")) { } /** - * @param finished - */ + */ public synchronized boolean writeToIndex() { try { @@ -341,11 +321,7 @@ public synchronized void closeIndex() { /** - * @param el - * @throws CorruptIndexException - * @throws ObjectDefinitionException - * @throws DocumentHandlerException - */ + */ private void addDocument(CommandQueueElement el) throws CorruptIndexException, ObjectDefinitionException { ObjectDefinition definition; @@ -364,13 +340,10 @@ private void addDocument(CommandQueueElement el) throws CorruptIndexException, O } /** - * @param el - * @throws IOException - * @throws CorruptIndexException - */ + */ private void deleteDocument(CommandQueueElement el) throws CorruptIndexException, IOException { - logger.debug("Deleteing document with objId: " + String.valueOf(el.getObjId())); + logger.debug("Deleteing document with objId: " + el.getObjId()); holder.getWriter().deleteDocuments(new Term("objId",String.valueOf(el.getObjId()))); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandControllerThread.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandControllerThread.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandControllerThread.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandControllerThread.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandQueue.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandQueue.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandQueue.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandQueue.java index a311d2df47d8..6a454c2a59df 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandQueue.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandQueue.java @@ -43,7 +43,7 @@ /** - * @todo make this class thread safe + * {@code @todo} make this class thread safe * * @author Stefan Meyer * @version $Id$ @@ -53,12 +53,11 @@ public class CommandQueue { protected Logger logger = LogManager.getLogger(CommandQueue.class); private Connection db = null; - private Vector elements = new Vector(); + private final Vector elements = new Vector(); private int currentIndex = 0; /** - * @throws SQLException - * + * */ public CommandQueue() throws SQLException { @@ -68,12 +67,11 @@ public CommandQueue() throws SQLException { /** * - * @param el - * @throws SQLException, IllegalArgumentException + * @throws SQLException, IllegalArgumentException */ public void setFinished(CommandQueueElement el) throws SQLException, IllegalArgumentException { - if(getElements().removeElement(el) == false) { + if(!getElements().removeElement(el)) { throw new IllegalArgumentException("Cannot find element!"); } @@ -93,10 +91,8 @@ public void setFinished(CommandQueueElement el) throws SQLException, IllegalArgu } /** - * - * @param objIds - * @throws SQLException - */ + * + */ public void setFinished(Vector objIds) throws SQLException { if(objIds.size() == 0) { @@ -114,8 +110,7 @@ public void setFinished(Vector objIds) throws SQLException { /** - * @throws SQLException - * + * */ public synchronized void loadFromDb() throws SQLException { @@ -160,9 +155,8 @@ public synchronized void loadFromDb() throws SQLException { /** - * - * @param objIds - */ + * + */ public synchronized void loadFromObjectList(Vector objIds) throws SQLException { @@ -204,8 +198,7 @@ public synchronized void loadFromObjectList(Vector objIds) throws SQLEx /** - * @throws SQLException - * + * */ private synchronized void substituteResetCommands() throws SQLException { @@ -238,8 +231,7 @@ private synchronized void substituteResetCommands() throws SQLException { } /** - * @param string - * @throws SQLException + * @throws SQLException */ private synchronized void deleteResetCommandByType(String objType) throws SQLException { @@ -260,8 +252,7 @@ private synchronized void deleteResetCommandByType(String objType) throws SQLExc } /** - * @param string - * @throws SQLException + * @throws SQLException */ public synchronized void deleteCommandsByType(String objType) throws SQLException { @@ -281,8 +272,7 @@ public synchronized void deleteCommandsByType(String objType) throws SQLExceptio } /** - * @param string - * @throws SQLException + * @throws SQLException */ private synchronized void addCommandsByType(String objType) throws SQLException { @@ -291,13 +281,13 @@ private synchronized void addCommandsByType(String objType) throws SQLException ResultSet res = null; PreparedStatement sta = null; - if(objType.equalsIgnoreCase("help") == true) { + if(objType.equalsIgnoreCase("help")) { sta = DBFactory.getPreparedStatement( "SELECT lm_id obj_id FROM help_module " ); } - else if(objType.equalsIgnoreCase("usr") != true) + else if(!objType.equalsIgnoreCase("usr")) { sta = DBFactory.getPreparedStatement( "SELECT DISTINCT(oda.obj_id) FROM object_data oda JOIN object_reference ore ON oda.obj_id = ore.obj_id " + @@ -385,8 +375,7 @@ public synchronized Vector getElements() { /** * * @param type - * @throws SQLException - */ + */ public synchronized void debug(String type) throws SQLException { PreparedStatement resetType = DBFactory.getPreparedStatement( @@ -410,8 +399,7 @@ public synchronized void debug(String type) throws SQLException { /** * Delete and add all types - * @throws SQLException - */ + */ public synchronized void addAll() throws SQLException { try { @@ -461,8 +449,7 @@ public synchronized void addAll() throws SQLException { /** * Delete command queue - * @throws SQLException - */ + */ public synchronized void deleteAll() throws SQLException { logger.info("Deleting search_command_queue"); @@ -481,9 +468,7 @@ public synchronized void deleteAll() throws SQLException { /** * Delete non incremental search command queue elements - * @throws java.sql.SQLException - * @throws de.ilias.services.settings.ConfigurationException - */ + */ public synchronized void deleteNonIncremental() throws SQLException, ConfigurationException { try { @@ -509,9 +494,7 @@ public synchronized void deleteNonIncremental() throws SQLException, Configurat /** * Add non incremental search command queue elements - * @throws java.sql.SQLException - * @throws de.ilias.services.settings.ConfigurationException - */ + */ public synchronized void addNonIncremental() throws SQLException, ConfigurationException { try { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandQueueElement.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandQueueElement.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/CommandQueueElement.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/CommandQueueElement.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHandler.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHandler.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHandlerException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHandlerException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHandlerException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHandlerException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHolder.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHolder.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHolder.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHolder.java index bcd33d8b89e0..481c27908b50 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/DocumentHolder.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/DocumentHolder.java @@ -40,7 +40,7 @@ public class DocumentHolder { protected static Logger logger = LogManager.getLogger(DocumentHolder.class); - private static ThreadLocal thDocumentHolder = new ThreadLocal() { + private static final ThreadLocal thDocumentHolder = new ThreadLocal() { /** * init document holder @@ -114,11 +114,7 @@ public Document getDocument() { } /** - * @param String name - * @param String value - * @param Field.Store store - * @param boolean index - */ + */ public void add(String name, String value,boolean isGlobal,Field.Store store, boolean indexed) { if(indexed) { @@ -134,6 +130,5 @@ public void add(String name, String value,boolean isGlobal,Field.Store store, bo getGlobalDocument().add(new StringField(name, value, store)); } } - return; - } + } } \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfo.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfo.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfo.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfo.java index 49dccbb08487..a14d02f8466c 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfo.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfo.java @@ -40,8 +40,8 @@ public class FieldInfo { protected static Logger logger = LogManager.getLogger(FieldInfo.class); - private static HashMap instances = new HashMap(); - private Vector fields = new Vector(); + private static final HashMap instances = new HashMap(); + private final Vector fields = new Vector(); /** * @@ -84,8 +84,7 @@ public void addField(String field) { if(!fields.contains(field)) { fields.add(field); } - return; - } + } /** * Get fields as Vector diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfoUser.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfoUser.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfoUser.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfoUser.java index 0bdc5dd69fc1..aba21e3d95bb 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/FieldInfoUser.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/FieldInfoUser.java @@ -38,8 +38,8 @@ public class FieldInfoUser { protected static Logger logger = LogManager.getLogger(FieldInfoUser.class); - private static HashMap instances = new HashMap(); - private Vector fields = new Vector(); + private static final HashMap instances = new HashMap(); + private final Vector fields = new Vector(); /** * @@ -82,8 +82,7 @@ public void addField(String field) { if(!fields.contains(field)) { fields.add(field); } - return; - } + } /** * Get fields as Vector diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexDirectoryFactory.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexDirectoryFactory.java similarity index 93% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexDirectoryFactory.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexDirectoryFactory.java index ed7391a7ffe1..2fe8442b5a46 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexDirectoryFactory.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexDirectoryFactory.java @@ -34,7 +34,7 @@ public static FSDirectory getDirectory(File indexPath) throws IOException { return NIOFSDirectory.open(indexPath.toPath()); } catch(IOException e) { - logger.warn("Cannot create path for file: " + indexPath.toString()); + logger.warn("Cannot create path for file: " + indexPath); throw e; } } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexHolder.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexHolder.java similarity index 77% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexHolder.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexHolder.java index 19fec2769214..05b36002b983 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexHolder.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexHolder.java @@ -22,47 +22,40 @@ package de.ilias.services.lucene.index; -import de.ilias.services.lucene.settings.LuceneSettings; -import java.io.File; -import java.io.IOException; -import java.util.HashMap; -import java.util.logging.Level; - -import org.apache.logging.log4j.LogManager; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.index.CorruptIndexException; -import org.apache.lucene.index.IndexWriter; import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; import de.ilias.services.settings.ServerSettings; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; +import java.io.File; +import java.io.IOException; +import java.util.HashMap; + /** - * Capsulates the interaction between IndexReader and IndexWriter + * Capsules the interaction between IndexReader and IndexWriter * This class is a singleton for each index path. * * @author Stefan Meyer - * @version $Id$ */ -public class IndexHolder { +public class IndexHolder implements AutoCloseable +{ protected static Logger logger = LogManager.getLogger(IndexHolder.class); public static final int MAX_NUM_SEGMENTS = 100; - private static HashMap instances = new HashMap(); - private ClientSettings settings; + private static final HashMap instances = new HashMap(); + private final ClientSettings settings; private IndexWriter writer; - /** - * @param indexPath - * @param indexType - * @throws IOException - */ private IndexHolder(String clientKey) throws IOException { try { @@ -74,30 +67,16 @@ private IndexHolder(String clientKey) throws IOException { } - /** - * - * @param clientKey - * @return - * @throws IOException - */ - public static synchronized IndexHolder getInstance(String clientKey) throws - IOException { - - String hash = clientKey; - - if(instances.containsKey(hash)) { - return instances.get(hash); + public static synchronized IndexHolder getInstance(String clientKey) throws + IOException { + + if(instances.containsKey(clientKey)) { + return instances.get(clientKey); } - instances.put(hash,new IndexHolder(clientKey)); - return instances.get(hash); + instances.put(clientKey,new IndexHolder(clientKey)); + return instances.get(clientKey); } - /** - * - * @param indexType - * @return - * @throws IOException - */ public static synchronized IndexHolder getInstance() throws IOException { return getInstance(LocalSettings.getClientKey()); @@ -111,16 +90,11 @@ public static void deleteIndex() throws ConfigurationException logger.info("Deleted index directory: " + indexPath.getAbsoluteFile()); } - /** - * Delete directory recursive - * @param path - * @return - */ - private static boolean deleteTree(File path) { + private static void deleteTree(File path) { if(!path.exists() || !path.isDirectory()) { - return false; + return; } for(File del : path.listFiles()) { @@ -132,21 +106,17 @@ private static boolean deleteTree(File path) { } } path.delete(); - return true; } - /** - * Close all writers - */ public static synchronized void closeAllWriters() { logger.info("Closing document writers..."); - for(Object key : instances.keySet()) { + for(String key : instances.keySet()) { try { - logger.info("Closing writer: " + (String) key); - IndexHolder holder = instances.get((String) key); - IndexDirectoryFactory.getDirectory(ClientSettings.getInstance((String) key).getIndexPath()).close(); + logger.info("Closing writer: " + key); + IndexHolder holder = instances.get(key); + IndexDirectoryFactory.getDirectory(ClientSettings.getInstance(key).getIndexPath()).close(); holder.close(); } catch (ConfigurationException | IOException ex) @@ -161,7 +131,6 @@ public static synchronized void closeAllWriters() { /** * @todo obtain lock for index writer - * @throws IOException */ public void init() throws IOException, ConfigurationException { @@ -185,16 +154,10 @@ public void init() throws IOException, ConfigurationException { } - /** - * @return the writer - */ public IndexWriter getWriter() { return writer; } - /** - * @param writer the writer to set - */ public void setWriter(IndexWriter writer) { this.writer = writer; } @@ -214,18 +177,4 @@ public void close() { logger.fatal("Error closing writer." + e); } } - - /* (non-Javadoc) - * @see java.lang.Object#finalize() - */ - @Override - protected void finalize() throws Throwable { - - try { - close(); - } - finally { - super.finalize(); - } - } } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexerException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexerException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/IndexerException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/IndexerException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/RPCIndexHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/RPCIndexHandler.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/RPCIndexHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/RPCIndexHandler.java diff --git a/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/ExtensionFileHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/ExtensionFileHandler.java new file mode 100644 index 000000000000..c44aaa0a2d7f --- /dev/null +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/ExtensionFileHandler.java @@ -0,0 +1,152 @@ +/* + +-----------------------------------------------------------------------------+ + | ILIAS open source | + +-----------------------------------------------------------------------------+ + | Copyright (c) 1998-2001 ILIAS open source, University of Cologne | + | | + | This program is free software; you can redistribute it and/or | + | modify it under the terms of the GNU General Public License | + | as published by the Free Software Foundation; either version 2 | + | of the License, or (at your option) any later version. | + | | + | This program is distributed in the hope that it will be useful, | + | but WITHOUT ANY WARRANTY; without even the implied warranty of | + | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | + | GNU General Public License for more details. | + | | + | You should have received a copy of the GNU General Public License | + | along with this program; if not, write to the Free Software | + | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | + +-----------------------------------------------------------------------------+ +*/ + +package de.ilias.services.lucene.index.file; + + +import de.ilias.services.settings.ConfigurationException; +import de.ilias.services.settings.ServerSettings; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.tika.exception.TikaException; +import org.apache.tika.metadata.Metadata; +import org.apache.tika.parser.AutoDetectParser; +import org.apache.tika.sax.BodyContentHandler; +import org.xml.sax.SAXException; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; + +/** + * + * + * @author Stefan Meyer + * @version $Id$ + */ +public class ExtensionFileHandler { + + protected static Logger logger = LogManager.getLogger(ExtensionFileHandler.class); + + + public ExtensionFileHandler() { + // Do nothing here + } + + /** + * + * @param file + * @return + * @throws FileHandlerException + */ + public String getContent(File file, String extension) throws FileHandlerException { + + // Stop here if no read permission is given + if(!file.canRead()) { + throw new FileHandlerException("No permission to read file: " + file.getAbsolutePath()); + } + + // Check file size + if(!checkFileSizeLimit(file)) { + throw new FileHandlerException("File size limit exceeded. Ignoring file " + file.getAbsolutePath()); + } + logger.info("Current file is: " + file.getAbsolutePath()); + String content = tryTikaParser(file); + if (content != "") { + return content; + } + try { + String fname = file.getName(); + int dotIndex = fname.lastIndexOf("."); + if ((extension.length() == 0) + && (dotIndex > 0) + && (dotIndex < fname.length())) { + extension = fname.substring(dotIndex + 1); + } + if (extension.equalsIgnoreCase("")) { + logger.warn("no valid extension found for: " + file.getName()); + return ""; + } + } + catch(Exception e) { + logger.warn("Parsing failed with message: " + e); + return ""; + } + return ""; + } + + private String tryTikaParser(File file) { + FileInputStream is = null; + BodyContentHandler handler = new BodyContentHandler(-1); + Metadata md = new Metadata(); + AutoDetectParser parser = new AutoDetectParser(); + + try { + is = new FileInputStream(file); + parser.parse(is, handler, md); + logger.info("Parsed content: {}", handler.toString()); + return handler.toString(); + } catch (FileNotFoundException e) { + logger.warn(e); + } catch (TikaException e) { + logger.warn(e); + } catch (IOException e) { + logger.warn(e); + } catch (SAXException e) { + logger.warn(e); + } finally { + try { + if(is != null) { + is.close(); + } + } + catch(IOException e) { + // Nothing + } + } + return ""; + } + + /** + * Check file size limit + * @param file + * @return bool + */ + private boolean checkFileSizeLimit(File file) + { + long maxFileSize = 0; + + try { + maxFileSize = ServerSettings.getInstance().getMaxFileSize(); + } + catch(ConfigurationException e) { + maxFileSize = ServerSettings.DEFAULT_MAX_FILE_SIZE; + } + + if(file.length() > maxFileSize) { + logger.info("File size is " + file.length() + " bytes."); + return false; + } + return true; + } +} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/FileHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/FileHandler.java similarity index 93% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/FileHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/FileHandler.java index a099dc300550..c275052b4040 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/FileHandler.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/FileHandler.java @@ -40,12 +40,12 @@ public interface FileHandler { * @throws FileHandlerException * @throws IOException */ - public String getContent(InputStream is) throws FileHandlerException, IOException; + String getContent(InputStream is) throws FileHandlerException, IOException; /** * * @param is * @return */ - public InputStream transformStream(InputStream is); + InputStream transformStream(InputStream is); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/FileHandlerException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/FileHandlerException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/FileHandlerException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/FileHandlerException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java similarity index 87% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java index 6f8af5a971e6..b34c4dca9a5f 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/ExerciseAssignmentPathCreator.java @@ -42,15 +42,15 @@ public File buildFile(CommandQueueElement el, ResultSet res) fullPath.append("ilExercise"); fullPath.append(System.getProperty("file.separator")); fullPath.append(PathUtils.buildSplittedPathFromId(objId,"exc")); - fullPath.append("ass_" + String.valueOf(DBFactory.getInt(res, "id"))); + fullPath.append("ass_" + DBFactory.getInt(res, "id")); - logger.info("Try to read from path: " + fullPath.toString()); + logger.info("Try to read from path: " + fullPath); file = new File(fullPath.toString()); if(file.exists() && file.canRead()) { return file; } - throw new PathCreatorException("Cannot access directory: " + fullPath.toString()); + throw new PathCreatorException("Cannot access directory: " + fullPath); } catch (ConfigurationException e) { throw new PathCreatorException(e); @@ -63,13 +63,6 @@ public File buildFile(CommandQueueElement el, ResultSet res) } } - /** - * - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return buildFile(el, null); - } @Override public String getExtension(CommandQueueElement el, ResultSet res) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileListPathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileListPathCreator.java similarity index 88% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileListPathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileListPathCreator.java index 4be9723635b8..569318ba9dfb 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileListPathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileListPathCreator.java @@ -22,24 +22,25 @@ package de.ilias.services.lucene.index.file.path; -import java.io.File; -import java.sql.ResultSet; -import java.sql.SQLException; - import de.ilias.services.db.DBFactory; import de.ilias.services.lucene.index.CommandQueueElement; import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.File; +import java.sql.ResultSet; +import java.sql.SQLException; /** - * - * * @author Stefan Meyer - * @version $Id$ */ public class FileListPathCreator implements PathCreator { + protected static Logger logger = LogManager.getLogger(FileListPathCreator.class); + protected String basePath = "ilFiles"; @@ -72,14 +73,8 @@ public String getBasePath() { } - /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement, java.sql.ResultSet) - */ - public File buildFile(CommandQueueElement el, ResultSet res) - throws PathCreatorException { - - - + public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorException + { StringBuilder fullPath = new StringBuilder(); StringBuilder versionPath = new StringBuilder(); @@ -116,10 +111,10 @@ public File buildFile(CommandQueueElement el, ResultSet res) return file; } if(!file.exists()) { - throw new PathCreatorException("Cannot find file: " + fullPath.toString()); + throw new PathCreatorException("Cannot find file: " + fullPath); } if(!file.canRead()) { - throw new PathCreatorException("Cannot read file: " + fullPath.toString()); + throw new PathCreatorException("Cannot read file: " + fullPath); } return null; } @@ -134,14 +129,6 @@ public File buildFile(CommandQueueElement el, ResultSet res) } } - /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement) - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return buildFile(el, null); - } - @Override public String getExtension(CommandQueueElement el, ResultSet res) { @@ -150,7 +137,7 @@ public String getExtension(CommandQueueElement el, ResultSet res) { String fileName = res.getString("file_name"); int dotIndex = fileName.lastIndexOf("."); if((dotIndex > 0) && (dotIndex < fileName.length())) { - extension.append(fileName.substring(dotIndex + 1, fileName.length())); + extension.append(fileName.substring(dotIndex + 1)); } } catch (SQLException ex) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileListPathCreator41.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileListPathCreator41.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileListPathCreator41.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileListPathCreator41.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java similarity index 91% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java index 3dce970e7f40..42a265814394 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator.java @@ -74,8 +74,7 @@ public String getBasePath() { /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement, java.sql.ResultSet) - */ + */ public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorException { @@ -117,10 +116,10 @@ public File buildFile(CommandQueueElement el, ResultSet res) return file; } if(!file.exists()) { - throw new PathCreatorException("Cannot find file: " + fullPath.toString()); + throw new PathCreatorException("Cannot find file: " + fullPath); } if(!file.canRead()) { - throw new PathCreatorException("Cannot read file: " + fullPath.toString()); + throw new PathCreatorException("Cannot read file: " + fullPath); } return null; } @@ -135,13 +134,6 @@ public File buildFile(CommandQueueElement el, ResultSet res) } } - /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement) - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return buildFile(el, null); - } @Override public String getExtension(CommandQueueElement el, ResultSet res) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator41.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator41.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator41.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator41.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java similarity index 79% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java index 631a09d75c04..297918be612c 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/FileObjectPathCreator7.java @@ -2,9 +2,6 @@ package de.ilias.services.lucene.index.file.path; -import java.io.File; -import java.sql.ResultSet; -import java.sql.SQLException; import de.ilias.services.lucene.index.CommandQueueElement; import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; @@ -12,6 +9,10 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.io.File; +import java.sql.ResultSet; +import java.sql.SQLException; + /** * @@ -46,8 +47,7 @@ public String getBasePath() { /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement, java.sql.ResultSet) - */ + */ public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorException { @@ -72,19 +72,19 @@ public File buildFile(CommandQueueElement el, ResultSet res) fullPath.append(res.getString("resource_path")); versionPath.append(fullPath); versionPath.append(System.getProperty("file.separator")); - versionPath.append(String.valueOf(versionCode)); + versionPath.append(versionCode); versionPath.append(System.getProperty("file.separator")); versionPath.append(BIN_NAME); - logger.info("Detected file object path is: " + versionPath.toString()); + logger.info("Detected file object path is: " + versionPath); file = new File(versionPath.toString()); if (!file.exists()) { - throw new PathCreatorException("Cannot find file: " + fullPath.toString()); + throw new PathCreatorException("Cannot find file: " + fullPath); } if (!file.canRead()) { - throw new PathCreatorException("Cannot read file: " + fullPath.toString()); + throw new PathCreatorException("Cannot read file: " + fullPath); } return file; @@ -94,13 +94,6 @@ public File buildFile(CommandQueueElement el, ResultSet res) } } - /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildPath(de.ilias.services.lucene.index.CommandQueueElement) - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return buildFile(el, null); - } @Override public String getExtension(CommandQueueElement el, ResultSet res) { @@ -110,9 +103,9 @@ public String getExtension(CommandQueueElement el, ResultSet res) { String fileName = res.getString("file_name"); int dotIndex = fileName.lastIndexOf("."); if((dotIndex > 0) && (dotIndex < fileName.length())) { - extension.append(fileName.substring(dotIndex + 1, fileName.length())); + extension.append(fileName.substring(dotIndex + 1)); } - logger.info("Extraced extension: " + extension.toString() + " from file name: " + fileName); + logger.info("Extracted extension: " + extension + " from file name: " + fileName); } catch (SQLException ex) { logger.error(ex.toString()); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java similarity index 91% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java index 412324aaf245..33aaf94a57be 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/HTLMObjectPathCreator.java @@ -59,25 +59,18 @@ public File buildFile(CommandQueueElement el, ResultSet res) fullPath.append("lm_data"); fullPath.append(System.getProperty("file.separator")); fullPath.append("lm_"); - fullPath.append(String.valueOf(objId)); + fullPath.append(objId); file = new File(fullPath.toString()); if(file.exists() && file.canRead()) { return file; } - throw new PathCreatorException("Cannot access directory: " + fullPath.toString()); + throw new PathCreatorException("Cannot access directory: " + fullPath); } catch (ConfigurationException e) { throw new PathCreatorException(e); } } - /** - * @see de.ilias.services.lucene.index.file.path.PathCreator#buildFile(de.ilias.services.lucene.index.CommandQueueElement) - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return buildFile(el, null); - } @Override public String getExtension(CommandQueueElement el, ResultSet res) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java similarity index 81% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java index ff788604f7ff..3b1e51b1b712 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/MailAttachmentPathCreator.java @@ -8,11 +8,12 @@ import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.File; import java.sql.ResultSet; import java.sql.SQLException; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; /** * @@ -37,15 +38,15 @@ public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorE fullPath.append("mail"); fullPath.append(System.getProperty("file.separator")); - fullPath.append(String.valueOf(DBFactory.getString(res, "path"))); + fullPath.append(DBFactory.getString(res, "path")); - logger.info("Try to read from path: " + fullPath.toString()); + logger.info("Try to read from path: " + fullPath); file = new File(fullPath.toString()); if(file.exists() && file.canRead()) { return file; } - throw new PathCreatorException("Cannot access directory: " + fullPath.toString()); + throw new PathCreatorException("Cannot access directory: " + fullPath); } catch (ConfigurationException e) { throw new PathCreatorException(e); @@ -59,18 +60,6 @@ public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorE } - /** - * not used - * @todo check and throw exception - * @param el - * @return - * @throws PathCreatorException - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException { - - return this.buildFile(el, null); - - } @Override public String getExtension(CommandQueueElement el, ResultSet res) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreator.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreator.java similarity index 72% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreator.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreator.java index 2c4802fb67c9..68e1d3376013 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreator.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreator.java @@ -22,48 +22,19 @@ package de.ilias.services.lucene.index.file.path; +import de.ilias.services.lucene.index.CommandQueueElement; + import java.io.File; import java.sql.ResultSet; -import org.apache.logging.log4j.LogManager; - -import de.ilias.services.lucene.index.CommandQueueElement; -import org.apache.logging.log4j.Logger; - /** - * - * + * Interface for file system path creation. * @author Stefan Meyer - * @version $Id$ */ -public interface PathCreator { +public interface PathCreator +{ - public static Logger logger = LogManager.getLogger(PathCreator.class); - - - /** - * Build absolute file path - * @param el - * @param res - * @return - * @throws PathCreatorException - */ - public File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorException; + File buildFile(CommandQueueElement el, ResultSet res) throws PathCreatorException; - /** - * Build absolute file path - * @param el - * @return - * @throws PathCreatorException - */ - public File buildFile(CommandQueueElement el) throws PathCreatorException; - - - /** - * - * @param el - * @param res - * @return String - */ - public String getExtension(CommandQueueElement el, ResultSet res); + String getExtension(CommandQueueElement el, ResultSet res); } \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreatorException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreatorException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreatorException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreatorException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java similarity index 83% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java index 6a7d54832a82..f530b89e04fd 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathCreatorFactory.java @@ -35,33 +35,33 @@ */ public class PathCreatorFactory { - private static Logger logger = LogManager.getLogger(PathCreator.class); + private static final Logger logger = LogManager.getLogger(PathCreator.class); public static PathCreator factory(String name) throws ObjectDefinitionException { if(name.equalsIgnoreCase("FileObjectPathCreator")) { - return (PathCreator) new FileObjectPathCreator(); + return new FileObjectPathCreator(); } if(name.equalsIgnoreCase("FileListPathCreator")) { - return (PathCreator) new FileListPathCreator(); + return new FileListPathCreator(); } if(name.equalsIgnoreCase("FileObjectPathCreator41")) { - return (PathCreator) new FileObjectPathCreator41(); + return new FileObjectPathCreator41(); } if(name.equalsIgnoreCase("FileListPathCreator41")) { - return (PathCreator) new FileListPathCreator41(); + return new FileListPathCreator41(); } if(name.equalsIgnoreCase("HTLMObjectPathCreator")) { - return (PathCreator) new HTLMObjectPathCreator(); + return new HTLMObjectPathCreator(); } if(name.equalsIgnoreCase("ExerciseAssignmentPathCreator")) { - return (PathCreator) new ExerciseAssignmentPathCreator(); + return new ExerciseAssignmentPathCreator(); } if(name.equalsIgnoreCase("MailAttachmentPathCreator")) { - return (PathCreator) new MailAttachmentPathCreator(); + return new MailAttachmentPathCreator(); } if(name.equalsIgnoreCase("FileObjectPathCreator7")) { - return (PathCreator) new FileObjectPathCreator7(); + return new FileObjectPathCreator7(); } throw new ObjectDefinitionException("Invalid path creator name given: " + name); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathUtils.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathUtils.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathUtils.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathUtils.java index 17ab43fcc332..39232239a903 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/file/path/PathUtils.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/file/path/PathUtils.java @@ -91,7 +91,7 @@ public static String buildSplittedPathFromId(int objId, String name) { } fullPath.append(name); fullPath.append('_'); - fullPath.append(String.valueOf(objId)); + fullPath.append(objId); fullPath.append(System.getProperty("file.separator")); return fullPath.toString(); @@ -108,18 +108,18 @@ public static String buildVersionDirectory(int version) { if(version < 10) { directoryName.append("00"); - directoryName.append(String.valueOf(version)); + directoryName.append(version); return directoryName.toString(); } else if(version < 100) { directoryName.append("0"); - directoryName.append(String.valueOf(version)); + directoryName.append(version); return directoryName.toString(); } else { - directoryName.append(String.valueOf(version)); + directoryName.append(version); return directoryName.toString(); } } diff --git a/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java new file mode 100644 index 000000000000..44b233c46335 --- /dev/null +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentObjectTransformer.java @@ -0,0 +1,53 @@ + +package de.ilias.services.lucene.index.transform; + +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; +import org.xml.sax.XMLReader; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParserFactory; +import java.io.IOException; +import java.io.StringReader; + +/** + * @author Stefan Meyer + */ +public class ContentObjectTransformer implements ContentTransformer { + + protected Logger logger = LogManager.getLogger(ContentObjectTransformer.class); + + /** + * Extract text from page_objects + * @see de.ilias.services.lucene.index.transform.ContentTransformer#transform(java.lang.String) + */ + public String transform(String content) { + + XMLReader reader; + PageObjectHandler handler; + StringReader stringReader = new StringReader(content); + + try { + reader = SAXParserFactory.newInstance().newSAXParser().getXMLReader(); + handler = new PageObjectHandler(); + + reader.setContentHandler(handler); + reader.parse(new InputSource(stringReader)); + + return handler.getContent(); + + } + catch (SAXException e) { + logger.warn("Cannot parse page_object content." + e); + } catch (IOException e) { + logger.warn("Found invalid content." + e); + } catch (ParserConfigurationException e) { + logger.error("Creating XMLReader failed: " + e); + } + return ""; + } + + +} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentTransformer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentTransformer.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentTransformer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentTransformer.java index 80c41ef645d5..98c3e0e9d64f 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/ContentTransformer.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/ContentTransformer.java @@ -35,7 +35,7 @@ */ public interface ContentTransformer { - public static Logger logger = LogManager.getLogger(ContentTransformer.class); + Logger logger = LogManager.getLogger(ContentTransformer.class); /** * String which will be filtered @@ -43,5 +43,5 @@ public interface ContentTransformer { * @param content * @return */ - public String transform(String content); + String transform(String content); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/FilnameExtractor.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/FilnameExtractor.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/FilnameExtractor.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/FilnameExtractor.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/LinefeedSanitizer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/LinefeedSanitizer.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/LinefeedSanitizer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/LinefeedSanitizer.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java index f41a7161c80d..519f8e1ba7ce 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/MimeTypeExtractor.java @@ -87,9 +87,9 @@ public class MimeTypeExtractor implements ContentTransformer { ); - private static final List MIME_PDF_LIST = Arrays.asList( - "pdf" - ); + private static final List MIME_PDF_LIST = List.of( + "pdf" + ); /** diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/PageObjectHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/PageObjectHandler.java similarity index 96% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/PageObjectHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/PageObjectHandler.java index 8e99057ff4a7..6f54dbb0677d 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/PageObjectHandler.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/PageObjectHandler.java @@ -40,7 +40,7 @@ public class PageObjectHandler extends DefaultHandler { protected Logger logger = LogManager.getLogger(PageObjectHandler.class); - private StringBuffer buffer = new StringBuffer(); + private final StringBuffer buffer = new StringBuffer(); private boolean isContent = false; public void endDocument() { @@ -91,7 +91,7 @@ public void endElement (String uri, String localName, String qName) /** * */ - public void characters (char ch[], int start, int length) + public void characters (char[] ch, int start, int length) throws SAXException { if(!isContent) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/QuotingSanitizer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/QuotingSanitizer.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/QuotingSanitizer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/QuotingSanitizer.java index 7003c6b23f38..e2859497d65a 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/QuotingSanitizer.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/QuotingSanitizer.java @@ -34,9 +34,8 @@ public class QuotingSanitizer implements ContentTransformer { /** - * - * @see de.ilias.services.lucene.index.transform.ContentTransformer#transform(java.io.InputStream) - */ + * + */ public String transform(String content) { return Pattern.compile("\\[quote\\].*?\\[/quote\\]",Pattern.DOTALL).matcher(content).replaceAll(""); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TagSanitizer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TagSanitizer.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TagSanitizer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TagSanitizer.java index 967838fcc37b..5e6fcf68fedc 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TagSanitizer.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TagSanitizer.java @@ -33,10 +33,9 @@ public class TagSanitizer implements ContentTransformer { /** - * @param String content - */ + */ public String transform(String content) { - return content.toString().replaceAll("\\<.*?>",""); + return content.replaceAll("\\<.*?>",""); } } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TransformerFactory.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TransformerFactory.java similarity index 96% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TransformerFactory.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TransformerFactory.java index ffca5665f016..d0bfaa95bc51 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/TransformerFactory.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/TransformerFactory.java @@ -39,7 +39,7 @@ public class TransformerFactory { protected static Logger logger = LogManager.getLogger(Transformer.class); - private static HashMap map = new HashMap(); + private static final HashMap map = new HashMap(); public static ContentTransformer factory(String name) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/WhitespaceSanitizer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/WhitespaceSanitizer.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/index/transform/WhitespaceSanitizer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/index/transform/WhitespaceSanitizer.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/QueryRewriter.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/QueryRewriter.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/QueryRewriter.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/QueryRewriter.java index db742393c111..45a82d227511 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/QueryRewriter.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/QueryRewriter.java @@ -46,14 +46,13 @@ public class QueryRewriter { protected static Logger logger = LogManager.getLogger(QueryRewriter.class); private String query; - private StringBuffer rewritten; + private final StringBuffer rewritten; private int mode; private Vector objIds = new Vector(); /** - * @param String query - */ + */ public QueryRewriter(int mode, String query) { this.query = query; @@ -106,7 +105,7 @@ private String rewriteHighlight() { } rewritten.append(" ) AND docType:separated)"); - logger.debug("Searching for: " + rewritten.toString()); + logger.debug("Searching for: " + rewritten); return rewritten.toString(); } @@ -129,7 +128,7 @@ private String rewriteMailHighlight(int userId, int folderId) { } rewritten.append(") AND docType:separated) "); - logger.debug("Searching for: " + rewritten.toString()); + logger.debug("Searching for: " + rewritten); return rewritten.toString(); } @@ -143,7 +142,7 @@ private String rewriteSearch() { rewritten.append(")"); rewritten.append(" AND +docType:combined"); - logger.debug("Searching for: " + rewritten.toString()); + logger.debug("Searching for: " + rewritten); return rewritten.toString(); } @@ -158,7 +157,7 @@ private String rewriteUserHighlight() { rewritten.append(")"); rewritten.append(" AND type:usr"); - logger.info("Searching for:" + rewritten.toString()); + logger.info("Searching for:" + rewritten); return rewritten.toString(); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/RPCSearchHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/RPCSearchHandler.java similarity index 86% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/RPCSearchHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/RPCSearchHandler.java index 7d0184d550c4..10971571e909 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/RPCSearchHandler.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/RPCSearchHandler.java @@ -22,37 +22,29 @@ package de.ilias.services.lucene.search; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Vector; - -import org.apache.logging.log4j.LogManager; -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.index.CorruptIndexException; -import org.apache.lucene.search.BooleanClause; -import org.apache.lucene.search.BooleanQuery; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.BooleanClause.Occur; - import de.ilias.services.lucene.index.FieldInfo; import de.ilias.services.lucene.index.FieldInfoUser; import de.ilias.services.lucene.search.highlight.HitHighlighter; +import de.ilias.services.lucene.settings.LuceneSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; - -import de.ilias.services.lucene.settings.*; -import java.sql.SQLException; -import java.util.logging.Level; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.apache.lucene.analysis.standard.StandardAnalyzer; +import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.queryparser.classic.MultiFieldQueryParser; import org.apache.lucene.queryparser.classic.ParseException; import org.apache.lucene.queryparser.classic.QueryParser.Operator; -import org.apache.lucene.search.TopScoreDocCollector; +import org.apache.lucene.search.*; +import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.highlight.InvalidTokenOffsetsException; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.sql.SQLException; +import java.util.Vector; + /** * * @@ -61,6 +53,8 @@ */ public class RPCSearchHandler { + private static final int topDocsCount = 1000; + Logger logger = LogManager.getLogger(RPCSearchHandler.class); /** @@ -73,11 +67,6 @@ public RPCSearchHandler() { /** * Multi field searcher * Searches in all defined fields. - * @todo allow configuration of searchable fields. - * - * - * @param clientKey - * @param query */ public String search(String clientKey, String queryString,int pageNumber) { @@ -120,10 +109,10 @@ public String search(String clientKey, String queryString,int pageNumber) { else { multiParser.setDefaultOperator(Operator.OR); } - - BooleanQuery.setMaxClauseCount(10000); + + IndexSearcher.setMaxClauseCount(10000); BooleanQuery query = (BooleanQuery) multiParser.parse(rewrittenQuery); - logger.info("Max clauses allowed: " + BooleanQuery.getMaxClauseCount()); + logger.info("Max clauses allowed: " + IndexSearcher.getMaxClauseCount()); //BooleanQuery query = (BooleanQuery) MultiFieldQueryParser.parse(rewrittenQuery, // fieldInfo.getFieldsAsStringArray(), @@ -131,10 +120,13 @@ public String search(String clientKey, String queryString,int pageNumber) { // new StandardAnalyzer()); - for(Object f : fieldInfo.getFields()) { - logger.info(((String) f).toString()); + for(String f : fieldInfo.getFields()) { + logger.info(f); } - TopScoreDocCollector collector = TopScoreDocCollector.create(1000); + TopScoreDocCollector collector = TopScoreDocCollector.create( + RPCSearchHandler.topDocsCount, + RPCSearchHandler.topDocsCount + ); long s_start = new java.util.Date().getTime(); searcher.search(query,collector); long s_end = new java.util.Date().getTime(); @@ -171,12 +163,6 @@ public String search(String clientKey, String queryString,int pageNumber) { } - /** - * Search for users - * @param clientKey - * @param queryString - * @return - */ public String searchUsers(String clientKey, String queryString) { LuceneSettings luceneSettings; @@ -190,7 +176,7 @@ public String searchUsers(String clientKey, String queryString) { // Store duration of request long start = new java.util.Date().getTime(); - fieldInfo = (FieldInfoUser) FieldInfoUser.getInstance(LocalSettings.getClientKey()); + fieldInfo = FieldInfoUser.getInstance(LocalSettings.getClientKey()); luceneSettings = LuceneSettings.getInstance(); // Rewrite query @@ -218,12 +204,15 @@ public String searchUsers(String clientKey, String queryString) { multiParser.setDefaultOperator(Operator.OR); } - BooleanQuery.setMaxClauseCount(10000); + IndexSearcher.setMaxClauseCount(10000); BooleanQuery query = (BooleanQuery) multiParser.parse(rewrittenQuery); - logger.info("Max clauses allowed: " + BooleanQuery.getMaxClauseCount()); + logger.info("Max clauses allowed: " + IndexSearcher.getMaxClauseCount()); logger.info("Rewritten query is: " + query.toString()); - TopScoreDocCollector collector = TopScoreDocCollector.create(1000); + TopScoreDocCollector collector = TopScoreDocCollector.create( + RPCSearchHandler.topDocsCount, + RPCSearchHandler.topDocsCount + ); searcher.search(query,collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; @@ -237,42 +226,16 @@ public String searchUsers(String clientKey, String queryString) { logger.info("Total time: " + (end - start)); return hh.toXML(); } - catch(IOException e) { - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - logger.fatal(writer.toString()); - } - catch(ConfigurationException e) { + catch(IOException | ConfigurationException | ParseException | SQLException | InvalidTokenOffsetsException e) { StringWriter writer = new StringWriter(); e.printStackTrace(new PrintWriter(writer)); logger.fatal(writer.toString()); } - catch(ParseException e) { - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - logger.fatal(writer.toString()); - } - catch(SQLException e) { - StringWriter writer = new StringWriter(); - e.printStackTrace(new PrintWriter(writer)); - logger.fatal(writer.toString()); - } - catch (InvalidTokenOffsetsException ex) { - StringWriter writer = new StringWriter(); - ex.printStackTrace(new PrintWriter(writer)); - logger.fatal(writer.toString()); - } - - - return ""; + + + return ""; } - /** - * - * @param clientKey - * @param objIds - * @return - */ public String highlight(String clientKey, Vector objIds, String queryString) { LuceneSettings luceneSettings; @@ -316,10 +279,13 @@ public String highlight(String clientKey, Vector objIds, String querySt ) ); - logger.info("What occurs" + occurs.toString()); + logger.info("What occurs" + occurs); logger.info("Rewritten query is: " + query.toString()); - TopScoreDocCollector collector = TopScoreDocCollector.create(1000); + TopScoreDocCollector collector = TopScoreDocCollector.create( + RPCSearchHandler.topDocsCount, + RPCSearchHandler.topDocsCount + ); searcher.search(query,collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; @@ -356,14 +322,6 @@ public String highlight(String clientKey, Vector objIds, String querySt return ""; } - /** - * Search for mails - * @param clientKey - * @param userId - * @param query - * @param folderId - * @return - */ public String searchMail(String clientKey, int userId, String queryString, int folderId) { LocalSettings.setClientKey(clientKey); @@ -398,7 +356,10 @@ public String searchMail(String clientKey, int userId, String queryString, int f ); logger.info("Rewritten query is: " + query.toString()); - TopScoreDocCollector collector = TopScoreDocCollector.create(500); + TopScoreDocCollector collector = TopScoreDocCollector.create( + RPCSearchHandler.topDocsCount, + RPCSearchHandler.topDocsCount + ); searcher.search(query,collector); ScoreDoc[] hits = collector.topDocs().scoreDocs; diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/ResultExport.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/ResultExport.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/ResultExport.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/ResultExport.java index 7a651870e236..766c56437d6c 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/ResultExport.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/ResultExport.java @@ -22,7 +22,7 @@ package de.ilias.services.lucene.search; -import org.jdom.Element; +import org.jdom2.Element; /** * XML export interface @@ -32,5 +32,5 @@ */ public interface ResultExport { - public Element addXML(); + Element addXML(); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHits.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHits.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHits.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHits.java index c92ea9273643..757f50f719d6 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHits.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHits.java @@ -22,11 +22,11 @@ package de.ilias.services.lucene.search; -import java.util.Vector; - import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jdom.Element; +import org.jdom2.Element; + +import java.util.Vector; /** @@ -42,7 +42,7 @@ public class SearchHits implements ResultExport { private int totalHits = 0; private int limit = 0; private double maxScore = 0.0; - private Vector objects = new Vector(); + private final Vector objects = new Vector(); /** * diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHolder.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHolder.java similarity index 88% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHolder.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHolder.java index 90223a2a7415..782b3a1959a1 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchHolder.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchHolder.java @@ -23,25 +23,22 @@ package de.ilias.services.lucene.search; import de.ilias.services.lucene.index.IndexDirectoryFactory; -import java.io.IOException; -import java.util.HashMap; - -import org.apache.logging.log4j.LogManager; -import org.apache.lucene.search.IndexSearcher; - import de.ilias.services.lucene.index.IndexHolder; import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import org.apache.lucene.index.DirectoryReader; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; +import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.store.FSDirectory; +import java.io.IOException; +import java.util.HashMap; + /** - * - * * @author Stefan Meyer * @version $Id$ */ @@ -51,18 +48,11 @@ public class SearchHolder { protected static Logger logger = LogManager.getLogger(IndexHolder.class); - private static HashMap instances = new HashMap(); + private static final HashMap instances = new HashMap(); private IndexSearcher searcher = null; - /** - * @param indexPath - * @param indexType - * @throws ConfigurationException - * @throws IOException - * @throws IOException - */ private SearchHolder() throws ConfigurationException, IOException { init(); @@ -98,14 +88,7 @@ public void reInit(IndexWriter writer) throws ConfigurationException, IOExceptio searcher = new IndexSearcher(reader); } - /** - * - * @param clientKey - * @return - * @throws IOException - * @throws ConfigurationException - */ - public static synchronized SearchHolder getInstance(String clientKey) throws + public static synchronized SearchHolder getInstance(String clientKey) throws IOException, ConfigurationException { String hash = clientKey; @@ -117,22 +100,11 @@ public static synchronized SearchHolder getInstance(String clientKey) throws return instances.get(hash); } - /** - * - * @param indexType - * @return - * @throws IOException - * @throws IOException - * @throws ConfigurationException - */ public static synchronized SearchHolder getInstance() throws IOException, ConfigurationException { return getInstance(LocalSettings.getClientKey()); } - /** - * @return the searcher - */ public IndexSearcher getSearcher() { return searcher; } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchObject.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchObject.java similarity index 99% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchObject.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchObject.java index 0666df7d32bf..c2d624cb6642 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchObject.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchObject.java @@ -24,7 +24,7 @@ import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; -import org.jdom.Element; +import org.jdom2.Element; /** * diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchResultWriter.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchResultWriter.java similarity index 83% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchResultWriter.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchResultWriter.java index 631aff7230e4..835880ab54e5 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/SearchResultWriter.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/SearchResultWriter.java @@ -22,39 +22,28 @@ package de.ilias.services.lucene.search; -import java.io.IOException; -import java.util.Vector; - +import de.ilias.services.settings.ConfigurationException; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.lucene.document.Document; -import org.apache.lucene.index.CorruptIndexException; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.ScoreDoc; -import org.jdom.output.XMLOutputter; +import org.jdom2.output.XMLOutputter; -import de.ilias.services.settings.ConfigurationException; -import org.apache.logging.log4j.Logger; +import java.io.IOException; /** - * - * * @author Stefan Meyer - * @version $Id$ */ public class SearchResultWriter { protected Logger logger = LogManager.getLogger(SearchResultWriter.class); - private IndexSearcher searcher = null; - private ScoreDoc[] hits = null; - private SearchHits result = null; + private IndexSearcher searcher; + private ScoreDoc[] hits; + private SearchHits result; private int offset = 0; - /** - * @param hits - * @throws ConfigurationException - * @throws IOException - */ public SearchResultWriter(ScoreDoc[] hits) throws IOException, ConfigurationException { this.hits = hits; @@ -63,12 +52,7 @@ public SearchResultWriter(ScoreDoc[] hits) throws IOException, ConfigurationExce result = new SearchHits(); } - /** - * @throws IOException - * @throws CorruptIndexException - * - */ - public void write() throws CorruptIndexException, IOException { + public void write() throws IOException { result.setTotalHits(hits.length); logger.info("Found " + result.getTotalHits() + " hits!"); @@ -91,7 +75,7 @@ public void write() throws CorruptIndexException, IOException { try { logger.debug("Added object"); object = new SearchObject(); - hitDoc = searcher.doc(hits[i].doc); + hitDoc = searcher.getIndexReader().storedFields().document(hits[i].doc); object.setId(Integer.parseInt(hitDoc.get("objId"))); object.setAbsoluteScore(hits[i].score); result.addObject(object); @@ -102,27 +86,16 @@ public void write() throws CorruptIndexException, IOException { } } - /** - * @return - */ public String toXML() { - - org.jdom.Document doc = new org.jdom.Document(result.addXML()); + org.jdom2.Document doc = new org.jdom2.Document(result.addXML()); XMLOutputter outputter = new XMLOutputter(); return outputter.outputString(doc); - } - /** - * @param offset the offset to set - */ public void setOffset(int offset) { this.offset = offset; } - /** - * @return the offset - */ public int getOffset() { return offset; } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightField.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightField.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightField.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightField.java index c22931e572ab..cb9002b53f42 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightField.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightField.java @@ -23,7 +23,7 @@ package de.ilias.services.lucene.search.highlight; import org.apache.logging.log4j.LogManager; -import org.jdom.Element; +import org.jdom2.Element; import de.ilias.services.lucene.search.ResultExport; import de.ilias.services.xml.XMLUtils; @@ -81,8 +81,7 @@ public String getHighlight() { /** * Add xml - * @see de.ilias.services.lucene.search.highlight.HighlightResultExport#addXML(org.jdom.Element) - */ + */ public Element addXML() { Element field = new Element("Field"); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightHits.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightHits.java similarity index 92% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightHits.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightHits.java index 0a97327d72b6..71280a9f0b1d 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightHits.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightHits.java @@ -22,15 +22,14 @@ package de.ilias.services.lucene.search.highlight; -import java.util.HashMap; - -import org.apache.logging.log4j.LogManager; -import org.jdom.Document; -import org.jdom.Element; -import org.jdom.output.XMLOutputter; - import de.ilias.services.lucene.search.ResultExport; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jdom2.Document; +import org.jdom2.Element; +import org.jdom2.output.XMLOutputter; + +import java.util.HashMap; /** * Highlight results (top most xml element) @@ -42,7 +41,7 @@ public class HighlightHits implements ResultExport { protected static Logger logger = LogManager.getLogger(HighlightHits.class); - private HashMap objects = new HashMap(); + private final HashMap objects = new HashMap(); private double maxScore = 0; @@ -99,8 +98,7 @@ public String toXML() { /** * Add xml - * @see de.ilias.services.lucene.search.highlight.HighlightResultExport#addXML(org.jdom.Element) - */ + */ public Element addXML() { Element hits = new Element("Hits"); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightItem.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightItem.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightItem.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightItem.java index 9abf75563e4c..8637bfae7605 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightItem.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightItem.java @@ -22,13 +22,12 @@ package de.ilias.services.lucene.search.highlight; -import java.util.Vector; - -import org.apache.logging.log4j.LogManager; -import org.jdom.Element; - import de.ilias.services.lucene.search.ResultExport; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jdom2.Element; + +import java.util.Vector; /** * @@ -42,7 +41,7 @@ public class HighlightItem implements ResultExport { private int subId; private double absoluteScore = 0; - private Vector fields = new Vector(); + private final Vector fields = new Vector(); /** @@ -111,8 +110,7 @@ public Vector getFields() { /** * Add xml - * @see de.ilias.services.lucene.search.highlight.HighlightResultExport#addXML(org.jdom.Element) - */ + */ public Element addXML() { Element item = new Element("Item").setAttribute("id", String.valueOf(getSubId())); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightObject.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightObject.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightObject.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightObject.java index 10b92bdeb83a..93f5dde44cbe 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HighlightObject.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HighlightObject.java @@ -23,13 +23,13 @@ package de.ilias.services.lucene.search.highlight; +import de.ilias.services.lucene.search.ResultExport; import org.apache.logging.log4j.LogManager; -import org.jdom.Element; +import org.apache.logging.log4j.Logger; +import org.jdom2.Element; -import de.ilias.services.lucene.search.ResultExport; import java.util.Comparator; import java.util.TreeMap; -import org.apache.logging.log4j.Logger; /** * @@ -41,7 +41,7 @@ public class HighlightObject implements ResultExport, Comparator { protected static Logger logger = LogManager.getLogger(HighlightObject.class); - private TreeMap items = new TreeMap(); + private final TreeMap items = new TreeMap(); private TreeMap sortedItems = new TreeMap(); private int objId; @@ -91,8 +91,7 @@ public int getObjId() { /** * Add xml - * @see de.ilias.services.lucene.search.highlight.HighlightResultExport#addXML(org.jdom.Element) - */ + */ public Element addXML() { Element obj = new Element("Object"); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HitHighlighter.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HitHighlighter.java similarity index 79% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HitHighlighter.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HitHighlighter.java index a89194663fb2..a58ded318d55 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/search/highlight/HitHighlighter.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/search/highlight/HitHighlighter.java @@ -22,53 +22,43 @@ package de.ilias.services.lucene.search.highlight; -import java.io.IOException; -import java.io.StringReader; -import java.sql.SQLException; - +import de.ilias.services.lucene.index.FieldInfo; +import de.ilias.services.lucene.search.SearchHolder; +import de.ilias.services.lucene.settings.LuceneSettings; +import de.ilias.services.settings.ConfigurationException; +import de.ilias.services.settings.LocalSettings; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.lucene.analysis.TokenStream; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; -import org.apache.lucene.document.Field; import org.apache.lucene.index.CorruptIndexException; +import org.apache.lucene.index.IndexableField; import org.apache.lucene.search.IndexSearcher; import org.apache.lucene.search.Query; import org.apache.lucene.search.ScoreDoc; -import org.apache.lucene.search.highlight.Fragmenter; -import org.apache.lucene.search.highlight.Highlighter; -import org.apache.lucene.search.highlight.QueryScorer; -import org.apache.lucene.search.highlight.SimpleFragmenter; -import org.apache.lucene.search.highlight.SimpleHTMLFormatter; +import org.apache.lucene.search.highlight.*; -import de.ilias.services.lucene.index.FieldInfo; -import de.ilias.services.lucene.search.SearchHolder; -import de.ilias.services.lucene.settings.LuceneSettings; -import de.ilias.services.settings.ConfigurationException; -import de.ilias.services.settings.LocalSettings; -import org.apache.logging.log4j.Logger; -import org.apache.lucene.index.IndexableField; -import org.apache.lucene.search.highlight.InvalidTokenOffsetsException; +import java.io.IOException; +import java.io.StringReader; +import java.sql.SQLException; /** - * - * * @author Stefan Meyer - * @version $Id$ */ public class HitHighlighter { - private static int FRAGMENT_TITLE_SIZE = 10000; - private static String HIGHLIGHT_SEPARATOR = "..."; + private static final int FRAGMENT_TITLE_SIZE = 10000; + private static final String HIGHLIGHT_SEPARATOR = "..."; - private static String HIGHLIGHT_BEGIN_TAG = ""; - private static String HIGHLIGHT_END_TAG = ""; + private static final String HIGHLIGHT_BEGIN_TAG = ""; + private static final String HIGHLIGHT_END_TAG = ""; protected static Logger logger = LogManager.getLogger(HitHighlighter.class); private IndexSearcher searcher; - private Query query; - private ScoreDoc[] hits; + private final Query query; + private final ScoreDoc[] hits; private Highlighter highlighter; private Highlighter titleHighlighter; @@ -77,12 +67,6 @@ public class HitHighlighter { private LuceneSettings luceneSettings; - /** - * @throws IOException - * @throws ConfigurationException - * @throws SQLException - * - */ public HitHighlighter(Query query,ScoreDoc[] hits) throws ConfigurationException, IOException, SQLException { this.query = query; @@ -90,18 +74,12 @@ public HitHighlighter(Query query,ScoreDoc[] hits) throws ConfigurationException init(); } - /** - * @throws IOException - * @throws CorruptIndexException - * - */ public void highlight() throws CorruptIndexException, IOException, InvalidTokenOffsetsException { result = new HighlightHits(); HighlightObject resObject; HighlightItem resItem; - HighlightField resField; - + TokenStream token; String fragment; @@ -113,8 +91,8 @@ public void highlight() throws CorruptIndexException, IOException, InvalidTokenO result.setMaxScore(hits[i].score); } - StringBuffer allContent = new StringBuffer(); - Document hitDoc = searcher.doc(hits[i].doc); + StringBuilder allContent = new StringBuilder(); + Document hitDoc = searcher.getIndexReader().storedFields().document(hits[i].doc); int objId; int subItem; @@ -164,23 +142,23 @@ public void highlight() throws CorruptIndexException, IOException, InvalidTokenO } } // All content - for(int j = 0; j < fields.length; j++) { - - // Do not add metaData Field, since this information is stored redundant in lom* fields - if(fields[j].equals("metaData")) { - continue; - } - - if(fields[j].equals("title") || fields[j].equals("description")) { - continue; - } - - IndexableField[] separatedFields = hitDoc.getFields(fields[j]); - for(int k = 0; k < separatedFields.length; k++) { - allContent.append(separatedFields[k].stringValue()); - allContent.append(" "); - } - } + for (String field : fields) { + + // Do not add metaData Field, since this information is stored redundant in lom* fields + if (field.equals("metaData")) { + continue; + } + + if (field.equals("title") || field.equals("description")) { + continue; + } + + IndexableField[] separatedFields = hitDoc.getFields(field); + for (IndexableField separatedField : separatedFields) { + allContent.append(separatedField.stringValue()); + allContent.append(" "); + } + } //logger.debug("All content" + allContent.toString()); token = new StandardAnalyzer().tokenStream("content", new StringReader(allContent.toString())); fragment = highlighter.getBestFragments( @@ -197,12 +175,6 @@ public void highlight() throws CorruptIndexException, IOException, InvalidTokenO } } - /** - * @throws ConfigurationException - * @throws IOException - * @throws SQLException - * - */ private void init() throws ConfigurationException, IOException, SQLException { // init lucene settings @@ -223,18 +195,14 @@ private void init() throws ConfigurationException, IOException, SQLException { Fragmenter titleFragmenter = new SimpleFragmenter(FRAGMENT_TITLE_SIZE); titleHighlighter.setTextFragmenter(titleFragmenter); - // init fieldinfo + // init field info fieldInfo = FieldInfo.getInstance(LocalSettings.getClientKey()); // init searcher searcher = SearchHolder.getInstance().getSearcher(); - - return; - } - /** - * @return - */ + } + public String toXML() { return result.toXML(); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/settings/LuceneSettings.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/settings/LuceneSettings.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/lucene/settings/LuceneSettings.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/settings/LuceneSettings.java index 3f86242ad15a..c86c022ad811 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/lucene/settings/LuceneSettings.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/lucene/settings/LuceneSettings.java @@ -22,6 +22,11 @@ package de.ilias.services.lucene.settings; +import de.ilias.services.db.DBFactory; +import de.ilias.services.settings.LocalSettings; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -29,12 +34,6 @@ import java.util.Date; import java.util.HashMap; -import org.apache.logging.log4j.LogManager; - -import de.ilias.services.db.DBFactory; -import de.ilias.services.settings.LocalSettings; -import org.apache.logging.log4j.Logger; - /** * * @@ -47,7 +46,7 @@ public class LuceneSettings { public static final int OPERATOR_OR = 2; protected static Logger logger = LogManager.getLogger(LuceneSettings.class); - private static HashMap instances = new HashMap(); + private static final HashMap instances = new HashMap(); private int fragmentSize = 30; @@ -142,7 +141,7 @@ public void setDefaultOperator(int defaultOperator) { public boolean isPrefixWildcardQueryEnabled() { - return this.prefixWildcard > 0 ? true : false; + return this.prefixWildcard > 0; } public void enablePrefixWildcardQuery(int stat) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/DataSource.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DataSource.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/DataSource.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DataSource.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/DataSourceFactory.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DataSourceFactory.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/DataSourceFactory.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DataSourceFactory.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/DirectoryDataSource.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DirectoryDataSource.java similarity index 96% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/DirectoryDataSource.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DirectoryDataSource.java index bc03f744666f..2e8bf44b1695 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/DirectoryDataSource.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DirectoryDataSource.java @@ -93,7 +93,7 @@ public void writeDocument(CommandQueueElement el, ResultSet res) for(Object field : getFields()) { ((FieldDefinition) field).writeDocument(content.toString()); } - logger.debug("Content is : " + content.toString()); + logger.debug("Content is : " + content); } catch (PathCreatorException e) { throw new DocumentHandlerException(e); @@ -119,10 +119,7 @@ public void traverse(File dir) { public boolean accept(File path) { if(path.isDirectory()) { - if(!path.getName().equals(".svn")) { - return true; - } - return false; + return !path.getName().equals(".svn"); } else { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/DocumentDefinition.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DocumentDefinition.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/DocumentDefinition.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/DocumentDefinition.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/FieldDefinition.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FieldDefinition.java similarity index 98% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/FieldDefinition.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FieldDefinition.java index 4d047b0941bd..277ff8498248 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/FieldDefinition.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FieldDefinition.java @@ -142,8 +142,7 @@ public Integer getIndexType() { /** - * @param index the index to set - */ + */ public void setIndexType(int type) { this.indexType = type; } @@ -209,7 +208,7 @@ public String getType() { */ public String parseName(ResultSet res) throws SQLException { - if(isDynamic == false) { + if(!isDynamic) { return getName(); } if(res != null) { @@ -348,8 +347,7 @@ else if(getType().equalsIgnoreCase("integer")) { } DocumentHolder.factory().add(fieldName, purged, isGlobal(), store, indexed); } - return; - } + } catch(NullPointerException e) { logger.error("Caught NullPointerException: " + e.getMessage()); } @@ -375,7 +373,6 @@ public void writeDocument(String content) { /** - * @param string * @return */ private String callTransformers(String value) { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/FileDataSource.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FileDataSource.java similarity index 99% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/FileDataSource.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FileDataSource.java index 6cede728de42..399491fea166 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/FileDataSource.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/FileDataSource.java @@ -75,7 +75,6 @@ public void writeDocument(CommandQueueElement el, ResultSet res) ((FieldDefinition) field).writeDocument(handler.getContent(file, extension)); } logger.debug("File path is: " + file.getAbsolutePath()); - return; } catch (PathCreatorException e) { if(file != null) diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/JDBCDataSource.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/JDBCDataSource.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/JDBCDataSource.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/JDBCDataSource.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinition.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinition.java similarity index 98% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinition.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinition.java index 990491698436..5e5932023dba 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinition.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinition.java @@ -51,7 +51,7 @@ public class ObjectDefinition implements DocumentHandler { private String type; private String indexType = "full"; - private Vector documents = new Vector(); + private final Vector documents = new Vector(); /** * @@ -129,7 +129,6 @@ public void removeDocumentDefinition(DocumentDefinition doc) { while((index = documents.indexOf(doc)) != -1) { documents.remove(index); } - return; } /* (non-Javadoc) diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionParser.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionParser.java similarity index 93% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionParser.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionParser.java index 15e681d6275b..5ca227989497 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionParser.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionParser.java @@ -22,35 +22,28 @@ package de.ilias.services.object; -import java.io.File; -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.util.Vector; - -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.dom.DOMSource; -import javax.xml.transform.stream.StreamResult; - -import org.apache.logging.log4j.LogManager; -import org.jdom.Element; -import org.w3c.dom.Node; -import org.xml.sax.SAXException; - import de.ilias.services.lucene.index.FieldInfo; import de.ilias.services.lucene.index.file.path.PathCreatorFactory; import de.ilias.services.settings.ClientSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import org.jdom2.Element; +import org.w3c.dom.Node; +import org.xml.sax.SAXException; + +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.transform.*; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Vector; /** * Parser for Lucene object definitions. @@ -62,8 +55,8 @@ public class ObjectDefinitionParser { protected Logger logger = LogManager.getLogger(ObjectDefinitionParser.class); private Vector objectPropertyFiles = new Vector(); - private ClientSettings settings; - private ObjectDefinitions definitions; + private final ClientSettings settings; + private final ObjectDefinitions definitions; /** * @throws ConfigurationException @@ -145,7 +138,7 @@ private void parseFile(File file) throws ObjectDefinitionException { // JDOM does not understand x:include but has a more comfortable API. - org.jdom.Document jdocument = convertToJDOM(document); + org.jdom2.Document jdocument = convertToJDOM(document); definitions.addDefinition(parseObjectDefinition(jdocument)); @@ -185,9 +178,9 @@ private void parseFile(File file) throws ObjectDefinitionException { * @param document * @return */ - private org.jdom.Document convertToJDOM(org.w3c.dom.Document document) { + private org.jdom2.Document convertToJDOM(org.w3c.dom.Document document) { - org.jdom.input.DOMBuilder builder = new org.jdom.input.DOMBuilder(); + org.jdom2.input.DOMBuilder builder = new org.jdom2.input.DOMBuilder(); return builder.build(document); } @@ -196,11 +189,11 @@ private org.jdom.Document convertToJDOM(org.w3c.dom.Document document) { * @return * @throws ObjectDefinitionException */ - private ObjectDefinition parseObjectDefinition(org.jdom.Document jdocument) throws ObjectDefinitionException { + private ObjectDefinition parseObjectDefinition(org.jdom2.Document jdocument) throws ObjectDefinitionException { ObjectDefinition definition; - org.jdom.Element root = jdocument.getRootElement(); + org.jdom2.Element root = jdocument.getRootElement(); if(!root.getName().equals("ObjectDefinition")) { throw new ObjectDefinitionException("Cannot find root element 'ObjectDefinition'"); @@ -223,7 +216,6 @@ private ObjectDefinition parseObjectDefinition(org.jdom.Document jdocument) thro } /** - * @param document * @return * @throws ObjectDefinitionException */ diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionReader.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionReader.java similarity index 91% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionReader.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionReader.java index e87caeddf130..81ef678bbbbb 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitionReader.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitionReader.java @@ -41,14 +41,14 @@ public class ObjectDefinitionReader { - private static Logger logger = LogManager.getLogger(ObjectDefinitionReader.class); - private static HashMap instances = new HashMap(); + private static final Logger logger = LogManager.getLogger(ObjectDefinitionReader.class); + private static final HashMap instances = new HashMap(); public static final String objectPropertyName = "LuceneObjectDefinition.xml"; public static final String pluginPath = "Customizing/global/plugins"; - private Vector objectPropertyFiles = new Vector(); + private final Vector objectPropertyFiles = new Vector(); File absolutePath; @@ -144,12 +144,9 @@ private void traverse(File dir) { public boolean accept(File path) { if(path.isDirectory()) { - if(!path.getName().equals(".svn")) { - //logger.debug("Found new directory: " + path.getAbsolutePath()); - return true; - } - return false; - } + //logger.debug("Found new directory: " + path.getAbsolutePath()); + return !path.getName().equals(".svn"); + } //logger.debug(path.getName() + " <-> " + objectPropertyName); if(path.getName().equalsIgnoreCase(objectPropertyName)) { logger.info("Found: " + path.getAbsolutePath()); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitions.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitions.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitions.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitions.java index 5426f92edc8f..073df8854768 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ObjectDefinitions.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ObjectDefinitions.java @@ -38,7 +38,7 @@ public class ObjectDefinitions { protected static Logger logger = LogManager.getLogger(ObjectDefinitions.class); - private static HashMap instances = new HashMap(); + private static final HashMap instances = new HashMap(); private File absolutePath; private Vector definitions = new Vector(); diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ParameterDefinition.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ParameterDefinition.java similarity index 97% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/ParameterDefinition.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ParameterDefinition.java index 7a0db2aa6732..c1e24afae6e4 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/object/ParameterDefinition.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/ParameterDefinition.java @@ -136,11 +136,9 @@ public void setValue(String value) { @Override public String toString() { - StringBuffer out = new StringBuffer(); - - out.append("Parameter " + format + " " + type + " " + value); - out.append("\n"); - return out.toString(); + String out = "Parameter " + format + " " + type + " " + value + + "\n"; + return out; } /** diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/object/TransformerDefinition.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/TransformerDefinition.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/object/TransformerDefinition.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/object/TransformerDefinition.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCAdministration.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCAdministration.java similarity index 86% rename from Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCAdministration.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCAdministration.java index 72be4bf70952..dbcd60f147df 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCAdministration.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCAdministration.java @@ -22,28 +22,26 @@ package de.ilias.services.rpc; -import java.sql.SQLException; - -import org.apache.logging.log4j.LogManager; - import de.ilias.ilServerStatus; import de.ilias.services.db.DBFactory; import de.ilias.services.lucene.index.IndexHolder; import de.ilias.services.lucene.settings.LuceneSettings; import de.ilias.services.settings.ConfigurationException; import de.ilias.services.settings.LocalSettings; +import de.ilias.services.settings.LogConfigManager; +import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; +import java.sql.SQLException; + /** - * * * @author Stefan Meyer - * @version $Id$ */ public class RPCAdministration { - private Logger logger = LogManager.getLogger(this.getClass().getName()); + private final Logger logger = LogManager.getLogger(RPCAdministration.class); /** @@ -73,7 +71,6 @@ public boolean stop() throws ConfigurationException { // Set server status inactive ilServerStatus.setActive(false); - return true; } @@ -82,8 +79,8 @@ public boolean stop() throws ConfigurationException { * @param clientKey * @return */ - public boolean refreshSettings(String clientKey) { - + public boolean refreshSettings(String clientKey) + { LuceneSettings settings = null; LocalSettings.setClientKey(clientKey); DBFactory.init(); @@ -100,6 +97,21 @@ public boolean refreshSettings(String clientKey) { return false; } } + + public boolean initLogManager(String iniPath) + { + LogConfigManager logConfigManager = new LogConfigManager(); + try { + logConfigManager.parse(iniPath); + logConfigManager.initLogManager(); + return true; + } catch (ConfigurationException e) { + logger.error("Init logging service failed with message: {}", e.getMessage()); + return false; + } + } + + public String status() { diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCDebug.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCDebug.java similarity index 99% rename from Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCDebug.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCDebug.java index b09e0a8d9275..9666ec335844 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCDebug.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCDebug.java @@ -41,8 +41,7 @@ public RPCDebug() { */ public void ping() { - return; - } + } /** * @return diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCServer.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCServer.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCServer.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCServer.java index 6b62fdca3d91..826952a43649 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/rpc/RPCServer.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/rpc/RPCServer.java @@ -22,20 +22,17 @@ package de.ilias.services.rpc; -import java.net.InetAddress; - +import de.ilias.services.lucene.index.RPCIndexHandler; +import de.ilias.services.settings.ConfigurationException; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.apache.xmlrpc.XmlRpcException; import org.apache.xmlrpc.server.PropertyHandlerMapping; import org.apache.xmlrpc.server.XmlRpcServer; import org.apache.xmlrpc.server.XmlRpcServerConfigImpl; import org.apache.xmlrpc.webserver.WebServer; -import de.ilias.services.lucene.index.RPCIndexHandler; -import de.ilias.services.lucene.search.RPCSearchHandler; -import de.ilias.services.settings.ConfigurationException; -import de.ilias.services.transformation.RPCTransformationHandler; -import org.apache.logging.log4j.Logger; +import java.net.InetAddress; /** @@ -47,7 +44,7 @@ public class RPCServer { private static RPCServer instance = null; - private Logger logger = LogManager.getLogger(this.getClass().getName()); + private final Logger logger = LogManager.getLogger(RPCServer.class); private WebServer server; private InetAddress host = null; @@ -142,8 +139,7 @@ private void initServer() throws XmlRpcException { config.setKeepAliveEnabled(true); config.setEncoding("UTF8"); // nothing to do in the moment. - - return; + } /** @@ -164,12 +160,10 @@ public void start() throws ConfigurationException { { logger.error("Cannot bind to host: " + getHost() + ", port: " + port + " " + e); throw new ConfigurationException(e.getMessage()); - } - catch(Exception e) { + } catch(Exception e) { logger.error("Cannot bind to host: " + getHost() + ", port: " + port + " " + e); throw new ConfigurationException(e.getMessage()); - } - catch(Throwable e) { + } catch(Throwable e) { logger.error(e); throw new ConfigurationException(e.getMessage()); } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/ClientSettings.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ClientSettings.java similarity index 94% rename from Services/WebServices/RPC/lib/src/de/ilias/services/settings/ClientSettings.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ClientSettings.java index db501936b25c..1e126e6b546d 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/ClientSettings.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ClientSettings.java @@ -22,14 +22,14 @@ package de.ilias.services.settings; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; - /** * A singleton for each client configuration * @@ -39,7 +39,7 @@ public class ClientSettings { protected static Logger logger = LogManager.getLogger(ClientSettings.class); - private static HashMap instances = new HashMap(); + private static final HashMap instances = new HashMap(); private String client; @@ -57,12 +57,6 @@ public class ClientSettings { private String dbUser; private String dbPass; - - - /** - * @param string - * @param string2 - */ public ClientSettings(String client, String nic) { this.client = client; @@ -95,19 +89,11 @@ public static synchronized ClientSettings getInstance(String clientKey) throws C return instances.get(clientKey); } - /** - * @param string - * @return - */ public static boolean exists(String clientKey) { return instances.containsKey(clientKey); } - /** - * get all clients - * @return - */ public static ArrayList getClients() { ArrayList clients = new ArrayList(); @@ -167,8 +153,7 @@ public File getDataDirectory() { /** * @param dataDirectory the dataDirectory to set - * @throws ConfigurationException - */ + */ public void setDataDirectory(String dataDirectory) throws ConfigurationException { logger.debug("ILIAS data directory: " + dataDirectory); @@ -188,8 +173,7 @@ public File getAbsolutePath() { /** * @param absolutePath the absolutePath to set - * @throws ConfigurationException - */ + */ public void setAbsolutePath(String absolutePath) throws ConfigurationException { logger.debug("ILIAS absolute path: " + absolutePath); @@ -209,9 +193,7 @@ public File getClientIniFile() { } /** - * @param the clientIniFile to set - * @throws ConfigurationException - */ + */ public void setClientIniFile(String clientIniPath) throws ConfigurationException { this.clientIniFile = new File(clientIniPath); @@ -225,8 +207,7 @@ public void setClientIniFile(String clientIniPath) throws ConfigurationException /** * @param iliasIniFile the iliasIniFile to set - * @throws ConfigurationException - */ + */ public void setIliasIniFile(String iliasIniFile) throws ConfigurationException { this.iliasIniFile = new File(iliasIniFile); @@ -268,8 +249,7 @@ public void setIndexPath(String indexPath) { /** * get db url - * @return - */ + */ public String getDbUrl() { if(getDbType().equalsIgnoreCase("mysql") || getDbType().equalsIgnoreCase("innodb")) { @@ -385,16 +365,14 @@ public void setDbPass(String dbPass) { /** * set Db port - * @param purgeString - */ + */ public void setDbPort(String purgeString) { this.dbPort = purgeString; } /** * get db port - * @return - */ + */ public String getDbPort() { return this.dbPort; } diff --git a/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/CommonsIniFileParser.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/CommonsIniFileParser.java new file mode 100644 index 000000000000..f91011e66989 --- /dev/null +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/CommonsIniFileParser.java @@ -0,0 +1,219 @@ +/** + * This file is part of ILIAS, a powerful learning management system + * published by ILIAS open source e-Learning e.V. + * + * ILIAS is licensed with the GPL-3.0, + * see https://www.gnu.org/licenses/gpl-3.0.en.html + * You should have received a copy of said license along with the + * source code, too. + * If this is not the case or you just want to try ILIAS, you'll find + * us at: + * https://www.ilias.de + * https://github.com/ILIAS-eLearning + * + *********************************************************************/ + +package de.ilias.services.settings; + +import org.apache.commons.configuration2.INIConfiguration; +import org.apache.commons.configuration2.SubnodeConfiguration; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; + +import java.io.*; + +/** + * @author Stefan Meyer + */ +public class CommonsIniFileParser +{ + Logger logger = LogManager.getLogger(CommonsIniFileParser.class); + + private ServerSettings serverSettings = null; + + + public CommonsIniFileParser() + { + } + + + public void parseSettings(String path, boolean parseClientSettings) throws ConfigurationException + { + serverSettings = ServerSettings.getInstance(); + ClientSettings clientSettings; + INIConfiguration ini = new INIConfiguration(); + + logger.debug("Start parsing {}", path); + try (FileReader fileReader = new FileReader(path)) { + logger.debug("Ini read..."); + ini.read(fileReader); + logger.debug("Ini read."); + for (String section: ini.getSections()) { + SubnodeConfiguration sectionConfig = ini.getSection(section); + // server settings from ilServer.ini + if (section.equals("Server")) { + logger.debug("section server"); + if(sectionConfig.containsKey("IpAddress")) { + logger.debug("Ip address {}", getConfig(ini, section, "IpAddress", false)); + serverSettings.setHost(getConfig(ini, section, "IpAddress", false)); + } + if(sectionConfig.containsKey("Port")) { + logger.debug("Port {}", getConfig(ini, section, "Port", false)); + serverSettings.setPort(getConfig(ini, section, "Port", false)); + } + if(sectionConfig.containsKey("IndexPath")) { + logger.debug("IndexPath {}", getConfig(ini, section, "IndexPath", false)); + serverSettings.setIndexPath(getConfig(ini, section, "IndexPath", false)); + } + if(sectionConfig.containsKey("LogFile")) { + logger.debug("LogFile {}", getConfig(ini, section, "LogFile", false)); + serverSettings.setLogFile(getConfig(ini, section, "LogFile", false)); + } + if(sectionConfig.containsKey("LogLevel")) { + logger.debug("LogLevel {}", getConfig(ini, section, "LogLevel", false)); + serverSettings.setLogLevel(getConfig(ini, section, "LogLevel", false)); + } + if(sectionConfig.containsKey("NumThreads")) { + logger.debug("NumThreads {}", getConfig(ini, section, "NumThreads", false)); + serverSettings.setThreadNumber(getConfig(ini, section, "NumThreads", false)); + } + logger.debug("Check ram size"); + if(sectionConfig.containsKey("RAMBufferSize")) { + logger.debug("RAM {}", getConfig(ini, section, "RAMBufferSize", false)); + serverSettings.setRAMSize(getConfig(ini, section, "RAMBufferSize", false)); + } + logger.debug("Check file size"); + if(sectionConfig.containsKey("IndexMaxFileSizeMB")) { + logger.debug("Index {}", getConfig(ini, section, "IndexMaxFileSizeMB", false)); + serverSettings.setMaxFileSizeMB(getConfig(ini, section, "IndexMaxFileSizeMB", false)); + } + } + logger.debug("check section client"); + if (section.startsWith("Client") && parseClientSettings) { + logger.debug("section client"); + if(sectionConfig.containsKey("ClientId")) { + String client = getConfig(ini, section, "ClientId", false); + String nic; + logger.debug("Client {}", client); + if(sectionConfig.containsKey("NicId")) + nic = getConfig(ini, section, "NicId", false); + else + nic = "0"; + clientSettings = ClientSettings.getInstance(client, nic); + if(sectionConfig.containsKey("IliasIniPath")) { + clientSettings.setIliasIniFile(getConfig(ini, section, "IliasIniPath", false)); + // Now parse the ilias.ini file + parseClientData(clientSettings); + } + } else { + logger.error("No ClientId given for section: {} ", section); + throw new ConfigurationException("No ClientId given for section: " + section); + } + } + } + } catch (IOException e) { + logger.fatal("Parsing ini file failed: {}", path); + throw new ConfigurationException("Parsing ini file failed.", e); + } catch (org.apache.commons.configuration2.ex.ConfigurationException e) { + logger.fatal("Parsing ini file failed: {} ", path); + throw new ConfigurationException("Parsing ini file failed.", e); + } + } + + private String getConfig(INIConfiguration ini, String section, String key, boolean replaceQuotes) + { + return purgeString(ini.getSection(section).getProperty(key).toString(), replaceQuotes); + } + + private String purgeString(String dirty, boolean replaceQuotes) + { + if(replaceQuotes) { + return dirty.replace('"',' ').trim(); + } + else { + return dirty.trim(); + } + } + + private void parseClientData(ClientSettings clientSettings) throws ConfigurationException + { + INIConfiguration ini = new INIConfiguration(); + try (StringReader stringReader = convertIniFile(clientSettings.getIliasIniFile())) { + ini.read(stringReader); + + clientSettings.setDataDirectory(getConfig(ini, "clients", "datadir", true)); + clientSettings.setAbsolutePath(getConfig(ini, "server", "absolute_path", true)); + + String dataName = getConfig(ini, "clients", "path", true); + String iniFileName = getConfig(ini, "clients", "inifile", true); + + clientSettings.setClientIniFile(clientSettings.getAbsolutePath().getCanonicalPath() + + System.getProperty("file.separator") + + dataName + System.getProperty("file.separator") + + clientSettings.getClient() + System.getProperty("file.separator") + + iniFileName); + clientSettings.setIndexPath(ServerSettings.getInstance().getIndexPath() + + System.getProperty("file.separator") + + clientSettings.getClientKey()); + } catch (IOException e) { + logger.fatal("Parsing ilias ini file failed: {}", clientSettings.getIliasIniFile().getAbsolutePath()); + throw new ConfigurationException("Parsing ilias ini file failed.", e); + } catch (org.apache.commons.configuration2.ex.ConfigurationException e) { + logger.fatal("Parsing ilias ini file failed: {}", clientSettings.getIliasIniFile().getAbsolutePath()); + throw new ConfigurationException("Parsing ini file failed.", e); + } + + try (StringReader stringReader = convertIniFile(clientSettings.getClientIniFile())) { + ini.read(stringReader); + + clientSettings.setDbType(getConfig(ini, "db", "type", true)); + clientSettings.setDbHost(getConfig(ini, "db", "host", true)); + clientSettings.setDbPort(getConfig(ini, "db", "port", true)); + clientSettings.setDbUser(getConfig(ini, "db", "user", true)); + clientSettings.setDbPass(getConfig(ini, "db", "pass", true)); + clientSettings.setDbName(getConfig(ini, "db", "name", true)); + + logger.debug("Client ID: {}", clientSettings.getClient()); + logger.debug("DB Type: {}", clientSettings.getDbType()); + logger.debug("DB Host: {}", clientSettings.getDbHost()); + logger.debug("DB Port: {}", clientSettings.getDbPort()); + logger.debug("DB Name: {}", clientSettings.getDbName()); + logger.debug("DB User: {}", clientSettings.getDbUser()); + logger.debug("DB Pass: {}", clientSettings.getDbPass()); + + } catch (IOException e) { + logger.fatal("Parsing client ini file failed: {}", clientSettings.getClientIniFile().getAbsolutePath()); + throw new ConfigurationException("Parsing client ini file failed.", e); + } catch (org.apache.commons.configuration2.ex.ConfigurationException e) { + logger.fatal("Parsing client ini file failed: {}", clientSettings.getClientIniFile().getAbsolutePath()); + throw new ConfigurationException("Parsing client ini file failed.", e); + } + } + + private StringReader convertIniFile(File iniFile) throws ConfigurationException + { + try { + String output; + InputStreamReader reader = new InputStreamReader(new FileInputStream(iniFile)); + + int c; + StringBuilder builder = new StringBuilder(); + + while((c = reader.read())!=-1){ + builder.append((char)c); + } + output = builder.toString(); + output = output.replaceFirst("<\\?php /\\*",""); + output = output.replaceFirst("\\*/ \\?>",""); + return new StringReader(output); + } + catch (FileNotFoundException e) { + logger.fatal("Cannot find ini file: {}", e.getMessage()); + throw new ConfigurationException(e); + } + catch (IOException e) { + logger.error("Caught IOException when trying to convert ini file: " + e.getMessage()); + throw new ConfigurationException(e); + } + } +} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/ConfigurationException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ConfigurationException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/settings/ConfigurationException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ConfigurationException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/IniFileSettings.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/IniFileSettings.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/settings/IniFileSettings.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/IniFileSettings.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/LocalSettings.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LocalSettings.java similarity index 95% rename from Services/WebServices/RPC/lib/src/de/ilias/services/settings/LocalSettings.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LocalSettings.java index 42119f9d6e55..2f8ca0698ddb 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/LocalSettings.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LocalSettings.java @@ -36,7 +36,7 @@ public class LocalSettings { protected static Logger logger = LogManager.getLogger(LocalSettings.class); - private static ThreadLocal clientKey = new ThreadLocal() { + private static final ThreadLocal clientKey = new ThreadLocal() { public String initialValue() { return ""; } @@ -62,6 +62,6 @@ public static void setClientKey(String ck) { * @return */ public static String getClientKey() { - return (String) clientKey.get(); + return clientKey.get(); } } \ No newline at end of file diff --git a/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LogConfigManager.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LogConfigManager.java new file mode 100644 index 000000000000..274f995cdcd1 --- /dev/null +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/LogConfigManager.java @@ -0,0 +1,173 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package de.ilias.services.settings; + +import org.apache.commons.configuration2.INIConfiguration; +import org.apache.commons.configuration2.SubnodeConfiguration; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.apache.logging.log4j.core.Filter; +import org.apache.logging.log4j.core.LoggerContext; +import org.apache.logging.log4j.core.appender.RollingFileAppender; +import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy; +import org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy; +import org.apache.logging.log4j.core.config.Configuration; +import org.apache.logging.log4j.core.config.LoggerConfig; +import org.apache.logging.log4j.core.filter.ThresholdFilter; +import org.apache.logging.log4j.core.layout.PatternLayout; + +import java.io.File; +import java.io.FileReader; +import java.io.IOException; + +public class LogConfigManager { + + private final Logger logger = LogManager.getLogger(LogConfigManager.class); + + private File file; + private Level level; + + private boolean isInitialized = false; + + + public Level getLogLevel() + { + return this.level; + } + + public File getLogFile() + { + return this.file; + } + + public void setLogLevel(String logLevel) + { + this.level = Level.toLevel(logLevel.trim(),Level.INFO); + } + + public void setLogFile(String logFile) throws ConfigurationException, IOException { + + this.file = new File(logFile); + if(!this.file.isAbsolute()) { + logger.error("Absolute path to logfile required: {}", logFile); + throw new ConfigurationException("Absolute path to logfile required: " + logFile); + } + if(this.file.isDirectory()) { + logger.error("Absolute path to logfile required. Directory name given: {}", logFile); + throw new ConfigurationException("Absolute path to logfile required: " + logFile); + } + if(this.file.createNewFile()) { + logger.debug("Creating new log file {}", logFile); + } + else { + logger.debug("Using existing log file: {}", this.file.getAbsolutePath()); + } + if(!this.file.canWrite()) { + throw new ConfigurationException("Cannot write to log file: " + logFile); + } + } + + + + + public void parse(String path) throws ConfigurationException { + + INIConfiguration ini = new INIConfiguration(); + try (FileReader fileReader = new FileReader(path)) { + ini.read(fileReader); + for (String section : ini.getSections()) { + if (section.equals("Server")) { + SubnodeConfiguration sectionConfig = ini.getSection(section); + if (sectionConfig.containsKey("LogLevel")) { + setLogLevel(purgeString(sectionConfig.getProperty("LogLevel").toString())); + } + if (sectionConfig.containsKey("LogFile")) { + setLogFile(purgeString(sectionConfig.getProperty("LogFile").toString())); + } + } + } + } catch (org.apache.commons.configuration2.ex.ConfigurationException e) { + throw new ConfigurationException(e); + } catch (IOException e) { + throw new ConfigurationException(e); + } + } + + public void initLogManager() + { + if (isInitialized) { + logger.warn("Logging service already initialized"); + } + + LoggerContext context = (LoggerContext) LogManager.getContext(false); + Configuration config = context.getConfiguration(); + LoggerConfig rootConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME); + LoggerConfig iliasConfig = config.getLoggerConfig("de.ilias"); + LoggerConfig iliasServerConfig = config.getLoggerConfig("de.ilias.ilServer"); + + // new rolling file appender + PatternLayout fileLayout = PatternLayout.newBuilder() + .withConfiguration(config) + .withPattern("%d{ISO8601} %-5p %t (%F:%L) - %m%n") + .build(); + + DefaultRolloverStrategy strategy = DefaultRolloverStrategy.newBuilder() + .withMax("3") + .withMin("1") + .withFileIndex("max") + .withConfig(config) + .build(); + + RollingFileAppender file = RollingFileAppender.newBuilder() + .setName("RollingFile") + .withFileName(getLogFile().getAbsolutePath()) + .withFilePattern(getLogFile().getName() + "%d") + .withStrategy(strategy) + .withPolicy(SizeBasedTriggeringPolicy.createPolicy("100MB")) + .setConfiguration(config) + .setLayout(fileLayout) + .build(); + file.start(); + config.addAppender(file); + + + rootConfig.addAppender( + file, + this.getLogLevel(), + ThresholdFilter.createFilter(Level.DEBUG, Filter.Result.ACCEPT, Filter.Result.NEUTRAL) + ); + iliasConfig.addAppender( + file, + this.getLogLevel(), + ThresholdFilter.createFilter(Level.DEBUG, Filter.Result.ACCEPT, Filter.Result.NEUTRAL) + ); + iliasServerConfig.addAppender( + file, + this.getLogLevel(), + ThresholdFilter.createFilter(Level.DEBUG, Filter.Result.ACCEPT, Filter.Result.NEUTRAL) + ); + context.updateLoggers(); + this.isInitialized = true; + } + + + public String purgeString(String dirty,boolean replaceQuotes) { + + if(replaceQuotes) { + return dirty.replace('"',' ').trim(); + } + else { + return dirty.trim(); + } + } + + public String purgeString(String dirty) { + + return purgeString(dirty,false); + } + +} diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/ServerSettings.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ServerSettings.java similarity index 65% rename from Services/WebServices/RPC/lib/src/de/ilias/services/settings/ServerSettings.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ServerSettings.java index e2c78a920629..e48d34a23be4 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/settings/ServerSettings.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/settings/ServerSettings.java @@ -22,33 +22,13 @@ package de.ilias.services.settings; +import org.apache.logging.log4j.Level; +import org.apache.logging.log4j.Logger; + import java.io.File; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException; -import org.apache.avalon.framework.configuration.AbstractConfiguration; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.Logger; -import org.apache.logging.log4j.core.Filter; -import org.apache.logging.log4j.core.Layout; -import org.apache.logging.log4j.core.LoggerContext; -import org.apache.logging.log4j.core.appender.ConsoleAppender; -import org.apache.logging.log4j.core.appender.FileAppender; -import org.apache.logging.log4j.core.appender.RollingFileAppender; -import org.apache.logging.log4j.core.config.Configuration; -import org.apache.logging.log4j.core.config.Configurator; -import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder; -import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory; -import org.apache.logging.log4j.core.config.builder.api.FilterComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder; -import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder; -import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration; -import org.apache.logging.log4j.core.layout.PatternLayout; /** * Stores general server settings like rpc host and port, global log file and @@ -82,8 +62,7 @@ public class ServerSettings { /** - * @param properties - */ + */ private ServerSettings() { } @@ -122,14 +101,12 @@ public String lookupTnsAdmin() { } public String getServerUrl() { - - StringBuilder builder = new StringBuilder(); - - builder.append("http://"); - builder.append(getHostString()); - builder.append(":" + getPort()); - builder.append("/xmlrpc"); - return builder.toString(); + + String builder = "http://" + + getHostString() + + ":" + getPort() + + "/xmlrpc"; + return builder; } /** @@ -269,70 +246,6 @@ public void setIndexPath(String indexPath) throws ConfigurationException { } } - /** - * @throws ConfigurationException - * - */ - public void initLogManager() { - - - ConfigurationBuilder builder; - builder = ConfigurationBuilderFactory.newConfigurationBuilder(); - builder.setStatusLevel(this.getLogLevel()); - - LayoutComponentBuilder layout = builder.newLayout("PatternLayout") - .addAttribute("pattern", "%d{ISO8601} %-5p %t (%F:%L) - %m%n"); - - ComponentBuilder component = builder.newComponent("Policies") - .addComponent( - builder.newComponent("CronTriggeringPolicy") - .addAttribute("schedule", "0 0 0 * * ?") - ) - .addComponent( - builder.newComponent("SizeBasedTriggeringPolicy") - .addAttribute("size", "100M" - ) - ); - - // Turn console off FATAL - AppenderComponentBuilder consoleAppender = builder.newAppender("console", "Console"); - FilterComponentBuilder treshold = builder.newFilter( - "ThresholdFilter", - Filter.Result.ACCEPT, - Filter.Result.DENY - ) - .addAttribute("level", Level.ERROR); - consoleAppender - .add(layout) - .add(treshold); - - builder.add(consoleAppender); - - AppenderComponentBuilder rollingAppender = builder.newAppender("rolling", "RollingFile") - .addAttribute("fileName", this.getLogFile().getAbsolutePath()) - .addAttribute("filePattern", this.getLogFile().getAbsolutePath() + ".%i") - .add(layout) - .addComponent(component); - - builder.add(rollingAppender); - builder.add(builder.newLogger("de.ilias", this.logLevel) - .add(builder.newAppenderRef("rolling")) - .add(builder.newAppenderRef("console")) - .addAttribute("additivity", false) - ); - builder.add(builder.newLogger("org.apache", Level.FATAL) - .add(builder.newAppenderRef("rolling")) - .add(builder.newAppenderRef("console")) - .addAttribute("additivity", false) - ); - builder.add(builder.newRootLogger(Level.ERROR) - .add(builder.newAppenderRef("rolling")) - .add(builder.newAppenderRef("console")) - ); - Configurator.initialize(builder.build()); - ServerSettings.logger = LogManager.getLogger(ServerSettings.class); - - } /** * @param purgeString diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/transformation/FO2PDF.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java similarity index 53% rename from Services/WebServices/RPC/lib/src/de/ilias/services/transformation/FO2PDF.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java index 8ce749f544c0..fb88ba200932 100644 --- a/Services/WebServices/RPC/lib/src/de/ilias/services/transformation/FO2PDF.java +++ b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/FO2PDF.java @@ -23,155 +23,108 @@ package de.ilias.services.transformation; +import org.apache.fop.apps.*; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.xml.sax.SAXException; + +import javax.xml.transform.*; +import javax.xml.transform.sax.SAXResult; +import javax.xml.transform.stream.StreamSource; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; -import java.io.IOException; import java.io.InputStream; -import java.io.UnsupportedEncodingException; import java.net.URISyntaxException; -import java.net.URL; - -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.Transformer; -import javax.xml.transform.TransformerConfigurationException; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.sax.SAXResult; -import javax.xml.transform.stream.StreamSource; -import org.apache.avalon.framework.configuration.Configuration; -import org.apache.avalon.framework.configuration.ConfigurationException; -import org.apache.avalon.framework.configuration.DefaultConfigurationBuilder; - -import org.apache.fop.apps.FOUserAgent; -import org.apache.fop.apps.Fop; -import org.apache.fop.apps.FopFactory; -import org.apache.fop.apps.FormattingResults; -import org.apache.fop.apps.MimeConstants; -import org.apache.fop.apps.PageSequenceResults; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.xml.sax.SAXException; +import java.nio.charset.StandardCharsets; +import java.util.List; public class FO2PDF { - + private static FO2PDF instance = null; - - private Logger logger = LogManager.getLogger(this.getClass().getName()); + + private final Logger logger = LogManager.getLogger(this.getClass().getName()); private String foString = null; private byte[] pdfByteArray = null; - private FopFactory fopFactory = null; - - /** - * Singleton contructor - */ - public FO2PDF() - { - try - { - // add font config - URL fopConfigUrl = getClass().getResource("/de/ilias/config/fopConfig.xml"); - logger.info("Using config uri: " + fopConfigUrl.toURI()); - - // load custom config - DefaultConfigurationBuilder config = new DefaultConfigurationBuilder(); - Configuration cfg = config.build(fopConfigUrl.toURI().toString()); - - fopFactory = FopFactory.newInstance(); - fopFactory.setUserConfig(cfg); - fopFactory.getFontManager().deleteCache(); - fopFactory.getFontManager().useCache(); - - } - catch (SAXException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - catch (IOException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - catch (ConfigurationException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - catch (URISyntaxException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - + private FopFactory fopFactory = null; + + /** + * Singleton constructor + */ + public FO2PDF() { + try { + fopFactory = FopFactory.newInstance(getClass().getResource("/de/ilias/config/fopConfig.xml").toURI()); + fopFactory.getFontManager().deleteCache(); + fopFactory.getFontManager().saveCache(); + + } catch (SAXException | URISyntaxException | NullPointerException ex) { + logger.error("Cannot load fop configuration:" + ex); + } + } - - /** - * clear fop uri cache - */ - public void clearCache() { - - fopFactory.getImageManager().getCache().clearCache(); - } - - /** - * Get FO2PDF instance - * @return - */ - public static FO2PDF getInstance() { - - if(instance == null) { - return instance = new FO2PDF(); - } - return instance; - } - - /** - * Transform - * @throws TransformationException - */ + + /** + * Get FO2PDF instance + */ + public static FO2PDF getInstance() { + + if (instance == null) { + return instance = new FO2PDF(); + } + return instance; + } + + /** + * clear fop uri cache + */ + public void clearCache() { + + fopFactory.getImageManager().getCache().clearCache(); + } + public void transform() - throws TransformationException { - + throws TransformationException { + try { - logger.info("Starting fop transformation..."); - + logger.info("Starting fop transformation..."); + FOUserAgent foUserAgent = fopFactory.newFOUserAgent(); // foUserAgent.setTargetResolution(300); ByteArrayOutputStream out = new ByteArrayOutputStream(); - + Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, foUserAgent, out); - + // Setup JAXP using identity transformer TransformerFactory factory = TransformerFactory.newInstance(); Transformer transformer = factory.newTransformer(); // identity transformer - + Source src = new StreamSource(getFoInputStream()); Result res = new SAXResult(fop.getDefaultHandler()); - - transformer.transform(src,res); - + + transformer.transform(src, res); + FormattingResults foResults = fop.getResults(); - java.util.List pageSequences = foResults.getPageSequences(); - for (java.util.Iterator it = pageSequences.iterator(); it.hasNext();) { - PageSequenceResults pageSequenceResults = (PageSequenceResults)it.next(); - logger.debug("PageSequenze " - + (String.valueOf(pageSequenceResults.getID()).length() > 0 - ? pageSequenceResults.getID() : "") + List pageSequences = foResults.getPageSequences(); + for (Object pageSequence : pageSequences) { + PageSequenceResults pageSequenceResults = (PageSequenceResults) pageSequence; + logger.debug("PageSequence " + + (String.valueOf(pageSequenceResults.getID()).length() > 0 + ? pageSequenceResults.getID() : "") + " generated " + pageSequenceResults.getPageCount() + " pages."); } logger.info("Generated " + foResults.getPageCount() + " pages in total."); - + this.setPdf(out.toByteArray()); - } - catch (SAXException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - catch (IOException ex) { - logger.error("Cannot load fop configuration:" + ex); - } - catch (TransformerConfigurationException e) { - logger.warn("Configuration exception: " + e); + } catch (TransformerConfigurationException e) { + logger.warn("Configuration exception: " + e); + throw new TransformationException(e); + } catch (TransformerException e) { + logger.warn("Transformer exception: " + e); throw new TransformationException(e); - } - catch (TransformerException e) { - logger.warn("Transformer exception: " + e); + } catch (FOPException e) { throw new TransformationException(e); - } + } } @@ -181,8 +134,8 @@ public void transform() public String getFoString() { return foString; } - - + + /** * @param foString The foString to set. */ @@ -193,15 +146,13 @@ public void setFoString(String foString) { public byte[] getPdf() { return this.pdfByteArray; } - + public void setPdf(byte[] ba) { - this.pdfByteArray = ba; } - - private InputStream getFoInputStream() throws UnsupportedEncodingException { - - return new ByteArrayInputStream(getFoString().getBytes("utf8")); + + private InputStream getFoInputStream() { + return new ByteArrayInputStream(getFoString().getBytes(StandardCharsets.UTF_8)); } } diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/transformation/RPCTransformationHandler.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/RPCTransformationHandler.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/transformation/RPCTransformationHandler.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/RPCTransformationHandler.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/transformation/TransformationException.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/TransformationException.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/transformation/TransformationException.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/transformation/TransformationException.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/services/xml/XMLUtils.java b/Services/WebServices/RPC/lib/src/main/java/de/ilias/services/xml/XMLUtils.java similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/services/xml/XMLUtils.java rename to Services/WebServices/RPC/lib/src/main/java/de/ilias/services/xml/XMLUtils.java diff --git a/Services/WebServices/RPC/lib/src/de/ilias/config/fopConfig.xml b/Services/WebServices/RPC/lib/src/main/resources/de/ilias/config/fopConfig.xml similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/config/fopConfig.xml rename to Services/WebServices/RPC/lib/src/main/resources/de/ilias/config/fopConfig.xml diff --git a/Services/WebServices/RPC/lib/src/de/ilias/config/unifont.ttf b/Services/WebServices/RPC/lib/src/main/resources/de/ilias/config/unifont.ttf similarity index 100% rename from Services/WebServices/RPC/lib/src/de/ilias/config/unifont.ttf rename to Services/WebServices/RPC/lib/src/main/resources/de/ilias/config/unifont.ttf diff --git a/Services/WebServices/RPC/lib/src/main/resources/log4j2.properties b/Services/WebServices/RPC/lib/src/main/resources/log4j2.properties new file mode 100644 index 000000000000..2a91110f9856 --- /dev/null +++ b/Services/WebServices/RPC/lib/src/main/resources/log4j2.properties @@ -0,0 +1,38 @@ +# see: https://logging.apache.org/log4j/2.x/manual/layouts.html#Patterns +property.pattern = %-5p %t (%F:%L) - %m%n + +appender.consoleMin.type = Console +appender.consoleMin.name = ConsoleMin +appender.consoleMin.filter.threshold.type = ThresholdFilter +appender.consoleMin.filter.threshold.level = ERROR +appender.consoleMin.layout.type = PatternLayout +appender.consoleMin.layout.pattern = ${pattern} + +appender.consoleMax.type = Console +appender.consoleMax.name = ConsoleMax +appender.consoleMax.filter.threshold.type = ThresholdFilter +appender.consoleMax.filter.threshold.level = INFO +appender.consoleMax.layout.type = PatternLayout +appender.consoleMax.layout.pattern = ${pattern} + +# Root logger only errors (org.apache, ...) +rootLogger.appenderRef.Console.ref = ConsoleMin +rootLogger.level = ERROR + +logger.xmlrpc.name = org.apache.xmlrpc +logger.xmlrpc.appenderRef.Console.ref = ConsoleMin +logger.xmlrpc.level = FATAL +logger.xmlrpc.additivity = false + +# de.ilias. Level is set programmatically using ilServer.ini LogLevel and LogFile +logger.ilias.name = de.ilias +logger.ilias.appenderRef.Console.ref = ConsoleMin +logger.ilias.level = ALL +logger.ilias.additivity = false + +# de.ilias.ilServer main class uses console filter limited to INFO which should be sufficient for systemd messages. +logger.iliasServer.name = de.ilias.ilServer +logger.iliasServer.appenderRef.Console.ref = ConsoleMax +logger.iliasServer.level = ALL +logger.iliasServer.additivity = false + diff --git a/docs/development/code-examples/repository-pattern/02_mock_for_developement/ilGeoLocationFileMockRepository.php b/docs/development/code-examples/repository-pattern/02_mock_for_developement/ilGeoLocationFileMockRepository.php index 3adc5cbdf015..3bbfb42c872f 100644 --- a/docs/development/code-examples/repository-pattern/02_mock_for_developement/ilGeoLocationFileMockRepository.php +++ b/docs/development/code-examples/repository-pattern/02_mock_for_developement/ilGeoLocationFileMockRepository.php @@ -1,267 +1,249 @@ -readFileAndReturnAsList($file); - fclose($file); - - // Update searched object in list - foreach($geo_locations as $key => $row) - { - if($row[0] == $a_obj->getId()) - { - $row[1] = $a_obj->getTitle(); - $row[2] = $a_obj->getLatitude(); - $row[3] = $a_obj->getLongitude(); - $row[4] = $a_obj->getExpirationAsTimestamp(); - } - } - - // Write back all geo locations to file - $file = fopen('mocked_geolocation_data.txt', 'w'); - $this->writeGeoLocationListToFile($file, $geo_locations); - fclose($file); - } - - /** - * Example for updating multiple objects at once - */ - public function updateGeoLocationTimestampByCoordinates(float $a_searched_latitude, float $a_searched_longitude, \DateTimeImmutable $a_update_timestamp) - { - // Read entire file - $file = fopen('mocked_geolocation_data.txt', 'r'); - $geo_locations = $this->readFileAndReturnAsList($file); - fclose($file); - - // Update searched objects in list - foreach($geo_locations as $key => $row) - { - if($row[2] == $a_searched_latitude && $row[3] == $a_searched_longitude) - { - $row[4] = $a_update_timestamp->getTimestamp(); - } - } - - // Write back all geo locations to file - $file = fopen('mocked_geolocation_data.txt', 'w'); - $this->writeGeoLocationListToFile($file, $geo_locations); - fclose($file); - } - - /** - * Delete single geo location identified by its id - */ - public function deleteGeoLocation(int $a_id) - { - $file = fopen('mocked_geolocation_data.txt', 'r'); - $geo_locations = $this->readFileAndReturnAsList($file); - fclose($file); - - // Delete searched object from list - foreach($geo_locations as $key => $row) - { - // Check if current row has searched id - if($row[0] == $a_id) - { - unset($geo_locations[$key]); - } - } - - // Write back all geo locations to file - $file = fopen('mocked_geolocation_data.txt', 'w'); - $this->writeGeoLocationListToFile($file, $geo_locations); - fclose($file); - } - - public function deleteGeoLocationsByCoordinates(float $a_latitude, float $a_longitude) - { - // Read all geo locations from file - $file = fopen('mocked_geolocation_data.txt', 'r'); - $geo_locations = $this->readFileAndReturnAsList($file); - fclose($file); - - // Filter out expired objects - $now = new DateTimeImmutable(); - foreach($geo_locations as $key => $row) - { - // Check if current row has searched attributes - if($row[2] == $a_latitude && $row[3] == $a_longitude) - { - unset($geo_locations[$key]); - } - } - - // Write objects back to file - $file = fopen('mocked_geolocation_data.txt', 'w'); - $this->writeGeoLocationListToFile($file, $geo_locations); - fclose($file); - } - - /** - * Example for a condition based deletion of multiple geo locations - */ - public function deleteExpiredGeoLocations() - { - // Read all geo locations from file - $file = fopen('mocked_geolocation_data.txt', 'r'); - $geo_locations = $this->readFileAndReturnAsList($file); - fclose($file); - - // Filter out expired objects - $now = new DateTimeImmutable(); - foreach($geo_locations as $key => $row) - { - // Check if current row contains an expired timestamp - // Note: This is an example but it needs to be tested if differences can be calculated like this - $dt = new DateTimeImmutable($row[4]); - if($now->diff($dt)->s >= 0) - { - unset($geo_locations[$key]); - } - } - - // Write objects back to file - $file = fopen('mocked_geolocation_data.txt', 'w'); - $this->writeGeoLocationListToFile($file, $geo_locations); - fclose($file); - } - - /** - * Protected function. Just for development purpose - */ - protected function readFileAndReturnAsList($file) - { - $geo_locations = array(); - while($row = fgetcsv($file)) $geo_locations[] = $row; - return $geo_locations; - } - - /** - * Protected function. Just for development purpose - */ - protected function writeGeoLocationListToFile($file, $list) - { - foreach($list as $obj_data) - { - // implode(';', $list) . "\n"; // <- this way might also work - $write_string = $obj_data[0].';'.$obj_data[1].';'.$obj_data[2].';'.$obj_data[3].';'.$obj_data[4]."\n"; - fwrite($file, $write_string . "\n"); - } - } + /** + * Create a new geo location entry + */ + public function createGeoLocation( + string $a_title, + float $a_latitude, + float $a_longitude, + \DateTimeImmutable $a_expiration_timestamp + ) : ilGeoLocation { + // Generate a random object id. This should just work fine for development + $generated_id = rand(1, 100000); + $file = fopen('mocked_geolocation_data.txt', FILE_APPEND); + + // Create a csv-string for object data for the file + $write_string = "$generated_id;$a_title;$a_latitude;$a_longitude;$a_expiration_timestamp\n"; + + // Write new object to file + fwrite($file, $write_string); + fclose($file); + + return new ilGeoLocation( + $generated_id, + $a_title, + $a_latitude, + $a_longitude, + $a_expiration_timestamp + ); + } + + /** + * Get a single geo location, identified by its id + */ + public function getGeoLocationById(int $a_id) : ilGeoLocation + { + $file = fopen('mocked_geolocation_data.txt', 'r'); + + // Go line by line through the file and return object if it was found + while ($row = fgetcsv($file)) { + if ($row[0] == $a_id) { + return new ilGeoLocation((int) $a_id, $row[1], (float) $row[2], (float) $row[3], new DateTimeImmutable($row[4])); + } + } + + throw new \InvalidArgumentException("Unknown id for geolocation: $a_id"); + } + + /** + * Example for reading an array of geo locations which have a given attribute + */ + public function getGeoLocationsByCoordinates(float $a_latitude, float $a_longitude) : array + { + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = array(); + + // Go line by line through the file and add searched objects to list + while ($row = fgetcsv($file)) { + if ($row[2] == $a_latitude && $row[3] == $a_longitude) { + $geo_locations[] = new ilGeoLocation((int) $row[0], $row[1], (float) $row[2], (float) $row[3], new DateTimeImmutable($row[4])); + } + } + + return $geo_locations; + } + + /** + * Example for checking if a geo location (one or more) with a given attribute exists + */ + public function ifGeoLocationExistsById(int $a_id) : bool + { + $file = fopen('mocked_geolocation_data.txt', 'r'); + + // Go line by line through the file and search for given id + while ($row = fgetcsv($file)) { + if ($row[0] == $a_id) { + return true; + } + } + + return false; + } + + + /** + * Example for checking if a geo location (one or more) with a given attribute exists + */ + public function ifAnyGeoLocationExistsByCoordinates(float $a_latitude, float $a_longitude) : bool + { + $file = fopen('mocked_geolocation_data.txt', 'r'); + + // Go line by line through the file and search for given attributes + while ($row = fgetcsv($file)) { + if ($row[2] == $a_latitude && $row[3] == $a_longitude) { + return true; + } + } + + return false; + } + + /** + * Update all attributes of a given geo location + */ + public function updateGeoLocation(ilGeoLocation $a_obj) + { + // Read entire file + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = $this->readFileAndReturnAsList($file); + fclose($file); + + // Update searched object in list + foreach ($geo_locations as $key => $row) { + if ($row[0] == $a_obj->getId()) { + $row[1] = $a_obj->getTitle(); + $row[2] = $a_obj->getLatitude(); + $row[3] = $a_obj->getLongitude(); + $row[4] = $a_obj->getExpirationAsTimestamp(); + } + } + + // Write back all geo locations to file + $file = fopen('mocked_geolocation_data.txt', 'w'); + $this->writeGeoLocationListToFile($file, $geo_locations); + fclose($file); + } + + /** + * Example for updating multiple objects at once + */ + public function updateGeoLocationTimestampByCoordinates(float $a_searched_latitude, float $a_searched_longitude, \DateTimeImmutable $a_update_timestamp) + { + // Read entire file + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = $this->readFileAndReturnAsList($file); + fclose($file); + + // Update searched objects in list + foreach ($geo_locations as $key => $row) { + if ($row[2] == $a_searched_latitude && $row[3] == $a_searched_longitude) { + $row[4] = $a_update_timestamp->getTimestamp(); + } + } + + // Write back all geo locations to file + $file = fopen('mocked_geolocation_data.txt', 'w'); + $this->writeGeoLocationListToFile($file, $geo_locations); + fclose($file); + } + + /** + * Delete single geo location identified by its id + */ + public function deleteGeoLocation(int $a_id) + { + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = $this->readFileAndReturnAsList($file); + fclose($file); + + // Delete searched object from list + foreach ($geo_locations as $key => $row) { + // Check if current row has searched id + if ($row[0] == $a_id) { + unset($geo_locations[$key]); + } + } + + // Write back all geo locations to file + $file = fopen('mocked_geolocation_data.txt', 'w'); + $this->writeGeoLocationListToFile($file, $geo_locations); + fclose($file); + } + + public function deleteGeoLocationsByCoordinates(float $a_latitude, float $a_longitude) + { + // Read all geo locations from file + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = $this->readFileAndReturnAsList($file); + fclose($file); + + // Filter out expired objects + $now = new DateTimeImmutable(); + foreach ($geo_locations as $key => $row) { + // Check if current row has searched attributes + if ($row[2] == $a_latitude && $row[3] == $a_longitude) { + unset($geo_locations[$key]); + } + } + + // Write objects back to file + $file = fopen('mocked_geolocation_data.txt', 'w'); + $this->writeGeoLocationListToFile($file, $geo_locations); + fclose($file); + } + + /** + * Example for a condition based deletion of multiple geo locations + */ + public function deleteExpiredGeoLocations() + { + // Read all geo locations from file + $file = fopen('mocked_geolocation_data.txt', 'r'); + $geo_locations = $this->readFileAndReturnAsList($file); + fclose($file); + + // Filter out expired objects + $now = new DateTimeImmutable(); + foreach ($geo_locations as $key => $row) { + // Check if current row contains an expired timestamp + // Note: This is an example but it needs to be tested if differences can be calculated like this + $dt = new DateTimeImmutable($row[4]); + if ($now->diff($dt)->s >= 0) { + unset($geo_locations[$key]); + } + } + + // Write objects back to file + $file = fopen('mocked_geolocation_data.txt', 'w'); + $this->writeGeoLocationListToFile($file, $geo_locations); + fclose($file); + } + + /** + * Protected function. Just for development purpose + */ + protected function readFileAndReturnAsList($file) + { + $geo_locations = array(); + while ($row = fgetcsv($file)) { + $geo_locations[] = $row; + } + return $geo_locations; + } + + /** + * Protected function. Just for development purpose + */ + protected function writeGeoLocationListToFile($file, $list) + { + foreach ($list as $obj_data) { + // implode(';', $list) . "\n"; // <- this way might also work + $write_string = $obj_data[0] . ';' . $obj_data[1] . ';' . $obj_data[2] . ';' . $obj_data[3] . ';' . $obj_data[4] . "\n"; + fwrite($file, $write_string . "\n"); + } + } } diff --git a/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculator.php b/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculator.php index 07d64989606c..fc7b23bf22fa 100644 --- a/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculator.php +++ b/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculator.php @@ -1,32 +1,31 @@ -geo_repository = $a_geo_repository; - } + public function __construct(ilGeoLocationRepository $a_geo_repository) + { + $this->geo_repository = $a_geo_repository; + } - public function calculateTimeTillNextExpiredGeoLocationAt(float $latitude, float $longitude) - { - $geo_locations = $this->geo_repository->getGeoLocationsByCoordinates($latitude, $longitude); + public function calculateTimeTillNextExpiredGeoLocationAt(float $latitude, float $longitude) + { + $geo_locations = $this->geo_repository->getGeoLocationsByCoordinates($latitude, $longitude); - if (count($geo_locations) === 0) { - return null; - } + if (count($geo_locations) === 0) { + return null; + } - $current = array_shift($geo_locations); + $current = array_shift($geo_locations); - foreach($geo_locations as $geo_location) - { - if($current->getExpirationAsTimestamp() >= $geo_location->getExpirationAsTimestamp()) { - $current = $geo_location; - } - } + foreach ($geo_locations as $geo_location) { + if ($current->getExpirationAsTimestamp() >= $geo_location->getExpirationAsTimestamp()) { + $current = $geo_location; + } + } - return $geo_location; - } + return $geo_location; + } } diff --git a/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculatorTest.php b/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculatorTest.php index 9bfdd733b8c1..9117741274a5 100644 --- a/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculatorTest.php +++ b/docs/development/code-examples/repository-pattern/03_use_for_unit_tests/ilGeoLocationCalculatorTest.php @@ -1,34 +1,33 @@ -createMock(ilGeoLocationRepository::class); - $mocked_repo->expects($this->once()) - ->method('getGeoLocationsByCoordinates') - ->with(1, 2) - ->will($this->returnValue(array($obj1, $obj2))); - $calc = new ilGeoLocationCalculator($mocked_repo); + // Arrange + $obj1 = new ilGeoLocation(1, "older", 0, 0, new \DateTimeImmutable($before)); + $obj2 = new ilGeoLocation(1, "newer", 0, 0, new \DateTimeImmutable($now)); + $mocked_repo = $this->createMock(ilGeoLocationRepository::class); + $mocked_repo->expects($this->once()) + ->method('getGeoLocationsByCoordinates') + ->with(1, 2) + ->will($this->returnValue(array($obj1, $obj2))); + $calc = new ilGeoLocationCalculator($mocked_repo); - // Act - $result = $calc->calculateNearestExpiration(1, 2); + // Act + $result = $calc->calculateNearestExpiration(1, 2); - // Assert - $this->assertEqual($result, $before); - } + // Assert + $this->assertEqual($result, $before); + } } diff --git a/docs/development/development-process.md b/docs/development/development-process.md new file mode 100644 index 000000000000..a975a75054da --- /dev/null +++ b/docs/development/development-process.md @@ -0,0 +1,53 @@ +# The Development Process + +ILIAS software is developed in a community-based open source process and published under the [General Public Licence version 3](https://www.gnu.org/licenses/gpl-3.0.html) (see also [licence](https://github.com/ILIAS-eLearning/ILIAS/blob/trunk/LICENSE) information in source code). This page describes how you can get involved in the software development of ILIAS and what you have to take into consideration. The ILIAS feature development process consists of these major steps: + +## 1. Having an idea +Anyone who envisages an improvement or extension of ILIAS should share ideas with the user community. An optional first step is to discuss your idea in the ILIAS forums. A mandatory step to bring anything into the ILIAS development is to add your idea to the Feature Wiki and to put it onto our Jour Fixe agenda. +Notice: You do not need to have any funding suggesting a new feature. But the chance that your suggestion becomes part of ILIAS is much higher when you - or someone else - has funding to pay the developers. + +## 2. Community Discussion +In the Feature Wiki all community members are invited to share their ideas and comments. Often the responsible maintainer (see list of maintainers) of the feature is also adding comments or ideas to a feature request. This step of the development process should create a common understanding of the feature and generalise its concept to make the feature usable for as much users as possible. + +## 3. Jour Fixe Decision +The decision whether a new feature should be part of a future ILIAS release or not is made in the bi-weekly Jour Fixe. In this meeting the ILIAS Product Manager, members of the Technical Board, developers of ILIAS components and interested community members meet to discuss the current ILIAS development. The final decision is taken by Product Manager and responsible maintainer. Decision and reasons are documented in the agenda of the meeting and published in the Feature Wiki, see list of Jour Fixes. + +Notice: Everytime you want the Jour Fixe to get involved in the discussion or to make a decision, put the topic on the Jour Fixe agenda. Sometimes the core team asks for additional concepts papers, use cases or mock-ups, especially when it comes to more complex features. All this is documented in the Feature Wiki. + +## 4. Funding +Every suggested feature needs funding to be implemented. If funding is not settled yet, the community is asked to look for supporters of new features. Sometimes multiple institutions join to fund a new development. For selected features the ILIAS society is setting up crowdfunding activities, see here. + +## 5. Implementation +Usually, new features extend existing components of ILIAS. In this case, there are two ways to implement the new feature depending on which model is applied to the related component: + +1. In case the component is developed under the coordinator model, every developer can implement the feature and make a pull request (PR) against the trunk of ILIAS. One of the responsible coordinators will revise the PR, maybe ask for changes and finally approve the code changes. The PR then can be merged to trunk. +2. In case the component is developed under classic maintainership, the first maintainer usually takes care of the implementation and commits the changed code to trunk. + +Which component is currently developed under which model is documented on the page Component Maintainers and Testers. The same page is also available in GitHub. +Everybody who wants to provide pull requests for extending existing components or even add new components to ILIAS has to follow our rules for getting involved as developer. Every developer has to respect the guidelines described within this document. +Developers need to create their own feature branches for development and approval by customer before merging code to the trunk following the procedure above. All new features must be integrated until Coding Completed (see the timeline of each ILIAS version in the Feature Wiki). + +## 6. Testing and Bug Reporting +New source code has always to be tested locally by the programmer on his or her installation before committing it to the GitHub repository of ILIAS. Every new feature is also tested by the customer that has ordered this implementation. If the customer has accepted the feature it is committed to the trunk of ILIAS. +Test cases to test this feature have to be available with the implementation of the feature (with the first beta release at the latest). They can be written by the customer or the service provider. During the beta phase of the upcoming version new and existing features are tested by voluntary community testers, see list of component testers. Testing is done on a dedicated test installation and supported by Testrail test case management system. +All bugs discovered in maintained ILIAS versions have to be reported to our Mantis bug tracker where they are assigned to the responsible maintainer and treated according to the defined bugfixing process, see below. + +![Schematic of the bug fixing process](https://files.ilias.de/images/bug_fixing_process.png) +*Bug fixing process as defined and accepted by General Meeting of Members in Bern 2015* + +## 7. Documentation +The user documentation of ILIAS is currently based on the instructions coming from the ILIAS online help and will be extended step-by-step in the next time. The former user documentation (Docu World) from ILIAS service provider Qualitus is no longer maintained. The online help for ILIAS is coordinated by the Head of Help and written and updated by a group of community members (currently only available in German). + +## 8. Release and Maintenance +In the last step a new release is packed and published. Major ILIAS releases are published once a year. Stable versions are to be used for productive systems. For each major release a number of maintenance releases will be published for up to two years. Information about every published release is added to the Roadmap and Releases document. +Major releases are identified by the first number of the release, e.g. 6.0, 7.0, 8.0. Major releases include new features and are published once a year. + +For maintenance releases (aka bug fix releases) the last number is incremented, e.g. 7.9, 7.10, 7.11. Bug fix releases do not include new features. Upgrading should be usually painless and customized templates or style sheets should not be affected. + +### Typical Major Release Timeline + +- New features can be suggested for an upcoming release until feature freeze, usually end of April. Already before and also after feature freeze, the core team decides which features will go into the new release and which not. The decisions are documented in the feature wiki. +- Coding of the new feature can already begin as soon as the ILIAS trunk is opened for the new version. This happens straight after Coding Completed of the former ILIAS version and the creation of a release branch for this version. +- All features for an upcoming ILIAS version have to be fully developed until Coding Completed. After Coding Completed only bug fixes and usabilty improvements are allowed to commit. +- Community testing starts as soon as the first beta release of an upcoming ILIAS version has been published. The ILIAS society provides general testing installations for all for each major release, e.g. test7.ilias.de, test8.ilias.de. +- Our target for a stable major release is usually March. \ No newline at end of file diff --git a/docs/development/use-developer-mode.md b/docs/development/use-developer-mode.md new file mode 100644 index 000000000000..065c1ef04d52 --- /dev/null +++ b/docs/development/use-developer-mode.md @@ -0,0 +1,36 @@ +# Developer Mode + +Sometimes features that are not implemented completely need to be committed to CVS because several programmers work on the same source code or new features or objects should be tested on dependencies to other parts of ILIAS. For these cases we have created the possibility to set parts of the system or whole object types into **developer mode**. + +Object types or functions in developer mode are not shown in ILIAS by default. So users are not affected with features that are not working properly yet. + +## Activating Objects + +To display functions in developer mode please add the following line in your `client.ini` in the `[system]` section: + +```php +DEVMODE = "1" +``` + +Now you will see everything as usual. + +If you delete the line or set the value to 0 you will disable developer mode again. + +## How to Use DEVMODE for Programming + +To hide entire object types by setting them to DEVMODE just add a new attribute to the desired object in `objects.xml`, e.g.: + +```xml + +``` + +In this case group objects will now not longer appear in the system. + +To hide particular code parts or functions use the new constant DEVMODE: + +```php +if (DEVMODE) + { + // do something only if devmode is activated + } +``` \ No newline at end of file diff --git a/docs/development/use-exceptions.md b/docs/development/use-exceptions.md new file mode 100644 index 000000000000..b52b569de69a --- /dev/null +++ b/docs/development/use-exceptions.md @@ -0,0 +1,104 @@ +# Using Exceptions + +If code identifies any problems that prevent the normal processing from being executed, e.g. a directory is not writable even if it should be, exceptions should be thrown. This usually happens within the application layer. Upper contexts that have called the application classes (e.g. GUI or SOAP) can act appropriate. E.g. the user interface layour can present the error using `ilUtil::sendFailure`. + +## Defining new Exceptions + +- New exceptions should be implemented as classes derived from `ilException` (found in component Services/Exceptions). +- These class file should be put into a subdirectory `exceptions` within the component directory, e.g. `Services/AdvancedEditing/exceptions`. +- If a component uses exceptions a top exception named after the component should be used. Other exceptions classes should be derived from this class, e.g. `Services/AdvancedEditing/exceptions/class.ilAdvancedEditingException.php`. + + +```php + + * @version $Id$ + * + */ +class ilAdvancedEditingException extends ilException +{ + /** + * Constructor + * + * A message is not optional as in build in class Exception + * + * @param string $a_message message + */ + public function __construct($a_message) + { + parent::__construct($a_message); + } +} +?> +``` + + +## Throwing and Catching Exceptions +Throwing an exception: + +```php +function update() +{ + if (!$this->getId()) + { + throw new ilObjectException('No id given'); + } +} +``` + +Catching an exception (in this case in the GUI layer): + +```php +try +{ + $this->object->setTitle($title); + $this->object->update(); + ilUtil::sendSuccess($this->lng->txt('saved_settings')); + return true; +} +catch (ilObjectException $e) +{ + ilUtil::sendFailure($e->getMessage()); + return false; +} +``` + + +## Exception Wrapping +Advantages of exception wrapping are: + +- Exception wrapping avoids the breaking of layer abstractions +- Exception wrapping gives layers the possibility to add context informations to the exception + +```php +Exception Wrapping I (application class): +... + try + { + $parser = new ilSaxParser($this->xml); + $parser->parse(); + ... + { + catch (ilSaxParserException $e) + { + throw new ilObjectException(?Cannot parse object XML: ?.e->getMessage()); + } +... + +Exception Wrapping II (here: GUI class): + +... + try + { + $this->object->import(); + lUtil::sendSuccess($this->$lng('obj_created')); + } + catch(ilObjectException $e) +``` \ No newline at end of file diff --git a/docs/development/write-unit-tests.md b/docs/development/write-unit-tests.md new file mode 100644 index 000000000000..cc4e7ecee06a --- /dev/null +++ b/docs/development/write-unit-tests.md @@ -0,0 +1,125 @@ +# Writing Unit Tests + +ILIAS supports unit testing with the PHPUnit testing framework. We highly recommend their [excellent documentation](https://phpunit.de/) that explains the basic ideas of unit testing, how PHPUnit works and how it is installed. + +## Configuration +After installing PHPUnit on your machine you need to configure ILIAS to work with it. The test cases are performed with an authenticated user in your ILIAS installation. The configuration determines which user is used to perform the test cases. You will find a configuration file template at: + +`Services/PHPUnit/config/cfg.phpunit.template.php` + +Make a copy at: + +`Services/PHPUnit/config/cfg.phpunit.php` + +Now change the file and provide a valid client ID, account ID, and username. + +>*Please activate the [developer mode](https://docu.ilias.de/goto_docu_pg_1082_42.html) in your `client.ini.php` when running PHPUnit tests.* + +## Test Cases +Test classes should be located in a subdirectory test of your module or service directory. + +`[Services/Modules]/[ComponentName]/test` + +E.g. the test classes for the Administration service are located at `Services/Administration/test`. The names for test class files should usually be derived from the application class they are written for. + +`[ApplicationClassName]Test.php` + +E.g. if you write test cases for a class ilSetting the test class file should be named `ilSettingTest.php`. + +The class should contain a method starting with "test" for each test case. + +```php +set("foo", "bar"); + $value = $set->get("foo"); + + $this->assertEquals("bar", $value); + } +[...] +} +?> +``` + +- Your test class must be **derived from class PHPUnit_Framework_TestCase**. +- Your test must be executable with **PHPUnit 5.7**. +- If your test needs an ILIAS Installation, it must be annotated with **@group needsInstalledILIAS**, and... + - you must set **$backupGlobals to false**, otherwise, your test cases will not work. + - the setUp() method should contain the **ilUnitUtil::performInitialisation();** call. ilUnitUtil can be found in Services/PHPUnit/classes. +- If your test does not need an ILIAS Installation, it must not be annotated with @group needsInstalledILIAS and also should not use ilUnitUtil::performInitialisation(). + +To run your test class you simply call phpunit in your ILIAS root directory with the local path of your test class (omit the .php suffix): + +`> phpunit Services/Administration/test/ilSettingTest` + + +>1. *Please write your test cases in a way that the* ***requirements to run them are minimal***. *The test cases should run on a usual system. They should not require that certain conditions are given on the test system, e.g. an empty repository.* +>2. ***Clean up the data*** *that is written during the test case. If possible, a test run should not leave any data created during the test in the system.* + +## Test Suites +Test suites allow to perform aggregated tests. They should be provided on the component level, one test suite for each service and module. The file name must follow the format: +`il[Services/Modules][ComponentName]Suite.php` + +E.g. the test suite class for the Administration service is located at: +`Services/Administration/test/ilServicesAdministrationSuite.php` + +The class is named: +`ilServicesAdministrationSuite` + +```php +addTestSuite("ilSettingTest"); + [...] + + return $suite; + } +} +?> +``` + +The example outlines the basic structure of a test suite class. To run the test suite, simply pass the class name to phpunit in the ILIAS main directory: +`> phpunit Services/Administration/test/ilServicesAdministrationSuite` + +## The Global Test Suite +The global test suite scans all Services and Modules directory automatically for component level test suites and aggregates them to one big test suite. The suite is located in the PHPUnit Service. You can run the suite by typing: +`> phpunit Services/PHPUnit/test/ilGlobalSuite` + +The global suite will first list all component suites that are included in execution. If your suite is not listed, you should check whether your suite file and class is following the naming conventions as written in the previous section. \ No newline at end of file diff --git a/lang/ilias_de.lang b/lang/ilias_de.lang index 80b56a2dfa3a..6b79e87b82b9 100644 --- a/lang/ilias_de.lang +++ b/lang/ilias_de.lang @@ -848,6 +848,7 @@ assessment#:#longmenu_answeroptions_differ#:#Diese Frage funktioniert nicht rich assessment#:#longmenu_text#:#‘Long Menu’-Text assessment#:#mailnottype#:#Ein Versand findet auch beim Beenden einzelner Testdurchläufe statt assessment#:#mailnottype_desc#:#Der Besitzer des Tests wird auch dann benachrichtigt, wenn die Anzahl Durchläufe nicht beschränkt ist. +assessment#:#mainbar_button_label_questionlist#:#Fragenliste assessment#:#maintenance#:#Wartung assessment#:#manscoring#:#Manuelle Bewertung assessment#:#manscoring_done#:#Bereits bewertete Teilnehmer @@ -1136,6 +1137,11 @@ assessment#:#result_units_info#:#Zum Beantworten der Frage werden die aktivierte assessment#:#result_x#:#Ergebnis %s assessment#:#results#:#Ergebnisse assessment#:#results_tab#:#Ergebnisse +assessment#:#resulttable_all#:#Alle +assessment#:#resulttable_correct#:#Korrekte +assessment#:#resulttable_incorrect#:#Inkorrekte/Unvollständige +assessment#:#resulttable_vc_sort_iooa#:#Reihenfolge im Test +assessment#:#resulttable_vc_sort_posscore#:#Höchste (mögliche) Punktzahl zuerst assessment#:#review_view#:#Vorschau assessment#:#saveOrder#:#Sortierung abspeichern assessment#:#saveOrderAndObligations#:#Sortierung und Obligationen abspeichern @@ -1191,6 +1197,7 @@ assessment#:#suggest_range#:#Bereich vorschlagen assessment#:#suggestedSolutionType#:#verweisen auf assessment#:#suggested_solution#:#Inhalte zur Wiederholung assessment#:#suggested_solution_added_successfully#:#Der Hinweis auf Inhalte zur Wiederholung wurde erfolgreich hinzugefügt! +assessment#:#ta_resulttable_vc_mode_aria#:#Anzeigeoptionen für Fragen assessment#:#tab_nest_answers#:#Einrückung assessment#:#term#:#Term assessment#:#term_image#:#Bild @@ -1338,6 +1345,8 @@ assessment#:#tst_dont_show_msg_again_in_current_session#:#Diese Meldung in meine assessment#:#tst_dont_use_previous_answers#:#Ihre vorherigen Antworten werden in zukünftigen Testdurchläufen nicht als vorgegebene Werte verwendet assessment#:#tst_edit_competence_assign#:#Bearbeite Zuordnungs-Eigenschaften assessment#:#tst_edit_scoring#:#Ändere Bewertung +assessment#:#tst_enable_questionlist#:#Fragenliste +assessment#:#tst_enable_questionlist_description#:#Teilnehmer können sich links neben den Testfragen eine Fragenliste anzeigen lassen. assessment#:#tst_ending_time#:#Ende assessment#:#tst_ending_time_before_starting_time#:#Bitte geben Sie für das Ende des Tests ein Datum ein, das nach dem Startdatum liegt. assessment#:#tst_ending_time_desc#:#Zeitpunkt, ab dem Teilnehmer keine Antworten mehr abgeben können. Wichtig: Benutzen Sie diese Option nicht für E-Klausuren/Fernklausuren. Verwenden Sie stattdessen die Funktion „Bearbeitungsdauer begrenzen“, siehe unten. Nur dann wird der Test serverseitig beendet und die letzte Eingabe jedes Teilnehmers automatisch gespeichert. @@ -1815,8 +1824,8 @@ assessment#:#tst_show_solution_signature#:#Platzhalter für Unterschrift assessment#:#tst_show_solution_signature_desc#:#Ist die Option „Detaillierte Testergebnisse anzeigen“ oder „Druckbare Liste der Antworten“ aktiviert, fügt ILIAS zusätzlich ein Unterschriftenfeld in den Ausdruck ein. In diesem kann die Person, die den Test durchgeführt hat, unterschreiben. assessment#:#tst_show_solution_suggested#:#Inhalte zur Wiederholung assessment#:#tst_show_solution_suggested_desc#:#Falls den Fragen im Test Inhalte zur Wiederholung des Stoffs zugeordnet wurden, werden diese angezeigt. Sie müssen die Option "Detaillierte Testergebnissen anzeigen" aktivieren, um diese Funktion zu nutzen. Teilnehmerinnen und Teilnehmer können so etwaige Wissenslücken schließen. -assessment#:#tst_show_summary#:#Fragenliste und Bearbeitungstand anzeigen -assessment#:#tst_show_summary_description#:#Teilnehmer können sich links neben den Testfragen eine Fragenliste anzeigen lassen. Mit dem Button 'Bearbeitungsstand' rufen die Teilnehmer eine Ãœbersicht auf, die zeigt, welche Fragen sie jeweils bereits bearbeitet oder markiert haben. Das Verhalten der Ãœbersicht 'Bearbeitungsstand' können Sie noch weiter konfigurieren: +assessment#:#tst_show_summary#:#Bearbeitungsstand +assessment#:#tst_show_summary_description#:#Mit der Schaltfläche 'Bearbeitungsstand' können Teilnehmer eine Ãœbersicht aufrufen, die zeigt, welche Fragen sie jeweils bereits bearbeitet oder markiert haben. Das Verhalten des 'Bearbeitungsstand' können Sie noch weiter konfigurieren: assessment#:#tst_show_toplist#:#Platzierung assessment#:#tst_shuffle_questions#:#Fragen mischen assessment#:#tst_shuffle_questions_description#:#Die Reihenfolge der Fragen wird pro Teilnehmer und pro Testdurchlauf neu gemischt. @@ -9115,6 +9124,7 @@ exc#:#exc_global_feedback_file_date#:#Verfügbarkeit exc#:#exc_global_feedback_file_date_deadline#:#Nach dem Abgabetermin exc#:#exc_global_feedback_file_date_upload#:#Nach der Abgabe exc#:#exc_go_to_exercise#:#Zur Ãœbung +exc#:#exc_graded_mem_notified#:#Alle ausgewählten Teilnehmer mit einer Bewertung wurden benachrichtigt. exc#:#exc_grades#:#Notenübersicht exc#:#exc_grades_overview#:#Notenübersicht exc#:#exc_hand_in#:#Datei abgeben @@ -9154,6 +9164,8 @@ exc#:#exc_min_nr_info#:#Dieser Wert muss mindestens so hoch sein, wie die Anzahl exc#:#exc_min_team_participants#:#Minimale Anzahl exc#:#exc_msg_all_mandatory_ass#:#Sie müssen alle verpflichtenden Ãœbungseinheiten bestehen, um die Ãœbung als ganze zu bestehen. exc#:#exc_msg_failed_mandatory#:#Sie haben mindestens eine obgligatorische Ãœbungseinheit nicht bestanden. +exc#:#exc_msg_grading_done#:#Es wurde eine Ãœbungseinheit in Ãœbung "%s" bewertet. +exc#:#exc_msg_grading_done_body#:#Ein Tutor hat Ihre Lösungsabgabe in Ãœbung "%s" bewertet. exc#:#exc_msg_min_number_ass#:#Sie müssen mindestens %s Ãœbungseinheiten bestehen, um die Ãœbung zu bestehen. exc#:#exc_msg_missed_minimum_number#:#Sie haben die Mindestanzahl an Ãœbungseinheiten nicht bestanden. exc#:#exc_msg_new_feedback_file_uploaded#:#Es wurde eine neue Feedback-Datei zur Ãœbung "%s" hinzugefügt. @@ -9175,6 +9187,7 @@ exc#:#exc_no_assignments_available#:#Keine Ãœbungseinheiten vorhanden. Bitte wä exc#:#exc_no_deadline_specified#:#Es wurde kein Abgabetermin festgelegt. exc#:#exc_no_feedback_dir_found_in_zip#:#Die Verzeichnisstruktur des hochgeladenen Zip-Archivs konnte nicht verarbeitet werden. exc#:#exc_no_get_target#:#Kein gültiges Link-Ziel gefunden. +exc#:#exc_no_graded_mem_selected#:#Bitte wählen Sie mindestens einen Teilnehmer mit Bewertung aus. exc#:#exc_no_participants#:#Zur Zeit gibt es keine Teilnehmer. exc#:#exc_no_portfolio_templates#:#Es sind keine Portfoliovorlagen vorhanden. exc#:#exc_no_team_yet#:#Keinem Team zugeordnet @@ -9307,6 +9320,7 @@ exc#:#exc_select_portfolio_change#:#Anderes Portfolio benutzen exc#:#exc_select_portfolio_info#:#Bitte wählen Sie eines Ihrer Portfolios, um es in dieser Ãœbungseinheit zu benutzen. exc#:#exc_select_portfolio_unlink#:#Portfolio entfernen exc#:#exc_send_assignment#:#Ãœbungseinheit per Mail verschicken +exc#:#exc_send_grading_notification#:#Benachrichtigung über Bewertung schicken exc#:#exc_settings_feedback#:#Rückmeldung exc#:#exc_settings_feedback_file#:#Datei exc#:#exc_settings_feedback_file_info#:#Rückmeldungen werden als Datei hochgeladen und im Reiter „Übungseinheiten“ angezeigt. Die Teilnehmerinnen und Teilnehmer werden darüber per Mail benachrichtigt. @@ -9330,6 +9344,7 @@ exc#:#exc_submission_notification_body#:#Eine neue Abgabe für die Ãœbung "%s" l exc#:#exc_submission_notification_info#:#Sie werden per Mail benachrichtigt, sobald neue Lösungen abgegeben wurden. Dies ist eine persönliche Einstellung, die nur für Sie gilt. Andere Personen, die Abgaben bewerten erhalten nur dann eine Mail, wenn auch sie diese Checkbox aktivieren. exc#:#exc_submission_notification_link#:#Link zur Ãœbung: %s exc#:#exc_submission_notification_subject#:#Eine neue Abgabe für die Ãœbung "%s" liegt vor +exc#:#exc_submission_open_notification_link#:#Abgabe öffnen: %s exc#:#exc_submission_text#:#Textabgabe exc#:#exc_submissions_and_grades#:#Abgaben und Noten exc#:#exc_submit_convenience_no_deadline#:#Geben Sie nach Bearbeitung der Ãœbungseinheit ab. Es gibt keinen festen Abgabetermin. @@ -11010,7 +11025,7 @@ mail#:#mail_maxsize_attachment_error#:#Die maximale Dateigröße beträgt: mail#:#mail_member_notification#:#Teilnehmerbenachrichtigung mail#:#mail_members_of_mailing_list#:#Mitglieder der Verteilerliste "%s" mail#:#mail_members_search_continue#:#Weiter -mail#:#mail_message_send#:#Die Mail wurde versandt +mail#:#mail_message_send#:#Die Mail wurde versandt. mail#:#mail_move_error#:#Fehler beim Mailversand mail#:#mail_move_to#:#Verschieben nach: mail#:#mail_move_to_folder_btn_label#:#Mail verschieben @@ -13014,6 +13029,7 @@ prtf#:#prtf_add_new_blog#:#Neues Blog hinzufügen prtf#:#prtf_add_new_blog_info#:#Das neue Blog wird Ihren persönlichen Ressourcen hinzugefügt. prtf#:#prtf_add_page#:#Seite hinzufügen prtf#:#prtf_add_portfolio#:#Portfolio hinzufügen +prtf#:#prtf_add_portfolio_from_template#:#Portfolio aus Vorlage hinzufügen prtf#:#prtf_all_pages#:#Gesamtes Portfolio prtf#:#prtf_allow_html#:#HTML/Javascript erlauben prtf#:#prtf_allow_html_info#:#Benutzer können HTML oder Javascript in Ihren Portfolio-Seiten verwenden. Dies kann zu Sicherheitsproblemen führen. @@ -13054,7 +13070,7 @@ prtf#:#prtf_link#:#Link prtf#:#prtf_manage_portfolios#:#Portfolios verwalten prtf#:#prtf_new_portfolio#:#Neues Portfolio prtf#:#prtf_no_blogs_info#:#Wenn Sie im Bereich "%s" einen Blog anlegen, können Sie dieses auch als Teil Ihres Portfolios verwenden. -prtf#:#prtf_no_offline_share_info#:#Das Portfolio muss zunächst online gesetzt werden bevor es für bestimmte Benutzer freigegeben werden kann. +prtf#:#prtf_no_offline_share_info#:#Das Portfolio muss zunächst online gesetzt werden, bevor es für bestimmte Benutzer freigegeben werden kann. prtf#:#prtf_no_submission#:#Keine Abgabe prtf#:#prtf_page_created#:#Seite wurde hinzugefügt prtf#:#prtf_page_element_my_courses_info#:#Dies ist eine Liste aller Kurse, in denen ich Mitglied bin und die aktuell online sind. @@ -13068,8 +13084,9 @@ prtf#:#prtf_page_type_prtf#:#Portfolioseite prtf#:#prtf_page_type_prtt#:#Portfoliovorlagenseite prtf#:#prtf_pages_copied#:#Die Seiten wurden kopiert. prtf#:#prtf_pdf#:#Exportieren als PDF +prtf#:#prtf_permanent_link#:#Link zum Portfolio: prtf#:#prtf_portfolio_created#:#Portfolio wurde hinzugefügt -prtf#:#prtf_portfolio_created_from_template#:#Dies ist die Vorschau Ihres neuen Portfolios. Um neue Seiten und Inhalte hinzuzufügen klicken Sie bitte auf "Bearbeiten" oben in dieser Ansicht. +prtf#:#prtf_portfolio_created_from_template#:#Dies ist die Vorschau Ihres neuen Portfolios. Um neue Inhalte und Seiten hinzuzufügen, klicken Sie in dieser Ansicht bitte auf "Portfolio bearbeiten" oder "Seite bearbeiten". prtf#:#prtf_portfolio_deleted#:#Portfolio wurde gelöscht prtf#:#prtf_portfolio_page_deleted#:#Portfolio- bzw. Blog-Seite wurde gelöscht. prtf#:#prtf_portfolios#:#Portfolios @@ -13100,6 +13117,8 @@ prtf#:#prtf_signature_date#:#Datum, Unterschrift prtf#:#prtf_signature_info#:#Das PDF enthält ein Feld, in welchem die Benutzer unterschreiben können. prtf#:#prtf_style#:#Portfolio-Style prtf#:#prtf_submission_on#:#Abgabe am $1 +prtf#:#prtf_successfully_shared_prtf#:#Bestätigung der Freigabe Ihres Portfolios "%s" +prtf#:#prtf_successfully_shared_prtf_body#:#Sie haben Ihr Portfolio "%s" erfolgreich freigegeben für: prtf#:#prtf_sure_delete_portfolio_pages#:#Wollen Sie die folgende Portfolio- bzw. Blog-Seite wirklich löschen? prtf#:#prtf_sure_delete_portfolios#:#Wollen Sie das folgende Portfolio wirklich löschen? prtf#:#prtf_tab_other_users#:#Portfolios anderer Benutzer @@ -13113,6 +13132,7 @@ prtf#:#prtf_template_title#:#Portfoliovorlage prtf#:#prtf_unset_as_default#:#Nicht als Mein Profil verwenden prtf#:#prtf_unset_default_share_info#:#Die Änderungen wurden gespeichert. Bitte überprüfen Sie die aktuellen Freigaben für das Portfolio. prtf#:#prtf_use_page_layout#:#Seitenlayout benutzen +prtf#:#prtf_visible_for_tutor#:#Einsehbar für Tutor prtf#:#prtt_title_info#:#Bitte beachten Sie, dass dieser Titel auch für die aus der Vorlage erstellten Porfolios verwendet wird. prtt#:#prtt_activation_limited_visibility_info#:#Falls aktiv, ist die Portfoliovorlage auch außerhalb der Zugriffszeiten sichtbar. prtt#:#prtt_activation_online_info#:#Wählen Sie diese Einstellung, um die Portfoliovorlage für Benutzer verfügbar zu machen. @@ -14967,6 +14987,7 @@ skmg#:#skmg_create_skill_template_reference#:#Vorlage einfügen skmg#:#skmg_create_skll#:#Kompetenz erstellen skmg#:#skmg_custom_image_alt#:#Bild für Kompetenzprofil skmg#:#skmg_delete_profiles#:#Wollen Sie wirklich die folgenden Profile löschen? +skmg#:#skmg_delete_warning#:#Sind Sie sicher, dass folgende Objekte gelöscht werden sollen? Wenn Sie die Objekte löschen, löschen Sie ebenfalls alle dazugehörigen Gebräuche, Zuordnungen und Leistungen. Um auf der sicheren Seite zu sein, finden Sie unten eine Liste mit sämtlichen Gebräuchen. Wenn das Objekt in einem Kompetenzprofil benutzt wird, wird es auch dort entfernt. Dies kann zur Erfüllung von Kompetenzprofilen der dort zugewiesenen Personen führen. Falls Sie sich nicht sicher sind, ob ein Objekt wirklich gelöscht werden soll, nutzen Sie die Status in den Einstellungen eines einzelnen Objekts. skmg#:#skmg_description_info#:#Die Beschreibung stammt aus der Vorlage. skmg#:#skmg_edit_level#:#Ausprägung editieren skmg#:#skmg_edit_profile#:#Profil bearbeiten @@ -16734,8 +16755,8 @@ ui#:#label_fieldselection_refresh#:#Anwenden ui#:#label_pagination_limit#:#Pagination - Anzahl der Zeilen ui#:#label_pagination_offset#:#Pagination - Start ui#:#label_sortation#:#Sortierung -ui#:#presentaion_table_collapse#:#alle minimieren -ui#:#presentaion_table_expand#:#alle zeigen +ui#:#presentation_table_collapse#:#alle minimieren +ui#:#presentation_table_expand#:#alle zeigen ui#:#ui_chars_max#:#Maximum: ui#:#ui_chars_min#:#Minimum: ui#:#ui_chars_remaining#:#Verbleibende Buchstaben @@ -17154,6 +17175,7 @@ wsp#:#wsp_permission_registered_info#:#Dieses Objekt ist für alle registrierten wsp#:#wsp_permission_removed#:#Der Eintrag wurde gelöscht. wsp#:#wsp_permissions#:#Freigabe wsp#:#wsp_personal_resources_description#:#Hier können Sie persönliche Dateien, Blogs und Nachweise verwalten. +wsp#:#wsp_send_mail#:#Mail senden wsp#:#wsp_set_permission_all#:#Internet/WWW wsp#:#wsp_set_permission_all_password#:#Internet/WWW mit Passwort wsp#:#wsp_set_permission_course#:#Kursmitglieder @@ -17161,7 +17183,7 @@ wsp#:#wsp_set_permission_group#:#Gruppenmitglieder wsp#:#wsp_set_permission_registered#:#Alle registrierten Benutzer wsp#:#wsp_set_permission_single_user#:#Ausgewählte Benutzer wsp#:#wsp_share_search_users#:#Benutzer suchen -wsp#:#wsp_share_success#:#Ein neuer Eintrag wurde hinzugefügt. +wsp#:#wsp_share_success#:#Die Ressource wurde freigegeben. wsp#:#wsp_share_with_members#:#Für Mitglieder freigeben wsp#:#wsp_share_with_users#:#Für Benutzer freigeben wsp#:#wsp_shared_date#:#Freigabedatum diff --git a/lang/ilias_en.lang b/lang/ilias_en.lang index c707048d191f..cf274cf22413 100644 --- a/lang/ilias_en.lang +++ b/lang/ilias_en.lang @@ -511,9 +511,9 @@ assessment#:#ass_mc_sel_lim_exhausted_hint#:#Please do not select more than %s o assessment#:#ass_mc_sel_lim_hint#:#Please select at most %s of the %s answers! assessment#:#ass_mc_sel_lim_setting#:#Answering Limitation assessment#:#ass_mc_sel_lim_setting_desc#:#With this setting the number of answers choosable by the participants can be limited. -assessment#:#ass_process_lock#:#Use Locking During Test Passes +assessment#:#ass_process_lock#:#Use Locking During Test Attempts assessment#:#ass_process_lock_desc#:#Without the use of any locking mechanism, race conditions are possible. This can lead to inconsistent test results. -assessment#:#ass_process_lock_mode#:#Lock Mode during Test Pass +assessment#:#ass_process_lock_mode#:#Lock Mode during Test Attempt assessment#:#ass_process_lock_mode_db#:#Use Database Table Locks assessment#:#ass_process_lock_mode_db_desc#:#This locking mechanism locks tables within the database. Concurrent processes for the same or other users in the same or in another test for the same or another question are waiting until the other process releases his locks. assessment#:#ass_process_lock_mode_file#:#Use Filesystem Locks @@ -730,10 +730,10 @@ assessment#:#final_statement_show_desc#:#Show concluding remarks after the test assessment#:#finalized_by#:#Completed by assessment#:#finalized_evaluation#:#Scoring completed assessment#:#finalized_on#:#Completed at -assessment#:#finish_all_user_passes#:#Finish all Test Passes -assessment#:#finish_pass_for_all_users#:#Are you sure you want to finish the test passes for all users? +assessment#:#finish_all_user_passes#:#Finish all Test Attempts +assessment#:#finish_pass_for_all_users#:#Are you sure you want to finish the test attempts for all users? assessment#:#finish_pass_for_all_users_in_processing_time#:#You cannot finish the passes of all users together, because for at least one user the processing time is not over yet. -assessment#:#finish_pass_for_user_confirmation#:#Are you sure you want to finish this test pass for the participant "%s"? +assessment#:#finish_pass_for_user_confirmation#:#Are you sure you want to finish this test attempt for the participant "%s"? assessment#:#finish_pass_for_user_in_processing_time#:#WARNING: the processing time for this user is not over yet! You should only end the test run if there is a compelling reason (e.g. exclusion from the test). assessment#:#finish_test#:#Finish Test assessment#:#finish_unfinished_passes#:#Finish Uncompleted Attempts @@ -848,13 +848,14 @@ assessment#:#longmenu_answeroptions_differ#:#This question does not work correct assessment#:#longmenu_text#:#Long Menu Text assessment#:#mailnottype#:#Send a notification every time a test attempt is completed. assessment#:#mailnottype_desc#:#Notify the owner of the test even if the number of test attempts has not been limited. +assessment#:#mainbar_button_label_questionlist#:#Questionlist assessment#:#maintenance#:#Maintenance assessment#:#manscoring#:#Manual Scoring assessment#:#manscoring_done#:#Scored Participants assessment#:#manscoring_hint#:#You have added at least one question which may require manual scoring. To avoid participants getting access to the test results before you have finished manual scoring, please set a suitable date before which the results cannot be accessed. assessment#:#manscoring_none#:#Unscored Participants assessment#:#manscoring_not_allowed#:#The Manual Scoring wasn‘t activated for a question type. You are not allowed to use this tab. -assessment#:#manscoring_questions_not_found#:#This test pass does not contain question types which can be scored manually. +assessment#:#manscoring_questions_not_found#:#This test attempt does not contain question types which can be scored manually. assessment#:#manscoring_results_pass#:#Manual Scored Questions for Pass %s assessment#:#manual_editing#:#Manual Editing assessment#:#mark_schema#:#Grading System @@ -1136,6 +1137,11 @@ assessment#:#result_units_info#:#The selected units are offered to the learner a assessment#:#result_x#:#Result %s assessment#:#results#:#Results assessment#:#results_tab#:#Results +assessment#:#resulttable_all#:#All +assessment#:#resulttable_correct#:#Correct +assessment#:#resulttable_incorrect#:#Incorrect/Incomplete +assessment#:#resulttable_vc_sort_iooa#:#in order of appearance +assessment#:#resulttable_vc_sort_posscore#:#highest possible score first assessment#:#review_view#:#Review assessment#:#saveOrder#:#Save Order assessment#:#saveOrderAndObligations#:#Save Order and Obligations @@ -1191,6 +1197,7 @@ assessment#:#suggest_range#:#Suggest Range assessment#:#suggestedSolutionType#:#Refer to assessment#:#suggested_solution#:#Content for Recapitulation assessment#:#suggested_solution_added_successfully#:#You successfully set a content for recapitulation! +assessment#:#ta_resulttable_vc_mode_aria#:#switch question mode assessment#:#tab_nest_answers#:#Nesting assessment#:#term#:#Term assessment#:#term_image#:#Term Image @@ -1287,7 +1294,7 @@ assessment#:#tst_back_to_top#:#Back to Top assessment#:#tst_back_to_virtual_pass#:#Back to Question Overview assessment#:#tst_best_solution_is#:#The best solution is assessment#:#tst_block_passes_after_passed#:#Block Additional Passes After Test is Passed -assessment#:#tst_block_passes_after_passed_info#:#After a participant has passed the test, no further test passes are allowed to the participant with this option. +assessment#:#tst_block_passes_after_passed_info#:#After a participant has passed the test, no further test attempts are allowed to the participant with this option. assessment#:#tst_browse_for_qpl_questions#:#Add from Pool assessment#:#tst_browse_for_tst_questions#:#Add from Other Test assessment#:#tst_btn_hide_best_solutions#:#Hide Best Solutions @@ -1335,9 +1342,11 @@ assessment#:#tst_delete_missing_mark#:#Please select at least one mark step to r assessment#:#tst_derive_new_pool#:#Derive New Question Pool assessment#:#tst_derive_new_pools#:#Derive New Question Pools assessment#:#tst_dont_show_msg_again_in_current_session#:#Don't show this message again in my current session. -assessment#:#tst_dont_use_previous_answers#:#Your previous answers will not be used as default values in future test passes +assessment#:#tst_dont_use_previous_answers#:#Your previous answers will not be used as default values in future test attempts assessment#:#tst_edit_competence_assign#:#Edit Assignment Properties assessment#:#tst_edit_scoring#:#Edit Scoring +assessment#:#tst_enable_questionlist#:#Show 'List of Questions’ +assessment#:#tst_enable_questionlist_description#:#Participants can switch on a list of the test questions on the left of the actual question. assessment#:#tst_ending_time#:#Finishing Time assessment#:#tst_ending_time_before_starting_time#:#Please enter a date for the end of the test that is after the start date. assessment#:#tst_ending_time_desc#:#Time from which participants can no longer submit answers. Important: Do not use this option for e-exams/distance exams. Instead, use the function "Limit processing time", see below. Only then will the test be ended on the server side and each participant's last entry automatically saved as an authorised answer. @@ -1371,7 +1380,7 @@ assessment#:#tst_final_information#:#Finishing the Test assessment#:#tst_finish_confirm_button#:#Yes, I want to finish the test assessment#:#tst_finish_confirm_cancel_button#:#No, go back to the previous question assessment#:#tst_finish_confirmation_question#:#You are going to finish this test. You won’t be able to enter this test attempt again to change your answers. Do you really want to finish this test? -assessment#:#tst_finish_confirmation_question_no_attempts_left#:#You are going to finish this test and reach the maximum number of allowed test passes. You won’t be able to enter this test again to change your answers. Do you really want to finish the test? +assessment#:#tst_finish_confirmation_question_no_attempts_left#:#You are going to finish this test and reach the maximum number of allowed test attempts. You won’t be able to enter this test again to change your answers. Do you really want to finish the test? assessment#:#tst_finish_notification#:#Notification assessment#:#tst_finish_notification_advanced#:#Send complete test result assessment#:#tst_finish_notification_content_type#:#Content of e-mail @@ -1448,7 +1457,7 @@ assessment#:#tst_instant_feedback_answer_generic_desc#:#If the answer provided i assessment#:#tst_instant_feedback_answer_specific#:#Specific Feedback for Each Answer provided assessment#:#tst_instant_feedback_answer_specific_desc#:#On clicking the ‘Check’-button, ILIAS will show a specific feedback for every answer option selected by the participant. The feedback has to be prepared along with the question. This specific feedback is not supported for all question types. assessment#:#tst_instant_feedback_contents#:#Included Contents -assessment#:#tst_instant_feedback_desc#:#When questions are configured with feedback it is provided to participants during the test pass. +assessment#:#tst_instant_feedback_desc#:#When questions are configured with feedback it is provided to participants during the test attempt. assessment#:#tst_instant_feedback_forced#:#Force Instant Feedback assessment#:#tst_instant_feedback_results#:#Points Attained assessment#:#tst_instant_feedback_results_desc#:#On clicking the ‘Check’ button ILIAS will display how many points were attained by answering this question. @@ -1465,7 +1474,7 @@ assessment#:#tst_introduction_text#:#Introductory Message assessment#:#tst_invited_nobody#:#No users, groups or roles have been added as fixed test participants assessment#:#tst_invited_selected_users#:#The selected users have been added as fixed test participants assessment#:#tst_level#:#Competence Level -assessment#:#tst_limit_nr_of_tries#:#Limit Number of Test Passes +assessment#:#tst_limit_nr_of_tries#:#Limit Number of Test Attempts assessment#:#tst_link_only_unassigned#:#You have selected at least one question that is already linked to a question pool. Only unassigned questions can be added to a question pool. assessment#:#tst_list_answer_details#:#Show in List Below assessment#:#tst_list_of_answers#:#List of Answers @@ -1542,8 +1551,8 @@ assessment#:#tst_notification_explanation_admin#:#You receive this mail from ILI assessment#:#tst_notify_manscoring_done_body_msg_reason#:#You have received this notification, because you participated in this test. assessment#:#tst_notify_manscoring_done_body_msg_subject#:#Manual Scoring for Test "%s" committed assessment#:#tst_notify_manscoring_done_body_msg_topic#:#Your test has been graded manually: -assessment#:#tst_nr_of_passes#:#Number of Test Passes -assessment#:#tst_nr_of_tries#:#Max. Number of Passes +assessment#:#tst_nr_of_passes#:#Number of Test Attempts +assessment#:#tst_nr_of_tries#:#Max. Number of Attempts assessment#:#tst_nr_of_tries_desc#:#Maximum number of passes a participant can take. assessment#:#tst_nr_of_tries_of_user#:#Passes Already Completed assessment#:#tst_num_all_questions#:#Number of All Questions @@ -1564,30 +1573,30 @@ assessment#:#tst_participant_fullname_pattern#:#%2$s, %1$s assessment#:#tst_participant_status#:#Participant Status assessment#:#tst_participating_users#:#Participating Users assessment#:#tst_pass_best_pass#:#Score the Best Pass -assessment#:#tst_pass_best_pass_desc#:#The pass in which a participant performed best will be scored. This setting does only apply when more than one test pass is possible. +assessment#:#tst_pass_best_pass_desc#:#The pass in which a participant performed best will be scored. This setting does only apply when more than one test attempt is possible. assessment#:#tst_pass_deletion#:#Previous Passes assessment#:#tst_pass_deletion_allowed#:#The deletion of non-scoring attempts is allowed. assessment#:#tst_pass_details#:#Detailed Results assessment#:#tst_pass_details_header_lo_initial#:#Initial Test Results for the Learning Objectives
      %s - %s assessment#:#tst_pass_details_header_lo_qualifying#:#Qualifying Test Results for the Learning Objectives
      %s - %s assessment#:#tst_pass_details_overview_table_title#:#Detailed Overview for Pass %s -assessment#:#tst_pass_finished#:#Test pass finished -assessment#:#tst_pass_finished_on#:#Test pass finished on -assessment#:#tst_pass_last_pass#:#Score the Last Pass -assessment#:#tst_pass_last_pass_desc#:#The last pass of a participant will be scored. -assessment#:#tst_pass_overview_for_participant#:#Test Passes for Participant: %s +assessment#:#tst_pass_finished#:#Test attempt finished +assessment#:#tst_pass_finished_on#:#Test attempt finished on +assessment#:#tst_pass_last_pass#:#Score the Last Attempt +assessment#:#tst_pass_last_pass_desc#:#The last attempt of a participant will be scored. +assessment#:#tst_pass_overview_for_participant#:#Test Attempts for Participant: %s assessment#:#tst_pass_overview_header_lo_initial_all_objectives#:#Initial Test Results
      for the Learning Objectives within the Course %s assessment#:#tst_pass_overview_header_lo_initial_per_objective#:#Initial Test Results
      for the Learning Objectives %s within the Course %s assessment#:#tst_pass_overview_header_lo_qualifying_all_objectives#:#Qualifying Test Results
      for the Learning Objectives within the Course %s assessment#:#tst_pass_overview_header_lo_qualifying_per_objective#:#Qualifying Test Results
      for the Learning Objectives %s within the Course %s assessment#:#tst_pass_scoring#:#Scoring Multiple Passes -assessment#:#tst_pass_scoring_best#:#Best Test Pass -assessment#:#tst_pass_scoring_last#:#Last Test Pass -assessment#:#tst_pass_waiting_enabled#:#Force Waiting Time between Passes +assessment#:#tst_pass_scoring_best#:#Best Test Attempt +assessment#:#tst_pass_scoring_last#:#Last Test Attempt +assessment#:#tst_pass_waiting_enabled#:#Force Waiting Time between Attempts assessment#:#tst_pass_waiting_info#:#With this option additional passes can not be started before the defined time is lapsed relating to the last finished pass. assessment#:#tst_pass_waiting_time#:#Waiting Time assessment#:#tst_passed#:#Passed -assessment#:#tst_passes#:#Test Passes +assessment#:#tst_passes#:#Test Attempts assessment#:#tst_password#:#Test Password assessment#:#tst_password_details#:#If you define a test password, all users with test access must enter this password to start the test. assessment#:#tst_password_enter#:#Enter Password @@ -1610,7 +1619,7 @@ assessment#:#tst_presentation_settings_section#:#Presentation assessment#:#tst_print#:#Test and Assessment - Print View assessment#:#tst_proceed#:#Proceed assessment#:#tst_processing_time#:#Limit Duration of Test -assessment#:#tst_processing_time_desc#:#Participants can work through the test only for a specified period of time. Time is clocking away from the moment a user starts a test for the first time. Suspending the test does not stop the clock. If the number of possible test passes is limited an additional feature for granting extra time to participants appears in the tab 'Dashboard'. +assessment#:#tst_processing_time_desc#:#Participants can work through the test only for a specified period of time. Time is clocking away from the moment a user starts a test for the first time. Suspending the test does not stop the clock. If the number of possible test attempts is limited an additional feature for granting extra time to participants appears in the tab 'Dashboard'. assessment#:#tst_processing_time_duration#:#Maximum Duration of the Test im Minutes assessment#:#tst_processing_time_duration_desc#:#Maximum of time granted to take the test. assessment#:#tst_qbt_filter_question_title#:#Title of Question @@ -1667,8 +1676,8 @@ assessment#:#tst_question_hints_table_link_edit_hint#:#Edit Hint assessment#:#tst_question_hints_table_link_edit_hint_page#:#Edit Page assessment#:#tst_question_hints_table_link_edit_hint_points#:#Edit Points assessment#:#tst_question_hints_table_no_items#:#No Existing Hints -assessment#:#tst_question_mark#:#Mark this question -assessment#:#tst_question_marked#:#You marked the question +assessment#:#tst_question_mark#:#Flag this question +assessment#:#tst_question_marked#:#You flagged the question assessment#:#tst_question_marker#:#Flagged assessment#:#tst_question_no#:#Order assessment#:#tst_question_not_from_pool_info#:#No Pool @@ -1697,7 +1706,7 @@ assessment#:#tst_random_question_set_source_questionpool_summary_string#:#%s (Pa assessment#:#tst_random_select_questionpool#:#Select the question pool to choose the questions from assessment#:#tst_reached_points#:#Reached Points assessment#:#tst_reached_points_of_max#:#%s of %s -assessment#:#tst_remove_mark#:#Remove this mark +assessment#:#tst_remove_mark#:#Remove this flag assessment#:#tst_remove_question#:#Are you sure you want to remove the following question from the test? assessment#:#tst_remove_questions#:#Are you sure you want to remove the following questions from the test? assessment#:#tst_remove_questions_and_results#:#This test was already executed by %s user(s). Removing questions from this test will remove all test results of these users. Are you sure you want to remove the following question(s) from the test? @@ -1717,21 +1726,21 @@ assessment#:#tst_res_tab_msg_res_after_date_no_res#:#When you take the test your assessment#:#tst_res_tab_msg_res_after_finish_test#:#After finishing the test your results will be offered here. assessment#:#tst_res_tab_msg_res_after_taking_test#:#After taking the test your results will be offered here. assessment#:#tst_res_tab_msg_res_after_test_passed#:#After passing the test your results will be offered here. -assessment#:#tst_reset_processing_time#:#Reset duration for every test pass -assessment#:#tst_reset_processing_time_desc#:#The duration will be reset to the defined maximum for every test pass. This setting requires multiple test passes to become effective. +assessment#:#tst_reset_processing_time#:#Reset duration for every test attempt +assessment#:#tst_reset_processing_time_desc#:#The duration will be reset to the defined maximum for every test attempt. This setting requires multiple test attempts to become effective. assessment#:#tst_result#:#Test Result -assessment#:#tst_result_pass#:#Results of Test Pass +assessment#:#tst_result_pass#:#Results of Test Attempt assessment#:#tst_result_user_name#:#Test Results for %s -assessment#:#tst_result_user_name_pass#:#Results of Test Pass %s for %s +assessment#:#tst_result_user_name_pass#:#Results of Test Attempt %s for %s assessment#:#tst_results#:#Test Results assessment#:#tst_results_access_always#:#Immediately -assessment#:#tst_results_access_always_desc#:#Participants can access their results within the ‘Results’-tab immediately after starting the test pass and while still taking the test. Additionally ILIAS will redirect to the 'Results'-tab after the test has been finished. +assessment#:#tst_results_access_always_desc#:#Participants can access their results within the ‘Results’-tab immediately after starting the test attempt and while still taking the test. Additionally ILIAS will redirect to the 'Results'-tab after the test has been finished. assessment#:#tst_results_access_date#:#Date assessment#:#tst_results_access_date_desc#:#Participants get access to their test results within a 'Results'-tab after the defined date. assessment#:#tst_results_access_enabled#:#Access to Test Results assessment#:#tst_results_access_enabled_desc#:#A tab 'Results' will be offered to participants. Options in this section and the following ones below configure what information is to be included into the report and when it will be accessible. -assessment#:#tst_results_access_finished#:#After Test Pass is Finished -assessment#:#tst_results_access_finished_desc#:#ILIAS displays the test results after the test pass is finished. After finishing the test pass participants can access their test results within the ‘Results’-tab at any time. +assessment#:#tst_results_access_finished#:#After Test Attempt is Finished +assessment#:#tst_results_access_finished_desc#:#ILIAS displays the test results after the test attempt is finished. After finishing the test attempt participants can access their test results within the ‘Results’-tab at any time. assessment#:#tst_results_access_passed#:#After Test has been Passed assessment#:#tst_results_access_passed_desc#:#ILIAS displays the test results after the participant has passed the test. After passing the test participants can access their test results within the 'Results'-tab at any time. assessment#:#tst_results_access_setting#:#Point in Time @@ -1761,10 +1770,10 @@ assessment#:#tst_rnd_quest_set_tb_add_pool_btn#:#New Rule for Selection of Quest assessment#:#tst_save_and_create_new_rule#:#Save and Add New Rule assessment#:#tst_save_and_proceed#:#Save and Proceed###fau: testNav assessment#:#tst_save_comp_points#:#Save Competence Points -assessment#:#tst_save_manscoring_failed#:#Saving the manual scoring for test pass %s has failed. +assessment#:#tst_save_manscoring_failed#:#Saving the manual scoring for test attempt %s has failed. assessment#:#tst_save_thresholds#:#Save Thresholds -assessment#:#tst_saved_manscoring_by_question_successfully#:#The manual scoring for the question %s for test pass %s has been saved successfully. -assessment#:#tst_saved_manscoring_successfully#:#The manual scoring for test pass %s for %s has been saved successfully. +assessment#:#tst_saved_manscoring_by_question_successfully#:#The manual scoring for the question %s for test attempt %s has been saved successfully. +assessment#:#tst_saved_manscoring_successfully#:#The manual scoring for test attempt %s for %s has been saved successfully. assessment#:#tst_score_cut_question#:#For Each Questions Negative Points are set to ‘0 Points’ assessment#:#tst_score_cut_question_desc#:#Participants may score negative results for a question that had negative points for assigned to individual answer options. This setting ensures that per question any negativ result is set to 0 points. assessment#:#tst_score_cut_test#:#For the Whole Test a Negative Result is set to ‘0 Points’ @@ -1777,7 +1786,7 @@ assessment#:#tst_select_questionpool#:#Please select a question pool to store th assessment#:#tst_selected_user_data_deleted#:#The test data of the selected user(s) was removed successfully assessment#:#tst_sequence#:#Sequence assessment#:#tst_sequence_fixed#:#The Sequence of Questions is Fixed -assessment#:#tst_sequence_postpone#:#Questions may be postponed to the end of a test pass +assessment#:#tst_sequence_postpone#:#Questions may be postponed to the end of a test attempt assessment#:#tst_sequence_properties#:#Administering the Test: Functionality Available to Participants assessment#:#tst_session_settings#:#Session Settings assessment#:#tst_set_offline_due_to_switched_question_set_type_setting#:#The test has been set to offline, because the test mode setting has been changed. You have to set a new test mode relating question config before the test can be set to online again. @@ -1795,8 +1804,8 @@ assessment#:#tst_show_answer_sheet#:#Show Answers assessment#:#tst_show_cancel#:#Suspend Test assessment#:#tst_show_cancel_description#:#Participants are presented with a button to stop the test run and to continue it later. Caution: Suspending the test does not stop the countdown of the maximum duration of the test. assessment#:#tst_show_comp_results#:#Competence Results -assessment#:#tst_show_pass_details#:#Show ‘Table of Detailed Test Results’ for each Test Pass upon Selected Point in Time -assessment#:#tst_show_pass_details_desc#:#The summary of results will be appended at the point in time indicated in the setting above: A ‘Table of Detailed Test Results’ will show the title of the questions and the points scored in a particular test pass.
      Other than that the table will be displayed after the last test pass possible (setting in link ‘General’, option ‘Limit Number of Test Passes’) or after the test is officially finished (setting in link ‘General’, option ‘Finishing Time’).
      Further settings about the content of the ‘Table of Detailed Test Results’ can be made in the section ‘Further Details to be Included in Test Results’ of this form. +assessment#:#tst_show_pass_details#:#Show ‘Table of Detailed Test Results’ for each Test Attempt upon Selected Point in Time +assessment#:#tst_show_pass_details_desc#:#The summary of results will be appended at the point in time indicated in the setting above: A ‘Table of Detailed Test Results’ will show the title of the questions and the points scored in a particular test attempt.
      Other than that the table will be displayed after the last test attempt possible (setting in link ‘General’, option ‘Limit Number of Test Attempts) or after the test is officially finished (setting in link ‘General’, option ‘Finishing Time’).
      Further settings about the content of the ‘Table of Detailed Test Results’ can be made in the section ‘Further Details to be Included in Test Results’ of this form. assessment#:#tst_show_results#:#Test Results assessment#:#tst_show_side_list#:#Show List of Questions assessment#:#tst_show_solution_answers_only#:#Print View of Results (Answers Only) @@ -1815,11 +1824,11 @@ assessment#:#tst_show_solution_signature#:#Signature Placeholder assessment#:#tst_show_solution_signature_desc#:#The prepared printout version will contain a signature placeholder for the participant. Please mind to activate ‘Table of Detailed Test Results’ to use this functionality. assessment#:#tst_show_solution_suggested#:#Content for Recapitulation assessment#:#tst_show_solution_suggested_desc#:#If content for recapitulation was assigned to the test questions in the first place, this content will be shown in the ‘Table of Detailed Test Results’-table. Participants get an opportunity for remedial learning. For this option to become effective you have to activate ‘Table of Detailed Test Results’ under ‘Access to Test Results’. -assessment#:#tst_show_summary#:#Show ‘List of Questions’ -assessment#:#tst_show_summary_description#:#Participants can switch on a list of test questions on the left of the actual question. Additionally, they are presented with a button ‘List of Questions’. On that screen the overall status of all questions will be displayed. +assessment#:#tst_show_summary#:#Show ‘Test Attempt Overview’ +assessment#:#tst_show_summary_description#:#Participants are presented with a button ‘Test Attempt Overview’. On that screen the overall status of all questions will be displayed.. assessment#:#tst_show_toplist#:#Ranking assessment#:#tst_shuffle_questions#:#Shuffle Questions -assessment#:#tst_shuffle_questions_description#:#Shuffles the sequence of questions for every participant and every test pass. +assessment#:#tst_shuffle_questions_description#:#Shuffles the sequence of questions for every participant and every test attempt. assessment#:#tst_signature#:#Signature assessment#:#tst_single_answer_details#:#Show Single Answer assessment#:#tst_single_results#:#Results by Question @@ -1835,7 +1844,7 @@ assessment#:#tst_solution_compare_cfg#:#Configuration for Solution Compare assessment#:#tst_source_question_pool#:#Question Pool assessment#:#tst_src_quest_pool_def_list_table#:#Rules for Random Selection of Questions assessment#:#tst_start_dyn_test_with_cur_quest_sel#:#Start Test with Current Question Selection -assessment#:#tst_start_new_test_pass#:#Start New Test Pass +assessment#:#tst_start_new_test_pass#:#Start New Attempt on Test assessment#:#tst_start_test#:#Start the Test assessment#:#tst_started#:#Test Started assessment#:#tst_starting_time#:#Starting Time @@ -1887,8 +1896,8 @@ assessment#:#tst_type#:#Test Type assessment#:#tst_unchanged_answer_is_correct#:#The preset answer is correct###fau: testNav assessment#:#tst_unchanged_order_is_correct#:#The preset order is correct###fau: testNav assessment#:#tst_use_previous_answers#:#Use Previous Answers -assessment#:#tst_use_previous_answers_description#:#Participants will be presented with their answers from previous test passes. This option has to be activated by individual participants on the Info-tab before starting a test pass. -assessment#:#tst_use_previous_answers_user#:#Use my previous answers as default values in future test passes +assessment#:#tst_use_previous_answers_description#:#Participants will be presented with their answers from previous test attempts. This option has to be activated by individual participants on the Info-tab before starting a test attempt. +assessment#:#tst_use_previous_answers_user#:#Use my previous answers as default values in future test attempts assessment#:#tst_user_finished_test#:#User finished test (%s) assessment#:#tst_view_competence_assign#:#View Assignment Properties assessment#:#tst_virtual_pass_header_lo_initial#:#Initial Test Results for the Learning Objective
      %s @@ -4271,7 +4280,7 @@ common#:#info_available_roles#:#Available Roles common#:#info_change_user_view#:#Change User common#:#info_deactivate_sure#:#Are you sure that you want to deactivate the following user(s)? common#:#info_delete_sure#:#Are you sure that you want to delete the following item(s)? -common#:#info_delete_warning_no_trash#:#(WARNING: Selected Objects will be removed irreversibly from System and may not be recovered anymore!) +common#:#info_delete_warning_no_trash#:#(WARNING: The selected object(s) will be irretrievably deleted from the system. The recovery of any such deleted objects will not be possible). common#:#info_deleted#:#Object(s) Deleted common#:#info_err_user_not_exist#:#User with that login name or user_id does not exists common#:#info_from_role#:#Granted by Role / Ownership @@ -7470,9 +7479,9 @@ crs#:#crs_loc_mem_show_res#:#Show Test Results crs#:#crs_loc_num_qst#:#Number of Questions crs#:#crs_loc_objective_passed_confirmation#:#You have already passed this learning objective. Starting a new test run will reset the result. Do you really want to start a new test run? crs#:#crs_loc_objectives_passed_confirmation#:#You have already passed all learning objectives. Starting a new test run will reset all results. Do you really want to start a new test run? -crs#:#crs_loc_passes_info#:#Maximum Number of test passes -crs#:#crs_loc_passes_left#:#Remaining number of test passes -crs#:#crs_loc_passes_reached#:#No further test passes possible +crs#:#crs_loc_passes_info#:#Maximum Number of test attempts +crs#:#crs_loc_passes_left#:#Remaining number of test attempts +crs#:#crs_loc_passes_reached#:#No further test attempts possible crs#:#crs_loc_perc#:#Required Percentage of Points crs#:#crs_loc_progress_do_qualifying#:#Please take the final test. crs#:#crs_loc_progress_do_qualifying_again#:#Please work through the learning objective materials again. @@ -7534,10 +7543,10 @@ crs#:#crs_loc_tbl_tst_qst_qpl#:#Questions / Question Pools crs#:#crs_loc_tbl_tst_type#:#Selection of Test Questions crs#:#crs_loc_test_results_of#:#Test results of: crs#:#crs_loc_tst_assignment#:#Test Assignment -crs#:#crs_loc_tst_new_run#:#Start New Test Pass +crs#:#crs_loc_tst_new_run#:#Start New Attempt on Test crs#:#crs_loc_tst_num_qst#:#Number of Questions: crs#:#crs_loc_tst_qpls#:#Available Question Pools: -crs#:#crs_loc_tst_resume#:#Continue Test Pass +crs#:#crs_loc_tst_resume#:#Continue Test Attempt crs#:#crs_loc_tst_start#:#Start Test crs#:#crs_loc_tt_info#:#You have reached %1$d%%. The test is passed with %2$d%%. crs#:#crs_loc_type_initial_all_info#:#Based on individual results of the initial test, ILIAS recommends learning content for the not-yet-sufficient learning objectives. The final achievement test assesses whether a test participant already mastered the learning objectives or if additional learning and training is needed. @@ -9107,6 +9116,7 @@ exc#:#exc_global_feedback_file_date#:#Availability exc#:#exc_global_feedback_file_date_deadline#:#After deadline exc#:#exc_global_feedback_file_date_upload#:#After submission exc#:#exc_go_to_exercise#:#Go to Exercise +exc#:#exc_graded_mem_notified#:#All graded participants have been notified. exc#:#exc_grades#:#Grades Overview exc#:#exc_grades_overview#:#Grades View exc#:#exc_hand_in#:#Hand In @@ -9146,6 +9156,8 @@ exc#:#exc_min_nr_info#:#This value must be equal or higher than the number of co exc#:#exc_min_team_participants#:#Minimal Number exc#:#exc_msg_all_mandatory_ass#:#You must pass all mandatory assignments to pass the exercise. exc#:#exc_msg_failed_mandatory#:#You failed in at least one mandatory assignment. +exc#:#exc_msg_grading_done#:#An assignment has been graded in exercise "%s". +exc#:#exc_msg_grading_done_body#:#a tutor has graded your submission in exercise "%s". exc#:#exc_msg_min_number_ass#:#You must pass a minimum of %s assignments to pass the exercise. exc#:#exc_msg_missed_minimum_number#:#You did not pass the minimum number of assignments. exc#:#exc_msg_new_feedback_file_uploaded#:#A new feedback file has been added to exercise "%s". @@ -9167,6 +9179,7 @@ exc#:#exc_no_assignments_available#:#No assignments created yet. Please open ‘ exc#:#exc_no_deadline_specified#:#No deadline specified. exc#:#exc_no_feedback_dir_found_in_zip#:#The directory structure of the uploaded zip-archive could not be processed. exc#:#exc_no_get_target#:#A valid target has not been sent. +exc#:#exc_no_graded_mem_selected#:#Please select at least one graded participant. exc#:#exc_no_participants#:#There are currently no participants. exc#:#exc_no_portfolio_templates#:#There are no Portfolio Templates available. exc#:#exc_no_team_yet#:#Not assigned to a team @@ -9299,6 +9312,7 @@ exc#:#exc_select_portfolio_change#:#Use different portfolio exc#:#exc_select_portfolio_info#:#Please select one of your portfolios to use it with this assignment. exc#:#exc_select_portfolio_unlink#:#Remove Portfolio exc#:#exc_send_assignment#:#Send Assignment by Mail +exc#:#exc_send_grading_notification#:#Send Grading Notification exc#:#exc_settings_feedback#:#Evaluation exc#:#exc_settings_feedback_file#:#By File exc#:#exc_settings_feedback_file_info#:#Tutors upload a file. The participant receives a notification about it and can access the file at the assignment overview. @@ -9322,6 +9336,7 @@ exc#:#exc_submission_notification_body#:#A new submission for exercise "%s" has exc#:#exc_submission_notification_info#:#You will be notified when submissions are uploaded. This is a personal setting which does not affect other administrators of the exercise. exc#:#exc_submission_notification_link#:#Link to exercise: %s exc#:#exc_submission_notification_subject#:#Exercise "%s" - New submission uploaded +exc#:#exc_submission_open_notification_link#:#Open submission: %s exc#:#exc_submission_text#:#Submission Text exc#:#exc_submissions_and_grades#:#Submissions and Grades exc#:#exc_submit_convenience_no_deadline#:#Submit your at your convenience. There is no specific deadline. @@ -13008,6 +13023,7 @@ prtf#:#prtf_add_new_blog#:#Add New Blog prtf#:#prtf_add_new_blog_info#:#The new blog will be added to your personal resources. prtf#:#prtf_add_page#:#Add Page prtf#:#prtf_add_portfolio#:#Add Portfolio +prtf#:#prtf_add_portfolio_from_template#:#Add Portfolio From Template prtf#:#prtf_all_pages#:#All Pages prtf#:#prtf_allow_html#:#Allow HTML/Javascript prtf#:#prtf_allow_html_info#:#Enables users to include HTML and/or Javascript in their portfolio pages. This can lead to security issues. @@ -13062,8 +13078,9 @@ prtf#:#prtf_page_type_prtf#:#Portfolio Page prtf#:#prtf_page_type_prtt#:#Portfolio Template Page prtf#:#prtf_pages_copied#:#The pages have been copied. prtf#:#prtf_pdf#:#Export as PDF +prtf#:#prtf_permanent_link#:#Link to Portfolio: prtf#:#prtf_portfolio_created#:#Portfolio added -prtf#:#prtf_portfolio_created_from_template#:#This is the preview of your new portfolio. To add pages and manage the content of the portfolio click on "Edit Portfolio" on top of this page. +prtf#:#prtf_portfolio_created_from_template#:#This is the preview of your new portfolio. To add new pages, please click "Edit Portfolio". To edit this page, please click "Edit Page". prtf#:#prtf_portfolio_deleted#:#Portfolio deleted prtf#:#prtf_portfolio_page_deleted#:#Portfolio / blog page deleted. prtf#:#prtf_portfolios#:#Portfolios @@ -13094,6 +13111,8 @@ prtf#:#prtf_signature_date#:#Date, Signature prtf#:#prtf_signature_info#:#Adds a field to the print where the author can sign the portfolio. prtf#:#prtf_style#:#Portfolio Style prtf#:#prtf_submission_on#:#Submitted on $1 +prtf#:#prtf_successfully_shared_prtf#:#Confirmation Shared Portfolio '%s' +prtf#:#prtf_successfully_shared_prtf_body#:#You have shared your portfolio '%s' with: prtf#:#prtf_sure_delete_portfolio_pages#:#Are you sure you want to delete the following portfolio page / blog page? prtf#:#prtf_sure_delete_portfolios#:#Are you sure you want to delete the following portfolio? prtf#:#prtf_tab_other_users#:#Portfolios of Other Users @@ -13107,6 +13126,7 @@ prtf#:#prtf_template_title#:#Portfolio Template prtf#:#prtf_unset_as_default#:#Unset As My Profile prtf#:#prtf_unset_default_share_info#:#Your changes have been saved. Please check the current ‘share’ settings for your portfolio. prtf#:#prtf_use_page_layout#:#Use Page Layout +prtf#:#prtf_visible_for_tutor#:#Visible For Tutor prtf#:#prtt_title_info#:#Please note that this will be also the default title for all portfolios being created form this template. prtt#:#prtt_activation_limited_visibility_info#:#If chosen, the portfolio template is visible even outside of the given availability. prtt#:#prtt_activation_online_info#:#Activate this setting to make the portfolio template accessible to users. @@ -14964,6 +14984,7 @@ skmg#:#skmg_create_skill_template_reference#:#Create Competence Template Referen skmg#:#skmg_create_skll#:#Create Competence skmg#:#skmg_custom_image_alt#:#Custom image for competence profile skmg#:#skmg_delete_profiles#:#Do you really want to delete the following profiles? +skmg#:#skmg_delete_warning#:#Are you sure that you want to delete the following item(s)? When you delete the items, you also delete all usages, assignments and achievements of it. To be on the safe side, you find a list of all usages below. If the item is used in a competence profile, it will be removed from the profile, too. This may cause the fulfilment of the competence profile for the assigned users. If your are not sure whether an item should really be deleted, please use the statuses in the settings of a single item. skmg#:#skmg_description_info#:#The description comes from the template. skmg#:#skmg_edit_level#:#Edit Level skmg#:#skmg_edit_profile#:#Edit Profile @@ -16731,8 +16752,8 @@ ui#:#label_fieldselection_refresh#:#Apply ui#:#label_pagination_limit#:#Pagination Number of Rows ui#:#label_pagination_offset#:#Pagination Offset ui#:#label_sortation#:#Sortation -ui#:#presentaion_table_collapse#:#collapse all -ui#:#presentaion_table_expand#:#expand all +ui#:#presentation_table_collapse#:#collapse all +ui#:#presentation_table_expand#:#expand all ui#:#ui_chars_max#:#Maximum: ui#:#ui_chars_min#:#Minimum: ui#:#ui_chars_remaining#:#Characters remaining: @@ -17151,6 +17172,7 @@ wsp#:#wsp_permission_registered_info#:#This object is shared with all registered wsp#:#wsp_permission_removed#:#Entry has been removed. wsp#:#wsp_permissions#:#Share wsp#:#wsp_personal_resources_description#:#Here you can manage your private files, blogs and artifacts. +wsp#:#wsp_send_mail#:#Send Mail wsp#:#wsp_set_permission_all#:#World Wide Web wsp#:#wsp_set_permission_all_password#:#World Wide Web with Password wsp#:#wsp_set_permission_course#:#Members of Course diff --git a/src/DI/Container.php b/src/DI/Container.php index e751adac5613..8c2c1700ab7b 100644 --- a/src/DI/Container.php +++ b/src/DI/Container.php @@ -231,13 +231,7 @@ public function news(): \ILIAS\News\Service public function object(): \ilObjectService { - return new \ilObjectService( - $this->database(), - $this->language(), - $this->filesystem()->web(), - $this->upload(), - $this['object.customicons.factory'] - ); + return new \ilObjectService(); } public function exercise(): \ILIAS\Exercise\Service diff --git a/src/UI/Component/Button/Button.php b/src/UI/Component/Button/Button.php index 3ec600f47159..91c69b59d0c9 100644 --- a/src/UI/Component/Button/Button.php +++ b/src/UI/Component/Button/Button.php @@ -1,7 +1,5 @@ active = false; + $clone->active = !$flag; return $clone; } diff --git a/src/UI/examples/Input/Field/DateTime/base.php b/src/UI/examples/Input/Field/DateTime/base.php index 81185ed65f74..a5b4e8cc9c55 100644 --- a/src/UI/examples/Input/Field/DateTime/base.php +++ b/src/UI/examples/Input/Field/DateTime/base.php @@ -19,7 +19,7 @@ function base() $ctrl = $DIC->ctrl(); //Step 1: define the inputs - $date = $ui->input()->field()->dateTime("Pick a date/time", "Pick any date you want. It will be shown in format YYYY-MM-DD"); + $date = $ui->input()->field()->dateTime("Pick a date", "Pick any date you want. It will be shown in format YYYY-MM-DD"); $date_now = new \DateTimeImmutable('now'); $formatted = $date diff --git a/src/UI/examples/Player/Audio/base.php b/src/UI/examples/Player/Audio/base.php index 7215bccff9b7..6e9e93bf1e54 100644 --- a/src/UI/examples/Player/Audio/base.php +++ b/src/UI/examples/Player/Audio/base.php @@ -26,7 +26,7 @@ function base() $renderer = $DIC->ui()->renderer(); $f = $DIC->ui()->factory(); - $audio = $f->player()->audio("https://files.ilias.de/ILIAS-Audio.mp3", "Erster Gesang: Pest im Lager. Zorn des Achilleus. Singe vom Ingrimm, Göttin, des Peleus-Sohnes Achilleus, vom Verfluchten, der zahllose Schmerzen schuf den Archaiern und viele kraftvolle Seelen der Helden vorwarf dem Hades..."); + $audio = $f->player()->audio("https://files.ilias.de/ks/ILIAS-Audio.mp3", "Erster Gesang: Pest im Lager. Zorn des Achilleus. Singe vom Ingrimm, Göttin, des Peleus-Sohnes Achilleus, vom Verfluchten, der zahllose Schmerzen schuf den Archaiern und viele kraftvolle Seelen der Helden vorwarf dem Hades..."); return $renderer->render($audio); } diff --git a/src/UI/examples/Player/Video/video_mp4.php b/src/UI/examples/Player/Video/video_mp4.php index 8c7496f6a475..0dd2e443de04 100644 --- a/src/UI/examples/Player/Video/video_mp4.php +++ b/src/UI/examples/Player/Video/video_mp4.php @@ -26,7 +26,7 @@ function video_mp4(): string $renderer = $DIC->ui()->renderer(); $f = $DIC->ui()->factory(); - $video = $f->player()->video("https://files.ilias.de/ILIAS-Video.mp4"); + $video = $f->player()->video("https://files.ilias.de/ks/ILIAS-Video.mp4"); $video = $video->withAdditionalSubtitleFile("en", "./src/UI/examples/Player/Video/subtitles_en.vtt"); $video = $video->withAdditionalSubtitleFile("de", "./src/UI/examples/Player/Video/subtitles_de.vtt"); diff --git a/src/UI/templates/default/Table/tpl.presentationrow.html b/src/UI/templates/default/Table/tpl.presentationrow.html index c485328ebac4..bd6af93871a2 100644 --- a/src/UI/templates/default/Table/tpl.presentationrow.html +++ b/src/UI/templates/default/Table/tpl.presentationrow.html @@ -29,11 +29,18 @@

      +
      - {IMPORTANT_FIELD_LABEL} - {IMPORTANT_FIELD_VALUE} - | +
      + +
      {IMPORTANT_FIELD_LABEL}
      + + +
      {IMPORTANT_FIELD_VALUE}
      + +
      +
      {SHY_EXPANDER} diff --git a/src/UI/templates/default/Table/tpl.presentationtable.html b/src/UI/templates/default/Table/tpl.presentationtable.html index 13a936655b54..ff3ec3981ca2 100644 --- a/src/UI/templates/default/Table/tpl.presentationtable.html +++ b/src/UI/templates/default/Table/tpl.presentationtable.html @@ -3,8 +3,14 @@

      {TITLE}

      -
      {EXPANDCOLLAPSEALL}
      - {VC} +
      +
      +
      {EXPANDCOLLAPSEALL}
      +
      +
      + {VC} +
      +
      diff --git a/templates/default/030-tools/_tool_buttons.scss b/templates/default/030-tools/_tool_buttons.scss index 09cc13205370..bb54f55a249b 100644 --- a/templates/default/030-tools/_tool_buttons.scss +++ b/templates/default/030-tools/_tool_buttons.scss @@ -177,7 +177,7 @@ $set-full-width: false !default; } // KEYBOARD FOCUS - @include focus.il-focus(); + @include focus.il-focus-outline-only(); // ACTIVE (BEING PRESSED) &:active { diff --git a/templates/default/030-tools/_tool_focus-outline.scss b/templates/default/030-tools/_tool_focus-outline.scss index 301cbbea9b76..41686cec0c79 100644 --- a/templates/default/030-tools/_tool_focus-outline.scss +++ b/templates/default/030-tools/_tool_focus-outline.scss @@ -6,45 +6,54 @@ $il-focus-outline-outer-width: 2px; $il-focus-outline-inner: $il-focus-outline-inner-width solid $il-focus-color; $il-focus-outline-outer: $il-focus-outline-outer-width solid $il-focus-protection-color; -// In order not to manually overwrite the focus in all places, the following bootstrap focus mixin is overwritten ilias/libs/bower/bower_components/bootstrap/scss/mixins/tab-focus.scss. - -@mixin tab-focus(){ - // WebKit-specific. Other browsers will keep their default outline style. - // (Initially tried to also force default via `outline: initial`, - // but that seems to erroneously remove the outline in Firefox altogether.) - outline: none; - outline-offset: 0px; - &:focus-visible { - outline: $il-focus-outline-outer; - outline-offset: $il-focus-outline-inner-width + $il-focus-outline-outer-width; - - @include il-focus-after(); - } - } - +// KEYBOARD FOCUS DEFAULT +// This is the mixin you should be using if possible @mixin il-focus(){ + &:focus { + outline: none; + outline-offset: 0px; + } &:focus-visible { position: relative; outline: $il-focus-outline-outer; outline-offset: $il-focus-outline-inner-width + $il-focus-outline-outer-width - 1px; - @include il-focus-after(); + &::after { + content: " "; + position: absolute; + top: -$il-focus-outline-outer-width; + left: -$il-focus-outline-outer-width; + right: -$il-focus-outline-outer-width; + bottom: -$il-focus-outline-outer-width; + border: $il-focus-outline-outer; + outline: $il-focus-outline-inner; + } } +} - &:active,&.engaged{ - outline: none; +// KEYBOARD FOCUS FOR BUTTONS, INPUTS AND ELEMENTS WITH :AFTER +// some elements like buttons and input field cannot display the il-focus mixin because of the :after element +// in this case use this mixin instead +@mixin il-focus-outline-only() { + &:focus-visible { + outline: $il-focus-outline-inner; + box-shadow: inset 0px 0px 0px 2px $il-focus-protection-color, 0px 0px 0px 2px $il-focus-protection-color; + &::after { + content: none; + } } } -@mixin il-focus-after(){ - &::after { - content: " "; - position: absolute; - top: -$il-focus-outline-outer-width; - left: -$il-focus-outline-outer-width; - right: -$il-focus-outline-outer-width; - bottom: -$il-focus-outline-outer-width; - border: $il-focus-outline-outer; - outline: $il-focus-outline-inner; +// KEYBOARD FOCUS FOR ELEMENTS AT THE EDGE +// some elements at the edge do not show the focus outline because it's already offscreen +// in this case use this mixin instead +@mixin il-focus-border-only() { + &:focus-visible { + outline: none; + border: $il-focus-outline-inner; + box-shadow: inset 0px 0px 0px 2px $il-focus-protection-color, 0px 0px 0px 2px $il-focus-protection-color; + &::after { + content: none; + } } } \ No newline at end of file diff --git a/templates/default/050-layout/_index.scss b/templates/default/050-layout/_index.scss index 5f8c3e2a53b0..60b3ba479408 100644 --- a/templates/default/050-layout/_index.scss +++ b/templates/default/050-layout/_index.scss @@ -3,5 +3,5 @@ @use "./layout_grid"; @use "./layout_container"; -@use "./layout_visibility-utilities"; @use "./layout_element-bar"; +@use "./layout_visibility-utilities"; \ No newline at end of file diff --git a/templates/default/070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss b/templates/default/070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss index 2ae13cfcdc80..2e355cd2e5a0 100644 --- a/templates/default/070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss +++ b/templates/default/070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss @@ -25,13 +25,7 @@ &:hover { color: $il-standard-page-breadcrumbs-active-color; } - &:focus { - border: $il-focus-outline-inner; - - &::after { - content: none; - } - } + @include il-focus-outline-only() } &>span+span:before { diff --git a/templates/default/070-components/UI-framework/Button/_ui-component_button.scss b/templates/default/070-components/UI-framework/Button/_ui-component_button.scss index 8031501e8747..01280f870031 100644 --- a/templates/default/070-components/UI-framework/Button/_ui-component_button.scss +++ b/templates/default/070-components/UI-framework/Button/_ui-component_button.scss @@ -1,5 +1,6 @@ @use "../../../010-settings/" as s; @use "../../../010-settings/legacy-settings/legacy-settings_form" as s-form; +@use "../../../030-tools/tool_focus-outline" as f; @use "../../../050-layout/basics"as l; @use "../../../050-layout/standardpage" as l-spage; @use "../../../030-tools/_tool_buttons" as * with ( @@ -94,7 +95,12 @@ input.btn { } .btn-ctrl { - @include make-button($input-field-height: s.$il-btn-ctrl-outer-height, $border-radius: s.$il-border-radius-secondary-large, $button-text-color: s.$il-btn-ctrl-color, $button-color: s.$il-btn-ctrl-bg, $border-color: s.$il-btn-ctrl-border); + @include make-button($input-field-height: s.$il-btn-ctrl-outer-height, + $border-radius: s.$il-border-radius-secondary-large, + $button-text-color: s.$il-btn-ctrl-color, + $button-color: s.$il-btn-ctrl-bg, + $border-color: s.$il-btn-ctrl-border, + $hover_border-color: s.$il-btn-ctrl-engaged-border); &.engaged, .open & { border: 1px solid s.$il-btn-ctrl-engaged-border; @@ -130,12 +136,10 @@ input.btn { } &, &:hover, - &:focus, &:active { border-color: transparent; } - &:hover, - &:focus { + &:hover { color: s.$il-link-hover-color; text-decoration: s.$il-link-hover-decoration; background-color: transparent; @@ -145,8 +149,7 @@ input.btn { background-color: s.$il-disabled-btn-bg; color: s.$il-disabled-btn-color; border: 1px solid s.$il-disabled-btn-border; - &:hover, - &:focus { + &:hover { text-decoration: none; } } @@ -192,6 +195,7 @@ input.btn { $engaged_text-color: inherit, $engaged_bg-color: s.$il-bulky-bg-color-engaged, $engaged_border-width: 1px); + @include f.il-focus-border-only(); } // same visual design for bulky buttons and links in slate and drilldown diff --git a/templates/default/070-components/UI-framework/Card/_ui-component_card.scss b/templates/default/070-components/UI-framework/Card/_ui-component_card.scss index db74095c32f8..06379242870e 100644 --- a/templates/default/070-components/UI-framework/Card/_ui-component_card.scss +++ b/templates/default/070-components/UI-framework/Card/_ui-component_card.scss @@ -155,11 +155,6 @@ $card-head-icon-filter: invert(50%); margin-left: auto; margin-right: auto; } - - &:focus-visible { - overflow: visible; - outline-offset: $il-focus-outline-inner-width + $il-focus-outline-outer-width - 1; - } } } } diff --git a/templates/default/070-components/UI-framework/Input/_ui-component_input.scss b/templates/default/070-components/UI-framework/Input/_ui-component_input.scss index 2038cb701597..87eb6d85a330 100644 --- a/templates/default/070-components/UI-framework/Input/_ui-component_input.scss +++ b/templates/default/070-components/UI-framework/Input/_ui-component_input.scss @@ -113,32 +113,6 @@ border-radius: 0; } -.form-control, .form-control:focus { - @include box-shadow(none); -} - -.form-control:focus-visible { - @include box-shadow(none); - outline: $il-focus-outline-inner; -} - -input[type="file"]:focus:focus-visible::after, -input[type="radio"]:focus:focus-visible::after, -input[type="checkbox"]:focus:focus-visible::after { - content: none; -} - -input.btn.btn-default:focus-visible { - outline: $il-focus-outline-inner; - outline-offset: $il-focus-outline-inner-width; -} - -.btn-file:focus-within, .btn-file:hover:focus-within { - z-index: 3; - outline: $il-focus-outline-inner; - outline-offset: $il-focus-outline-inner-width; -} - textarea.form-control { max-width: 100%; } @@ -159,10 +133,4 @@ td.form-inline > div.form-group { padding: 4px 0; } -input[type="radio"]:focus:focus-visible, -input[type="checkbox"]:focus:focus-visible { - outline: $il-focus-outline-inner; - outline-offset: $il-focus-outline-outer-width; -} - diff --git a/templates/default/070-components/UI-framework/Layout/_ui-component_standardpage.scss b/templates/default/070-components/UI-framework/Layout/_ui-component_standardpage.scss index d998f9f007a6..02dac51c4739 100644 --- a/templates/default/070-components/UI-framework/Layout/_ui-component_standardpage.scss +++ b/templates/default/070-components/UI-framework/Layout/_ui-component_standardpage.scss @@ -116,6 +116,9 @@ div.il-system-infos { justify-self: start; display: flex; align-items: center; + a { + display: block; // so keyboard focus surrounds logo + } } .il-pagetitle { diff --git a/templates/default/070-components/UI-framework/Link/_ui-component_link.scss b/templates/default/070-components/UI-framework/Link/_ui-component_link.scss index 76b916233593..50553a54c934 100644 --- a/templates/default/070-components/UI-framework/Link/_ui-component_link.scss +++ b/templates/default/070-components/UI-framework/Link/_ui-component_link.scss @@ -1,11 +1,6 @@ @use "../../../010-settings/"as *; @use "../../../030-tools/tool_focus-outline" as *; -.il-link{ - @include il-focus(); -} - - .il-link.link-bulky { text-decoration: none; diff --git a/templates/default/070-components/UI-framework/MainControls/_ui-component_mainbar.scss b/templates/default/070-components/UI-framework/MainControls/_ui-component_mainbar.scss index 36b43b8011aa..a79052afa9f8 100644 --- a/templates/default/070-components/UI-framework/MainControls/_ui-component_mainbar.scss +++ b/templates/default/070-components/UI-framework/MainControls/_ui-component_mainbar.scss @@ -1,6 +1,6 @@ @use "../../../010-settings/"as *; @use "../../../010-settings/legacy-settings/legacy-settings_symbol" as *; -@use "../../../030-tools/tool_focus-outline" as *; +@use "../../../030-tools/tool_focus-outline" as f; @use "../../../030-tools/tool_screen-reader-only" as *; @use "../../../030-tools/tool_multi-line-cap" as t-line-cap; @use "../../../050-layout/basics" as *; @@ -71,6 +71,15 @@ $il-slate-bulky-link-padding: $il-slate-bulky-padding-vertical $il-padding-base- .il-link.link-bulky { height:$il-mainbar-btn-height; width: $il-mainbar-btn-width; + } +} + +.il-mainbar-triggers, +.il-mainbar-tools-button, +.il-mainbar-tool-trigger-item, +.il-maincontrols-metabar { + .btn-bulky, + .il-link.link-bulky { padding: $il-mainbar-btn-padding; border: 0; border-bottom: $il-mainbar-btn-border; @@ -80,6 +89,7 @@ $il-slate-bulky-link-padding: $il-slate-bulky-padding-vertical $il-padding-base- gap: $il-mainbar-btn-label-icon-gap; font-size: $il-mainbar-btn-label-size; line-height: $il-mainbar-btn-label-size * $il-line-height-large; + @include f.il-focus-border-only(); .bulky-label { @include t-line-cap.il-multi-line-cap-mixin(2); word-break: break-word; diff --git a/templates/default/070-components/UI-framework/Table/_ui-component_table.scss b/templates/default/070-components/UI-framework/Table/_ui-component_table.scss index 63aeb7f7347c..212da9bb74c9 100644 --- a/templates/default/070-components/UI-framework/Table/_ui-component_table.scss +++ b/templates/default/070-components/UI-framework/Table/_ui-component_table.scss @@ -18,23 +18,9 @@ $il-table-presentation-details-viewcontrols-btn-color: $il-main-color; $il-table-presentation-details-viewcontrols-btn-bg: white; .il-table-presentation-viewcontrols { - background-color: $il-table-presentation-details-viewcontrols-bg-color; - display: flex; - flex-wrap: wrap; - justify-content: space-between; - - > div { - padding: $il-padding-large-vertical; - } - - .il-viewcontrol-pagination { - order: 1; - } - .il-viewcontrol-mode { - order: 2; - } - .il-viewcontrol-sortatio { - order: 3; + margin-bottom: $il-margin-large-vertical; + @media print { + display: none !important; } } @@ -100,6 +86,12 @@ $il-table-presentation-details-viewcontrols-btn-bg: white; } } + // add : to both importantfields and desclist keys + .il-table-presentation-row-header-fields-label::after, + .il-table-presentation-desclist .il-listing-characteristic-value-label::after { + content: ":"; + } + .il-table-presentation-row-expanded { //Using row mixin, to make this responsive @include l-grid.make-row; diff --git a/templates/default/070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss b/templates/default/070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss index e39d972fccb9..5ba18c7bcbd9 100644 --- a/templates/default/070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss +++ b/templates/default/070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss @@ -56,8 +56,9 @@ $il-vc-pagination-btn-active-bg: $il-main-bg; // viewcontrols as single buttons // should in the future be done by using btn-ctrl class on these buttons -.il-viewcontrol-sortation { - .btn-default.btn { +.il-viewcontrol-sortation .dropdown, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element { + > .btn-default.btn { @extend .btn-ctrl; border-radius: $il-border-radius-secondary-large; } diff --git a/templates/default/070-components/_index.scss b/templates/default/070-components/_index.scss index 6b4237e97e1b..20f8e2eefc25 100644 --- a/templates/default/070-components/_index.scss +++ b/templates/default/070-components/_index.scss @@ -56,7 +56,6 @@ @use "./legacy/_component_map.scss"; @use "./legacy/component_media-object"; @use "./legacy/_component_overlay.scss"; -@use "./legacy/_component_permalinks.scss"; @use "./legacy/_component_rightPanel.scss"; @use "./legacy/_component_delostable.scss"; diff --git a/templates/default/070-components/legacy/Modules/_component_test.scss b/templates/default/070-components/legacy/Modules/_component_test.scss index 921fa7b0a457..d16ccd1726f4 100644 --- a/templates/default/070-components/legacy/Modules/_component_test.scss +++ b/templates/default/070-components/legacy/Modules/_component_test.scss @@ -120,4 +120,29 @@ $il-test-working-time-font-weight: $il-font-weight-bold; #tst_pass_details_overview tr { scroll-margin-top: 30px; +} + +// +// test result +// + +.il-table-presentation-desclist.inline .il-listing-characteristic-value-row { + display: flex; + width: auto; + padding-right: $il-padding-xxxlarge-horizontal; +} + +.il-table-presentation-desclist.inline .il-listing-characteristic-value { + display: flex; + .il-listing-characteristic-value-item { + padding-left: $il-padding-small-horizontal; + } +} + +.il-listing-characteristic-value-label, .il-listing-characteristic-value-item { + width: fit-content; +} + +.il-listing-characteristic-value-row.clearfix { + border-top: none; } \ No newline at end of file diff --git a/templates/default/070-components/legacy/Services/_component_form.scss b/templates/default/070-components/legacy/Services/_component_form.scss index 7bf89515197c..35eb62671244 100644 --- a/templates/default/070-components/legacy/Services/_component_form.scss +++ b/templates/default/070-components/legacy/Services/_component_form.scss @@ -87,10 +87,10 @@ select[size] { } // Focus for file, radio, and checkbox -input[type="file"]:focus, -input[type="radio"]:focus, -input[type="checkbox"]:focus { - @include tab-focus(); +input[type="file"], +input[type="radio"], +input[type="checkbox"] { + @include il-focus-outline-only(); } @@ -132,17 +132,7 @@ input[type="checkbox"]:focus { @include transition(border-color ease-in-out .15s, box-shadow ease-in-out .15s); // Customize the `:focus` state to imitate native WebKit styles. - @mixin form-control-focus($color: $il-input-border-focus) { - $color-rgba: rgba(red($color), green($color), blue($color), .6); - - &:focus { - border-color: $color; - outline: 0; - @include box-shadow(inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px $color-rgba); - } - } - - @include form-control-focus; + @include il-focus-outline-only(); // Placeholder @include placeholder; diff --git a/templates/default/070-components/legacy/Services/_component_webdav.scss b/templates/default/070-components/legacy/Services/_component_webdav.scss index 99336c3ffccd..7860fd717e7c 100644 --- a/templates/default/070-components/legacy/Services/_component_webdav.scss +++ b/templates/default/070-components/legacy/Services/_component_webdav.scss @@ -2,5 +2,5 @@ .webdav-view-control { text-align: center; - padding: $il-focus-outline-inner-width + $il-focus-outline-outer-width; + @include il-focus(); } \ No newline at end of file diff --git a/templates/default/070-components/legacy/_component_permalinks.scss b/templates/default/070-components/legacy/_component_permalinks.scss deleted file mode 100644 index b5f7f18aeb13..000000000000 --- a/templates/default/070-components/legacy/_component_permalinks.scss +++ /dev/null @@ -1,59 +0,0 @@ -@use "../../010-settings/" as *; -@use "../../030-tools/tool_focus-outline" as *; - - -/* ----------------- permanent link ------------- */ -#current_perma_link { - color: $il-text-color; - font-size: $il-font-size-small; - - &:focus-visible { - outline: $il-focus-outline-inner-width solid $il-focus-protection-color; - outline-offset: $il-focus-outline-outer-width; - } -} -a.permalink_label { - > span.glyphicon { - display: none; - } -} - -.ilPermalinkContainer { - width: 100%; -} - -div.ilPermanentLinkWrapper { - clear: both; - margin-top: 10px; - display: inline-block; - width: 100%; - a.permalink_label { - > span.glyphicon { - @media only screen and (max-width: $il-grid-float-breakpoint-max) { - display: inline; - } - } - } - .ilPermalinkContainer { - table-layout: fixed; - line-height: 22px; - @media only screen and (max-width: $il-grid-float-breakpoint-max) { - padding-right: 0; - } - > label { - width: 150px; - display: table-cell; - vertical-align: middle; - @media only screen and (max-width: $il-grid-float-breakpoint-max) { - padding-right: 0; - width: 24px; - } - } - > input, .btn-group { - z-index: 0; /* see bug #24567 */ - } - .input-group-btn { - width: 28px; - } - } -} \ No newline at end of file diff --git a/templates/default/delos.css b/templates/default/delos.css index 1a781aa79b32..7c03fc97cc7c 100644 --- a/templates/default/delos.css +++ b/templates/default/delos.css @@ -1976,6 +1976,38 @@ th { } /* Responsive container system from Bootstrap 5 has been removed */ +.l-bar__container, +.l-bar__group { + display: flex; + flex-direction: row; + flex-wrap: wrap; + align-items: center; +} + +.l-bar__container:not(:empty) { + margin-bottom: -9px; +} +.l-bar__container:not(:empty).l-bar__container--space-between { + justify-content: space-between; +} + +.l-bar__container > .l-bar__group { + margin-right: 15px; +} +.l-bar__container > .l-bar__group:last-child { + margin-right: 0; +} + +.l-bar__container > .l-bar__element, +.l-bar__group > .l-bar__element { + margin-right: 3px; + margin-bottom: 9px; +} +.l-bar__container > .l-bar__element:last-child, +.l-bar__group > .l-bar__element:last-child { + margin-right: 0; +} + .hidden, .visible-xs-block, .visible-xs-inline, @@ -2195,38 +2227,6 @@ th { display: none !important; } } -.l-bar__container, -.l-bar__group { - display: flex; - flex-direction: row; - flex-wrap: wrap; - align-items: center; -} - -.l-bar__container:not(:empty) { - margin-bottom: -9px; -} -.l-bar__container:not(:empty).l-bar__container--space-between { - justify-content: space-between; -} - -.l-bar__container > .l-bar__group { - margin-right: 15px; -} -.l-bar__container > .l-bar__group:last-child { - margin-right: 0; -} - -.l-bar__container > .l-bar__element, -.l-bar__group > .l-bar__element { - margin-right: 3px; - margin-bottom: 9px; -} -.l-bar__container > .l-bar__element:last-child, -.l-bar__group > .l-bar__element:last-child { - margin-right: 0; -} - * { box-sizing: border-box; } @@ -2448,6 +2448,10 @@ a:hover, a:focus { color: #3a4c65; text-decoration: underline; } +a:focus { + outline: none; + outline-offset: 0px; +} a:focus-visible { position: relative; outline: 2px solid #FFFFFF; @@ -2463,9 +2467,6 @@ a:focus-visible::after { border: 2px solid #FFFFFF; outline: 3px solid #0078D7; } -a:active, a.engaged { - outline: none; -} small, .small, sub, sup { @@ -2700,10 +2701,11 @@ code { .breadcrumb_wrapper .breadcrumb span.crumb a:hover { color: #3a4c65; } -.breadcrumb_wrapper .breadcrumb span.crumb a:focus { - border: 3px solid #0078D7; +.breadcrumb_wrapper .breadcrumb span.crumb a:focus-visible { + outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } -.breadcrumb_wrapper .breadcrumb span.crumb a:focus::after { +.breadcrumb_wrapper .breadcrumb span.crumb a:focus-visible::after { content: none; } .breadcrumb_wrapper .breadcrumb > span + span:before { @@ -2798,22 +2800,11 @@ input.btn, input.il-link.link-bulky, border-color: #3a4c65; } .btn-default:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; -} -.btn-default:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } -.btn-default:active, .btn-default.engaged { - outline: none; +.btn-default:focus-visible::after { + content: none; } .btn-default:active { transform: scale(0.95); @@ -2863,22 +2854,11 @@ input.btn, input.il-link.link-bulky, border-color: #3b5620; } .btn-primary:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; -} -.btn-primary:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } -.btn-primary:active, .btn-primary.engaged { - outline: none; +.btn-primary:focus-visible::after { + content: none; } .btn-primary:active { transform: scale(0.95); @@ -2920,7 +2900,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default, .il-viewcontrol-pagination .last > .btn-link, .il-viewcontrol-mode > .btn-default, -.il-viewcontrol-mode > .btn-link, .il-viewcontrol-sortation .btn-default.btn { +.il-viewcontrol-mode > .btn-link, .il-viewcontrol-sortation .dropdown > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn { display: inline-flex; vertical-align: middle; align-items: center; @@ -2960,7 +2941,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default + .btn-ctrl, .il-viewcontrol-pagination .last > .btn-link + .btn-ctrl, .il-viewcontrol-mode > .btn-default + .btn-ctrl, -.il-viewcontrol-mode > .btn-link + .btn-ctrl, .il-viewcontrol-sortation .btn-default.btn + .btn-ctrl, .il-viewcontrol-section > .btn-ctrl + .btn-default, .il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-section > .btn-link + .btn-default, +.il-viewcontrol-mode > .btn-link + .btn-ctrl, .il-viewcontrol-sortation .dropdown > .btn-default.btn + .btn-ctrl, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn + .btn-ctrl, .il-viewcontrol-section > .btn-ctrl + .btn-default, .il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-section > .btn-link + .btn-default, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-default + .btn-default, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-link + .btn-default, .il-viewcontrol-section.il-viewcontrol-pagination__sectioncontrol > .btn-default + .btn-default, @@ -2974,7 +2956,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-default + .btn-default, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-link + .btn-default, .il-viewcontrol-section.il-viewcontrol-mode > .btn-default + .btn-default, -.il-viewcontrol-section.il-viewcontrol-mode > .btn-link + .btn-default, .il-viewcontrol-sortation .il-viewcontrol-section > .btn-default.btn + .btn-default, .il-viewcontrol-section > .btn-ctrl + .btn-link, .il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-section > .btn-link + .btn-link, +.il-viewcontrol-section.il-viewcontrol-mode > .btn-link + .btn-default, .il-viewcontrol-sortation .il-viewcontrol-section.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-section > .btn-ctrl + .btn-link, .il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-section > .btn-link + .btn-link, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-default + .btn-link, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-link + .btn-link, .il-viewcontrol-section.il-viewcontrol-pagination__sectioncontrol > .btn-default + .btn-link, @@ -2988,7 +2971,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-default + .btn-link, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-link + .btn-link, .il-viewcontrol-section.il-viewcontrol-mode > .btn-default + .btn-link, -.il-viewcontrol-section.il-viewcontrol-mode > .btn-link + .btn-link, .il-viewcontrol-sortation .il-viewcontrol-section > .btn-default.btn + .btn-link, +.il-viewcontrol-section.il-viewcontrol-mode > .btn-link + .btn-link, .il-viewcontrol-sortation .il-viewcontrol-section.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-section .btn-group > .btn-ctrl + .btn-default, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-link + .btn-default, @@ -3010,8 +2994,10 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-section .il-viewcontrol-pagination .btn-group.last > .btn-link + .btn-default, .il-viewcontrol-section .btn-group.il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-section .btn-group.il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-section .btn-group > .btn-default.btn + .btn-default, -.il-viewcontrol-section .il-viewcontrol-sortation .btn-group > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-section .btn-group.dropdown > .btn-default.btn + .btn-default, +.il-viewcontrol-section .il-viewcontrol-sortation .btn-group.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section .btn-group.l-bar__element > .btn-default.btn + .btn-default, +.il-viewcontrol-section .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .btn-group.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-section .btn-group > .btn-ctrl + .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-link + .btn-link, @@ -3033,8 +3019,10 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-section .il-viewcontrol-pagination .btn-group.last > .btn-link + .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-section .btn-group > .btn-default.btn + .btn-link, -.il-viewcontrol-section .il-viewcontrol-sortation .btn-group > .btn-default.btn + .btn-link, +.il-viewcontrol-sortation .il-viewcontrol-section .btn-group.dropdown > .btn-default.btn + .btn-link, +.il-viewcontrol-section .il-viewcontrol-sortation .btn-group.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section .btn-group.l-bar__element > .btn-default.btn + .btn-link, +.il-viewcontrol-section .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .btn-group.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-pagination__sectioncontrol > .btn-ctrl + .btn-default, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-section > .btn-link + .btn-default, @@ -3052,7 +3040,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination__sectioncontrol.last > .btn-link + .btn-default, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination__sectioncontrol.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-pagination__sectioncontrol > .btn-ctrl + .btn-link, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-section > .btn-link + .btn-link, @@ -3070,7 +3059,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination__sectioncontrol.last > .btn-link + .btn-link, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol > .btn-default.btn + .btn-link, +.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination__sectioncontrol.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-pagination__num-of-items > .btn-ctrl + .btn-default, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-section > .btn-link + .btn-default, @@ -3088,7 +3078,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination__num-of-items.last > .btn-link + .btn-default, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination__num-of-items.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-pagination__num-of-items > .btn-ctrl + .btn-link, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-section > .btn-link + .btn-link, @@ -3106,7 +3097,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination__num-of-items.last > .btn-link + .btn-link, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-pagination__num-of-items.il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items > .btn-default.btn + .btn-link, +.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination__num-of-items.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-pagination > .btn-ctrl + .btn-default, .il-viewcontrol-pagination.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-pagination.il-viewcontrol-section > .btn-link + .btn-default, @@ -3124,7 +3116,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination.last > .btn-link + .btn-default, .il-viewcontrol-pagination.il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-pagination.il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-pagination > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-pagination.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-pagination > .btn-ctrl + .btn-link, .il-viewcontrol-pagination.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-pagination.il-viewcontrol-section > .btn-link + .btn-link, @@ -3142,7 +3135,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-pagination.last > .btn-link + .btn-link, .il-viewcontrol-pagination.il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-pagination.il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-pagination > .btn-default.btn + .btn-link, +.il-viewcontrol-sortation .il-viewcontrol-pagination.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-pagination .dropdown > .btn-ctrl + .btn-default, .il-viewcontrol-pagination .dropdown.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-pagination .dropdown.il-viewcontrol-section > .btn-link + .btn-default, @@ -3164,6 +3158,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .dropdown.il-viewcontrol-mode > .btn-link + .btn-default, .il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown > .btn-default.btn + .btn-default, .il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .dropdown.l-bar__element > .btn-default.btn + .btn-default, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .dropdown.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-pagination .dropdown > .btn-ctrl + .btn-link, .il-viewcontrol-pagination .dropdown.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-pagination .dropdown.il-viewcontrol-section > .btn-link + .btn-link, @@ -3185,6 +3181,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .dropdown.il-viewcontrol-mode > .btn-link + .btn-link, .il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown > .btn-default.btn + .btn-link, .il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .dropdown.l-bar__element > .btn-default.btn + .btn-link, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .dropdown.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-pagination .last > .btn-ctrl + .btn-default, .il-viewcontrol-pagination .last.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-pagination .last.il-viewcontrol-section > .btn-link + .btn-default, @@ -3204,8 +3202,10 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-link + .btn-default, .il-viewcontrol-pagination .last.il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-pagination .last.il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-pagination .last > .btn-default.btn + .btn-default, -.il-viewcontrol-pagination .il-viewcontrol-sortation .last > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-pagination .last.dropdown > .btn-default.btn + .btn-default, +.il-viewcontrol-pagination .il-viewcontrol-sortation .last.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .last.l-bar__element > .btn-default.btn + .btn-default, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .last.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-pagination .last > .btn-ctrl + .btn-link, .il-viewcontrol-pagination .last.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-pagination .last.il-viewcontrol-section > .btn-link + .btn-link, @@ -3225,8 +3225,10 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-link + .btn-link, .il-viewcontrol-pagination .last.il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-pagination .last.il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-pagination .last > .btn-default.btn + .btn-link, -.il-viewcontrol-pagination .il-viewcontrol-sortation .last > .btn-default.btn + .btn-link, +.il-viewcontrol-sortation .il-viewcontrol-pagination .last.dropdown > .btn-default.btn + .btn-link, +.il-viewcontrol-pagination .il-viewcontrol-sortation .last.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .last.l-bar__element > .btn-default.btn + .btn-link, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .last.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-mode > .btn-ctrl + .btn-default, .il-viewcontrol-mode.il-viewcontrol-section > .btn-default + .btn-default, .il-viewcontrol-mode.il-viewcontrol-section > .btn-link + .btn-default, @@ -3244,7 +3246,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-mode.last > .btn-link + .btn-default, .il-viewcontrol-mode > .btn-default + .btn-default, .il-viewcontrol-mode > .btn-link + .btn-default, -.il-viewcontrol-sortation .il-viewcontrol-mode > .btn-default.btn + .btn-default, +.il-viewcontrol-sortation .il-viewcontrol-mode.dropdown > .btn-default.btn + .btn-default, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-mode.l-bar__element > .btn-default.btn + .btn-default, .il-viewcontrol-mode > .btn-ctrl + .btn-link, .il-viewcontrol-mode.il-viewcontrol-section > .btn-default + .btn-link, .il-viewcontrol-mode.il-viewcontrol-section > .btn-link + .btn-link, @@ -3262,27 +3265,56 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .il-viewcontrol-mode.last > .btn-link + .btn-link, .il-viewcontrol-mode > .btn-default + .btn-link, .il-viewcontrol-mode > .btn-link + .btn-link, -.il-viewcontrol-sortation .il-viewcontrol-mode > .btn-default.btn + .btn-link, .il-viewcontrol-sortation .btn-ctrl + .btn-default.btn, .il-viewcontrol-sortation .il-viewcontrol-section > .btn-default + .btn-default.btn, .il-viewcontrol-sortation .il-viewcontrol-section > .btn-link + .btn-default.btn, -.il-viewcontrol-section .il-viewcontrol-sortation .btn-group > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-section .btn-group > .btn-default + .btn-default.btn, -.il-viewcontrol-section .il-viewcontrol-sortation .btn-group > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-section .btn-group > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-mode.dropdown > .btn-default.btn + .btn-link, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-mode.l-bar__element > .btn-default.btn + .btn-link, .il-viewcontrol-sortation .dropdown > .btn-ctrl + .btn-default.btn, .il-viewcontrol-sortation .dropdown.il-viewcontrol-section > .btn-default + .btn-default.btn, .il-viewcontrol-sortation .dropdown.il-viewcontrol-section > .btn-link + .btn-default.btn, +.il-viewcontrol-section .il-viewcontrol-sortation .dropdown.btn-group > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-section .dropdown.btn-group > .btn-default + .btn-default.btn, +.il-viewcontrol-section .il-viewcontrol-sortation .dropdown.btn-group > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-section .dropdown.btn-group > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__sectioncontrol > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__sectioncontrol > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__num-of-items > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__num-of-items > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination > .btn-link + .btn-default.btn, .il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown > .btn-default + .btn-default.btn, .il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown > .btn-default + .btn-default.btn, .il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown > .btn-link + .btn-default.btn, .il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown > .btn-link + .btn-default.btn, -.il-viewcontrol-pagination .il-viewcontrol-sortation .last > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination .last > .btn-default + .btn-default.btn, -.il-viewcontrol-pagination .il-viewcontrol-sortation .last > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination .last > .btn-link + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-mode > .btn-default + .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-mode > .btn-link + .btn-default.btn, .il-viewcontrol-sortation .btn-default.btn + .btn-default.btn { +.il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown.last > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown.last > .btn-default + .btn-default.btn, +.il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown.last > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown.last > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-mode > .btn-default + .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-mode > .btn-link + .btn-default.btn, .il-viewcontrol-sortation .dropdown > .btn-default.btn + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-sortation .dropdown.l-bar__element > .btn-default.btn + .btn-default.btn, +.il-viewcontrol-sortation .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .dropdown.l-bar__element > .btn-default.btn + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-ctrl + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-section > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-section > .btn-link + .btn-default.btn, +.il-viewcontrol-section .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.btn-group > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section .l-bar__element.btn-group > .btn-default + .btn-default.btn, +.il-viewcontrol-section .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.btn-group > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section .l-bar__element.btn-group > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__sectioncontrol > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__sectioncontrol > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__num-of-items > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__num-of-items > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination > .btn-link + .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.dropdown > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.dropdown > .btn-default + .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.dropdown > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.dropdown > .btn-link + .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.last > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.last > .btn-default + .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.last > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.last > .btn-link + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-mode > .btn-default + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-mode > .btn-link + .btn-default.btn, +.il-viewcontrol-sortation .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.dropdown > .btn-default.btn + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-sortation .l-bar__element.dropdown > .btn-default.btn + .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn + .btn-default.btn { margin-left: 3px; } .btn-ctrl:hover, .il-viewcontrol-section > .btn-default:hover, .il-viewcontrol-section > .btn-link:hover, @@ -3299,13 +3331,14 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default:hover, .il-viewcontrol-pagination .last > .btn-link:hover, .il-viewcontrol-mode > .btn-default:hover, -.il-viewcontrol-mode > .btn-link:hover, .il-viewcontrol-sortation .btn-default.btn:hover { +.il-viewcontrol-mode > .btn-link:hover, .il-viewcontrol-sortation .dropdown > .btn-default.btn:hover, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn:hover { text-decoration: none; background-color: white; color: #4c6586; border-width: 1px; border-style: solid; - border-color: white; + border-color: #4c6586; } .btn-ctrl:focus-visible, .il-viewcontrol-section > .btn-default:focus-visible, .il-viewcontrol-section > .btn-link:focus-visible, .il-viewcontrol-section .btn-group > .btn-default:focus-visible, @@ -3321,10 +3354,10 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default:focus-visible, .il-viewcontrol-pagination .last > .btn-link:focus-visible, .il-viewcontrol-mode > .btn-default:focus-visible, -.il-viewcontrol-mode > .btn-link:focus-visible, .il-viewcontrol-sortation .btn-default.btn:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; +.il-viewcontrol-mode > .btn-link:focus-visible, .il-viewcontrol-sortation .dropdown > .btn-default.btn:focus-visible, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn:focus-visible { + outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } .btn-ctrl:focus-visible::after, .il-viewcontrol-section > .btn-default:focus-visible::after, .il-viewcontrol-section > .btn-link:focus-visible::after, .il-viewcontrol-section .btn-group > .btn-default:focus-visible::after, @@ -3340,46 +3373,9 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default:focus-visible::after, .il-viewcontrol-pagination .last > .btn-link:focus-visible::after, .il-viewcontrol-mode > .btn-default:focus-visible::after, -.il-viewcontrol-mode > .btn-link:focus-visible::after, .il-viewcontrol-sortation .btn-default.btn:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; - outline: 3px solid #0078D7; -} -.btn-ctrl:active, .il-viewcontrol-section > .btn-default:active, .il-viewcontrol-section > .btn-link:active, -.il-viewcontrol-section .btn-group > .btn-default:active, -.il-viewcontrol-section .btn-group > .btn-link:active, -.il-viewcontrol-pagination__sectioncontrol > .btn-default:active, -.il-viewcontrol-pagination__sectioncontrol > .btn-link:active, -.il-viewcontrol-pagination__num-of-items > .btn-default:active, -.il-viewcontrol-pagination__num-of-items > .btn-link:active, -.il-viewcontrol-pagination > .btn-default:active, -.il-viewcontrol-pagination > .btn-link:active, -.il-viewcontrol-pagination .dropdown > .btn-default:active, -.il-viewcontrol-pagination .dropdown > .btn-link:active, -.il-viewcontrol-pagination .last > .btn-default:active, -.il-viewcontrol-pagination .last > .btn-link:active, -.il-viewcontrol-mode > .btn-default:active, -.il-viewcontrol-mode > .btn-link:active, .il-viewcontrol-sortation .btn-default.btn:active, .btn-ctrl.engaged, .il-viewcontrol-section > .engaged.btn-default, .il-viewcontrol-section > .engaged.btn-link, -.il-viewcontrol-section .btn-group > .engaged.btn-default, -.il-viewcontrol-section .btn-group > .engaged.btn-link, -.il-viewcontrol-pagination__sectioncontrol > .engaged.btn-default, -.il-viewcontrol-pagination__sectioncontrol > .engaged.btn-link, -.il-viewcontrol-pagination__num-of-items > .engaged.btn-default, -.il-viewcontrol-pagination__num-of-items > .engaged.btn-link, -.il-viewcontrol-pagination > .engaged.btn-default, -.il-viewcontrol-pagination > .engaged.btn-link, -.il-viewcontrol-pagination .dropdown > .engaged.btn-default, -.il-viewcontrol-pagination .dropdown > .engaged.btn-link, -.il-viewcontrol-pagination .last > .engaged.btn-default, -.il-viewcontrol-pagination .last > .engaged.btn-link, -.il-viewcontrol-mode > .engaged.btn-default, -.il-viewcontrol-mode > .engaged.btn-link, .il-viewcontrol-sortation .engaged.btn-default.btn { - outline: none; +.il-viewcontrol-mode > .btn-link:focus-visible::after, .il-viewcontrol-sortation .dropdown > .btn-default.btn:focus-visible::after, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn:focus-visible::after { + content: none; } .btn-ctrl:active, .il-viewcontrol-section > .btn-default:active, .il-viewcontrol-section > .btn-link:active, .il-viewcontrol-section .btn-group > .btn-default:active, @@ -3395,7 +3391,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-default:active, .il-viewcontrol-pagination .last > .btn-link:active, .il-viewcontrol-mode > .btn-default:active, -.il-viewcontrol-mode > .btn-link:active, .il-viewcontrol-sortation .btn-default.btn:active { +.il-viewcontrol-mode > .btn-link:active, .il-viewcontrol-sortation .dropdown > .btn-default.btn:active, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn:active { transform: scale(0.95); background-color: white; color: #4c6586; @@ -3417,7 +3414,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > [disabled].btn-default, .il-viewcontrol-pagination .last > [disabled].btn-link, .il-viewcontrol-mode > [disabled].btn-default, -.il-viewcontrol-mode > [disabled].btn-link, .il-viewcontrol-sortation [disabled].btn-default.btn, +.il-viewcontrol-mode > [disabled].btn-link, .il-viewcontrol-sortation .dropdown > [disabled].btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > [disabled].btn-default.btn, .btn-ctrl fieldset[disabled], .il-viewcontrol-section > .btn-default fieldset[disabled], .il-viewcontrol-section > .btn-link fieldset[disabled], @@ -3435,7 +3433,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .btn-link fieldset[disabled], .il-viewcontrol-mode > .btn-default fieldset[disabled], .il-viewcontrol-mode > .btn-link fieldset[disabled], -.il-viewcontrol-sortation .btn-default.btn fieldset[disabled] { +.il-viewcontrol-sortation .dropdown > .btn-default.btn fieldset[disabled], +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn fieldset[disabled] { background-color: white; border-width: 1px; border-style: solid; @@ -3458,7 +3457,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .engaged.btn-default, .il-viewcontrol-pagination .last > .engaged.btn-link, .il-viewcontrol-mode > .engaged.btn-default, -.il-viewcontrol-mode > .engaged.btn-link, .il-viewcontrol-sortation .engaged.btn-default.btn { +.il-viewcontrol-mode > .engaged.btn-link, .il-viewcontrol-sortation .dropdown > .engaged.btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .engaged.btn-default.btn { background-color: white; border-width: 3px; border-style: solid; @@ -3479,7 +3479,8 @@ input.btn, input.il-link.link-bulky, .il-viewcontrol-pagination .last > .engaged.btn-default, .il-viewcontrol-pagination .last > .engaged.btn-link, .il-viewcontrol-mode > .engaged.btn-default, -.il-viewcontrol-mode > .engaged.btn-link, .il-viewcontrol-sortation .engaged.btn-default.btn, .open .btn-ctrl, .open .il-viewcontrol-section > .btn-default, .open .il-viewcontrol-section > .btn-link, +.il-viewcontrol-mode > .engaged.btn-link, .il-viewcontrol-sortation .dropdown > .engaged.btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .engaged.btn-default.btn, .open .btn-ctrl, .open .il-viewcontrol-section > .btn-default, .open .il-viewcontrol-section > .btn-link, .open .il-viewcontrol-section .btn-group > .btn-default, .il-viewcontrol-section .open .btn-group > .btn-default, .open .il-viewcontrol-section .btn-group > .btn-link, @@ -3499,7 +3500,9 @@ input.btn, input.il-link.link-bulky, .open .il-viewcontrol-pagination .last > .btn-link, .il-viewcontrol-pagination .open .last > .btn-link, .open .il-viewcontrol-mode > .btn-default, -.open .il-viewcontrol-mode > .btn-link, .open .il-viewcontrol-sortation .btn-default.btn, .il-viewcontrol-sortation .open .btn-default.btn { +.open .il-viewcontrol-mode > .btn-link, .open .il-viewcontrol-sortation .dropdown > .btn-default.btn, .il-viewcontrol-sortation .open .dropdown > .btn-default.btn, +.open .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .open .l-bar__element > .btn-default.btn { border: 1px solid #4c6586; background-color: white; } @@ -3523,7 +3526,9 @@ input.btn, input.il-link.link-bulky, .open .il-viewcontrol-pagination .last > .btn-link, .il-viewcontrol-pagination .open .last > .btn-link, .open .il-viewcontrol-mode > .btn-default, -.open .il-viewcontrol-mode > .btn-link, .open .il-viewcontrol-sortation .btn-default.btn, .il-viewcontrol-sortation .open .btn-default.btn { +.open .il-viewcontrol-mode > .btn-link, .open .il-viewcontrol-sortation .dropdown > .btn-default.btn, .il-viewcontrol-sortation .open .dropdown > .btn-default.btn, +.open .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .open .l-bar__element > .btn-default.btn { box-shadow: none; } @@ -3541,10 +3546,10 @@ input.btn, input.il-link.link-bulky, -webkit-box-shadow: none; box-shadow: none; } -.btn-link, .btn-link:hover, .btn-link:focus, .btn-link:active { +.btn-link, .btn-link:hover, .btn-link:active { border-color: transparent; } -.btn-link:hover, .btn-link:focus { +.btn-link:hover { color: #3a4c65; text-decoration: underline; background-color: transparent; @@ -3554,7 +3559,7 @@ input.btn, input.il-link.link-bulky, color: black; border: 1px solid #b0b0b0; } -.btn-link[disabled]:hover, .btn-link[disabled]:focus, fieldset[disabled] .btn-link:hover, fieldset[disabled] .btn-link:focus { +.btn-link[disabled]:hover, fieldset[disabled] .btn-link:hover { text-decoration: none; } .btn-link.engaged { @@ -3590,28 +3595,13 @@ input.btn, input.il-link.link-bulky, .btn-bulky:focus-visible, .il-link.link-bulky:focus-visible, .il-drilldown .menulevel:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; + outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } .btn-bulky:focus-visible::after, .il-link.link-bulky:focus-visible::after, .il-drilldown .menulevel:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; - outline: 3px solid #0078D7; -} -.btn-bulky:active, .btn-bulky.engaged, -.il-link.link-bulky:active, -.il-link.link-bulky.engaged, -.il-drilldown .menulevel:active, -.il-drilldown .menulevel.engaged { - outline: none; + content: none; } .btn-bulky:active, .il-link.link-bulky:active, @@ -3657,6 +3647,18 @@ input.btn, input.il-link.link-bulky, .il-drilldown .menulevel .button-content_grow { flex-grow: 1; } +.btn-bulky:focus-visible, +.il-link.link-bulky:focus-visible, +.il-drilldown .menulevel:focus-visible { + outline: none; + border: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; +} +.btn-bulky:focus-visible::after, +.il-link.link-bulky:focus-visible::after, +.il-drilldown .menulevel:focus-visible::after { + content: none; +} .il-maincontrols-slate .btn-bulky, .il-maincontrols-slate .il-link.link-bulky, @@ -3944,10 +3946,6 @@ button .minimize, button .close { margin-left: auto; margin-right: auto; } -.il-card .il-card-repository-head > div.il-card-repository-dropdown > .dropdown > button:focus-visible { - overflow: visible; - outline-offset: 4px; -} .il-panel-report .il-card { background-color: #f9f9f9; @@ -4753,34 +4751,6 @@ hr.il-divider-with-label { border-radius: 0; } -.form-control, .form-control:focus { - -webkit-box-shadow: none; - box-shadow: none; -} - -.form-control:focus-visible { - -webkit-box-shadow: none; - box-shadow: none; - outline: 3px solid #0078D7; -} - -input[type=file]:focus:focus-visible::after, -input[type=radio]:focus:focus-visible::after, -input[type=checkbox]:focus:focus-visible::after { - content: none; -} - -input.btn.btn-default:focus-visible { - outline: 3px solid #0078D7; - outline-offset: 3px; -} - -.btn-file:focus-within, .btn-file:hover:focus-within { - z-index: 3; - outline: 3px solid #0078D7; - outline-offset: 3px; -} - textarea.form-control { max-width: 100%; } @@ -4799,12 +4769,6 @@ td.form-inline > div.form-group { padding: 4px 0; } -input[type=radio]:focus:focus-visible, -input[type=checkbox]:focus:focus-visible { - outline: 3px solid #0078D7; - outline-offset: 2px; -} - .il-std-item-container:not(:last-child) { border-bottom: 1px solid #dddddd; } @@ -5021,22 +4985,11 @@ input[type=checkbox]:focus:focus-visible { border-color: #3b5620; } .c-launcher .btn-bulky:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; -} -.c-launcher .btn-bulky:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; } -.c-launcher .btn-bulky:active, .c-launcher .btn-bulky.engaged { - outline: none; +.c-launcher .btn-bulky:focus-visible::after { + content: none; } .c-launcher .btn-bulky:active { transform: scale(0.95); @@ -5186,6 +5139,9 @@ div.il-system-infos { display: flex; align-items: center; } +.il-logo a { + display: block; +} .il-pagetitle { font-weight: 600; @@ -5531,25 +5487,6 @@ footer { flex-direction: column; } -.il-link:focus-visible { - position: relative; - outline: 2px solid #FFFFFF; - outline-offset: 4px; -} -.il-link:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; - outline: 3px solid #0078D7; -} -.il-link:active, .il-link.engaged { - outline: none; -} - .il-link.link-bulky { text-decoration: none; } @@ -6128,6 +6065,16 @@ footer { .il-mainbar-tool-trigger-item .il-link.link-bulky { height: 80px; width: 80px; +} + +.il-mainbar-triggers .btn-bulky, +.il-mainbar-triggers .il-link.link-bulky, +.il-mainbar-tools-button .btn-bulky, +.il-mainbar-tools-button .il-link.link-bulky, +.il-mainbar-tool-trigger-item .btn-bulky, +.il-mainbar-tool-trigger-item .il-link.link-bulky, +.il-maincontrols-metabar .btn-bulky, +.il-maincontrols-metabar .il-link.link-bulky { padding: 0; border: 0; border-bottom: 1px solid #dddddd; @@ -6137,12 +6084,36 @@ footer { font-size: 0.625rem; line-height: 0.83125rem; } +.il-mainbar-triggers .btn-bulky:focus-visible, +.il-mainbar-triggers .il-link.link-bulky:focus-visible, +.il-mainbar-tools-button .btn-bulky:focus-visible, +.il-mainbar-tools-button .il-link.link-bulky:focus-visible, +.il-mainbar-tool-trigger-item .btn-bulky:focus-visible, +.il-mainbar-tool-trigger-item .il-link.link-bulky:focus-visible, +.il-maincontrols-metabar .btn-bulky:focus-visible, +.il-maincontrols-metabar .il-link.link-bulky:focus-visible { + outline: none; + border: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; +} +.il-mainbar-triggers .btn-bulky:focus-visible::after, +.il-mainbar-triggers .il-link.link-bulky:focus-visible::after, +.il-mainbar-tools-button .btn-bulky:focus-visible::after, +.il-mainbar-tools-button .il-link.link-bulky:focus-visible::after, +.il-mainbar-tool-trigger-item .btn-bulky:focus-visible::after, +.il-mainbar-tool-trigger-item .il-link.link-bulky:focus-visible::after, +.il-maincontrols-metabar .btn-bulky:focus-visible::after, +.il-maincontrols-metabar .il-link.link-bulky:focus-visible::after { + content: none; +} .il-mainbar-triggers .btn-bulky .bulky-label, .il-mainbar-triggers .il-link.link-bulky .bulky-label, .il-mainbar-tools-button .btn-bulky .bulky-label, .il-mainbar-tools-button .il-link.link-bulky .bulky-label, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label, -.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label { +.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label, +.il-maincontrols-metabar .btn-bulky .bulky-label, +.il-maincontrols-metabar .il-link.link-bulky .bulky-label { /* edge, chrome, safari go here... */ /* may come with next firefox 68, https://caniuse.com/#search=clamp */ word-break: break-word; @@ -6156,7 +6127,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label, .il-mainbar-tools-button .il-link.link-bulky .bulky-label, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label, -.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label { +.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label, +.il-maincontrols-metabar .btn-bulky .bulky-label, +.il-maincontrols-metabar .il-link.link-bulky .bulky-label { position: relative; max-height: 3em; overflow: hidden; @@ -6167,7 +6140,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label:after, .il-mainbar-tools-button .il-link.link-bulky .bulky-label:after, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label:after, -.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after { +.il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after, +.il-maincontrols-metabar .btn-bulky .bulky-label:after, +.il-maincontrols-metabar .il-link.link-bulky .bulky-label:after { content: ""; text-align: right; position: absolute; @@ -6183,7 +6158,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label, .il-mainbar-tools-button .il-link.link-bulky .bulky-label, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label, - .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label { + .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label, + .il-maincontrols-metabar .btn-bulky .bulky-label, + .il-maincontrols-metabar .il-link.link-bulky .bulky-label { overflow: hidden; text-overflow: ellipsis; display: -webkit-box; @@ -6195,7 +6172,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label:after, .il-mainbar-tools-button .il-link.link-bulky .bulky-label:after, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label:after, - .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after { + .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after, + .il-maincontrols-metabar .btn-bulky .bulky-label:after, + .il-maincontrols-metabar .il-link.link-bulky .bulky-label:after { display: none; } } @@ -6205,7 +6184,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label, .il-mainbar-tools-button .il-link.link-bulky .bulky-label, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label, - .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label { + .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label, + .il-maincontrols-metabar .btn-bulky .bulky-label, + .il-maincontrols-metabar .il-link.link-bulky .bulky-label { overflow: hidden; text-overflow: ellipsis; display: -moz-box; @@ -6217,7 +6198,9 @@ footer { .il-mainbar-tools-button .btn-bulky .bulky-label:after, .il-mainbar-tools-button .il-link.link-bulky .bulky-label:after, .il-mainbar-tool-trigger-item .btn-bulky .bulky-label:after, - .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after { + .il-mainbar-tool-trigger-item .il-link.link-bulky .bulky-label:after, + .il-maincontrols-metabar .btn-bulky .bulky-label:after, + .il-maincontrols-metabar .il-link.link-bulky .bulky-label:after { display: none; } } @@ -9102,22 +9085,12 @@ div.alert ul > li:before { } } .il-table-presentation-viewcontrols { - background-color: #e2e8ef; - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} -.il-table-presentation-viewcontrols > div { - padding: 6px; -} -.il-table-presentation-viewcontrols .il-viewcontrol-pagination { - order: 1; -} -.il-table-presentation-viewcontrols .il-viewcontrol-mode { - order: 2; + margin-bottom: 6px; } -.il-table-presentation-viewcontrols .il-viewcontrol-sortatio { - order: 3; +@media print { + .il-table-presentation-viewcontrols { + display: none !important; + } } .il-table-presentation-row { @@ -9171,6 +9144,10 @@ div.alert ul > li:before { .il-table-presentation-row .il-table-presentation-row-header .il-table-presentation-row-header-fields { display: block; /*initially visible*/ } +.il-table-presentation-row .il-table-presentation-row-header-fields-label::after, +.il-table-presentation-row .il-table-presentation-desclist .il-listing-characteristic-value-label::after { + content: ":"; +} .il-table-presentation-row .il-table-presentation-row-expanded { --bs-gutter-x: 30px; --bs-gutter-y: 0; @@ -9553,7 +9530,8 @@ td.c-table-data__cell--highlighted { border-radius: 10px; } -.il-viewcontrol-section > .btn-default, .il-viewcontrol-section > .btn-link, .il-viewcontrol-section > .btn-ctrl, .il-viewcontrol-sortation .il-viewcontrol-section > .btn-default.btn, .il-viewcontrol-section > .btn-default, .il-viewcontrol-section > .btn-link, +.il-viewcontrol-section > .btn-default, .il-viewcontrol-section > .btn-link, .il-viewcontrol-section > .btn-ctrl, .il-viewcontrol-sortation .dropdown.il-viewcontrol-section > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-section > .btn-default.btn, .il-viewcontrol-section > .btn-default, .il-viewcontrol-section > .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-default, .il-viewcontrol-section .btn-group.il-viewcontrol-section > .btn-link, .il-viewcontrol-pagination__sectioncontrol.il-viewcontrol-section > .btn-default, @@ -9571,8 +9549,10 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-section .btn-group > .btn-default, .il-viewcontrol-section .btn-group > .btn-link, .il-viewcontrol-section .btn-group > .btn-ctrl, -.il-viewcontrol-section .il-viewcontrol-sortation .btn-group > .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-section .btn-group > .btn-default.btn, +.il-viewcontrol-section .il-viewcontrol-sortation .dropdown.btn-group > .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-section .dropdown.btn-group > .btn-default.btn, +.il-viewcontrol-section .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.btn-group > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-section .l-bar__element.btn-group > .btn-default.btn, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-default, .il-viewcontrol-section .il-viewcontrol-section.btn-group > .btn-link, .il-viewcontrol-section .btn-group > .btn-default, @@ -9596,7 +9576,8 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-pagination__sectioncontrol > .btn-default, .il-viewcontrol-pagination__sectioncontrol > .btn-link, .il-viewcontrol-pagination__sectioncontrol > .btn-ctrl, -.il-viewcontrol-sortation .il-viewcontrol-pagination__sectioncontrol > .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__sectioncontrol > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__sectioncontrol > .btn-default.btn, .il-viewcontrol-section.il-viewcontrol-pagination__sectioncontrol > .btn-default, .il-viewcontrol-section.il-viewcontrol-pagination__sectioncontrol > .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-pagination__sectioncontrol > .btn-default, @@ -9616,7 +9597,8 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-pagination__num-of-items > .btn-default, .il-viewcontrol-pagination__num-of-items > .btn-link, .il-viewcontrol-pagination__num-of-items > .btn-ctrl, -.il-viewcontrol-sortation .il-viewcontrol-pagination__num-of-items > .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination__num-of-items > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination__num-of-items > .btn-default.btn, .il-viewcontrol-section.il-viewcontrol-pagination__num-of-items > .btn-default, .il-viewcontrol-section.il-viewcontrol-pagination__num-of-items > .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-pagination__num-of-items > .btn-default, @@ -9636,7 +9618,8 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-pagination > .btn-default, .il-viewcontrol-pagination > .btn-link, .il-viewcontrol-pagination > .btn-ctrl, -.il-viewcontrol-sortation .il-viewcontrol-pagination > .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-pagination > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-pagination > .btn-default.btn, .il-viewcontrol-section.il-viewcontrol-pagination > .btn-default, .il-viewcontrol-section.il-viewcontrol-pagination > .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-pagination > .btn-default, @@ -9658,6 +9641,8 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-pagination .dropdown > .btn-ctrl, .il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown > .btn-default.btn, .il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown > .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.dropdown > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.dropdown > .btn-default.btn, .il-viewcontrol-pagination .il-viewcontrol-section.dropdown > .btn-default, .il-viewcontrol-pagination .il-viewcontrol-section.dropdown > .btn-link, .il-viewcontrol-pagination .il-viewcontrol-section .btn-group.dropdown > .btn-default, @@ -9679,8 +9664,10 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-pagination .last > .btn-default, .il-viewcontrol-pagination .last > .btn-link, .il-viewcontrol-pagination .last > .btn-ctrl, -.il-viewcontrol-pagination .il-viewcontrol-sortation .last > .btn-default.btn, -.il-viewcontrol-sortation .il-viewcontrol-pagination .last > .btn-default.btn, +.il-viewcontrol-pagination .il-viewcontrol-sortation .dropdown.last > .btn-default.btn, +.il-viewcontrol-sortation .il-viewcontrol-pagination .dropdown.last > .btn-default.btn, +.il-viewcontrol-pagination .il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.last > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .il-viewcontrol-pagination .l-bar__element.last > .btn-default.btn, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-default, .il-viewcontrol-pagination .il-viewcontrol-section.last > .btn-link, .il-viewcontrol-pagination .il-viewcontrol-section .btn-group.last > .btn-default, @@ -9702,7 +9689,8 @@ td.c-table-data__cell--highlighted { .il-viewcontrol-mode > .btn-default, .il-viewcontrol-mode > .btn-link, .il-viewcontrol-mode > .btn-ctrl, -.il-viewcontrol-sortation .il-viewcontrol-mode > .btn-default.btn, +.il-viewcontrol-sortation .dropdown.il-viewcontrol-mode > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element.il-viewcontrol-mode > .btn-default.btn, .il-viewcontrol-section.il-viewcontrol-mode > .btn-default, .il-viewcontrol-section.il-viewcontrol-mode > .btn-link, .il-viewcontrol-section .btn-group.il-viewcontrol-mode > .btn-default, @@ -9724,7 +9712,8 @@ td.c-table-data__cell--highlighted { border-radius: 10px; } -.il-viewcontrol-sortation .btn-default.btn { +.il-viewcontrol-sortation .dropdown > .btn-default.btn, +.il-table-presentation-viewcontrols .l-bar__container .l-bar__group .l-bar__element > .btn-default.btn { border-radius: 10px; } @@ -10233,62 +10222,6 @@ a.light:hover { box-shadow: 2px 2px 4px #c0c0c0; } -/* ----------------- permanent link ------------- */ -#current_perma_link { - color: #161616; - font-size: 0.75rem; -} -#current_perma_link:focus-visible { - outline: 3px solid #FFFFFF; - outline-offset: 2px; -} - -a.permalink_label > span.glyphicon { - display: none; -} - -.ilPermalinkContainer { - width: 100%; -} - -div.ilPermanentLinkWrapper { - clear: both; - margin-top: 10px; - display: inline-block; - width: 100%; -} -@media only screen and (max-width: 768px) { - div.ilPermanentLinkWrapper a.permalink_label > span.glyphicon { - display: inline; - } -} -div.ilPermanentLinkWrapper .ilPermalinkContainer { - table-layout: fixed; - line-height: 22px; -} -@media only screen and (max-width: 768px) { - div.ilPermanentLinkWrapper .ilPermalinkContainer { - padding-right: 0; - } -} -div.ilPermanentLinkWrapper .ilPermalinkContainer > label { - width: 150px; - display: table-cell; - vertical-align: middle; -} -@media only screen and (max-width: 768px) { - div.ilPermanentLinkWrapper .ilPermalinkContainer > label { - padding-right: 0; - width: 24px; - } -} -div.ilPermanentLinkWrapper .ilPermalinkContainer > input, div.ilPermanentLinkWrapper .ilPermalinkContainer .btn-group { - z-index: 0; /* see bug #24567 */ -} -div.ilPermanentLinkWrapper .ilPermalinkContainer .input-group-btn { - width: 28px; -} - /* right panel (e.g. notes, comments) */ div.ilRightPanel { overflow: auto; @@ -13319,6 +13252,27 @@ div.ilc_Page.readonly textarea[disabled] { scroll-margin-top: 30px; } +.il-table-presentation-desclist.inline .il-listing-characteristic-value-row { + display: flex; + width: auto; + padding-right: 18px; +} + +.il-table-presentation-desclist.inline .il-listing-characteristic-value { + display: flex; +} +.il-table-presentation-desclist.inline .il-listing-characteristic-value .il-listing-characteristic-value-item { + padding-left: 6px; +} + +.il-listing-characteristic-value-label, .il-listing-characteristic-value-item { + width: fit-content; +} + +.il-listing-characteristic-value-row.clearfix { + border-top: none; +} + /* Modules/Wiki */ a.ilWikiPageMissing:link, a.ilWikiPageMissing:visited { color: #d00; @@ -13481,6 +13435,10 @@ div.ilc_va_icont_VAccordICont { border-bottom: 1px solid #dddddd; background-color: white; } +.ilAwarenessItem > div[role=button]:focus-visible:focus { + outline: none; + outline-offset: 0px; +} .ilAwarenessItem > div[role=button]:focus-visible:focus-visible { position: relative; outline: 2px solid #FFFFFF; @@ -13496,9 +13454,6 @@ div.ilc_va_icont_VAccordICont { border: 2px solid #FFFFFF; outline: 3px solid #0078D7; } -.ilAwarenessItem > div[role=button]:focus-visible:active, .ilAwarenessItem > div[role=button]:focus-visible.engaged { - outline: none; -} .ilAwarenessItem ul { margin: 0; padding: 0; @@ -15310,6 +15265,10 @@ p#copg-auto-save { position: static; } +.ilPageVideo button:focus, .ilPageAudio button:focus { + outline: none; + outline-offset: 0px; +} .ilPageVideo button:focus-visible, .ilPageAudio button:focus-visible { position: relative; outline: 2px solid #FFFFFF; @@ -15325,9 +15284,6 @@ p#copg-auto-save { border: 2px solid #FFFFFF; outline: 3px solid #0078D7; } -.ilPageVideo button:active, .ilPageVideo button.engaged, .ilPageAudio button:active, .ilPageAudio button.engaged { - outline: none; -} /* Services/FileUpload */ .ilFileUploadEntryProgressPercent { @@ -15392,29 +15348,16 @@ select[size] { height: auto; } -input[type=file]:focus, -input[type=radio]:focus, -input[type=checkbox]:focus { - outline: none; - outline-offset: 0px; -} -input[type=file]:focus:focus-visible, -input[type=radio]:focus:focus-visible, -input[type=checkbox]:focus:focus-visible { - outline: 2px solid #FFFFFF; - outline-offset: 5px; -} -input[type=file]:focus:focus-visible::after, -input[type=radio]:focus:focus-visible::after, -input[type=checkbox]:focus:focus-visible::after { - content: " "; - position: absolute; - top: -2px; - left: -2px; - right: -2px; - bottom: -2px; - border: 2px solid #FFFFFF; +input[type=file]:focus-visible, +input[type=radio]:focus-visible, +input[type=checkbox]:focus-visible { outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; +} +input[type=file]:focus-visible::after, +input[type=radio]:focus-visible::after, +input[type=checkbox]:focus-visible::after { + content: none; } .form-control { @@ -15435,11 +15378,12 @@ input[type=checkbox]:focus:focus-visible::after { -o-transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s; } -.form-control:focus { - border-color: #8198b7; - outline: 0; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(129, 152, 183, 0.6); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(129, 152, 183, 0.6); +.form-control:focus-visible { + outline: 3px solid #0078D7; + box-shadow: inset 0px 0px 0px 2px #FFFFFF, 0px 0px 0px 2px #FFFFFF; +} +.form-control:focus-visible::after { + content: none; } .form-control::-moz-placeholder { color: #6f6f6f; @@ -18238,6 +18182,10 @@ a.ilMediaLightboxClose:hover { border: 0 none; background-color: #f9f9f9; } +.ilToolbar .navbar-toggle:focus { + outline: none; + outline-offset: 0px; +} .ilToolbar .navbar-toggle:focus-visible { position: relative; outline: 2px solid #FFFFFF; @@ -18253,9 +18201,6 @@ a.ilMediaLightboxClose:hover { border: 2px solid #FFFFFF; outline: 3px solid #0078D7; } -.ilToolbar .navbar-toggle:active, .ilToolbar .navbar-toggle.engaged { - outline: none; -} .ilToolbar .ilToolbarItems { padding: 0; } @@ -18761,7 +18706,25 @@ img.ilUserXXSmall { .webdav-view-control { text-align: center; - padding: 5px; +} +.webdav-view-control:focus { + outline: none; + outline-offset: 0px; +} +.webdav-view-control:focus-visible { + position: relative; + outline: 2px solid #FFFFFF; + outline-offset: 4px; +} +.webdav-view-control:focus-visible::after { + content: " "; + position: absolute; + top: -2px; + left: -2px; + right: -2px; + bottom: -2px; + border: 2px solid #FFFFFF; + outline: 3px solid #0078D7; } /* diff --git a/templates/default/delos.css.map b/templates/default/delos.css.map index 3a211c9ecd2b..a5fa3ad91a33 100644 --- a/templates/default/delos.css.map +++ b/templates/default/delos.css.map @@ -1 +1 @@ -{"version":3,"sourceRoot":"","sources":["020-dependencies/modifications/datetimepicker/bootstrap-datetimepicker.scss","030-tools/_tool_browser-prefixes.scss","010-settings/_settings_typography.scss","030-tools/_tool_screen-reader-only.scss","010-settings/_settings_borders.scss","010-settings/_settings_color-palette.scss","010-settings/_settings_button.scss","010-settings/legacy-settings/_legacy-settings_menu.scss","070-components/UI-framework/Dropdown/_ui-component_dropdown.scss","030-tools/legacy-bootstrap-mixins/_nav-divider.scss","050-layout/basics/_layout_spacing-variables.scss","020-dependencies/modifications/_jquery-autocomplete.scss","020-dependencies/modifications/_additions_tinymce.scss","020-dependencies/modifications/_additions_yui2.scss","020-dependencies/_index.scss","040-normalize/_normalize_print.scss","040-normalize/_normalize_typography.scss","040-normalize/_normalize_input.scss","040-normalize/_normalize_structure.scss","040-normalize/_normalize_table.scss","040-normalize/_index.scss","050-layout/_layout_grid.scss","050-layout/_layout_container.scss","050-layout/_layout_visibility-utilities.scss","050-layout/_layout_element-bar.scss","060-elements/_elements_html-body.scss","060-elements/_elements_input.scss","010-settings/legacy-settings/_legacy-settings_form.scss","060-elements/_elements_lists.scss","060-elements/_elements_media.scss","060-elements/_elements_objects.scss","060-elements/_elements_tables.scss","060-elements/_elements_typography.scss","030-tools/_tool_focus-outline.scss","060-elements/_index.scss","070-components/UI-framework/_ui-component_tooltip.scss","030-tools/_tool_typography-mixins.scss","070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss","050-layout/standardpage/_layout_standardpage.scss","070-components/UI-framework/Button/_ui-component_button.scss","030-tools/_tool_buttons.scss","070-components/UI-framework/Button/_ui-component_tag.scss","070-components/UI-framework/Button/_ui-component_toggle.scss","070-components/UI-framework/Card/_ui-component_card.scss","010-settings/legacy-settings/_legacy-settings_panel.scss","070-components/UI-framework/Chart/_ui-component_chart.scss","010-settings/legacy-settings/_legacy-settings_chart.scss","070-components/UI-framework/Counter/_ui-component_counter.scss","070-components/UI-framework/Deck/_ui-component_deck.scss","070-components/UI-framework/Divider/_ui-component_divider.scss","070-components/UI-framework/Dropzone/_ui-component_dropzone.scss","010-settings/legacy-settings/_legacy-settings_dropzone.scss","070-components/UI-framework/Entity/_ui-component_entity.scss","070-components/UI-framework/Input/_ui-component_tag.scss","070-components/UI-framework/Input/_ui-component_password.scss","070-components/UI-framework/Input/_ui-component_radio.scss","070-components/UI-framework/Input/_ui-component_multiselect.scss","070-components/UI-framework/Input/_ui-component_textarea.scss","070-components/UI-framework/Input/_ui-component_filter.scss","070-components/UI-framework/Input/_ui-component_duration.scss","070-components/UI-framework/Input/_ui-component_file.scss","010-settings/legacy-settings/_legacy-settings_ui-input-file.scss","070-components/UI-framework/Input/_ui-component_markdown.scss","070-components/UI-framework/Input/_ui-component_input.scss","070-components/UI-framework/Item/_ui-component_item.scss","070-components/UI-framework/Launcher/_ui-component_launcher.scss","010-settings/legacy-settings/_legacy-settings_symbol.scss","070-components/UI-framework/Layout/_ui-component_standardpage.scss","010-settings/_settings_header.scss","010-settings/_settings_footer.scss","050-layout/standardpage/_layout_standardpage-mobile.scss","070-components/UI-framework/Layout/_ui-component_alignment.scss","070-components/UI-framework/Link/_ui-component_link.scss","070-components/UI-framework/Listing/_ui-component_properties.scss","030-tools/_tool_clearfix.scss","070-components/UI-framework/Listing/_ui-component_characteristic_value.scss","050-layout/basics/_layout_positioning.scss","070-components/UI-framework/Listing/_ui-component_workflow.scss","070-components/UI-framework/Listing/_ui-component_entitylisting.scss","070-components/UI-framework/MainControls/Slate/_ui-component_slate.scss","070-components/UI-framework/MainControls/_ui-component_metabar.scss","030-tools/_tool_multi-line-cap.scss","070-components/legacy/_component_screen-reader-only.scss","070-components/UI-framework/MainControls/_ui-component_mainbar.scss","070-components/UI-framework/MainControls/_ui-component_footer.scss","070-components/UI-framework/MainControls/_ui-component_mode_info.scss","070-components/UI-framework/MainControls/_ui-component_system_info.scss","070-components/UI-framework/Menu/_ui-component_drilldown.scss","070-components/UI-framework/MessageBox/_ui-component_messagebox.scss","070-components/UI-framework/Modal/_ui-component_modal.scss","070-components/UI-framework/Panel/_ui-component_panel.scss","030-tools/_tool_border-radius.scss","070-components/UI-framework/Player/_ui-component_player.scss","020-dependencies/modifications/webui-popover/jquery.webui-popover.scss","070-components/UI-framework/Popover/_ui-component_popover.scss","070-components/UI-framework/Symbol/_ui-component_icon.scss","070-components/UI-framework/Symbol/_ui-component_glyph.scss","070-components/UI-framework/Symbol/_ui-component_avatar.scss","070-components/UI-framework/Table/_ui-component_table.scss","070-components/UI-framework/Toast/_ui-component_toast.scss","070-components/UI-framework/Tree/_ui-component_tree.scss","010-settings/legacy-settings/_legacy-settings_tree.scss","070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss","070-components/legacy/_component_agreement.scss","070-components/legacy/_component_alert.scss","070-components/legacy/_component_bottom-center-area.scss","070-components/legacy/_component_headline.scss","070-components/legacy/_component_helpsidebar.scss","070-components/legacy/_component_icon.scss","070-components/legacy/_component_LeftNavSpace.scss","070-components/legacy/_component_link.scss","070-components/legacy/_component_map.scss","070-components/legacy/_component_media-object.scss","070-components/legacy/_component_overlay.scss","070-components/legacy/_component_permalinks.scss","070-components/legacy/_component_rightPanel.scss","070-components/legacy/_component_delostable.scss","070-components/legacy/_component_animated-collapse-fade.scss","070-components/legacy/_component_btn-group.scss","070-components/legacy/_component_carousel.scss","050-layout/_layout_responsive-img.scss","070-components/legacy/_component_input-group.scss","070-components/legacy/Modules/_component_bibliographic.scss","070-components/legacy/Modules/_component_blog.scss","070-components/legacy/Modules/_component_bookingmanager.scss","070-components/legacy/Modules/_component_chatroom.scss","070-components/legacy/Modules/_component_course.scss","070-components/legacy/Modules/_component_datacollection.scss","070-components/legacy/Modules/_component_excercise.scss","070-components/legacy/Modules/_component_forum.scss","070-components/legacy/Modules/_component_learningmodule.scss","070-components/legacy/Modules/_component_learningsequence.scss","070-components/legacy/Modules/_component_lticonsumer.scss","070-components/legacy/Modules/_component_mediacast.scss","070-components/legacy/Modules/_component_mediapool.scss","070-components/legacy/Modules/_component_orgunit.scss","070-components/legacy/Modules/_component_poll.scss","070-components/legacy/Modules/_component_portfolio.scss","070-components/legacy/Modules/_component_scormaicc.scss","070-components/legacy/Modules/_component_survey.scss","070-components/legacy/Modules/_component_test_legacy.scss","070-components/legacy/Modules/_component_test.scss","070-components/legacy/Modules/_component_wiki.scss","070-components/legacy/Modules/_component_workspacefolder.scss","070-components/legacy/Services/_component_accesscontrol.scss","070-components/legacy/Services/_component_accordion.scss","070-components/legacy/Services/_component_awareness.scss","070-components/legacy/Services/_component_badge.scss","070-components/legacy/Services/_component_block.scss","070-components/legacy/Services/_component_bookmarks.scss","070-components/legacy/Services/_component_calendar.scss","070-components/legacy/Services/_component_chart.scss","070-components/legacy/Services/_component_container.scss","070-components/legacy/Services/_component_copage.scss","070-components/legacy/Services/_component_fileupload.scss","070-components/legacy/Services/_component_form.scss","070-components/legacy/Services/_component_help.scss","070-components/legacy/Services/_component_infoscreen.scss","070-components/legacy/Services/_component_init.scss","070-components/legacy/Services/_component_learninghistory.scss","070-components/legacy/Services/_component_like.scss","070-components/legacy/Services/_component_mail.scss","070-components/legacy/Services/_component_mediaobjects.scss","070-components/legacy/Services/_component_membership.scss","070-components/legacy/Services/_component_navigation.scss","070-components/legacy/Services/_component_news.scss","070-components/legacy/Services/_component_notes.scss","070-components/legacy/Services/_component_object.scss","070-components/legacy/Services/_component_onscreenchat.scss","070-components/legacy/Services/_component_rating.scss","070-components/legacy/Services/_component_search.scss","070-components/legacy/Services/_component_skill.scss","070-components/legacy/Services/_component_style.scss","070-components/legacy/Services/_component_table.scss","070-components/legacy/Services/_component_tags.scss","070-components/legacy/Services/_component_termsofservice.scss","070-components/legacy/Services/UIComponent/_component_advancedselectionlist.scss","070-components/legacy/Services/UIComponent/_component_checklist.scss","070-components/legacy/Services/UIComponent/_component_explorer2.scss","070-components/legacy/Services/UIComponent/_component_groupedlist.scss","070-components/legacy/Services/UIComponent/_component_lightbox.scss","070-components/legacy/Services/UIComponent/_component_modal.scss","070-components/legacy/Services/UIComponent/_component_progressbar.scss","070-components/legacy/Services/UIComponent/_component_tabs.scss","070-components/legacy/Services/UIComponent/_component_toolbar.scss","010-settings/_settings_layout.scss","070-components/legacy/Services/UIComponent/_component_tooltip.scss","070-components/legacy/Services/_component_user.scss","070-components/legacy/Services/_component_webdav.scss","070-components/_index.scss","080-hacks/_index.scss"],"names":[],"mappings":"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;AgCmBb;EACC,OhCyBkB;;AgCvBnB;EACC,QJvBqB;;AIyBrB;EACC;;AAKH;EACC,SCMsC;EDLtC,OhCfsB;EgCgBtB;EACA;;;AA8BH;AAEA;EACC;EACA,WnC3DqB;;AmC6DrB;EACC;;AAGD;EARD;IASE;IACA;;;;AE3CF;AAAA;ECgFY;EACA;EAQJ;EACA;EACA,QA3BW;EA4BX;EACA;EAGA,atC/HoB;EsCgIpB;EACA,aD3HQ;EC4HR;EACA,atCpGiB;EsCqGjB,iBDlIY;ECsIZ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;;A8BoGtB;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,aAfa;;;ADjEvB;AAAA;AAAA;AAAA;EAEE;;;AAKJ;AAAA;EACE,WZf0B;;AYiB1B;EAHF;AAAA;IAII;;;;AAIJ;ECqFQ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBnCzJQ;EmC0JR,OlClJgB;EkCmJhB,cDpJS;ECqJT;EACA,cnC7JQ;EmC+JJ,epC3JY;;AoC+JhB;EACI,iBD/JQ;ECiKR,kBAtGS;EAuGT,OlC/JY;EkCgKZ,cDjKK;ECkKL;EACA,cA1GS;;AP5CpB;EACC;EACA,SArBuB;EAsBvB;;AAWD;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QAxCuB;EAyCvB,SA1CuB;;AA4BxB;EACC;;AOoJM;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OlC7KY;EkC8KZ,cD/KK;ECgLL;EACA,cA5GU;;AAgHd;AAAA;EAEI,kBlC7JS;EkC8JT,cDxLK;ECyLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;EA8FV;;AAqBJ;EACI,kBDjMQ;ECkMR,cDtJe;ECuJf;EACA,cnC7NI;EmC8NJ,OnC/LI;;;AkCyChB;ECmEQ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBlCxIY;EkCyIZ,OlC3Ie;EkC4If,cDpJS;ECqJT;EACA,clC1IgB;EkC4IZ,epC3JY;;AoC+JhB;EACI,iBD/JQ;ECiKR,kBAtGS;EAuGT,OlCxJW;EkCyJX,cDjKK;ECkKL;EACA,cA1GS;;AP5CpB;EACC;EACA,SArBuB;EAsBvB;;AAWD;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QAxCuB;EAyCvB,SA1CuB;;AA4BxB;EACC;;AOoJM;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OlCtKW;EkCuKX,cD/KK;ECgLL;EACA,cA5GU;;AAgHd;AAAA;EAEI,kBlC7JS;EkC8JT,cDxLK;ECyLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;EA8FV;;AAqBJ;EACI,kBDjMQ;ECkMR,cDpIe;ECqIf;EACA,clC1MY;EkC2MZ,OnC/LI;;;AkC2DhB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECwBY;EACA;EAQJ;EACA;EACA,QA3BW;EA4BX;EACA;EAGA,atC/HoB;EsCgIpB;EACA,aD3HQ;EC4HR;EACA,atCpGiB;EsCqGjB,iBDlIY;ECsIZ,YlC/GmB;EkCmHf,WlCnHe;EkCqHnB,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBnC7HU;EmC8HV,OnC1JQ;EmC2JR,cDpJS;ECqJT;EACA,cnCjIU;EmCmIN,epCtJuB;;AoC6G3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,aAfa;;AA2D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;EACI;EACA;EACA,evDpByB;;;AuDuB7B;EACI;EACA;;AACA;EACI;;;AAIR;EACI,cvDtB0B;EuDuB1B;EACA;;AACA;EACI,QCxCa;EDyCb,OCzCa;;;ACQrB;AAAA;AAAA;AAAA;AAAA;AAOA;EACC,Y9DCY;E8DAZ;EACA;EACG;EACA;EACA;EACH;EACA;EACA;EACA;EACA;EACA;;AAEC;EACC;;AAKF;EACC;;AAEA;EACC;;AAGA;EACC;EACA;EACA,SAzCqC;;AA0CrC;EACC;EACA;EACA;;AAIF;EACC;;;AAOJ;EACC;EACA;EACA;EACA,SAhEgC;EAiEhC,Y7BrBuC;;;A6ByBxC;EACC;EACA;EACA;EACA,kB9DzDY;E8D0DZ;EACA;EACA,SAxEqC;EAyErC,Y7BjCuC;;;A6BqCxC;EACC;EACA;EACA;EACA,SAhFoC;;;AAoFrC;EACI;EACA,Y9D3ES;E8D4ET;EACA;EACA,QCnG6B;EDoG7B;EACA;EACA;EACA;;;AAIJ;EACC;EACA,QC/G8B;EDgH9B;EACA;EACE;;;AAGH;EACC,ajEhFwB;EiEiFxB;EACA,WjExGqB;EiEyGrB;EACA;EACA,O9D1Fe;;;A8D6FhB;EACC;;;AAGD;EACC;EACA;EACA,SA7HsC;;;AAiIvC;EACC;EACA;EACA;EACA;EACA,O7B3HsB;;A6BkIvB;EACC;EACA;EACA,SA/IiC;;;AAmJlC;EACC;EACA;;;AAID;EACC;;;AAGD;EAIC;EACA;EACA;;AALA;EACC;;AAKD;EACI;EACA;;;AAIL;AACA;EACC,kB9D9JY;E8D+JZ;EACA;EACA,QEtLkB;;;AF0LnB;AAAA;AAAA;AAAA;AAAA;AASC;EADD;IAEE;;;;AAGF;EAEE;IACC;;;AAKH;EAEE;IACC;;EAED;AAAA;IAEC;IACA;;;AAKH;EAEC;IACC,Y9D1MW;I8D2MX;IACA;IACA;;EACA;IACC;IACA;IACA,SAhOoC;IAiOpC;;EACA;IACC;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACC;;EAED;IACC;IACA;IACA;IACA;IACA,Y7BzMmB;;E6B2MpB;IACC;IACA;IACA;IACA;;EAIH;IACC;IACA;;EACA;IACC;IACA;IACA;IACA;IACA;;EACA;IACC;IACG;IACH;IACA;IACA;IACA;;EACA;IACC,Y7BpOkB;;E6BuOnB;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,SAzRmC;;EA0RnC;IACC;;EAIF;IAEC;;EAQL;IACC;IACA;IACA;IACA;;EAID;IACC;IACG,QG/TkC;IHgUlC;IACA;IACH,Y7B7QsC;;E6BiRvC;IACC,OGrUkC;;EHyUnC;IACC;;EAID;IACC;;EAGD;IACC;;EAEA;IACC;;EAED;IACC;IACA;;EAGD;IACC;IACA;IACA,O9DjVgB;I8DkVhB,WjEjVmB;IiEkVnB;IACA;IACA;IACA;;EACA;IACI;IACA;IACA,WjEzVe;IiE0Vf,czDxWW;;EyD4WhB;IACC;;EAED;AAAA;AAAA;AAAA;AAAA;AAAA;IAOC,Y9DjWU;I8DkWV,c9DlWU;I8DmWV,O9D3WgB;I8D4WhB;;EAGD;IACC;;EAKF;IACC;IACA;;EAID;IACC;IACA;IACA;IACA,YG/YsC;IHgZtC,YA5YyD;IA6YzD;IACA,SAxYgC;;EA4YjC;IACC;IACG;IACH;IACG;;EAGJ;IACC,QG5Z4B;IH6Z5B,OG5Z2B;;EHga3B;IACC,QGla2B;IHma3B,OGla0B;;EHoa3B;IACC;IACA;IACA;IACA;;EAGD;IACI,QG7awB;;EHwb7B;IACC;IACA;IACA;IACA;;EAQD;IACC;;EACA;IACC;;EAKF;IACC;;EAGD;IACC;IACA;IACA;IACA,gBGtdsC;;EHudtC;IACC;;EAIF;IACC,e7BndwB;;;A6Bud1B;AAAA;AAAA;AAAA;AAAA;AAMA;EACC;IACC;IACA;;EAEA;IACC;IACA;IACA;;EAEA;AAAA;AAAA;AAAA;AAAA;IAKC;;EAGF;AAAA;IAEC;;;AI1fH;EACC;EACA;EACA;EACA,K7DI6B;;A6DD5B;EACC;;AACA;EAFD;IAGE;;;AAMF;EACC;;AAIF;EACC;EACA;;;AtCDD;EACC;EACA,SArBuB;EAsBvB;;AAWD;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QAxCuB;E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;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;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cCxB8B;ED0B9B;EACA;EACA;EACA;EAEA;EACA,WlGxBkB;EkGyBlB,O/FGkB;;A+FDnB;EACC,cCpC8B;EDqC9B;;AAGF;EACC,kB/Ffe;;A+FkBf;EACC,O/F7BqB;E+F+BrB;EACA;EACA;EACA;;AAED;EAEC;EACA;;AAGF;EACC;;;AEpDH;AAAA;AAAA;AAAA;EAIC;EACA;EACA,K5FM0B;;;A4FF3B;AAAA;AAAA;EAGC;EACA,YhGK0B;EgGJ1B,WhGI0B;EgGH1B;EACA,S5FL0B;E4FM1B,kBjGCiB;EiGAjB,elGnBkC;;;AkGmClC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC,YhGhB6B;EgGiB7B,WhGjB6B;EgGkB7B,elGtCi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;EACC;EACA;EACA;EACA;;AAGE;EADD;IAEE;;;AAIH;EACC;EACA;;AACA;EAHD;IAIE;;;AAED;EACC;EACA;EACA;;AACA;EAJD;IAKE;IACA;;;AAGF;EACC;;AAED;EACC;;;ACvDH;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;ACTA;EADD;IAEE;IACA;;;;AAKD;EADD;IAEQ;;;;AAIR;AAEA;EACI;EACA;EACA;;;AAGJ;EACI;;;AAGJ;EACG,O/GOa;E+GNb,kB/GFe;E+GGf;EACA;EACA;;;AAIH;EACG,O/GFa;E+GGb,kB/GXe;E+GYf;EACA;;;AAGH;EACG,O/GTa;E+GUb;EACA;EACA;;;AAIH;EACC;EACA;EACA;AACA;;;AAGD;EACG;EACA;EACA;EACA;EACA;EACA;;;AAGH;EACG;;;AAGH;EACG;EACA,O/GtCa;E+GuCb;;;AAGH;EACG;EACA;EACA,alH1CsB;;;AkH6CzB;EACG;EACA;;;AAGH;EACG;;;AAGH;EACG,kB/GpEU;E+GqEV,O/G3Da;E+G4Db;EACA,alHxDsB;EkHyDtB;EACA;EACA;;;AAGH;EACG;EACA,O/GrEa;E+GsEb;EACA,alHlEsB;EkHmEtB;EACA;;;AAGH;EACG;EACA,O/G9Ea;E+G+Eb;EACA;EACA;EACA;;;AAGH;EACG;EACA,O/GvFa;E+GwFb;EACA;EACA;EACA;;;AAGH;EACG;EACA,O/GhGa;E+GiGb;EACA;EACA,alHhGsB;EkHiGtB;EACA;;;AAGH;EACG;;;AAGH;AACA;AAAA;EAEG,WlHpImB;EkHqInB;EACA;EACA;EACA,alHhHsB;;;AkHmHzB;AAAA;EAEG;;;AAGH;EACG;EACA;;;AAGH;EACG;;;AAGH;EACG;EACA;EACA,alHpIsB;EkHqItB,WlH3JoB;EkH4JpB;;;AAGH;EACG;EACA;EACA;;;AAGH;EACG;EACA;EACA,alHlJsB;EkHmJtB,WlH3KmB;;;AkH8KtB;EACG;EACA;EACA,alHzJsB;EkH0JtB,WlHlLmB;EkHmLnB;;;AAGH;EACG;EACA,alHhKsB;;;AkHmKzB;EACG;EAC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sHoBrB;EACA;EACA,kBtHrCiB;EsHsCjB;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC,OtH1EkB;EsH2ElB;EACA,WzH1EqB;EyH2ErB;EACA;EACA,kBtHlEY;;;AsHqEb;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;IACC;;;ACtHF;AAKA;EACC;;;AAGD;EACC;EACA;EACA;;AACA;EACC,clHTgB;;;AkHkBlB;EAHC;;;AAMD;EANC;;;AASD;EATC;;;AAYD;EAZC;;;AAeD;EAfC;;;AAkBD;EAlBC;;;AAqBD;EArBC;;;AAwBD;EAxBC;;;AA2BD;EA3BC;;;AAsCD;EANC;EACA;EACA;EAlCA;;;AAyCD;EATC;EACA;EACA;EAlCA;;;AA4CD;EAZC;EACA;EACA;EAlCA;;;AA+CD;EAfC;EACA;EACA;EAlCA;;;AAkDD;EAlBC;EACA;EACA;EAlCA;;;AAqDD;EArBC;EACA;EACA;EAlCA;;;AAwDD;EAxBC;EACA;EACA;EAlCA;;;AA2DD;EA3BC;EACA;EACA;EAlCA;;;AA8DD;EA9BC;EACA;EACA;EAlCA;;;AChBD;AAEA;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAKH;EAIC;EACA;EACA;EACA;;AANA;EACC;;;AAQF;EACC;IACC;;;AAIF;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC,OxHzDoB;EwH0DpB,W3HtFoB;E2HuFpB;EACA;EACA;;AAGD;EACC;EACA,OxHlEoB;EwHmEpB;EACA;EACA;;AAGD;EACC,kBxHxFgB;EwHyFhB;EACA,W3HvGoB;;A2H0GrB;EACC,OxHtFc;;AwHyFf;EACC,OxHrFoB;;AwHwFrB;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC,kBxH3GgB;;AwH8GjB;EACC;EACA;E5HzEA,oB4H0EA;E5HzEQ,Y4HyER;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;AAGD;EACC;;AAGD;EACC;;;ACzKF;AAEA;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA,OzHiBe;EyHhBf;EACA;EACA;;;AAED;EACC;EACA,OzHUe;EyHTf;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;;;AAID;EACC,W5HxCqB;;;A4H2CtB;EACC,W5HxCqB;E4HyCrB;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAID;AAEA;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;E7HfE,oB6HgBD;E7HfS,Y6HeT;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,kBzH7EwB;;;AyHgFzB;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AC7GD;AAEA;EACC;EACA;;;AAGD;EACC;EACA,W7HGqB;;;A6HAtB;EACC;EACA;;;AAGD;EACE;;;AAGF;EACC,a7HcwB;E6HbxB;EACA,W7HZqB;E6HalB;EACA;;;AAGJ;EACE;;;AAGF;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;ACjDD;AAEA;EACC,ctHU+B;EsHT/B,etHS+B;;;AsHNhC;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,W9HbqB;;;A8HgBtB;EACC;EACA;EACA;;;AAED;EACC,kB3HTiB;E2HUjB;;;AAGD;EACC;;AACA;EACC;EACA;;AAED;EACC;;AAED;EACC;EACA;;;AAKF;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA,O3H/DwB;E2HgExB;EACA;EACA;EACA;;;ACtFD;AAQA;EACC,a/H0BwB;;;A+HvBzB;EACC,a/HwBwB;;;A+HrBzB;EACC;EACA,a/HmBwB;;;A+HhBzB;EACC;EACA;EACA;EACA,W/HdqB;;;A+HiBtB;EACC,a/HQwB;E+HPxB,W/HnBqB;E+HoBrB;;;AAGD;AACA;EACC;EACA;EACA;EACA,kB5HjBY;;;A4HoBb;EACC;EACA;EACA;;AACA;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;;;;AAKH;EACC;EACA;EACA;EACA;;;AAGD;EACC,YvHnD8B;EuHoD9B,W/HpDqB;;A+HqDrB;EAHD;IAIE,YvH/D0B;IuHgE1B,W/HzDqB;;;;A+H6DvB;EACC,O5HpCqB;;;A4HuCtB;EACC;EACA;EACA;;AACA;EAJD;IAKE,cvHhE4B;IuHiE5B;;;AAGA;EADD;IAEE;IACA;;;;AAKH;EACC;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;;AAIF;EACC,YvHjG8B;;;AuHoG/B;EACC;EACA,evHtG8B;EuHuG9B;;AAEA;EACC,kB5HnGW;E4HoGX;;AAGD;EACC;EACA;;AACA;EACC;;AAED;EACC;;AAGA;EADD;IAEE;;;AAKF;EADD;IAEE;IACA;;;;AAKH;EAEE;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;;AAKH;EACC;EACA;EACA,a/HlJwB;E+HmJxB,O5H/KkB;;;A4HkLnB;EACC;EACA,a/HxJwB;;A+HyJxB;EACC,a/H5JuB;;A+H8JxB;EACC;;;AAIF;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC,YvHrM8B;;;AuHwM/B;EACC;;;AAGD;EACC,O5HnNkB;;;A4HsNnB;EACC,a/H3LwB;;;A+H8LzB;EACC;EACA;EACA;EACA;EACA;EACA;EACA,O5H1Me;E4H2Mf;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;ACjQD;AAEA;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;AACA;EACA,kB7HRiB;E6HSjB;AACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AC7GD;EACI,kB9HmBS;E8HlBT,oBvFFc;EuFGd,YvFHc;;AuFIjB;AAAA;EAEC;EACA;EACA;;;AAKD;EACC;;;AAGF;EACC;EACA,kB9HGiB;;A8HFjB;EACC;;AAED;EACC;;;AAMA;EACC;;;AAKH;EACC,kB9HfiB;;A8HiBjB;EACC;;;AAGF;AAEA;EACC;;;AClDD;AAUA;EACE;EACA;;;AAEF;EACE;EACA,SARmB;EASnB,OAfiB;EAgBjB,QAfkB;;;AAiBpB;ACpBA;EACE;;AACA;EACE;;;AAKF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAIA;EACE;EACA;EACA;;AAGF;EACE;EAIA;;AAHA;EACE;;AAKJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAIJ;EACE;;;ACjEJ;AAEA;EACC;EACA;EACA;EACA;;;AAGD;EACC,kBjIgBiB;EiIfjB;;;AAGD;EACC;;;AChBC;EACD;EACA;EACA;;AAGC;EACD;;AAGC;EACD;EACA;;AAGC;EACD;EACA;;AAGC;EACD;EACA;EACA;;;AAID;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;ACtDF;AAEA;EACC;EACA,WtISqB;EsIRrB,OnIMkB;;;AmIHnB;EACC;EACA,WtIGqB;EsIFrB,OnI8BqB;;;AmI3BtB;EACC;EACA;EACA;EACA,WtILqB;EsIMrB;;;AAGD;EACC;EACA;EACA;EACA,WtIbqB;EsIcrB,OnIcqB;;;AmIXtB;EACC;EACA;;;AAGD;EACC;EACA,WtIxBqB;;;AsI2BtB;EACC;;;AAGD;EACC;EACA,WtIjCqB;;;AsIoCtB;EACC;;;AAGD;EACC,kBnInDe;;;AmIsDhB;EACC;;;AAGD;EACC,WtI7CqB;;;AuIjBtB;AAEA;EACC;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,WvIRqB;AuISrB;;;AAGD;EAEC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EAKC;;AAJA;EACC;EACA;;;AAKF;EACC;;;AAGD;EACC;;;AC7DD;AAEA;EACC,OrI+Be;EqI9Bf,kBrIsBiB;EqIrBjB;EACA;;;AAGD;EACC,kBrIgBiB;EqIfjB,OrIuBe;EqItBf;EACA;EACA;;;AAGD;EACC;EACA,OrIee;EqIdf;EACA;EACA;;;ACrBD;AAEA;EAEC;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGD;IACC;IACA;IACA;IACA;;EAGD;IACC;IACA;IACA;IACA;;EAGD;IACC;;EAGD;IACC;IACA;;EAGD;IAEC;IACA;AACA;AAAA;AAAA;;EAKD;IAEC;IACA;IACA;;EAGD;IAEC;;EAGD;IACC;;EAGD;IACC;IACA;;EAGD;IACC;IACA;IACA;IACA;IACA;;EAGD;IACC;IACA,azIxCuB;IyIyCvB;IACA;IACA;;EAGD;IACC;IACA;;EAGD;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;IACA,azI5EuB;IyI6EvB;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;IACA;IACA,azInGuB;IyIoGvB;IACA;;;AAIF;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA,kBtI/IiB;EsIgJjB;;;AAGD;EACC;EACA;;;AAGD;EACC;;AACA;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAMA;EACC;;;ACnMH;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;EACH;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;AAEA;EAHD;IAIE;;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EAEI;EACA;EACA;;;AAGJ;EACC;EACA;EACA;EAEA,SlIxH+B;;AkIyH/B;EACC,clI1H8B;EkI2H9B,elI3H8B;;;AkI+HhC;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;AAEA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EAEC;EACA;EACA;;;AAGD;EAEC;EACA;EACA;;;AAGD;EAEC;EACA;EACA;;;AAGD;EAC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CA;EACA;EACA,QAxCuB;EAyCvB,SA1CuB;;AA4BxB;EACC;;AiHqCD;EACC;EACA;;AAEA;EACC;EACA;;;AAKH;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC,O7IjDqB;E6IkDrB,WhJ9EqB;EgJ+ErB;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,kB7IhFiB;E6IiFjB;EACA,WhJ/FqB;;;AgJkGtB;EACC,O7I9Ee;;;A6IiFhB;EACC,O7I7EqB;;;A6IgFtB;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;AACC;EACA;EACA;EACA;AACA;AACA;AACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAIA;EACC;EACA;EACA;;;AAIF;EACC;EACA;;;AAGD;EACC,kB7IhKiB;E6IiKjB,O7IvJqB;;;A6I0JtB;EACC;;;AAGD;AACA;EACC;EACA;EACA;;;AAGD;EACC;;;ACjND;AAEA;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;AAEA;EACC;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAIF;EACC;EACA;EACA;;;AAKD;EACC;EACA;EACA;;;ACnDF;AAEA;EACC;EACA;EACA;EACA,elJoByB;EkJnBzB;EACA;EACA;EACA,kB/IeiB;E+IdjB;EACA;EACA,S1IXiB;;;A0IclB;EACC,kB/IQiB;;;A+ILlB;AAAA;AAEC;EACA,alJewB;EkJdxB;EACA;EACA;EACA,O/IZkB;E+IalB;AACA;;;AAGD;EACC,WlJnBsB;;;AkJsBvB;EACC,alJCwB;EkJAxB;EACA;EACA,WlJxBqB;EkJyBrB;;;AAGD;EACC,alJPwB;EkJQxB;EACA;EACA,WlJlCsB;EkJmCtB;;;AAID;AACA;EACC,WlJ3CqB;EkJ4CrB,O/IhBqB;;;A+ImBtB;AACA;EACC,WlJjDqB;EkJkDrB,O/ItBqB;E+IuBrB;EACA,kB/IvCiB;E+IwCjB;;;AAGD;EACC,SlJvDsB;;;AkJ0DvB;EACC,S1IlD0B;E0ImD1B;;;AAGD;EACC,O/ItCqB;;;AgJ3CtB;AAEA;EACC;EACA;;;AAGD;EACC;EACA;;;ACND;AAIA;EACC,OjJ4Be;EiJ3Bf,kBjJmBiB;EiJlBjB;;;AAGD;EACC,OjJsBe;EiJrBf,kBjJemB;EiJdnB;;;AAGD;EACC,kBjJUmB;;;AiJNpB;EACC,kBjJGiB;;;AiJAlB;EACC,kBjJDiB;;;AiJIlB;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;AACA;EACA;EACA;AACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAMD;EACC;EACA,WpJ1EqB;EoJ2ErB;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EAGA;EACA,kBjJ7EiB;EiJ8EjB;EACA,e5I3F6B;;A4I4F7B;EACC;EACA;EAEA;EACA;EACA,OjJ9Ec;EiJ+Ed;;AAJA;EAHD;IAG4C;;;AAM5C;EACC,kBjJ5FW;;AiJ8FZ;EACC,apJhFuB;EoJiFvB;;AAID;EACC,kBjJlHiB;;AiJmHjB;EACC;;AAGF;AAAA;EAEC,OjJlGc;EiJmGd;;AAED;EACO;EACA;;;AAIR;EACC;EACA;;;AAID;EACC;EACA;;;AAED;EACC;EACA;EACA;;;AAID;EACC,Y5IvJ2B;E4IwJ3B,OjJ9He;EiJ+Hf;EACA;EACA;;;AAGD;EACC,OjJrIe;EiJsIf,apJnIwB;EoJoIxB,kBjJ/IiB;;;AiJmJlB;EACC;EACA,kBjJrJiB;EiJsJjB,apJ3IwB;EoJ4IxB;EACA;EACA;EACA;EACA,clJnLsB;;;AkJsLvB;EACC,kBjJ/JiB;EiJgKjB;EACA;EACA;EACA;EACA,clJ5LsB;EkJ6LtB;EACA;;;AAGD;EACC;EACA;EACA,kBjJ1KmB;EiJ2KnB;EACA;;;AAGD;EACC;;;AAED;EACC;EACA;EACA;EACA,oBlJhNsB;;;AkJmNvB;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA,qBlJ5NsB;;;AkJ+NvB;AACC;EACA;EACA;;;AAGD;AAAA;EAEC,kBjJjNY;;;AiJoNb;EACC;EACA,clJ5OsB;EkJ8OtB;EACA;EAEA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA,oBlJpQsB;;;AkJwQvB;EACC;EACA,kBjJpPY;EiJqPZ;EACA;EACA;EACA;EACA,clJ/QsB;EkJgRtB;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA,clJ1RsB;;;AkJ8RvB;EACC;EACA;EACA;EACA;EACA;EACA;EACA,clJrSsB;;;AkJwSvB;EACC;EACA,kBjJlRiB;EiJmRjB;EACA;EACA;EACA;EACA,clJ/SsB;;;AkJkTvB;EACC;EACA,kBjJ5RiB;EiJ6RjB;EACA;EACA;EACA;EACA,clJzTsB;;;AkJ4TvB;EACC;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;;AAIF;EAEC;AACA;EACA;EACA;EACA;EACA;EACA,clJlVsB;EkJmVtB;AACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA,apJlUwB;;;AoJqUzB;EACC;EACA;;;AAID;EAEC;;;AAID;EACC,OjJrVe;EiJsVf,kBjJ9ViB;;;AiJiWlB;EACC;EACA;EACA,apJzVwB;EoJ0VxB,kBjJvWY;;;AiJ6Wb;EACC,apJ7VyB;;;AoJgW1B;EACC;EACA;;;AAGD;EACC;EACA;EACA,kBjJzXY;EiJ0XZ;EACA;EACA;EACA,clJnZsB;EkJoZtB;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA,clJ9ZsB;EkJ+ZtB;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA,clJzasB;EkJ0atB;EACA;EACA;;;AAGD;EACC;EACA,kBjJzZiB;EiJ0ZjB;EACA;EACA,clJpbsB;EkJqbtB;EACA;EACA;;;AAGD;EACC;EACA,kBjJpaiB;EiJqajB;EACA;EACA,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A;EACA;EACA;;;AAGD;EACC;EACA,kBpJhOY;;;AoJmOb;EACC;;;AAED;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;AACA;AACA;EACA;EACA;;AAEA;EACC;EACA;EACA;;AAGD;EAbD;IAcE;IACA;IACA;IACA;;;;AAIF;EACC,YpJzQY;EoJ0QZ;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;AACA;EAHD;IAIE;IACA;IACA;IACA;;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;AAGE;EACC;EACA;EACA;EACA;EACA;;AAED;EACC,OpJrSkB;EoJsSlB;;AAKF;EACC;;AAIF;EACC;;;AAOF;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC,WvJrXqB;EuJsXrB;EACA,kBpJ1WiB;EoJ2WjB;EACA;;;AAGD;EACC;EACA,WvJ5XsB;EuJ6XtB;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC,kBpJnaY;EoJoaZ;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,kBpJvcY;EoJwcZ;EACA;EACA;EACA;;;AAGD;EACC,kBpJ/cY;;;AoJkdb;EACC;EACA,WvJ3dqB;EuJ4drB;;;AAGD;EACC;EACA,kBpJ1dY;EoJ2dZ;EACA;;;AAGD;AAEA;EACC;EACA;;;AAGD;EACC,cpJ5fe;;;AoJ+fhB;EACC,cpJxfkB;;;AoJ2fnB;EACC,cpJlgBoB;;;AoJqgBrB;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA,OpJnfqB;;;AoJsftB;EACC,OpJvfqB;;;AoJ0ftB;EACC;;;AAGD;EACC;;;AAGD;EACC;;AACA;EACC;;AAGA;EACC;EACA;EACA;EACA;EACA,kBpJ1hBe;EoJ2hBf;EACA;;AAIF;EACC;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA,WvJjkBqB;EuJkkBrB;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA,kBpJtkBiB;EoJukBjB;;;AAGD;EACC,kBpJtkBiB;;;AoJykBlB;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;AAAA;EAEC;;;AAID;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;AAAA;EAGC;;;AAGD;EACC;;;AAID;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EAEC;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;;AAIF;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;AAEA;EACC;EACA;;AAGD;EACC;EACA;;AACA;EAHD;IAIE;;;AAIF;EACC;;AAED;EACC,e/IztB2B;;A+I0tB3B;EACC;;AACA;EACC,WvJztBmB;;AuJ4tBrB;EACC;;AAED;EACC;EACA;EACA;EACA;EACA;;AAED;EACC;EACA,kBpJ/tBU;;AoJmuBZ;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAED;EACC;;;AAID;AACA;EACC;;AAEA;EACC;EACA;;AACA;EACC;EACA;;;AAKH;AAAA;AAAA;AAAA;AAAA;AAKA;EACC;;;AAGD;EAEC,kBpJtxBY;;AoJwxBZ;EACC,kBpJvxBgB;;AoJwxBhB;EACC,kBpJzxBe;EoJ0xBf;EACA,OpJnxBa;EoJoxBb;EACA;;AAIF;EACC;;AAGD;EACC;;;AAIF;AAAA;EAEC;EACA,OpJ9xBqB;EoJ+xBrB;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;AACA;EACC;EACA;EACA;;;AAMA;EACC;EACA;;AAED;EACC;;;AxHn1BF;EACC;EACA,SArBuB;EAsBvB;;AAWD;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QAxCuB;EAyCvB,SA1CuB;;AA4BxB;EACC;;;AyHhCF;AAEA;EACC,WxJQsB;;;AwJLvB;EACC,WxJMqB;;;AwJHtB;EACC;;;ACSD;EACC;EACA;EACA;EAIA;;;AAGD;EACC;EACA;EACA;EACA;EACA,azJEwB;;;AyJSzB;E1J8BE,oB0J7BmB;E1J8BhB,iB0J9BgB;E1J+BX,Y0J/BW;EACpB;EACA;;;AAID;AAAA;EAEC;EACA;EACA;;AAMA;AAAA;AAAA;AAAA;EAGC,QA5DgB;;;AAgElB;EACC;;;AAID;EACC;EACA;;;AAID;AAAA;EAEC;;;AAID;AAAA;AAAA;E1H3EI;EACA;;AACA;AAAA;AAAA;EACI,SAXiB;EAYjB;;AAqBP;AAAA;AAAA;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QAxCuB;EAyCvB,SA1CuB;;;A0HiHzB;EACC;EACA;EACA,QhIjFqB;EgIkFrB;EACA,WzJ5GqB;EyJ6GrB,azJhGsB;EyJiGtB,OtJzFe;EsJ0Ff,kBtJpGY;EsJqGZ;EACA;EACA,evJxHuB;EH+DtB,oB0J0DD;E1JzDS,Y0JyDT;E1J2DC,oB0J1DD;E1J2DM,e0J3DN;E1J4DS,Y0J5DT;;AAMC;EACC,chI7FqB;EgI8FrB;E1JnED,oB0JoEC;E1JnEO,Y0JmEP;;A1JlCD;EACE,OIhEkB;EJiElB;;AAEF;EAA0B,OInEN;;AJoEpB;EAAgC,OIpEZ;;AsJ2GrB;EACC;EACA;;AAQD;EAGC,kBtJvIgB;EsJwIhB;;AAGD;EAEC,QAjKgB;;AAqKjB;EACC;;;AAIF;EACI;;;AAWJ;EACC;;;AAaD;EAME;AAAA;AAAA;AAAA;IACC,ahI5KyB;;;AgIuL5B;EACC,ejJlN4B;;;AiJ0N7B;AAAA;EAEC;EACA;EACA;EACA;;AAKC;AAAA;AAAA;EACC,QA1Oe;;AA8OjB;AAAA;EACC,YzJ1NwB;EyJ2NxB;EACA;EACA,azJnNuB;EyJoNvB;;;AAIF;AAAA;AAAA;AAAA;EAIE;EACA;EACA;EACA;EACA;;AACA;EATF;AAAA;AAAA;AAAA;IAUI;;;;AAGJ;AAAA;EAEE;;;AAGF;AAAA;EAEC;;;AAID;AAAA;EAEC;EACA;EACA;EACA;EACA;EACA,ahIvP2B;EgIwP3B,azJxPwB;EyJyPxB;;;AAGD;EACI,ahI7PwB;;;AgIgQ5B;AAAA;EAEC;EACA;;;AAOD;AAAA;EAEC;;AAEA;AAAA;AAAA;AAAA;EAGC,QAhTgB;;;AAwTjB;AAAA;AAAA;EAEC,QA1TgB;;;AAoUhB;AAAA;AAAA;EACC,QArUe;;;AAgVlB;EACC;EACA,OtJtTe;EsJuTf,WzJ5UqB;EyJ8UrB;EACA;EAEA;;AAEA;EACC;;AAGD;EACC;EACA;EAEA,OtJ3VgB;EsJ4VhB,kBtJtSmB;EsJuSnB,ctJtSuB;;;AsJyTxB;EAGC;IACC;IACA;IACA;;EAID;IACC;IACA;IACA;;EAID;IACC;;EAGD;IACC;IACA;;EAEA;AAAA;AAAA;IAGC;;EAKF;IACC;;EAGD;IACC;IACA;;EAKD;AAAA;IAEC;IACA;IACA;IACA;;EAEA;AAAA;IACC;;EAIF;AAAA;IAEC;IACA;;EAID;IACC;;;;AAiBH;EACC,ejJ9b8B;EiJ+b9B,YtJxbY;AsJweZ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AA9CA;EACC;EACA;EACA,kBtJ7bW;;AsJmcZ;AAAA;AAAA;AAAA;EAIC;EACA;EACA;EACG;;AAKJ;AAAA;EAEC;;AAGD;EACC,OtJ3cc;EsJ4cd;;AAGD;EACC,YhIldyB;EgIqdzB;EACA;;AACA;EAND;IAOG;IACA;IACA;;;AAEF;EACE;;;AAkBJ;EACC,ShIvfsC;;AgIyftC;EACC,QhIxf+B;EgIyf/B,YhIvfkC;;AgI0fnC;EACC;;AAGD;EACC;EACA;;AAGD;EACC;;;AAIF;AAAA;EAEC,OtJrgBe;EsJsgBf,kBtJhhBY;;;AsJmhBb;EACC,kBtJhhBmB;EsJihBnB;EACA,ejJniB4B;EiJoiB5B,ajJhiB+B;;AiJkiB/B;EACC,kBtJthBkB;EsJuhBlB;;AAEA;EAJD;IAKE;;;AAIF;EACC;;;AAIF;EACC;EACA;;;AAGD;EACC;;;AAGD;AACA;AAAA;EAEC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC,OtJ7kBkB;AsJ8kBlB;;;AAGD;EACC;;;AAGD;AACA;AAAA;EAEC,OtJjkBe;EsJkkBf,kBtJ5kBY;EsJ6kBZ;;;AAGD;EACC;;AAEA;EACC;;;AAIF;EACC;EACA;;;AAGD;AAAA;EAEC;;;AASD;AAAA;AAAA;EAGC;EACA;;;AAGD;EACC;;;AAKD;AAAA;EAEC;EACA;;;AAGD;AAAA;EAEC;;;AAGD;EACC;;;AAID;EACC;EACA;;;AAGD;AACA;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA,ctJrrBiB;;;AsJwrBlB;EACC;;;AAGD;AACA;EACC;;;AC3sBD;AAEA;EACC,a1JoCwB;;;A0JjCzB;EACC;;;AAGD;EACC;EACA,W1JCqB;;;A0JEtB;AAAA;EAEC;EACA;;;AAGD;AAAA;AAAA;AAAA;EAIC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA,W1JxBqB;E0JyBrB,a1JCwB;E0JAxB;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;AACA;EAHD;IAIE;;;;AAIF;EACC;EACA;;;AC3DD;EACC,QlIyBgC;EkIxBhC,YlI0BmC;;;AkIvBpC;EACC;EACA;;AAEA;EACC;;;ACTF;AAGC;EADD;IAEE;;;;AAIF;EASC,a5JQyB;E4JPzB;EACA;EACA;;AAVA;EACE;;AACD;EACC;;AAQF;EAbD;IAcM;IAEA;;EAEA;IACE;;EACA;IACE;;;;AAOV;EACC;;AACA;EACC;;;AAIF;EACC,QlHzCiB;EkH0CjB,e1JlCkC;E0J6ClC;EACA;;AAVA;EACC;EACA,kBzJzBgB;;AyJ4BjB;EACC;;AAKD;EAfD;IAgBE;;;;AC5DF;EACC;;;AAGD;EACC,kB1JkBY;E0JjBZ;;;ACPD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,W9JbsB;E8JctB;EACA;;;AAGD;EACC;AACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;AACA;EACA,kB3JvBmB;;;A2J0BpB;EACC;EACA;;;ACxDD;AAEA;EACC,a/JkCwB;;;A+J/BzB;EACC,a/JgCwB;;;A+J7BzB;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAIA;EACC;;AAED;EACC;EACA;;;ACnCF;AAEA;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA,WhKFqB;EgKGrB;EACA;EACA;AACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;ACtDD;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;ACnBD;AAEA;EACC;EACA;EACA;EACA;EACA;EACA,WlKGsB;;;AkKAvB;EACC;EACA;EACA;EACA;EACA;EACA,kB/JWmB;;;A+JRpB;EACC;EACA;EACA;EACA;;;ACtBD;AAEA;EACC;;AACA;EACC;;AAED;EACC;;AAED;EACC;;AAED;EACC;EACA;;AAED;EACC;;;AAIF;EACC;IACC;;;AAIF;EACC,kBhKpBkB;EgKqBlB;EACA;EACA,WnKvBsB;EmKwBtB;EACA;EACA;;AACA;EACC;EACA;;;AAIF;AAEA;EACC;EACA;EACA;;AACA;EACC;EACA;EACA;EACA;EACA;EACA,kBjKpD0B;EiKqD1B;EACA;;AACA;EATD;IAUE;;;AAGF;EACC;EACA;EACA;;AACA;EACC;EACA;;AACA;EAHD;IAIE;;;AAED;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;;;AAIH;EArBD;IAsBE;;;AAED;EACC;EACA;;AAED;EACC;;AAED;EACC;EACA;EACA;EACA;EACA,YhKzEe;EgK0Ef,QzH/Fe;;AyHgGf;EAPD;IAQE;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAGF;EACC;EACA;EACA;EACA;EACA;EACA,WnK9GoB;EmK+GpB;EACA;EACA;EACA,kBhK5GsB;EgK6GtB;EACA;EACA;EACA;;AACA;EAfD;IAgBE;IACA;IACA;;;AAED;EACC,WnK7HmB;;AmK+HpB;EACC,WnKpImB;;AmKsIpB;EACC;EACA;;AAGF;EACC;;AACA;EAFD;IAGE;;;AAED;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;IACA;IACA;;;AAGF;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;IACA;IACA;;;AAKJ;EACC;EACA;;AAED;EACC,kBhKhKgB;;;AgKoKlB;AACC;AAAA;AAAA;;;AAKD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;AAEA;EALD;IAME;;;;AAIF;EACC;EACA;;AAEA;EAJD;IAKE;IACA;;;;AAIF;EACC;;AACA;EAFD;IAGE;;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC;EACA;EpK9DC,oBoK+DD;EpK9DM,eoK8DN;EpK7DS,YoK6DT;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AClRD;AAEA;AACI;;;AAEJ;EACI;;;AAEJ;EACC,kBjKaY;EiKZZ;;;AAGD;EACC,kBjKQY;;;AiKLb;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;AACA;EACC;EACA;;;AAIF;EACC,WpKzBqB;EoK0BrB;;;AAGD;EACC,kBjKjBiB;EiKkBjB;EACA;;AAEC;EACC;EACA;;;AAMF;EACC;;;AAIF;EACC;;;AAGD;EACC,WpKhDqB;EoKiDrB,OjKhCe;EiKiCf;;;AAGD;EACC,WpKxDsB;EoKyDtB;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAIA;EACC;;AAED;EACC;;;AAIF;EACC,e5JzF4B;;;A4J6F5B;EACC;EACA;;;AAIF;EACC,Y1H1GiB;;A0H2GjB;EACC;;;AAIF;EACC;;;ACtHD;AAcA;EACC;EACA;;;AAID;EACC,WrKVsB;EqKWtB;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC,enK7BgB;EmK8BhB,kBlKXY;;AkKYT;EACI;;;AAKR;EACI;;AAEI;EACI,kBlKtBC;;AkKyBD;EACI;;AAGA;EACI;;;ACtDpB;EACC;;;AAIA;EACC;EACA;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAKH;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA,kBnKjCW;;AmKmCX;EACC;;AAGD;EACC;EACA;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;AAEA;EACC;EACA,kBnK/Ha;;AmKiIb;EACC,WtK/IgB;;AsKmJlB;EACC;EACA;;AAIA;EACC;EACA;EACA;;AAKD;EACC;EACA;;AAMA;EACC,WtK5KgB;;AsKgLlB;EACC;EACA,OnKpJgB;EmKqJhB,WtKjLgB;;AsKuLpB;EACC;EACA;EACA;;AAEA;EACC,WtK/LmB;EsKgMnB;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;;AAGD;EACC;;AAGD;EACC;EACA;;AAIF;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAKH;EACC;EACA;EACA;EACA;;;AAOH;EACC;;AAED;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;AChSD;AAEA;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACG;EACA;EACA;;;ACdH;EACC;;AACA;EACC,axK+BuB;;;AwK1BxB;EACC;EACA;EACA,WxKGoB;EwKFpB;;AAED;EACC;;;AAIF;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA,OrKDe;EqKEf;EACA;EACA;EACA;EACA;EzK8BC,oByK7BE;EzK8BM,YyK9BN;EACH;;;AAGD;EACC,kBrKpBiB;EqKqBjB;EACA,WxKrCsB;;AwKsCtB;EACC;;AAED;EACC;EACA;;;AAKD;EACC,ahKpD0B;;AgKsD3B;EACC;;AAED;EACC;;;AAIF;EACC;EzKDC,oByKEE;EzKDM,YyKCN;EACH,OrKvCe;;;AqK0ChB;EACC,axKtCwB;;;AwKyCzB;EACC;EACA,WxKvEsB;EwKwEtB,axK9CwB;EwK+CxB;;;AAGD;EACC;;;AAGD;EACC;;AACA;EACC;;;AC9FF;AAEA;EACC,YtKuBiB;EsKtBjB;EACA;EACA;;;AAGD;EACC;EACA;EACA,WzKKqB;EyKJrB;;;AAGD;EACC;EACA;EACA,WzKJsB;EyKKtB,OtKqBqB;EsKpBrB;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,WzKrCsB;EyKsCtB;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC,kBtKrCiB;;;AsKwClB;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;AAEA;EACC;EACA;;;AAKF;EACC,ctKfqB;;;AsKkBtB;EACC,ctKrBqB;;;AsKwBtB;EACC;;AACA;EACC;EACA;;;AAKD;EACC;;AAED;EACC;;AACA;EACC;EACA;;;AAOH;EACC;;;AAGD;EACC,OtKlDqB;;;AsKqDtB;EACC,OtKxDqB;;;AsK2DtB;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;AACA;EACC;EACA;;;AAIF;EACC;;;AC9JD;AAEA;EACC;;;AAGD;AAEA;EACC;EACA;EACA,QlKP0B;EkKQ1B,kBvKWY;EuKVZ;EACA;;;AAGD;AAAA;AAAA;AAAA;EAIC;EACA;EACA;EACA,W1KdsB;E0KetB;EACA,kBvKHY;EuKIZ,a1KWwB;;;A0KRzB;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC,W1K/BqB;E0KgCrB,a1KNwB;E0KOxB;EACA;EACA,OvKde;EuKef;;;AChCD;EACI;;AAMA;EACI;EACA;EACA;;AAKA;AAAA;EACI;EACA;EACA;;;AAKZ;EACI,anKtCc;EmKuCd,gBnKvCc;EmKwCd,OxK3Be;EwK4Bf;;;AAGJ;EACI;;;AAKF;EACD;EACA;EACA;;AAMC;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE,SnK7Dc;EmK8Dd,a3KvCmB;E2KwCnB;EACA;;AAKH;EACE;EACA;;AAOD;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;;AAKH;EACE;;AAIF;EACE,kBxKtEU;;;AwKkFX;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE,SnKvF0B;;;AmKkG7B;EACE,kBxKhGU;;;AwK0GX;EACD;EACA;;AAEA;EAJC;IAKC;IACA;IACA;IACA;IACA;;EAGA;IACD;;EAOC;AAAA;AAAA;AAAA;AAAA;AAAA;IAEE;;;;AAWL;AAEA;EACC,a3KjIwB;E2KkIxB,kBxK7IiB;EwK8IjB;EACA,W3K9JsB;E2K+JtB;;;AAGD;EACC,a3KzIwB;E2K0IxB;EACA,W3KrKsB;E2KsKtB;EAEA,a3KxJyB;;A2K2JxB;EACC;;AAED;EACC;;AAIF;EACC;;AAED;EAEC;;AAED;EAEC;;;AAIF;EACC,OxK1Ke;EwK2Kf,a3KxKwB;E2KyKxB,kBxKpLiB;EwKqLjB;;;AAGD;EACC;EACA;EACA,kBxK3LiB;;;AwK8LlB;EACC,a3KlLwB;E2KmLxB;EACA,W3K9MqB;E2K+MrB,OxK1Le;EwK2Lf;;;AAGD;EACC;EACA;;AACA;EACC;;;AAIF;EACC,a3KlMwB;E2KmMxB,W3K3NsB;E2K4NtB;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,kBxK5NiB;;;AwK+NlB;EACC,kBxKlOY;EwKmOZ;EACA,W3K/OqB;E2KgPrB;;;AAGD;EACC;;;AAGD;EACC,kBxK3OiB;EwK4OjB;EACA,W3K1PqB;;;A2K6PtB;EACC,OxKzOe;;;AwK4OhB;EACC;;;AAGD;EACC;;;AAID;EACC;EACA;;;AAGD;EACC,W3KlRsB;E2KmRtB;EACA;EACA;EACA,a3K5PwB;E2K6PxB;;AACA;EACC;EACA;EACA;;;AAIF;EACC,kBxKjRiB;EwKkRjB;EACA;;;AAGD;EACC;EACA,kBxKxRiB;EwKyRjB;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA,W3KhUsB;E2KiUtB;EACA;EACA;;;AAID;EACC,W3KxUsB;E2KyUtB,a3K7SwB;E2K8SxB;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC,a3K1TwB;;;A2K6TzB;EACC,a3K9TwB;E2K+TxB,kBxK1UiB;EwK2UjB,W3KxVqB;E2KyVrB;;;AAGD;AACA;EACC,kBxK/UmB;EwKgVnB,OxK1Ue;EwK2Uf;;;AAGD;EACC,kBxKzVY;EwK0VZ,OxKhVe;EwKiVf;;;AAGD;EACC;;;AAGD;EACC,kBxK5ViB;EwK6VjB,OxK1Ve;EwK2Vf;;;AAGD;EACC,kBxKrWmB;EwKsWnB,OxKhWe;EwKiWf;EACA;;;AAGD;EACC,kBxKhXY;EwKiXZ,OxKvWe;EwKwWf;EACA;;;AAGD;EACC,kBxKhXiB;EwKiXjB,OxK9We;EwK+Wf;EACA;;;AAMD;EACC;EACA,kBxKlYY;;;AwKqYb;EACC,kBxKtYY;;AwKyYX;EACC,cnKtZ4B;;;AmK2Z/B;EACI;;;AAKF;EACC;;;AAeH;EACC;IACC;IACA;;;AAIF;EACC;IACC;;;ACncF;AAEA;EACC,W5KOqB;E4KNrB;;;AAGA;EACC;;;AAGF;EACC,kBxKyBe;AwKxBf;EACA;EACA;EACA;EACA;EACA;EACA,e1KTkC;;A0KclC;EACC;EACA;;AAED;EACC;EACA;;AAED;EACC;EACA;;AAED;EACC;EACA;;AAGD;EACC;EACA;;AAEA;EACC;;;AAKH;EACC;EACA;EACA;;;AAGD;EACC;;;AC9DC;EACE;;;ACEJ;AAEA;EACC;E/KiEC,oB+KhEE;E/KiEM,Y+KjEN;;;AAGJ;EACC,O3KwBe;E2KvBf,kB3KaY;E2KZZ;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA,a9KMwB;;;A8KHzB;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA,kB3KlCY;E2KmCZ;EACA;EACA;;;AAQA;EACC;AAAA;AAAA;AAAA;IACC;;EAED;AAAA;AAAA;AAAA;IACC;;;AAGF;EAZD;AAAA;AAAA;AAAA;IAaE;IACA;;;;AAKD;EAFD;IAGE;;;AAED;EALD;IAME;;;AAED;EARD;IASE;;;;AAID;EADD;IAEE;IACA,kB3KzEW;;;;A2K6Eb;EACC;EACA;EACA;EACA;EACA;;AACA;EACC;EACA;;AACA;EACC;;AAED;EACC;EACA;EACA;;AACA;EACC;;;AAOH;EACC;;;AC9HF;AAEA;EACC;EACA;EACA;;;AAGD;EACC;EACA,W/KGqB;;;A+KAtB;EACC;EACA;EACA;;;AAGD;EACC;EACA,O5KlBe;;;A4KqBhB;EACC,kB5KMiB;;;A4KHlB;EACC,O5KYqB;E4KXrB,W/KnBsB;E+KoBtB;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;ACzCD;AAEA;EACC;EACA,kB7KoBiB;;;A6KXlB;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA,kB7KNiB;;;A6KSlB;EAC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","file":"delos.css"} \ No newline at end of file +{"version":3,"sourceRoot":"","sources":["020-dependencies/modifications/datetimepicker/bootstrap-datetimepicker.scss","030-tools/_tool_browser-prefixes.scss","010-settings/_settings_typography.scss","030-tools/_tool_screen-reader-only.scss","010-settings/_settings_borders.scss","010-settings/_settings_color-palette.scss","010-settings/_settings_button.scss","010-settings/legacy-settings/_legacy-settings_menu.scss","070-components/UI-framework/Dropdown/_ui-component_dropdown.scss","030-tools/legacy-bootstrap-mixins/_nav-divider.scss","050-layout/basics/_layout_spacing-variables.scss","020-dependencies/modifications/_jquery-autocomplete.scss","020-dependencies/modifications/_additions_tinymce.scss","020-dependencies/modifications/_additions_yui2.scss","020-dependencies/_index.scss","040-normalize/_normalize_print.scss","040-normalize/_normalize_typography.scss","040-normalize/_normalize_input.scss","040-normalize/_normalize_structure.scss","040-normalize/_normalize_table.scss","040-normalize/_index.scss","050-layout/_layout_grid.scss","050-layout/_layout_container.scss","050-layout/_layout_element-bar.scss","050-layout/_layout_visibility-utilities.scss","060-elements/_elements_html-body.scss","060-elements/_elements_input.scss","010-settings/legacy-settings/_legacy-settings_form.scss","060-elements/_elements_lists.scss","060-elements/_elements_media.scss","060-elements/_elements_objects.scss","060-elements/_elements_tables.scss","060-elements/_elements_typography.scss","030-tools/_tool_focus-outline.scss","060-elements/_index.scss","070-components/UI-framework/_ui-component_tooltip.scss","030-tools/_tool_typography-mixins.scss","070-components/UI-framework/Breadcrumbs/_ui-component_breadcrumbs.scss","050-layout/standardpage/_layout_standardpage.scss","070-components/UI-framework/Button/_ui-component_button.scss","030-tools/_tool_buttons.scss","070-components/UI-framework/Button/_ui-component_tag.scss","070-components/UI-framework/Button/_ui-component_toggle.scss","070-components/UI-framework/Card/_ui-component_card.scss","010-settings/legacy-settings/_legacy-settings_panel.scss","070-components/UI-framework/Chart/_ui-component_chart.scss","010-settings/legacy-settings/_legacy-settings_chart.scss","070-components/UI-framework/Counter/_ui-component_counter.scss","070-components/UI-framework/Deck/_ui-component_deck.scss","070-components/UI-framework/Divider/_ui-component_divider.scss","070-components/UI-framework/Dropzone/_ui-component_dropzone.scss","010-settings/legacy-settings/_legacy-settings_dropzone.scss","070-components/UI-framework/Entity/_ui-component_entity.scss","070-components/UI-framework/Input/_ui-component_tag.scss","070-components/UI-framework/Input/_ui-component_password.scss","070-components/UI-framework/Input/_ui-component_radio.scss","070-components/UI-framework/Input/_ui-component_multiselect.scss","070-components/UI-framework/Input/_ui-component_textarea.scss","070-components/UI-framework/Input/_ui-component_filter.scss","070-components/UI-framework/Input/_ui-component_duration.scss","070-components/UI-framework/Input/_ui-component_file.scss","010-settings/legacy-settings/_legacy-settings_ui-input-file.scss","070-components/UI-framework/Input/_ui-component_markdown.scss","070-components/UI-framework/Input/_ui-component_input.scss","070-components/UI-framework/Item/_ui-component_item.scss","070-components/UI-framework/Launcher/_ui-component_launcher.scss","010-settings/legacy-settings/_legacy-settings_symbol.scss","070-components/UI-framework/Layout/_ui-component_standardpage.scss","010-settings/_settings_header.scss","010-settings/_settings_footer.scss","050-layout/standardpage/_layout_standardpage-mobile.scss","070-components/UI-framework/Layout/_ui-component_alignment.scss","070-components/UI-framework/Link/_ui-component_link.scss","070-components/UI-framework/Listing/_ui-component_properties.scss","030-tools/_tool_clearfix.scss","070-components/UI-framework/Listing/_ui-component_characteristic_value.scss","050-layout/basics/_layout_positioning.scss","070-components/UI-framework/Listing/_ui-component_workflow.scss","070-components/UI-framework/Listing/_ui-component_entitylisting.scss","070-components/UI-framework/MainControls/Slate/_ui-component_slate.scss","070-components/UI-framework/MainControls/_ui-component_metabar.scss","030-tools/_tool_multi-line-cap.scss","070-components/legacy/_component_screen-reader-only.scss","070-components/UI-framework/MainControls/_ui-component_mainbar.scss","070-components/UI-framework/MainControls/_ui-component_footer.scss","070-components/UI-framework/MainControls/_ui-component_mode_info.scss","070-components/UI-framework/MainControls/_ui-component_system_info.scss","070-components/UI-framework/Menu/_ui-component_drilldown.scss","070-components/UI-framework/MessageBox/_ui-component_messagebox.scss","070-components/UI-framework/Modal/_ui-component_modal.scss","070-components/UI-framework/Panel/_ui-component_panel.scss","030-tools/_tool_border-radius.scss","070-components/UI-framework/Player/_ui-component_player.scss","020-dependencies/modifications/webui-popover/jquery.webui-popover.scss","070-components/UI-framework/Popover/_ui-component_popover.scss","070-components/UI-framework/Symbol/_ui-component_icon.scss","070-components/UI-framework/Symbol/_ui-component_glyph.scss","070-components/UI-framework/Symbol/_ui-component_avatar.scss","070-components/UI-framework/Table/_ui-component_table.scss","070-components/UI-framework/Toast/_ui-component_toast.scss","070-components/UI-framework/Tree/_ui-component_tree.scss","010-settings/legacy-settings/_legacy-settings_tree.scss","070-components/UI-framework/ViewControl/_ui-component_viewcontrol.scss","070-components/legacy/_component_agreement.scss","070-components/legacy/_component_alert.scss","070-components/legacy/_component_bottom-center-area.scss","070-components/legacy/_component_headline.scss","070-components/legacy/_component_helpsidebar.scss","070-components/legacy/_component_icon.scss","070-components/legacy/_component_LeftNavSpace.scss","070-components/legacy/_component_link.scss","070-components/legacy/_component_map.scss","070-components/legacy/_component_media-object.scss","070-components/legacy/_component_overlay.scss","070-components/legacy/_component_rightPanel.scss","070-components/legacy/_component_delostable.scss","070-components/legacy/_component_animated-collapse-fade.scss","070-components/legacy/_component_btn-group.scss","070-components/legacy/_component_carousel.scss","050-layout/_layout_responsive-img.scss","070-components/legacy/_component_input-group.scss","070-components/legacy/Modules/_component_bibliographic.scss","070-components/legacy/Modules/_component_blog.scss","070-components/legacy/Modules/_component_bookingmanager.scss","070-components/legacy/Modules/_component_chatroom.scss","070-components/legacy/Modules/_component_course.scss","070-components/legacy/Modules/_component_datacollection.scss","070-components/legacy/Modules/_component_excercise.scss","070-components/legacy/Modules/_component_forum.scss","070-components/legacy/Modules/_component_learningmodule.scss","070-components/legacy/Modules/_component_learningsequence.scss","070-components/legacy/Modules/_component_lticonsumer.scss","070-components/legacy/Modules/_component_mediacast.scss","070-components/legacy/Modules/_component_mediapool.scss","070-components/legacy/Modules/_component_orgunit.scss","070-components/legacy/Modules/_component_poll.scss","070-components/legacy/Modules/_component_portfolio.scss","070-components/legacy/Modules/_component_scormaicc.scss","070-components/legacy/Modules/_component_survey.scss","070-components/legacy/Modules/_component_test_legacy.scss","070-components/legacy/Modules/_component_test.scss","070-components/legacy/Modules/_component_wiki.scss","070-components/legacy/Modules/_component_workspacefolder.scss","070-components/legacy/Services/_component_accesscontrol.scss","070-components/legacy/Services/_component_accordion.scss","070-components/legacy/Services/_component_awareness.scss","070-components/legacy/Services/_component_badge.scss","070-components/legacy/Services/_component_block.scss","070-components/legacy/Services/_component_bookmarks.scss","070-components/legacy/Services/_component_calendar.scss","070-components/legacy/Services/_component_chart.scss","070-components/legacy/Services/_component_container.scss","070-components/legacy/Services/_component_copage.scss","070-components/legacy/Services/_component_fileupload.scss","070-components/legacy/Services/_component_form.scss","070-components/legacy/Services/_component_help.scss","070-components/legacy/Services/_component_infoscreen.scss","070-components/legacy/Services/_component_init.scss","070-components/legacy/Services/_component_learninghistory.scss","070-components/legacy/Services/_component_like.scss","070-components/legacy/Services/_component_mail.scss","070-components/legacy/Services/_component_mediaobjects.scss","070-components/legacy/Services/_component_membership.scss","070-components/legacy/Services/_component_navigation.scss","070-components/legacy/Services/_component_news.scss","070-components/legacy/Services/_component_notes.scss","070-components/legacy/Services/_component_object.scss","070-components/legacy/Services/_component_onscreenchat.scss","070-components/legacy/Services/_component_rating.scss","070-components/legacy/Services/_component_search.scss","070-components/legacy/Services/_component_skill.scss","070-components/legacy/Services/_component_style.scss","070-components/legacy/Services/_component_table.scss","070-components/legacy/Services/_component_tags.scss","070-components/legacy/Services/_component_termsofservice.scss","070-components/legacy/Services/UIComponent/_component_advancedselectionlist.scss","070-components/legacy/Services/UIComponent/_component_checklist.scss","070-components/legacy/Services/UIComponent/_component_explorer2.scss","070-components/legacy/Services/UIComponent/_component_groupedlist.scss","070-components/legacy/Services/UIComponent/_component_lightbox.scss","070-components/legacy/Services/UIComponent/_component_modal.scss","070-components/legacy/Services/UIComponent/_component_progressbar.scss","070-components/legacy/Services/UIComponent/_component_tabs.scss","070-components/legacy/Services/UIComponent/_component_toolbar.scss","010-settings/_settings_layout.scss","070-components/legacy/Services/UIComponent/_component_tooltip.scss","070-components/legacy/Services/_component_user.scss","070-components/legacy/Services/_component_webdav.scss","070-components/_index.scss","080-hacks/_index.scss"],"names":[],"mappings":"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a;;AgCmBb;EACC,OhCyBkB;;A4BbrB;EACC,SAjCuB;EAkCvB;;AACA;EACC;;AIXD;EACC,SCYsC;EDXtC,OhCTsB;EgCUtB;EACA;;;AA8BH;AAEA;EACC;EACA,WnCrDqB;;AmCuDrB;EACC;;AAGD;EARD;IASE;IACA;;;;AEpCF;AAAA;EC+EY;EACA;EAQJ;EACA;EACA,QA3BW;EA4BX;EACA;EAGA,atC/HoB;EsCgIpB;EACA,aD1HQ;EC2HR;EACA,atCpGiB;EsCqGjB,iBDjIY;ECqIZ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;;A8BoGtB;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,aAfa;;;ADhEvB;AAAA;AAAA;AAAA;EAEE;;;AAKJ;AAAA;EACE,WZhB0B;;AYkB1B;EAHF;AAAA;IAII;;;;AAIJ;ECoFQ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBnCzJQ;EmC0JR,OlClJgB;EkCmJhB,cDnJS;ECoJT;EACA,cnC7JQ;EmC+JJ,epC3JY;;AoC+JhB;EACI,iBD9JQ;ECgKR,kBAtGS;EAuGT,OlC/JY;EkCgKZ,cDhKK;ECiKL;EACA,cA1GS;;APhCpB;EACC,SAjCuB;EAkCvB;;AACA;EACC;;AO6IK;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OlC7KY;EkC8KZ,cD9KK;EC+KL;EACA,cA5GU;;AAgHd;AAAA;EAEI,kBlC7JS;EkC8JT,cDvLK;ECwLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;EA8FV;;AAqBJ;EACI,kBDhMQ;ECiMR,cDrJe;ECsJf;EACA,cnC7NI;EmC8NJ,OnC/LI;;;AkC0ChB;ECkEQ,YbxGc;Ea4GV,Wb5GU;Ea8Gd,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBlCxIY;EkCyIZ,OlC3Ie;EkC4If,cDnJS;ECoJT;EACA,clC1IgB;EkC4IZ,epC3JY;;AoC+JhB;EACI,iBD9JQ;ECgKR,kBAtGS;EAuGT,OlCxJW;EkCyJX,cDhKK;ECiKL;EACA,cA1GS;;APhCpB;EACC,SAjCuB;EAkCvB;;AACA;EACC;;AO6IK;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OlCtKW;EkCuKX,cD9KK;EC+KL;EACA,cA5GU;;AAgHd;AAAA;EAEI,kBlC7JS;EkC8JT,cDvLK;ECwLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;EA8FV;;AAqBJ;EACI,kBDhMQ;ECiMR,cDnIe;ECoIf;EACA,clC1MY;EkC2MZ,OnC/LI;;;AkC4DhB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ECuBY;EACA;EAQJ;EACA;EACA,QA3BW;EA4BX;EACA;EAGA,atC/HoB;EsCgIpB;EACA,aD1HQ;EC2HR;EACA,atCpGiB;EsCqGjB,iBDjIY;ECqIZ,YlC/GmB;EkCmHf,WlCnHe;EkCqHnB,WtCvIc;EsCyId;EACA,K9BlIsB;E8BuItB,kBnC7HU;EmC8HV,OnC1JQ;EmC2JR,cDnJS;ECoJT;EACA,cnCjIU;EmCmIN,epCtJuB;;AoC6G3B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,aAfa;;AA2DjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,iBD9JQ;ECgKR,kBAtGS;EAuGT,OnCvKI;EmCwKJ,cDhKK;ECiKL;EACA,cnC1KI;;A4BgCf;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC,SAjCuB;EAkCvB;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC;;AO6IK;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OnCrLI;EmCsLJ,cD9KK;EC+KL;EACA,cA5GU;;AAgHd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI,kBA1HY;EA2HZ,cDvLK;ECwLL;EACA,cA3HgB;EA4HhB,OA7Hc;EA8Hd,QA7FU;EA8FV;;AAqBJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACI,kBA1IW;EA2IX,cAlIe;EAmIf;EACA,cnCjMM;EmCkMN,OA7Ia;;ADiBvB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEE;EACA,kBlChFS;;AkCkFX;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACE;;;AAUJ;EACE;EACD;EACA;EACC;EACA;EACA,arCtFuB;EqCuFvB,OlCzHc;;AkC2Hd;EAKE;EtC7DF,oBsC8DE;EtC7DM,YsC6DN;;AAEF;EAGE;;AAEF;EACE,OlC5FkB;EkC6FlB,iBrC/FuB;EqCgGvB;;AAEF;EAEE,kBjC9GiB;EiC+GjB,OjChHoB;EiCiHpB;;AACA;EACE;;AAGJ;EACE,OlCxHY;EkCyHZ,kBlC5Hc;;;AkCyIlB;AAAA;AAAA;EC1BQ,YD/GiB;ECiHb;EAIJ,WtCrIe;EsCuIf;EACA,K9B/IoB;E8BoJpB,kBnChIY;EmCiIZ,OnC3HQ;EmC4HR,cDnJS;ECoJT;EACA,cnCpIY;EmCsIR,epC3JY;;AoC+JhB;AAAA;AAAA;EACI,iBD9JQ;ECgKR,kBnC1IM;EmC2IN,OnCxII;EmCyIJ,cDhKK;ECiKL;EACA,cnC9IM;;A4BIjB;AAAA;AAAA;EACC,SAjCuB;EAkCvB;;AACA;AAAA;AAAA;EACC;;AO6IK;AAAA;AAAA;EAGI,kBAxGU;EAyGV,OnCtJI;EmCuJJ,cD9KK;EC+KL;EACA,cA5GU;;AAgHd;AAAA;AAAA;AAAA;AAAA;AAAA;EAEI,kBlC7JS;EkC8JT,cDvLK;ECwLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;;AAmHd;AAAA;AAAA;EACI,kBnC9LM;EmC+LN,cD5Be;EC6Bf;EACA,cnCpMQ;EmCqMR,ODjCa;;ACiDb;AAAA;AAAA;EACI;EACA;EACA,K9B5OY;E8B6OZ;;AAGJ;AAAA;AAAA;EACI;;APzMf;AAAA;AAAA;EACC;EACA,QA/CuB;EAgDvB;;AACA;AAAA;AAAA;EACC;;;AMoJD;AAAA;AAAA;AAAA;EAEE,eDtKuB;;ACuKvB;AAAA;AAAA;AAAA;EACE;EACA;;;AAIN;EACE;EACA;EACA,eDhLyB;;;ACsL3B;EC7EQ,YD/GiB;ECmHb,WDnHa;ECqHjB,WtCnIc;EsCqId;EACA,K9BlIsB;;;A6B8M9B;ECrFQ,YDyFe;ECrFX,WDqFW;ECnFf,WtCzIe;EsC2If;EACA,K9BlIsB;;;A6BwN9B;EACE;;;AAGF;EACE;;;AAOF;EACC;EACC,kBjCvNmB;EiCwNnB,cjCvNuB;EiC4NxB;EACA;EACA;;AANC;EACE,kBjC1NiB;EiC2NjB,cjC1NqB;;;AiCiOzB;EACE;EACA,arCjOuB;EqCkOvB;EACA,OlCrPuB;;AkCuPvB;EAEE,OlC9Pe;EkC+Pf;;AAGF;EACE;EACA;EACA;EACA;;;AAIJ;EACE;;;AEtRF;EACI;EACA;EACA;EACA;EACA,erCG+B;;AqCD/B;EACI;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;AAGJ;EACI;EACA;;;ACcR;EACE;EACA;EACA,QA3CqB;EA4CrB,cA3CsB;EA4CtB,eA5CsB;EA6CtB,eA3C4B;EA4C1B;;;AAGJ;EACE;EACA,KA5CkC;EA6ClC,MAzC4C;EA0C5C,OA7C0B;EA8C1B,QA9C0B;EA+C1B,eArD4B;EAsD5B,oBA/CgC,uBA+CsB;EACtD,YAhDgC;;;AAoDhC;EACE,YrCtEiB;EqCuEjB;;AACA;EACE;EACA,KApD4B;EAqD5B,MApDiC;EAqDjC,axC1CmB;EwC2CnB,WxCrEgB;EwCsEhB,OrC3DO;;AqC6DT;EACE,MA/DuC;EAgEvC,YrC/DO;EqCgEP;;AAGJ;EACE,YtC1FmB;EsC2FnB;;AACA;EACE;EACA,KArE4B;EAsE5B,MApEkC;EAqElC,axC3DmB;EwC4DnB,WxCtFgB;;AwCwFlB;EACE,YrC9EO;EqC+EP;;AAGJ;EACE,YrCtFqB;EqCuFrB;;AACA;EACE,YrC9Fa;EqC+Fb;;;AAOJ;EACE,QhClHuB;;AgCoHzB;EACE,WxC7GkB;;;AyCYtB;EACC;EACA;EACA;EACA,kBtCLY;EsCMZ,QCzBiB;ED0BjB,eATuB;EAUvB,YC5BiB;ADoDjB;;AAtBA;EACC;EACA;EACA;;AAEA;EACC;;AAIF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAID;EACC;;AAGD;EACC,WzC/CqB;;AyCkDtB;EACC;EACA,WzCtDoB;;AyCwDpB;EACC;;AAGD;EACC;;AAGF;EACC,YtCnEiB;EsCoEjB,QjCvE0B;EiCwE1B;;AAED;EACC;EACA,QjC5E0B;EiC6E1B;;AAGD;EACC;EAGA;EACA;;AAEA;EACC;;AAKA;EACC,azCjEqB;EyCkErB,OtC9DkB;EsC+DlB,ajChGwB;;AiCqG3B;EACC,kBAhG8B;EAiG9B;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC,QAjGqB;;AAoGtB;EACC;EACA;;AAGD;EACC;EACA;;AAEA;EACC;EACA;;AAKF;EACC;EACA;;AAGC;EACC;EACA,QAnIgC;EAoIhC;EACA;;AAEA;EACC;EACA;EACA;;;AAQN;EACC,kBtCxIiB;;;AsC2IlB;EAEE;IACC;IACA;;EAEA;IACC;;;AAMJ;AACA;EACC;IACC,WAlKqB;IAmKrB;IACA;;;AEjLF;AACA;AACA;AACA;EACE;EACA;EACA;EACA;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;;;AAGF;EACE;;;AAGF;EACE,W3CpBqB;E2CqBrB;EACA,OxCCc;EwCAd;EACA,kBC/B0B;EDgC1B;EACA;EACA;;;AAGF;EACE,OCvC2B;EDwC3B,kBxCxCc;;;AwC2ChB;AACA;AACA;AACA;EACE;EACA;;AAEA;EACE,OCdgC;;ADiBlC;EACE;EACA,WClD+B;EDmD/B,WCjD+B;EDkD/B;EACA;;AAEA;EACE;EACA;EACA,WC1D6B;ED2D7B,YCzD6B;;AD2D7B;EACE,QClD0B;EDmD1B;EACA,cC5DiC;ED6DjC;;AAGF;EACE;EACA;;AAGA;EACE,cClEkC;;ADsEpC;EACE,cCrEiC;;ADyErC;EACE,QChE4B;;ADkE9B;EACE,QCrEyB;;ADuE3B;EACE,QCpE4B;;ADsE9B;EACE,QCrEwB;;ADwE1B;EACE;;AAGA;EACE,W3CnGa;E2CoGb,a3CxEe;E2C0Ef,MC9EgC;;ADgFlC;EACE;EACA,MClFgC;;ADoFlC;AAAA;EAEE;EACA,MCrF+B;;ADyFnC;EAEE;;AAEA;EACE,QC1GmC;ED2GnC;;AAEF;EACE,MChH4B;EDiH5B;;AAIJ;EACE;;AAOJ;EACE,WC1GkC;ED2GlC,WCzGkC;;AD2GlC;EACE,WC9GgC;ED+GhC,YC7GgC;;AD+GhC;EACE,QC1G6B;ED2G7B,cC/IoC;;ADkJtC;EACE,cCnJoC;;ADsJtC;EACE,QC/G+B;;ADiHjC;EACE,QChH4B;;ADmH9B;EACE,QCxHiC;EDyHjC;EACA,cC9HwC;ED+HxC;EAEA;;AAEF;EACE;;;AAQV;AACA;AACA;AACA;EACE,anCxL4B;EmCyL5B,gBnCzL4B;;;AmC4L9B;EACE,anC7L4B;EmC8L5B,gBnC9L4B;;;AqCa9B;EACE;EACA,W7CbqB;E6CcrB,aAjBuB;EAkBvB;EACA;EACA;EACA;EACA,O1CNW;E0COX;EACA,e3CpBiC;;A2CqBjC;EACE;;;AAIJ;EACE;;;AAGF;EACE,SArCmB;EAsCnB;EACA,KAzBgC;EA0BhC,kB1CnCiB;;;A0CqCnB;EACE,SA3CmB;EA4CnB;EACA,QArCkC;EAsClC,kB1C/BuB;;;A0CmCvB;EACA,aAjDuB;EAkDvB,W7C/CqB;E6CgDrB,SArDmB;EAsDnB;;;AC1DA;EACE;EACA;EACA,etCS0B;;AsCP1B;EACE,ctCgBqB;EsCfrB,etCeqB;EsCdrB,etCFsB;;AsCMtB;EACE;;AAGF;EACE;;;AAMR;EAEE;EACA;EACA;EACA;EACA;;AAEA;EACE;;;AC1BJ;EACC;EACA;EACA,kB5CaY;E4CZZ;EACA;EACA,a/CiBsB;E+ChBtB,O5CmBe;;;A4ChBhB;EACC;;;AAGD;EACC;EACA,cvCH6B;EuCI7B,evCJ6B;;;AwCb9B;EACC;EACA,eCF2B;EDG3B,Y7CaY;E6CZZ;EACA,exCW0B;EwCV1B;;AACA;EACC;EACA,e9CNgC;E8COhC,kB7CQgB;E6CPhB,axCJ8B;EwCK9B,gBxCL8B;;;AwCShC;EACC;EACA;;;AAGD;EACC;EACA,YC1B0B;;;AD6B3B;EACC;EACA,kBC7BsB;;;ADgCvB;EACC,WhDzBsB;EgD0BtB;EACA,cxCjC6B;;;AwCoC9B;EACC;;;AAID;AAAA;EAEC;;;AEjDG;EACI;EACA,qBACI;EAQJ;EACA,QhDVS;EgDWT,kB/CQK;E+CPL;;AACA;EACI;;AAIR;EACI;EACA,WlDNiB;;AkDSrB;EACI;EACA;EACA;;AACA;EACI;;AAIR;EAYI;;AAXA;EAGI;;AAEJ;EACI;;AAEJ;EACI;;AAKR;EACI;EACA,alDfiB;EkDgBjB,WlDlCkB;;AkDqCtB;EACI;EACA,WlDzCiB;;AkD4CrB;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EACI;;AAGJ;EAGI;;AAGJ;EACI;EACA;EACA;EACA;;;ACnFR;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,anDSsB;;;AmDNvB;EACE;EACA,YnDIqB;;AmDFtB;EACC;EACA;EACA;EACA;EACA,anDHqB;EmDIrB;EACA;;AAGD;EACC;;;AAIF;EACC,kBApC6B;EAqC7B;;AAEA;EACC;;AAED;EACC,kBA3C4B;;;ACL5B;EACE;EACA;EACA;;AAGF;EACE;;AAEF;EACE;;AAIA;EACE;;AAEF;EACE;;;AClBL;EACC;EACA;EACA;;;ACJF;EACC;EACA;;;ACID;EACC,WvDQqB;;;AuDLtB;EACC,QAPoB;;;ACsCpB;EACC;;AAED;EACC,ahDpC0B;EgDqC1B,gBhDrC0B;EgDsC1B;;AAID;EACC;EACA;;AAGD;EACC;EACA;EACA;;AAGD;EACC,OA9CqC;EA+CrC,QA9CsC;EA+CtC;;AAEA;EACC,OAnDoC;EAoDpC,QAnDqC;EAoDrC,QAnDsC;EAoDtC,kBrD9CU;;AqDiDX;EACC,kBrD9CiB;;AqDkDnB;EACC;EACA;EACA;EACA,OA/D+B;;AAkEhC;EACC;EACA;EACA;EACA,OArEsC;;AAuEtC;EACC;;;AAKH;EACC;EACA;EACA,kBrD1EiB;;AqD4EjB;EACC;;AAEA;EACC;EACA,OA3FoC;EA4FpC;EACA,WxD9FoB;;AwDgGpB;EACC,eAxGyC;;AA6G5C;EACC;EACA,cA9G2C;;;AAkH7C;EACC;EACA,QAvGoC;EAwGpC,cAvG0C;EAwG1C,gBAvG4C;;AAyG5C;EACC;EACA;EACA,WxDrHqB;;;AwD0HtB;EACC,WxD3HqB;;;AwDgIvB;EACC,kBrDtHiB;EqDuHjB;;AAEA;EACC;EACA;EACA;EACA;EACA,kBrDhIW;EqDiIX,WxD5IoB;EwD6IpB;EACA;EACA;EACA;;;AAIF;EACC,YAtJ6C;EAuJ7C;EACA,gBAvJiD;EAwJjD,ehD5J6B;EgD6J7B,QAxJyC;EAyJzC,YrD7IiB;;AqD+IjB;EACC,WxD7JoB;;AwDgKrB;EACC,QA/JoD;;;AAmKtD;EACC;EACA;EACA;EACA;;;AAGD;EAEE;IACC;IACA;;EAID;IACC;;EAED;IACC,SArKkD;IAsKlD,YArKqD;IAsKrD,QArKiD;IAsKjD;IACA,kBrD/Ke;;;AqDqLjB;EACC,OrDvKoB;;;AqD2KtB;EACC;EACA,QAnLkD;EAoLlD,SAnLmD;;AAqLnD;EACC;EACA;EACA,OAvLuD;;;ACtCvD;EACE;EACA;;;ACMJ;EACC;EACA;;;AAGD;EACC,W1DEsB;E0DDtB,alDXiB;;;AkDclB;EACC,W1DHsB;E0DItB,OvDNiB;;;AuDSlB;AAAA;EAEC,OtDYoB;EsDXpB;EACA;;;AAGD;EACC;EACA,elDvB2B;EkDwB3B,SlD7BiB;;;AkDgClB;EACC,W1DrBsB;;A0DsBtB;EACC;;AAED;EACC,alDtCgB;EkDuChB;;AAED;EACC,clD1CgB;;AkD4CjB;EACC,clD7CgB;EkD8ChB;;;AAIF;EACC,QClD+B;EDmD/B,kBvD3BmB;EuD4BnB,YlDrDiB;EkDsDjB;EACA;EACA;;AAEA;EACC,kBxD1D0B;EwD2D1B;EACA;EACA;EACA;EACA;EACA;;AACA;EACC,kBvD/DgB;;AuDiEjB;EACC,kBvD9DgB;;;AyDbnB;AAAA;AAAA;AASA;EACE;EACA;EACA;EACA,KpDNyB;EoDOzB,epDPyB;;;AoDa3B;AAAA;EAEE,OzDIW;;;AyDDb;EACE,YLtBmB;EKuBnB,Q1DpBe;E0DqBf;EACA;EACA,cpDnB4B;EoDoB5B,epDpB4B;EoDqB5B;;;AAIF;EACE;;;ACbF;EACE,kB1DCW;E0DAX,YrDhB0B;;AqDmB1B;EACE;;AACA;EACE;EACA,WpCIsB;EoCHtB;;AAEA;EALF;IAMI;;;AAKN;EACE,crDhC0B;EqDiC1B,erDjC0B;EqDmC1B,kB1DpBS;E0DqBT,O1DXY;;A0Dcd;EACE,SpCxBmC;EoC0BnC,kB1D3BS;E0D4BT,O1DlBY;;A0DqBd;EACE;;AAEF;EACE,QpChC6B;EoCiC7B,YpC/BgC;;AoCkClC;EACE,W7D7CqB;E6D8CrB,a7D1BqB;E6D2BrB;EACA,gBrD/CwB;;AqDmD1B;EACE,W7D3DkB;;A6D+DpB;EACE;EACA;;AAEA;EACE;EACA;;AAIJ;EACE,kB1D3DgB;E0D4DhB;;AACA;EACE;;AAIJ;EACE;EACA;;;AAKJ;EACC;EACA,W7DxFsB;E6DyFtB,a7DnEwB;E6DoExB;EACA,O1DxEe;E0DyEf;EACA,kB1DlFiB;E0DmFjB;EACA;;;AAGD;EACE;;;AAGF;EACE;EACA;;;AAKF;EACE,crD9G8B;;;AqDiHhC;EACE;EACA;;;AC7GF;EACC,e5DjBgB;;;A4DoBjB;EACC,kB3DFY;E2DGZ;EACA,StDhB8B;;AsDkB9B;EACC,W9DhBqB;E8DiBrB;;AACA;EACC;EACA,a9DToB;;A8DWpB;EACC;;AAKH;EACC;EACA,SArCwB;EAsCxB,QArCuB;EAsCvB;EACA;EACA,eAvC8B;;AA0C/B;EACC;EACA;;AAGD;EACC,SA/C4B;EAgD5B,W9D9CoB;E8D+CpB;;AAGD;EACC,W9DnDoB;E8DoDpB,O3DxBoB;E2DyBpB;;AACA;EACC;;AAIF;EACC,W9D5DoB;E8D6DpB;;AAGD;EACC,WlBrEiC;EkBsEjC;EACA;;AAIA;EADD;IAEE,atD7EyB;;;AsDiF3B;EACC;;AAGD;EACC;;AAGD;EACC,SAtFsB;;;AA2FxB;EACC,aA1F4B;;;AA6F7B;EACC;EACA,kB3DnFiB;;A2DqFjB;EACC;EACA,O3D/Ec;E2DgFd,W9DjGoB;E8DkGpB,a9D9EuB;E8D+EvB,SpBlHyB;EoBmHzB;;AAGD;EACC;;;AAIF;EACC;;AAEA;EACC;EACA;EACA;;;AAID;EACC,YtDhI0B;;;AsDoI5B;EAEC;;AAEA;EACC,W9DhIoB;E8DiIpB;EACA;;AAGD;EACC;;AAGD;EAEC;;AAGD;EACC;;;AAKF;EACC;EACA,KAtJmB;;AAwJnB;EACC;EACA;EACA,qBACC;EAID;;AAEA;EACC;;AAED;EACC;;AAED;EACC;;AAED;EACC;;AAED;EACC;EACA;EACA;EACA,KAnLgB;;;AAwLnB;EAEC;IACC;;EAEA;IACC;;EAGD;IACC;IACA;;EAGD;IACC;IACA;;EAGD;IACC,YtDvNwB;IsDwNxB;IACA;;EACA;IACC;;EAIF;IACC;;EAED;IACC;;;AAMH;AACA;EACC;;;AAGD;EAEE;IACC,SA9OuB;IA+OvB;IACA;;EAKD;IACC;;EAKD;IACC;;;AChQC;EzBwJI,kBlCxIY;EkCyIZ,OlC3Ie;EkC4If,cDnJS;ECoJT;EACA,clC5IY;EkC8IR,epCtJuB;E6DE3B;EACA;;AzBuJA;EACI,iBD9JQ;ECgKR,kBAtGS;EAuGT,OlCxJW;EkCyJX,cDhKK;ECiKL;EACA,cA1GS;;APhCpB;EACC,SAjCuB;EAkCvB;;AACA;EACC;;AO6IK;EACI,WAlFW;EAoFX,kBAxGU;EAyGV,OlCtKW;EkCuKX,cD9KK;EC+KL;EACA,cA5GU;;AAgHd;AAAA;EAEI,kBlC7JS;EkC8JT,cDvLK;ECwLL;EACA,clC/Ja;EkCgKb,OlClKY;EkCmKZ,QA7FU;EA8FV;;AAqBJ;EACI,kBA1IW;EA2IX,cAlIe;EAmIf;EACA,clC5MQ;EkC6MR,OA7Ia;;AyBpEjB;EACI;;AAEJ;EACI,O5DIC;;A4DFL;EAlBJ;IAmBQ;;;;AAKZ;EACI;EACA;EACA,evDpByB;;;AuDuB7B;EACI;EACA;;AACA;EACI;;;AAIR;EACI,cvDtB0B;EuDuB1B;EACA;;AACA;EACI,QCxCa;EDyCb,OCzCa;;;ACQrB;AAAA;AAAA;AAAA;AAAA;AAOA;EACC,Y9DCY;E8DAZ;EACA;EACG;EACA;EACA;EACH;EACA;EACA;EACA;EACA;EACA;;AAEC;EACC;;AAKF;EACC;;AAEA;EACC;;AAGA;EACC;EACA;EACA,SAzCqC;;AA0CrC;EACC;EACA;EACA;;AAIF;EACC;;;AAOJ;EACC;EACA;EACA;EACA,SAhEgC;EAiEhC,Y7BrBuC;;;A6ByBxC;EACC;EACA;EACA;EACA,kB9DzDY;E8D0DZ;EACA;EACA,SAxEqC;EAyErC,Y7BjCuC;;;A6BqCxC;EACC;EACA;EACA;EACA,SAhFoC;;;AAoFrC;EACI;EACA,Y9D3ES;E8D4ET;EACA;EACA,QCnG6B;EDoG7B;EACA;EACA;EACA;;;AAIJ;EACC;EACA,QC/G8B;EDgH9B;EACA;EACE;;AACF;EACC;;;AAIF;EACC,ajEnFwB;EiEoFxB;EACA,WjE3GqB;EiE4GrB;EACA;EACA,O9D7Fe;;;A8DgGhB;EACC;;;AAGD;EACC;EACA;EACA,SAhIsC;;;AAoIvC;EACC;EACA;EACA;EACA;EACA,O7B9HsB;;A6BqIvB;EACC;EACA;EACA,SAlJiC;;;AAsJlC;EACC;EACA;;;AAID;EACC;;;AAGD;EAIC;EACA;EACA;;AALA;EACC;;AAKD;EACI;EACA;;;AAIL;AACA;EACC,kB9DjKY;E8DkKZ;EACA;EACA,QEzLkB;;;AF6LnB;AAAA;AAAA;AAAA;AAAA;AASC;EADD;IAEE;;;;AAGF;EAEE;IACC;;;AAKH;EAEE;IACC;;EAED;AAAA;IAEC;IACA;;;AAKH;EAEC;IACC,Y9D7MW;I8D8MX;IACA;IACA;;EACA;IACC;IACA;IACA,SAnOoC;IAoOpC;;EACA;IACC;IACA;IACA;IACA;IACA;IACA;IACA;;EAEA;IACC;;EAED;IACC;IACA;IACA;IACA;IACA,Y7B5MmB;;E6B8MpB;IACC;IACA;IACA;IACA;;EAIH;IACC;IACA;;EACA;IACC;IACA;IACA;IACA;IACA;;EACA;IACC;IACG;IACH;IACA;IACA;IACA;;EACA;IACC,Y7BvOkB;;E6B0OnB;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA;IACA,SA5RmC;;EA6RnC;IACC;;EAIF;IAEC;;EAQL;IACC;IACA;IACA;IACA;;EAID;IACC;IACG,QGlUkC;IHmUlC;IACA;IACH,Y7BhRsC;;E6BoRvC;IACC,OGxUkC;;EH4UnC;IACC;;EAID;IACC;;EAGD;IACC;;EAEA;IACC;;EAED;IACC;IACA;;EAGD;IACC;IACA;IACA,O9DpVgB;I8DqVhB,WjEpVmB;IiEqVnB;IACA;IACA;IACA;;EACA;IACI;IACA;IACA,WjE5Ve;IiE6Vf,czD3WW;;EyD+WhB;IACC;;EAED;AAAA;AAAA;AAAA;AAAA;AAAA;IAOC,Y9DpWU;I8DqWV,c9DrWU;I8DsWV,O9D9WgB;I8D+WhB;;EAGD;IACC;;EAKF;IACC;IACA;;EAID;IACC;IACA;IACA;IACA,YGlZsC;IHmZtC,YA/YyD;IAgZzD;IACA,SA3YgC;;EA+YjC;IACC;IACG;IACH;IACG;;EAGJ;IACC,QG/Z4B;IHga5B,OG/Z2B;;EHma3B;IACC,QGra2B;IHsa3B,OGra0B;;EHua3B;IACC;IACA;IACA;IACA;;EAGD;IACI,QGhbwB;;EH2b7B;IACC;IACA;IACA;IACA;;EAQD;IACC;;EACA;IACC;;EAKF;IACC;;EAGD;IACC;IACA;IACA;IACA,gBGzdsC;;EH0dtC;IACC;;EAIF;IACC,e7BtdwB;;;A6B0d1B;AAAA;AAAA;AAAA;AAAA;AAMA;EACC;IACC;IACA;;EAEA;IACC;IACA;IACA;;EAEA;AAAA;AAAA;AAAA;AAAA;IAKC;;EAGF;AAAA;IAEC;;;AI7fH;EACC;EACA;EACA;EACA,K7DI6B;;A6DD5B;EACC;;AACA;EAFD;IAGE;;;AAMF;EACC;;AAIF;EACC;EACA;;;ACvBF;EACC;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC,OnEqBc;;;AoElChB;EACI;;;AAGJ;EACI,Y/DGwB;;;AgETxB;EAEE;EACA;;AAEF;EACE;;;ACEN;AACA;AACqB;EACnB;EACA;;ADZE;EAEE;EACA;;AAEF;EACE;;;ACQN;EACE;;;AAEF;ECjBI;EDmBF;EACA;;AACA;EAJF;IAKC;IACA;;;;AAGD;ECtBI;EDwBF,cjElB4B;EiEmB5B;EACA;;AACA;EALF;IAMC;IACA;;;;AAGD;AACA;EACE;EACA;;;AAEF;EACE,cjEpB4B;EiEqB5B;EACA;;;AAEF;EvClCC;EuCoCC;EACA;;;AEpCF;EACC;;AACA;EACC,oBjCXgB;EiCYhB,YjCZgB;;;AiCkBjB;EACC,kBxEGgB;EwEFhB,OxEUc;EwETd,W3ENuB;E2EOvB,a3EWuB;E2EVvB,enEnB0B;EmEoB1B;EACA;;;AAGF;EACC;EACA;;AAEC;EACC,kBA7B2B;EA8B3B;EACA;EACA,OAhC2B;EAiC3B;EACA;EACA;EACA,QArCqB;EAsCrB;EACA;EACA;EACA;EACA;EACA,OA3CqB;;AA6CtB;EACC;;AAGD;EACC,W3E1CoB;E2E2CpB,a3EvBuB;;A2E6BxB;AAAA;EACC;EACA,OzEhEoB;EyEiEpB,kBxEzCe;EwE0Cf;;AAGA;AAAA;EACC;EACA,OAjE0B;;AAmE3B;AAAA;EACC,OxE5De;EwE6Df;;AAGF;AAAA;EACC,OzE/EoB;;AyEmFrB;EACC;;AAMD;AAAA;EACC,kBzE3FoB;EyE4FpB,OAtF2B;;AA0F5B;EACC;;AAID;EACC;;AAMD;AAAA;AAAA;EACC,kBxE5Ga;;AwEiHd;EACC;EACA;EACA;EACA,W3ErGsB;;A2EuGvB;EAEI;EACH,kBxE1Ha;;AwE6Hb;AAAA;EAEC,OxE/HY;EwEgIZ,W3ElHkB;E2EmHlB,a3E/FqB;;A2EoGxB;EACC;EACA;EACA;EACA;;AACA;EACC;;AAGF;AAAA;EAEC,OxElHc;EwEmHd,W3EpIoB;E2EqIpB,a3EjHuB;E2EkHvB;;;AAIF;EAEC,QjCxJiB;EiCyJjB,ezEjJkC;EyEkJlC,oBjC3JiB;EiC4JjB,YjC5JiB;;AiC8JjB;EACC,kBxEzIgB;EwE0IhB;EACA,SjCnKyB;;AiCqKzB;EACC;EACA;EACA,OxExIa;EwEyIb,W3ExJsB;E2EyJtB,a3E/IqB;E2EgJrB,a3EtIsB;;A2E0IxB;EACC;;;ACpLF;EACI;EACA;;;ACSH;EACC;;AAMA;AAAA;AAAA;EAEE;EACA,WzCewB;;AyCb1B;AAAA;EACE;;AAEF;AAAA;EACE;;AAEF;AAAA;EACC;;AAGF;EACC,kB1ENgB;;A0EUhB;EACC,SrE5B2B;;AqE6B3B;EASC;EACA;EACA;EACA,oB1ExBc;E0EyBd,SrE1C0B;EqE4C1B;EAEA;;AAfC;EACC;EACA;EACA,WzCRqB;EyCSrB;;AAqBF;EACC;EACA;EACA,WzCjCsB;;AyCyCzB;EACC;EACA;EACA;EACA;EACA;;;AAUD;AAAA;EAEC,kB1EnEe;;A0EuEhB;AAAA;EAEC;;AAID;AAAA;EAEC;;;AAMF;EACC;EACA;EACA;;AACA;EACC;;AAGF;EACC;;AAED;EACC;;AAED;EACC,SAxHsB;;AA0HvB;EACC;;;AAMD;AAAA;EACC;;;AAIF;EACC;;AACA;EACC;;AAED;EACC;EACA;EACA;;;AAKF;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACC;;AAED;EACC,kB1E7IW;E0E8IX;EACA;EACA;EACA;EACA;;AACA;EACC;;AAED;EACC,kB1EvJU;E0EwJV;;AAED;EAEC;;;AAQH;EAEE;IACC;IACA;;EAED;IACC;;EAED;IACC;;;ACnLH;EACC;EACG;EACA;EAEH;;AAGA;E7EtBG;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;A6EmBH;EACC;EACA;EACA;EACA,ctEd4B;EsEe5B;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;AAGA;EACA,QAjEwB;EAkExB;EACA,QAlEwB;EAmExB,WAlEuB;;AAoEvB;EANA;IAOC,QV7EoC;IU8EpC,WV9EoC;;;AUgFrC;EAEC;;AAED;EACC,Y1ClCuB;E0CmCvB,kBA3E0B;EA4E1B,QAjFuB;EAkFvB;EACA;;AAED;EACC,O3EtEsB;E2EuEtB,WApFqB;;AAwFvB;EACC;IACC,KtE1FyB;;EsE4F1B;IACC;;EAGD;IACC,etEvF8B;;EsEwF9B;IACC;;EACA;IACC,ctExFyB;;EsE0F1B;IACC;IACA,ctEzFsB;;EsE0FtB;IACC;;EAED;IACC,YtExGwB;;;;AsEgH9B;EACC,Y1C7EyB;E0C8EtB,kBAtHyB;EAuH5B;EAEA,WA1HyB;EA8HzB;EACA;EACA;EAEA,KArIyB;;AA8HzB;EACC,WA5HwB;;AAoIzB;EACC;EACA;;AAGD;EApBD;IAqBE;IACA,KVrJqC;IUsJrC;;EAEA;IACC,O3EnIsB;I2EoItB,WAxI2B;;EA0I5B;AAAA;IAEC;IACA,KtEtJyB;;EsEwJ1B;IACC;;EAED;IACC;;EAIA;IACC;IAEA;IACA;IACA,W1C3IwB;I0C4IxB,OtErK0B;IsEsK1B,KtE9J2B;IsE+J3B,a9ErJsB;;E8EyJxB;IACC;;;;ACpLH;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;ACKA;E/EDI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAQA;EAEE;EACA;EACA;EACA;EACA;EACA;;;AgF4BN;EACC,Y7CNyB;;;A6CiBzB;AAAA;AAAA;AAAA;AAAA;AAAA;EAEC,Q7ClDsB;E6CmDtB,O7ClDqB;;;A6C0DtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAEC,SAxEuB;EAyEvB;EACA,eAzDsB;EA2DtB;EACA;EACA,KzE/DuB;EyEgEvB,WjF5EqB;EiF6ErB;;AlDxCD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC;EACA,QA/CuB;EAgDvB;;AACA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC;;AkDqCD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AF7DD;AAeA;EEgDE;EACA;EACA;EACA;EACA;;AFrFF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC;EACA;EACA;EACA,a/EgBqB;;A+EbtB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAID;EACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IACC;IACA;IACA;IACA,oBEwD4C;IFvD5C;;EAGD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IACC;;;AAKF;EACC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IACC;IACA;IACA;IACA,iBEyC4C;IFxC5C;;EAGD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;IACC;;;;AEoDF;EAEC;EACA;EACA;EACA;;AAKD;AAAA;EAEC,Y9EvGiB;;A8EwGjB;AAAA;EACC,OA9GoB;EA+GpB;;AAED;AAAA;EACC,QAxG0B;;AAyG1B;AAAA;EACC,OApG2B;EAqG3B,QArG2B;;AA0H7B;AAAA;EAbC;EACA;;AACA;AAAA;EACC;;AAED;AAAA;EACC;;AAED;AAAA;EACC;;AAOF;AAAA;EAhBC;EACA;;AACA;AAAA;EACC;;AAED;AAAA;EACC;;AAED;AAAA;EACC;;AAUF;AAAA;EACC;EApBA;EACA;;AACA;AAAA;EACC;;AAED;AAAA;EACC;;AAED;AAAA;EACC;;AAcF;AAAA;EACC,OArJoB;;AAwJtB;EACC,Y9EpJiB;;A8EuJlB;EAGE;AAAA;IACC,kB9E3Je;I8E4Jf,O9E5Je;;E8E6Jf;AAAA;IACC,QAzJwB;;EA2JzB;AAAA;IACC,OAtKkB;;EAyKpB;AAAA;IACC,kB9E7JS;I8E8JT,O9EtKe;;E8EuKf;AAAA;IACC,QAjKgC;;EAmKjC;AAAA;IACC,O9E3Kc;;;;A8EuLnB;EACC,Y7CtJyB;E6CuJzB,Y9EjLY;E8EkLZ;EACA;;;AAGD;EACC,kB9E/LkB;;;A8EoMlB;AAAA;EACC,e7ChLyB;;A6CiLzB;AAAA;EACC,Y9E7Le;;;A8EoMjB;AAAA;EACC;;;AAUF;EACC;;AACA;AAAA;EAEC,kB9ElOiB;E8EmOjB;;AACA;AAAA;EACC,QA3N0B;;AA8N5B;EACC,kBA/MgC;EAgNhC,O9ErOiB;;A8EsOjB;EACC;;;AAOH;EACC;;AACA;EACC;EACA,Q7C/OsB;E6CgPtB;;AAED;AAAA;EAEC,kB9EpQc;E8EqQd,OA7PqB;;AA8PrB;AAAA;EACC,QArP0B;;AAuP3B;AAAA;EACC;EACA;;AAED;AAAA;EACC,kBA3OmC;EA+OnC,O9ErQgB;;A8EkQhB;AAAA;EACC;;AAGD;AAAA;EACC;;AAIH;EACC;EACA,cA7P0B;;AA8P1B;EACC;;;AAKH;EACC,kBAhQiC;EAiQjC;EACA,Q7CpRuB;E6CqRvB;EAEA;EACA;;;AAKD;EACC;;AACA;AACC;EACA;EACG;EACA;;AAEJ;EACC,O9EtTc;E8EuTX;EACA,ajFxRqB;EiFyRxB,Q7CzSsB;E6C0StB;EACA;;;AAMF;EACC;;AACA;EACC,Y7CxSkC;E6CySlC;EACA,YAhTsB;;AAiTtB;EhFrUE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AgFkUD;EACC;EACA;EACA;EACA;;AAED;EACC;;;AAMJ;EACC;EACA;EACA;EACA;;;AAEA;EAIC;;AAHA;EACC;;AAID;EACC;EACA;;;AAQH;EACC;IACI;IACA;IACA;IACA;;EAGJ;IACC,Y7CtUsC;;E6CyUvC;IACG;IACA;;EAKF;AAAA;AAAA;AAAA;IAEM;IACH;IACA,QbtYyB;IauYzB,ObtYwB;;EauYxB;AAAA;AAAA;AAAA;IACC,QjBxYe;IiByYf,OjBzYe;;EiB+YnB;IACC,QbjZ2B;;EakZ3B;IACC;;EACA;IACC;IACA,QbtZyB;;;Aaia9B;EAOE;AAAA;AAAA;AAAA;AAAA;IACC;;;ACpaH;EACC;EACA,kB/EeY;E+EdZ,SANmB;EAOnB;;;AAED;EACC,O/EoBe;E+EnBf,WlFFqB;EkFGrB;;AAEA;EACC;;AAIA;EACC;EACA;EACA;;AAED;EACC;EACA,c1ENwB;;A0EOxB;EACC,O/E7BY;;A+E+Bb;EACC;;AAGF;EACC;EACA;;AAED;EACC;EACA;;AAED;EACC;;AAIF;EACC,c1E5ByB;;A0E+B1B;EACC;;;AHvDF;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AIYA;EACE;EACA;EACA,SANoB;EAOpB;EACA;EACA;EACA;;AAEA;EACE,QAhBkB;EAiBlB;EACA;EACA;EACA;EACA,SAlBkB;;AAqBpB;EACE;EACA;EACA;EACA,kBhFxBe;EgFyBf,2BjFxB+B;EiFyB/B,4BjFzB+B;EiF0B/B,oBA3BkB;EA4BlB,iBA5BkB;EA6BlB,YA7BkB;EA8BlB;EACA,K3ExB6B;E2EyB7B,YAnCkB;EAoClB;EACA;;AAEA;EAhBF;IAiBI;IACA;IACA,YfnDiC;IeoDjC;;;AAIJ;EAEE,OAhDsB;EAiDtB,WnFzCkB;EmF0ClB;EACA;EACA;EACA;EACA;;AACA;AAAA;AAAA;EAEE,OAzDoB;;AA6DxB;AJzCD;AAeA;EI4BG;;AJ7DH;EACC;EACA;EACA;EACA,a/EgBqB;;A+EbtB;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAID;EACC;IACC;IACA;IACA;IACA,oBIoCkC;IJnClC;;EAGD;IACC;;;AAKF;EACC;IACC;IACA;IACA;IACA,iBIqBkC;IJpBlC;;EAGD;IACC;;;AIqBC;EADF;IAEM,Qf9E+B;;;;AgBEvC;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;AAAA;AAAA;AAAA;AAoBA;AAGA;AAEA;AAIA;AAEA;AAEA;AAKA;EA8BE,apF1CwB;EoF2CxB,a5E9D0B;E4E+D1B,gB5E/D0B;E4EgE1B;EAIA;EACA;EACA;EACA;;AApCE;EAEE,oBApBgC;EAqBhC,iBArBgC;EAsBhC,YAtBgC;EAuBhC,kBAb+C;EAe/C;EACA;EACA;EACA;EAEA,OAbe;;AAef;EACE,OAhBa;;AACjB;EAEE,oBApBgC;EAqBhC,iBArBgC;EAsBhC,YAtBgC;EAuBhC,kBAZiD;EAcjD;EACA;EACA;EACA;EAEA,OAbe;;AAef;EACE,OAhBa;;AACjB;EAEE,oBApBgC;EAqBhC,iBArBgC;EAsBhC,YAtBgC;EAuBhC,kBAXgD;EAahD;EACA;EACA;EACA;EAEA,OAbe;;AAef;EACE,OAhBa;;AAwCnB;EACE;EACA;;AAGF;EACE;EACA;EACA;EACA;;AAEA;EACE,gBAxE4C;EAyE5C,apFxDmB;EoFyDnB,c5E7FY;;A4EqGhB;EACE;;AAGF;EACE,WpF5FkB;EoF6FlB;EACA;EACA;EACA;;AAEA;EACE,e5E3GwB;;A4E8G1B;EACE;;AAIJ;EACE;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAMA;EACE;IACE;;;AAIJ;AAAA;AAAA;AAAA;AAAA;AAMA;EACE;IACE;;;AClIH;EACC;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA,YAtB2B;EAuB3B,ejDOyB;EiDNzB;EACA;;AACA;EACC,WrFfsB;EqFgBtB;;AAED;EACC;EACA;EAEA;EACA;EACA;EACA;;AACA;EACC;EACA;EACG;;AAIN;EACC;;AACA;EACC;;AAKF;AAAA;AAAA;AAAA;EAII;;AAEJ;AAAA;AAAA;EAGI;;AAEJ;EACC;;AAGD;EACC;;AAED;AAAA;EAEC,kBArEsB;EAsEtB,cAtEsB;;AAuEtB;AAAA;EACC,kBlFpDe;EkFqDZ;;AAEJ;AAAA;EACC;;;AC9EF;EACC,YALyB;;AAO1B;EACC,YAPmC;EAQnC,kBnFYgB;EmFXhB;EACA,WtFHoB;EsFIpB,OnFwBoB;EmFvBpB;;AAED;EACC,SAjB0B;AAkB1B;;;AC2BF;EACC;;;AAIC;EACD;EACA;EACA;EACA;EACA;EACA,SApD0B;EAqD1B;EACA;EACA;EAIA;;AAGA;EACC;EACA,qBArC0B;EAsC1B;EACA;;AAED;ExF+DC;EACI;EACC;EACG;EAkER;EACG;EACE;EACG;;AwFnIT;ExF2DC;EACI;EACC;EACG;;AwF1DR;EACC,kBpFrEgB;EoFsEhB,OpF9DU;;AoF+DV;EACC,qBpFhES;;AoFmEX;EACC,OpFpEU;EoFqEV,kBpF7EgB;EoF8EhB;EACA;;;AAID;EACD;EACA;;;AAIC;EACD;EACA;EACA;;;AAIC;EACD;EACA,kBAvG8C;EAwG9C;EACA;EACA;EACA,erF9GwB;EqFiHxB;;;AAIC;EACD;EACA;EACA;EACA;EACA;EACA,SA5H0B;EA6H1B,kBAlH6B;;AAoH7B;ExF+FC;EACA,SwFhGyB;;AAC1B;ExF8FC;EACA,SwFlN4B;;;AAwH5B;EACD,SA/GqB;EAgHrB;;Af/IG;EAEE;EACA;;AAEF;EACE;;;Ae6IJ;EACD;;;AAIC;EACD,WvFvIqB;EuFwIrB;EACA,avFhIsB;;;AuFqIrB;EACD;EACA,SAhIqB;;;AAoIpB;EACD,SArIqB;EAsIrB;EACA;;AfzKG;EAEE;EACA;;AAEF;EACE;;AeuKL;EACE;EACA;;AAGF;EACE;;AAGF;EACE;;;AAKD;EACD;EACA;EACA;EACA;EACA;;;AAIC;EAED;IACE,OA5K2B;IA6K3B;;EAEF;IxFpIC,oBwFqIC;IxFpIO,YwFoIP;;EAIF;IAAY,OAnLiB;;;AAsL5B;EACD;IAAY,OAzLiB;;;AAkM3B;EACC;;AAED;EACC;;;AAOH;EACE,e/EvN4B;;A+EyN5B;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;EACA,OpF3MkB;EoF4MlB,c/EhO0B;;;AgFV9B;EACC,exFeyB;EwFdzB,Q9CRiB;E8CSjB,etFDkC;EsFElC,oB9CXiB;E8CYjB,Y9CZiB;;A8CcjB;EACC,S9CjByB;E8CkBzB;EACA;ECpBA,wBDqB2B;ECpB3B,yBDoB2B;;AAE3B;EACC,OpFdqB;;AoFkBvB;AAAA;EAEC,kBrFLgB;EqFMhB;EACA;;AAEA;AAAA;AAAA;EACC;EACA,OrFHa;EqFIb,WxFnBsB;EwFoBtB,axFVqB;EwFWrB,axFDsB;;AwFIvB;AAAA;AAAA;EACC;EACA,OrFXa;EqFYb,WxF/BoB;;AwFmCtB;EACC;EACA;EACA;;AAGD;EACC;EACA,kBrFlCW;;AqEzBT;EAEE;EACA;;AAEF;EACE;;;AgB0DN;EACC,S9CzDyB;E8C0DzB,kBrFvCiB;EqFwCjB;ECzDC,4BD0D6B;ECzD7B,2BDyD6B;;;AAK9B;EACC;;AAED;EACC;;AAED;EACC;EACA;EACA;EACA,KhF/EgB;EgFgFhB;;AAED;EACC;;AAED;EACC;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;;;AAMD;EACC,axFjEuB;;;AwFsEzB;EACC,oB9C1GiB;E8C2GjB,Y9C3GiB;;A8C6GhB;EACC,WxFjGmB;;AwFoGpB;EACC,WxFrGmB;;AwF0GpB;EACC;;AACA;EACC;;AAED;EACC;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC,chFjI2B;;AgFmI3B;EACC;;AAMJ;EACC;EACA;EACA,WxF1IqB;EwF2IrB,OrFxHc;EqFyHd;;AAGD;EACC,etF1Je;;;AsF+JjB;EACC;EACA;EACA;EAEA;;AAEA;EACC;;AAIA;EACC,S9C/KwB;;;A8CsL1B;EACC;;AAED;EACC,ehFpL0B;;AgFsL3B;EACC;;;AAMF;EACC,kBrF5KiB;EqF6KjB,epD3LkC;;AoD6LlC;EACC,OrFxKc;EqFyKd,WxFxLuB;EwFyLvB,axFrKuB;EwFsKvB;EACA,S9C5MyB;E8C6MzB;EACA,axFnLsB;;AwFsLvB;EACC;;AAED;EACC,S9CrNyB;;A8CuNzB;EACC,gBhFtMyB;;;AkFf1B;EACE,OALoB;;;AAQxB;EACE,YvFMiB;;;AwFqEnB;EACE;;;AAGF;EACG;EACA;;;AAGH;AACA;EACE;EACA;EACA;EACA,SArDgB;EAsDhB;EACA,WA7FoC;EA8FpC,YA5FoC;EA6FpC;EACA;EACA;EACA,kBAxGkC;EAyGlC;EACA;EACA;EACA,eA3EkC;EAelC,oBA6DoB;EA5DZ,YA4DY;;AAEpB;EAAmC;;AACnC;EAAuC,aA3FH;;AA4FpC;EAAwC,YA5FJ;;AA6FpC;EAAqC;;AAGrC;EAnDE,mBAoDmB;EAnDd,cAmDc;EAlDX,WAkDW;EA9CpB,oBA+CqB;EA9Cf,eA8Ce;EA7CZ,YA6CY;EAlEtB,SAmEmB;EAhEnB;;AAkEA;EA5CE,6BA6C6B;EA5CxB,wBA4CwB;EA3CrB,qBA2CqB;EAnD9B,oBAoDqB;EAnDf,eAmDe;EAlDZ,YAkDY;EAvEtB,SAwEmB;EArEnB;;AAwEA;EAxDC,oBAyDqB;EAxDf,eAwDe;EAvDZ,YAuDY;EA5EtB,SA6EmB;EA1EnB;;AA4EA;EA/EA,SAgFmB;EA7EnB;;AAgFA;EAtEE,mBAsEuB;EArElB,cAqEkB;EApEf,WAoEe;EAnFzB,SAmFiD;EAhFjD;;AAkFA;EACE;EACA;EACA;;AACA;EACE;;;AAON;EACE;EACA;EACA;EACA,WAjHkC;EAkHlC;EACA,aAnHkC;EAoHlC,OAnHkC;EAoHlC;EAzGA,SA0GiB;EAvGjB;EAwGA;;AACA;EA5GA,SA6GkB;EA1GlB;;AA4GA;EACE;EACA;EACA;EACA;EAEA;;;AAIJ;EACE;EACA;EACA,WA7IgC;EA8IhC;EACA;EACA,kBApLkC;EAqLlC;EACA;;;AAGF;EACE;EACA;EACA;;;AAIF;EACE,kBA/LsB;EAgMtB,OA9LyB;;AAgMzB;EACC,YAnMqB;EAoMrB;EACA,OAnMwB;;;AAwM1B;EACC;;AAED;EACC;EACE;;AACA;EACD;;AAEC;EACD;;;AAOD;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIF;EACE,cA9MoC;;;AAgNtC;EACE,cAtNoC;EAuNpC;;;AAIA;EAIE;EACD;EACA;EACA,kBAzNmC;EA0NnC,kBA5NmC;EA6NnC;;AACA;EACG;EACA;EACF;EACA,kBAvOkC;EAwOlC;;AAGF;EAGE;EACA;EACA;EACA;EACA,oBA3OkC;EA4OlC,oBA9OkC;;AA+OlC;EACE;EACA;EACA;EACA;EACA,oBAzPgC;;AA4PpC;EAIE;EACD;EACA;EACA,qBA5PmC;EA6PnC,qBA/PmC;EAgQnC;;AACA;EACG;EACA;EACF;EACA,qBA1QkC;EA2QlC;;AAGF;EAGE;EACA;EACA;EACA;EACA,mBA9QkC;EA+QlC,mBAjRkC;;AAkRlC;EACE;EACA;EACA;EACA,mBA3RgC;EA4RhC;;;AASJ;EACC,kBA3TqB;;AAiUtB;EACC,oBAlUqB;;AAwUtB;EACC,qBAzUqB;;AA+UtB;EACC,mBAhVqB;;;AAqVxB;EACE;;;AAGF;EACG;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIH;EACE;IAAM;;;AAGR;EACE;IAAM;;;AAGR;EACE;EACA;EACA;EACA;EACA;EACA;EACA,SA3UyB;;;AAgVvB;EACE;EACA;EACA;EACA;EACA;EACA;;;AC5VN;EACE,WA9BqB;;AA+BrB;EACD;;AAEC;EACD,YArBuB;EAsBvB;;AACA;EACE;;AACA;EACD;EACA;EACA;EACA;;AAIA;EACD;EACA;;AAGC;EACD,kBzFrCmB;;AyFsCnB;EACE,W5FlDmB;E4FmDnB,a5F/BsB;E4FgCtB;EACA;EACA;EACA,OzFtCa;;AyF0Cd;EACD;;;AAID;EAEC;IACE;IACA;IACA;;;ACzEH;EACC;EACA;;AAEA;EACC,Q7BfmB;E6BgBnB,a7BhBmB;;A6BkBpB;EACC,Q7BjBoB;E6BkBpB,a7BlBoB;;A6BoBrB;EACC,Q7BnBmB;E6BoBnB,a7BpBmB;;A6BsBpB;EACC;EACA,a7B1BoB;;A6B6BrB;EACC,gBA1BiC,iBA0BkB;EACnD,QA3BiC;;;ACQlC;EACE;EACA;EACA;;AASH;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAIqC;EAAW;;;AACX;EAAW;;;AAEX;AAAA;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AASX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AACX;EAAW;;;AAMjD;EACC,O3F5Te;;A2F8Tf;EACC,O3FvTiB;;A2FwTjB;EACC,O3FzTgB;;A2F6TlB;EACC,O3FpTuB;E2FqTvB;;AAGD;EACC,O3F9RoB;E2F+RpB;;;AAKD;EACC;;;AAIF;AAAA;EAEC;;;AAGD;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAED;EACC;;;AAID;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;EACC;EACA;;;AAED;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D;EATC;EACA;EACA;EAlCA;;;AA4CD;EAZC;EACA;EACA;EAlCA;;;AA+CD;EAfC;EACA;EACA;EAlCA;;;AAkDD;EAlBC;EACA;EACA;EAlCA;;;AAqDD;EArBC;EACA;EACA;EAlCA;;;AAwDD;EAxBC;EACA;EACA;EAlCA;;;AA2DD;EA3BC;EACA;EACA;EAlCA;;;AA8DD;EA9BC;EACA;EACA;EAlCA;;;AChBD;AAEA;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;;AAKH;EAIC;EACA;EACA;EACA;;AANA;EACC;;;AAQF;EACC;IACC;;;AAIF;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC,OvHzDoB;EuH0DpB,W1HtFoB;E0HuFpB;EACA;EACA;;AAGD;EACC;EACA,OvHlEoB;EuHmEpB;EACA;EACA;;AAGD;EACC,kBvHxFgB;EuHyFhB;EACA,W1HvGoB;;A0H0GrB;EACC,OvHtFc;;AuHyFf;EACC,OvHrFoB;;AuHwFrB;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC,kBvH3GgB;;AuH8GjB;EACC;EACA;E3HzEA,oB2H0EA;E3HzEQ,Y2HyER;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;AAGD;EACC;;AAGD;EACC;;;ACzKF;AAEA;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA,OxHiBe;EwHhBf;EACA;EACA;;;AAED;EACC;EACA,OxHUe;EwHTf;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;EACC;;;AAID;EACC,W3HxCqB;;;A2H2CtB;EACC,W3HxCqB;E2HyCrB;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAID;AAEA;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;E5HfE,oB4HgBD;E5HfS,Y4HeT;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,kBxH7EwB;;;AwHgFzB;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AC7GD;AAEA;EACC;EACA;;;AAGD;EACC;EACA,W5HGqB;;;A4HAtB;EACC;EACA;;;AAGD;EACE;;;AAGF;EACC,a5HcwB;E4HbxB;EACA,W5HZqB;E4HalB;EACA;;;AAGJ;EACE;;;AAGF;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;ACjDD;AAEA;EACC,crHU+B;EqHT/B,erHS+B;;;AqHNhC;EACC;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,W7HbqB;;;A6HgBtB;EACC;EACA;EACA;;;AAED;EACC,kB1HTiB;E0HUjB;;;AAGD;EACC;;AACA;EACC;EACA;;AAED;EACC;;AAED;EACC;EACA;;;AAKF;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA,O1H/DwB;E0HgExB;EACA;EACA;EACA;;;ACtFD;AAQA;EACC,a9H0BwB;;;A8HvBzB;EACC,a9HwBwB;;;A8HrBzB;EACC;EACA,a9HmBwB;;;A8HhBzB;EACC;EACA;EACA;EACA,W9HdqB;;;A8HiBtB;EACC,a9HQwB;E8HPxB,W9HnBqB;E8HoBrB;;;AAGD;AACA;EACC;EACA;EACA;EACA,kB3HjBY;;;A2HoBb;EACC;EACA;EACA;;AACA;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;;;;AAKH;EACC;EACA;EACA;EACA;;;AAGD;EACC,YtHnD8B;EsHoD9B,W9HpDqB;;A8HqDrB;EAHD;IAIE,YtH/D0B;IsHgE1B,W9HzDqB;;;;A8H6DvB;EACC,O3HpCqB;;;A2HuCtB;EACC;EACA;EACA;;AACA;EAJD;IAKE,ctHhE4B;IsHiE5B;;;AAGA;EADD;IAEE;IACA;;;;AAKH;EACC;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;;AAIF;EACC,YtHjG8B;;;AsHoG/B;EACC;EACA,etHtG8B;EsHuG9B;;AAEA;EACC,kB3HnGW;E2HoGX;;AAGD;EACC;EACA;;AACA;EACC;;AAED;EACC;;AAGA;EADD;IAEE;;;AAKF;EADD;IAEE;IACA;;;;AAKH;EAEE;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;EAED;IACC;;;AAKH;EACC;EACA;EACA,a9HlJwB;E8HmJxB,O3H/KkB;;;A2HkLnB;EACC;EACA,a9HxJwB;;A8HyJxB;EACC,a9H5JuB;;A8H8JxB;EACC;;;AAIF;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC,YtHrM8B;;;AsHwM/B;EACC;;;AAGD;EACC,O3HnNkB;;;A2HsNnB;EACC,a9H3LwB;;;A8H8LzB;EACC;EACA;EACA;EACA;EACA;EACA;EACA,O3H1Me;E2H2Mf;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;ACjQD;AAEA;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;AACA;EACA,kB5HRiB;E4HSjB;AACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAID;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AC7GD;EACI,kB7HmBS;E6HlBT,oBtFFc;EsFGd,YtFHc;;AsFIjB;AAAA;EAEC;EACA;EACA;;;AAKD;EACC;;;AAGF;EACC;EACA,kB7HGiB;;A6HFjB;EACC;;AAED;EACC;;;AAMA;EACC;;;AAKH;EACC,kB7HfiB;;A6HiBjB;EACC;;;AAGF;AAEA;EACC;;;AClDD;AAUA;EACE;EACA;;;AAEF;EACE;EACA,SARmB;EASnB,OAfiB;EAgBjB,QAfkB;;;AAiBpB;ACpBA;EACE;;AACA;EACE;;;AAKF;EACE;;;AAIJ;EACE;;;AAGF;EACE;;;AAGF;EACE;;;AAIA;EACE;EACA;EACA;;AAGF;EACE;EAIA;;AAHA;EACE;;AAKJ;EACE;;AAGF;EACE;;AAGF;EACE;EACA;;AAGF;EACE;EACA;;AAIA;EACE;;AAIJ;EACE;;;ACjEJ;AAEA;EACC;EACA;EACA;EACA;;;AAGD;EACC,kBhIgBiB;EgIfjB;;;AAGD;EACC;;;AChBC;EACD;EACA;EACA;;AAGC;EACD;;AAGC;EACD;EACA;;AAGC;EACD;EACA;;AAGC;EACD;EACA;EACA;;;AAID;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;AAGF;EACE;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;;;AAGF;EACE;EACA;EACA;;;ACtDF;AAEA;EACC;EACA,WrISqB;EqIRrB,OlIMkB;;;AkIHnB;EACC;EACA,WrIGqB;EqIFrB,OlI8BqB;;;AkI3BtB;EACC;EACA;EACA;EACA,WrILqB;EqIMrB;;;AAGD;EACC;EACA;EACA;EACA,WrIbqB;EqIcrB,OlIcqB;;;AkIXtB;EACC;EACA;;;AAGD;EACC;EACA,WrIxBqB;;;AqI2BtB;EACC;;;AAGD;EACC;EACA,WrIjCqB;;;AqIoCtB;EACC;;;AAGD;EACC,kBlInDe;;;AkIsDhB;EACC;;;AAGD;EACC,WrI7CqB;;;AsIjBtB;AAEA;EACC;;AACA;EACC;EACA;;;AAIF;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA,WtIRqB;AsISrB;;;AAGD;EAEC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EAKC;;AAJA;EACC;EACA;;;AAKF;EACC;;;AAGD;EACC;;;AC7DD;AAEA;EACC,OpI+Be;EoI9Bf,kBpIsBiB;EoIrBjB;EACA;;;AAGD;EACC,kBpIgBiB;EoIfjB,OpIuBe;EoItBf;EACA;EACA;;;AAGD;EACC;EACA,OpIee;EoIdf;EACA;EACA;;;ACrBD;AAEA;EAEC;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGD;IACC;IACA;IACA;IACA;;EAGD;IACC;IACA;IACA;IACA;;EAGD;IACC;;EAGD;IACC;IACA;;EAGD;IAEC;IACA;AACA;AAAA;AAAA;;EAKD;IAEC;IACA;IACA;;EAGD;IAEC;;EAGD;IACC;;EAGD;IACC;IACA;;EAGD;IACC;IACA;IACA;IACA;IACA;;EAGD;IACC;IACA,axIxCuB;IwIyCvB;IACA;IACA;;EAGD;IACC;IACA;;EAGD;IACC;IACA;IACA;IACA;IACA;IACA;IACA;IACA;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;IACA,axI5EuB;IwI6EvB;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;;EAGD;IACC;IACA;IACA,axInGuB;IwIoGvB;IACA;;;AAIF;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA,kBrI/IiB;EqIgJjB;;;AAGD;EACC;EACA;;;AAGD;EACC;;AACA;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAMA;EACC;;;ACnMH;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EAEI;EACH;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;AAEA;EAHD;IAIE;;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EAEI;EACA;EACA;;;AAGJ;EACC;EACA;EACA;EAEA,SjIxH+B;;AiIyH/B;EACC,cjI1H8B;EiI2H9B,ejI3H8B;;;AiI+HhC;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;;;AAGD;AAEA;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EAEC;EACA;EACA;;;AAGD;EAEC;EACA;EACA;;;AAGD;EAEC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAID;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EAOC;;;AAGD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;EASI;;;AAEJ;AAAA;EAGI;;;AAEJ;EAEI;EACA;;;AAEJ;EAEI;EACA;EACA;;;AAKJ;EAEI;;;AAEJ;EAEI;;;AAEJ;AAAA;EAGI;;;AAGJ;EAEC;;;AAED;EAEC;;;AAED;EAEC;;;AAED;AAAA;EAGC;;;AAED;EAEC;;;AAED;EAEC;;;AAED;EAEC;;;AAED;EAEC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;AAAA;EAEC;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAED;EACC;EACA;EACA;;;AAOD;EACC;EACA;;;AAGD;E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JrSkB;EmJsSlB;;AAKF;EACC;;AAIF;EACC;;;AAOF;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC,WtJrXqB;EsJsXrB;EACA,kBnJ1WiB;EmJ2WjB;EACA;;;AAGD;EACC;EACA,WtJ5XsB;EsJ6XtB;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;AACA;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC,kBnJnaY;EmJoaZ;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;;AACA;EACC;EACA;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC,kBnJvcY;EmJwcZ;EACA;EACA;EACA;;;AAGD;EACC,kBnJ/cY;;;AmJkdb;EACC;EACA,WtJ3dqB;EsJ4drB;;;AAGD;EACC;EACA,kBnJ1dY;EmJ2dZ;EACA;;;AAGD;AAEA;EACC;EACA;;;AAGD;EACC,cnJ5fe;;;AmJ+fhB;EACC,cnJxfkB;;;AmJ2fnB;EACC,cnJlgBoB;;;AmJqgBrB;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA,OnJnfqB;;;AmJsftB;EACC,OnJvfqB;;;AmJ0ftB;EACC;;;AAGD;EACC;;;AAGD;EACC;;AACA;EACC;;AAGA;EACC;EACA;EACA;EACA;EACA,kBnJ1hBe;EmJ2hBf;EACA;;AAIF;EACC;;AAGD;EACC;EACA;;AAGD;EACC;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA,WtJjkBqB;EsJkkBrB;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;EACA,kBnJtkBiB;EmJukBjB;;;AAGD;EACC,kBnJtkBiB;;;AmJykBlB;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;AAAA;EAEC;;;AAID;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;AAAA;AAAA;EAGC;;;AAGD;EACC;;;AAID;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EAEC;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;;AAIF;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;AAEA;EACC;EACA;;AAGD;EACC;EACA;;AACA;EAHD;IAIE;;;AAIF;EACC;;AAED;EACC,e9IztB2B;;A8I0tB3B;EACC;;AACA;EACC,WtJztBmB;;AsJ4tBrB;EACC;;AAED;EACC;EACA;EACA;EACA;EACA;;AAED;EACC;EACA,kBnJ/tBU;;AmJmuBZ;EACC;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAED;EACC;;;AAID;AACA;EACC;;AAEA;EACC;EACA;;AACA;EACC;EACA;;;AAKH;AAAA;AAAA;AAAA;AAAA;AAKA;EACC;;;AAGD;EAEC,kBnJtxBY;;AmJwxBZ;EACC,kBnJvxBgB;;AmJwxBhB;EACC,kBnJzxBe;EmJ0xBf;EACA,OnJnxBa;EmJoxBb;EACA;;AAIF;EACC;;AAGD;EACC;;;AAIF;AAAA;EAEC;EACA,OnJ9xBqB;EmJ+xBrB;;;AAGD;EACC;EACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;EACA;EACA;;;AAGD;EACC;;AACA;EACC;EACA;EACA;;;AAMA;EACC;EACA;;AAED;EACC;;;AvHj2BF;EACC;EACG;;AAEJ;EACC;EACA,SAXuB;EAYvB;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA,QArBsB;EAsBtB,SAvBsB;;;AwHHzB;AAEA;EACC,WvJQsB;;;AuJLvB;EACC,WvJMqB;;;AuJHtB;EACC;;;ACSD;EACC;EACA;EACA;EAIA;;;AAGD;EACC;EACA;EACA;EACA;EACA,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A;;;AAGD;EACC;EACA,W/JFqB;E+JGrB;EACA;EACA;AACA;EACA;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;ACtDD;AAEA;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;EACA;EACA;;;ACnBD;AAEA;EACC;EACA;EACA;EACA;EACA;EACA,WjKGsB;;;AiKAvB;EACC;EACA;EACA;EACA;EACA;EACA,kB9JWmB;;;A8JRpB;EACC;EACA;EACA;EACA;;;ACtBD;AAEA;EACC;;AACA;EACC;;AAED;EACC;;AAED;EACC;;AAED;EACC;EACA;;AAED;EACC;;;AAIF;EACC;IACC;;;AAIF;EACC,kB/JpBkB;E+JqBlB;EACA;EACA,WlKvBsB;EkKwBtB;EACA;EACA;;AACA;EACC;EACA;;;AAIF;AAEA;EACC;EACA;EACA;;AACA;EACC;EACA;EACA;EACA;EACA;EACA,kBhKpD0B;EgKqD1B;EACA;;AACA;EATD;IAUE;;;AAGF;EACC;EACA;EACA;;AACA;EACC;EACA;;AACA;EAHD;IAIE;;;AAED;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;;;AAIH;EArBD;IAsBE;;;AAED;EACC;EACA;;AAED;EACC;;AAED;EACC;EACA;EACA;EACA;EACA,Y/JzEe;E+J0Ef,QxH/Fe;;AwHgGf;EAPD;IAQE;;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAED;EACC;;AAGF;EACC;EACA;EACA;EACA;EACA;EACA,WlK9GoB;EkK+GpB;EACA;EACA;EACA,kB/J5GsB;E+J6GtB;EACA;EACA;EACA;;AACA;EAfD;IAgBE;IACA;IACA;;;AAED;EACC,WlK7HmB;;AkK+HpB;EACC,WlKpImB;;AkKsIpB;EACC;EACA;;AAGF;EACC;;AACA;EAFD;IAGE;;;AAED;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;IACA;IACA;;;AAGF;EACC;EACA;EACA;EACA;;AACA;EALD;IAME;IACA;IACA;IACA;;;AAKJ;EACC;EACA;;AAED;EACC,kB/JhKgB;;;A+JoKlB;AACC;AAAA;AAAA;;;AAKD;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;EACA;EACA;;AAEA;EALD;IAME;;;;AAIF;EACC;EACA;;AAEA;EAJD;IAKE;IACA;;;;AAIF;EACC;;AACA;EAFD;IAGE;;;;AAIF;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AAGD;AACA;EACC;EACA;EnK9DC,oBmK+DD;EnK9DM,emK8DN;EnK7DS,YmK6DT;EACA;;;AAGD;AACA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAGD;EACC;EACA;;;AClRD;AAEA;AACI;;;AAEJ;EACI;;;AAEJ;EACC,kBhKaY;EgKZZ;;;AAGD;EACC,kBhKQY;;;AgKLb;EACC;EACA;;;AAGD;EACC;;;AAGD;EACC;EACA;;AACA;EACC;EACA;;;AAIF;EACC,WnKzBqB;EmK0BrB;;;AAGD;EACC,kBhKjBiB;EgKkBjB;EACA;;AAEC;EACC;EACA;;;AAMF;EACC;;;AAIF;EACC;;;AAGD;EACC,WnKhDqB;EmKiDrB,OhKhCe;EgKiCf;;;AAGD;EACC,WnKxDsB;EmKyDtB;EACA;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;;;AAGD;EACC;;;AAIA;EACC;;AAED;EACC;;;AAIF;EACC,e3JzF4B;;;A2J6F5B;EACC;EACA;;;AAIF;EACC,YzH1GiB;;AyH2GjB;EACC;;;AAIF;EACC;;;ACtHD;AAcA;EACC;EACA;;;AAID;EACC,WpKVsB;EoKWtB;EACA;EACA;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC,elK7BgB;EkK8BhB,kBjKXY;;AiKYT;EACI;;;AAKR;EACI;;AAEI;EACI,kBjKtBC;;AiKyBD;EACI;;AAGA;EACI;;;ACtDpB;EACC;;;AAIA;EACC;EACA;EACA;EACA;;;AAIF;EACC;EACA;EACA;EACA;EACA;AACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;;AACA;EACC;EACA;;AAEA;EACC;;AAGD;EACC;EACA;;AAKH;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA,kBlKjCW;;AkKmCX;EACC;;AAGD;EACC;EACA;;AAGD;EACC;;AAGD;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAED;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;;AAED;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;EACA;;AAGD;EACC;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;;AAGD;EACC;;AAEA;EACC;EACA,kBlK/Ha;;AkKiIb;EACC,WrK/IgB;;AqKmJlB;EACC;EACA;;AAIA;EACC;EACA;EACA;;AAKD;EACC;EACA;;AAMA;EACC,WrK5KgB;;AqKgLlB;EACC;EACA,OlKpJgB;EkKqJhB,WrKjLgB;;AqKuLpB;EACC;EACA;EACA;;AAEA;EACC,WrK/LmB;EqKgMnB;EACA;EACA;EACA;EACA;;AAEA;EACC;;AAGD;EACC;EACA;EACA;;AAGD;EACC;;AAGD;EACC;EACA;;AAIF;EACC;;AAGD;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;EACA;;AAEA;EACC;EACA;EACA;EACA;EACA;EACA;;AAKH;EACC;EACA;EACA;EACA;;;AAOH;EACC;;AAED;EACC;;;AAIF;EACC;EACA;EACA;EACA;EACA;;;AChSD;AAEA;EACC;EACA;;;AAGD;EACC;EACA;;;AAGD;EACC;;;AAGD;EACG;EACA;EACA;;;ACdH;EACC;;AACA;EACC,avK+BuB;;;AuK1BxB;EACC;EACA;EACA,WvKGoB;EuKFpB;;AAED;EACC;;;AAIF;EACC;;;AAGD;EACC;EACA;EACA;;;AAGD;EACC;EACA;EA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","file":"delos.css"} \ No newline at end of file diff --git a/templates/default/images/copyrights/all_rights_reserved.svg b/templates/default/images/copyrights/all_rights_reserved.svg index 2e390d9ecdcc..5e0523b3587b 100644 --- a/templates/default/images/copyrights/all_rights_reserved.svg +++ b/templates/default/images/copyrights/all_rights_reserved.svg @@ -1,27 +1,22 @@ - + + + + + + + + + diff --git a/tests/UI/Component/Button/ButtonTest.php b/tests/UI/Component/Button/ButtonTest.php index 6c4cb58be8c1..bb72b780cde2 100644 --- a/tests/UI/Component/Button/ButtonTest.php +++ b/tests/UI/Component/Button/ButtonTest.php @@ -1,7 +1,5 @@ assertFalse($b->isActive()); $this->assertEquals("http://www.ilias.de", $b->getAction()); + + $b = $b->withUnavailableAction(false); + $this->assertTrue($b->isActive()); } /** diff --git a/tests/UI/Component/Table/PresentationTest.php b/tests/UI/Component/Table/PresentationTest.php index b9b9f2172eea..0d6d82debaa2 100644 --- a/tests/UI/Component/Table/PresentationTest.php +++ b/tests/UI/Component/Table/PresentationTest.php @@ -149,9 +149,14 @@ public function testFullRendering(): void

      title

      -
      - - +
      +
      +
      + + +
      +
      +
      @@ -175,7 +180,17 @@ public function testFullRendering(): void

      some title
      some type

      -
      important-1|important-2|
      +
      +
      +
      +
      important-1
      +
      +
      +
      important-2
      +
      +
      + +
      @@ -211,7 +226,7 @@ public function testFullRendering(): void $f = $this->getFactory(); $pt = $f->presentation('title', [], $mapping); $actual = $r->render($pt->withData($this->getDummyData())); - $this->assertHTMLEquals( + $this->assertEquals( $this->brutallyTrimHTML($expected), $this->brutallyTrimHTML($this->brutallyTrimSignals($actual)) ); @@ -230,9 +245,16 @@ public function testMinimalRendering(): void

      title

      -
      - - + +
      +
      +
      + + + +
      +
      +
      @@ -256,6 +278,7 @@ public function testMinimalRendering(): void

      some title

      +
      @@ -279,7 +302,7 @@ public function testMinimalRendering(): void $f = $this->getFactory(); $pt = $f->presentation('title', [], $mapping); $actual = $r->render($pt->withData($this->getDummyData())); - $this->assertHTMLEquals( + $this->assertEquals( $this->brutallyTrimHTML($expected), $this->brutallyTrimHTML($this->brutallyTrimSignals($actual)) );