diff --git a/Modules/Exercise/test/PeerReview/ExcPeerReviewTest.php b/Modules/Exercise/test/PeerReview/ExcPeerReviewTest.php
new file mode 100644
index 000000000000..f2df1e66a5e9
--- /dev/null
+++ b/Modules/Exercise/test/PeerReview/ExcPeerReviewTest.php
@@ -0,0 +1,84 @@
+
+ */
+class ExcPeerReviewTest extends TestCase
+{
+ //protected $backupGlobals = false;
+
+ protected function setUp() : void
+ {
+ parent::setUp();
+ }
+
+ protected function tearDown() : void
+ {
+ }
+
+ protected function getDistribution($user_ids, $num_assignments)
+ {
+ include_once("./Modules/Exercise/PeerReview/class.ExcPeerReviewDistribution.php");
+ return new \ILIAS\Exercise\PeerReview\ExcPeerReviewDistribution($user_ids, $num_assignments);
+ }
+
+ /**
+ * Test if each rater has $num_assignments peers
+ */
+ public function testDistributionNumberOfPeers()
+ {
+ $user_ids = [100,200,300,400,500];
+ $num_assignments = 3;
+
+ $distribution = $this->getDistribution($user_ids, $num_assignments);
+
+ foreach ($user_ids as $user_id) {
+ $this->assertEquals(count($distribution->getPeersOfRater($user_id)), $num_assignments);
+ }
+ }
+
+ /**
+ * Test if each peer is assigned to $num_assignments raters
+ */
+ public function testDistributionNumberOfRaters()
+ {
+ $user_ids = [10,20,30,40,50];
+ $num_assignments = 4;
+
+ $distribution = $this->getDistribution($user_ids, $num_assignments);
+
+ $peer_raters = [];
+ foreach ($user_ids as $user_id) {
+ foreach ($distribution->getPeersOfRater($user_id) as $peer) {
+ $peer_raters[$peer][$user_id] = $user_id;
+ }
+ }
+
+ $this->assertEquals(count($peer_raters), count($user_ids));
+
+ foreach ($peer_raters as $peer => $raters) {
+ $this->assertEquals(count($raters), $num_assignments);
+ }
+ }
+
+ /**
+ * Test if raters are not assigned as peers to themselves
+ */
+ public function testDistributionNoSelfAssignment()
+ {
+ $user_ids = [10,20,30,40,50];
+ $num_assignments = 4;
+
+ $distribution = $this->getDistribution($user_ids, $num_assignments);
+
+ foreach ($user_ids as $user_id) {
+ foreach ($distribution->getPeersOfRater($user_id) as $peer) {
+ $this->assertNotEquals($user_id, $peer);
+ }
+ }
+ }
+}
diff --git a/Modules/Exercise/test/bootstrap.php b/Modules/Exercise/test/bootstrap.php
new file mode 100644
index 000000000000..958a143d478a
--- /dev/null
+++ b/Modules/Exercise/test/bootstrap.php
@@ -0,0 +1,5 @@
+
+ */
+class ilModulesExerciseSuite extends TestSuite
+{
+ public static function suite()
+ {
+ $suite = new ilModulesExerciseSuite();
+
+ require_once("./Modules/Exercise/test/PeerReview/ExcPeerReviewTest.php");
+ $suite->addTestSuite("ExcPeerReviewTest");
+
+ return $suite;
+ }
+}
diff --git a/Modules/File/classes/Versions/class.ilFileVersionFormGUI.php b/Modules/File/classes/Versions/class.ilFileVersionFormGUI.php
index 1d17e79b8881..4fd6a18f75e7 100644
--- a/Modules/File/classes/Versions/class.ilFileVersionFormGUI.php
+++ b/Modules/File/classes/Versions/class.ilFileVersionFormGUI.php
@@ -93,7 +93,11 @@ private function initForm()
// File
if ($this->dnd) {
// File (D&D)
- $file = new ilFileStandardDropzoneInputGUI($this->lng->txt(self::F_FILE), self::F_FILE);
+ $file = new ilFileStandardDropzoneInputGUI(
+ ilFileVersionsGUI::CMD_DEFAULT,
+ $this->lng->txt(self::F_FILE),
+ self::F_FILE
+ );
$file->setRequired(true);
// $file->setUploadUrl($this->ctrl->getLinkTarget($this->calling_gui, ilFileVersionsGUI::C, "", true, true));
$file->setMaxFiles(1);
diff --git a/Modules/File/classes/class.ilFileXMLParser.php b/Modules/File/classes/class.ilFileXMLParser.php
index fa0711c616a4..d26ace102059 100644
--- a/Modules/File/classes/class.ilFileXMLParser.php
+++ b/Modules/File/classes/class.ilFileXMLParser.php
@@ -13,6 +13,9 @@
* @extends ilSaxParser
*/
+use ILIAS\Data\DataSize;
+use ILIAS\Filesystem\Util\LegacyPathHelper;
+
include_once './Services/Xml/classes/class.ilSaxParser.php';
include_once 'Modules/File/classes/class.ilFileException.php';
include_once 'Services/Utilities/classes/class.ilFileUtils.php';
@@ -334,12 +337,19 @@ public function handlerEndTag($a_xml_parser, $a_name)
}
}
- //$this->content = $content;
- // see #17211
-
if ($this->version == $this->file->getVersion()) {
- if (is_file($this->tmpFilename)) {
- $this->file->setFileSize(filesize($this->tmpFilename)); // strlen($this->content));
+ global $DIC;
+ $rel = LegacyPathHelper::createRelativePath($this->tmpFilename);
+ if ($DIC->filesystem()->temp()->has($rel)) {
+ $this->file->setFileSize($DIC->filesystem()->temp()->getSize($rel, DataSize::Byte)->getSize());
+ } else {
+ $array = $DIC->filesystem()->temp()->listContents(dirname($rel));
+ $first_file = reset($array);
+
+ if ($first_file instanceof \ILIAS\Filesystem\DTO\Metadata) {
+ $this->file->setFileSize($DIC->filesystem()->temp()->getSize($first_file->getPath(),
+ DataSize::Byte)->getSize());
+ }
}
// if no file type is given => lookup mime type
@@ -410,9 +420,15 @@ public function setFileContents()
foreach ($this->versions as $version) {
if (!file_exists($version["tmpFilename"])) {
- ilLoggerFactory::getLogger('file')->error(__METHOD__ . ' "' . $version["tmpFilename"] . '" file not found.');
-
- continue;
+ // try to get first file of dir
+ $files = scandir(dirname($version["tmpFilename"]));
+ $version["tmpFilename"] = rtrim(dirname($version["tmpFilename"]),
+ "/") . "/" . $files[2];// because [0] = "." [1] = ".."
+ if (!file_exists($version["tmpFilename"])) {
+ ilLoggerFactory::getLogger('file')->error(__METHOD__ . ' "' . ($version["tmpFilename"]) . '" file not found.');
+
+ continue;
+ }
}
if (filesize($version["tmpFilename"]) == 0) {
diff --git a/Modules/File/classes/class.ilObjFile.php b/Modules/File/classes/class.ilObjFile.php
index ae57fa2f215d..a7f9963f7a5b 100755
--- a/Modules/File/classes/class.ilObjFile.php
+++ b/Modules/File/classes/class.ilObjFile.php
@@ -889,7 +889,7 @@ public function sendFile($a_hist_entry_id = null)
return true;
}
- throw new FileNotFoundException("This file cannot be found in ILIAS or has been blocked due to security reasons.");
+ throw new FileNotFoundException($this->lng->txt('file_not_found_sec'));
}
diff --git a/Modules/File/classes/class.ilObjFileGUI.php b/Modules/File/classes/class.ilObjFileGUI.php
index 08740d381a9a..7328a2a03419 100755
--- a/Modules/File/classes/class.ilObjFileGUI.php
+++ b/Modules/File/classes/class.ilObjFileGUI.php
@@ -582,7 +582,11 @@ protected function initPropertiesForm($mode = "create")
}
if ($upload_possible) {
- $file = new ilFileStandardDropzoneInputGUI($this->lng->txt('obj_file'), 'file');
+ $file = new ilFileStandardDropzoneInputGUI(
+ 'cancel',
+ $this->lng->txt('obj_file'),
+ 'file'
+ );
$file->setRequired(false);
$form->addItem($file);
@@ -1026,7 +1030,7 @@ public function uploadFiles()
foreach ($DIC->upload()->getResults() as $result) {
if (!ilFileUtils::hasValidExtension($result->getName())) {
ilUtil::sendInfo(
- $this->lng->txt('file_upload_info_file_with_critical_unknown_extension_later_renamed_when_downloading'),
+ $this->lng->txt('file_upload_info_file_with_critical_extension'),
true
);
}
diff --git a/Modules/Forum/classes/class.ilForumExporter.php b/Modules/Forum/classes/class.ilForumExporter.php
index a98743d62357..26d604586e15 100644
--- a/Modules/Forum/classes/class.ilForumExporter.php
+++ b/Modules/Forum/classes/class.ilForumExporter.php
@@ -57,6 +57,13 @@ public function getXmlExportTailDependencies($a_entity, $a_target_release, $a_id
);
}
+ // news settings
+ $res[] = [
+ "component" => "Services/News",
+ "entity" => "news_settings",
+ "ids" => $a_ids
+ ];
+
return $res;
}
diff --git a/Modules/Forum/classes/class.ilForumPostDraft.php b/Modules/Forum/classes/class.ilForumPostDraft.php
index dec32ca4a8e1..512c2dbfd157 100644
--- a/Modules/Forum/classes/class.ilForumPostDraft.php
+++ b/Modules/Forum/classes/class.ilForumPostDraft.php
@@ -493,12 +493,7 @@ public function updateDraft()
array(
'post_subject' => array('text', $this->getPostSubject()),
'post_message' => array('clob', $this->getPostMessage()),
- 'notify' => array('integer', $this->getNotify()),
- 'post_notify' => array('integer', $this->getPostNotify()),
- 'post_update' => array('timestamp', date("Y-m-d H:i:s")),
- 'update_user_id' => array('integer', $this->getUpdateUserId()),
- 'post_user_alias' => array('text', $this->getPostUserAlias()),
- 'pos_display_usr_id' => array('integer', $this->getPostDisplayUserId())
+ 'post_user_alias' => array('text', $this->getPostUserAlias())
),
array('draft_id' => array('integer', $this->getDraftId()))
);
diff --git a/Modules/Forum/classes/class.ilObjForumAccess.php b/Modules/Forum/classes/class.ilObjForumAccess.php
index 02b0ff504404..88bddc73f9a5 100644
--- a/Modules/Forum/classes/class.ilObjForumAccess.php
+++ b/Modules/Forum/classes/class.ilObjForumAccess.php
@@ -132,6 +132,7 @@ public static function _lookupDiskUsage($a_obj_id)
*/
public static function prepareMessageForLists($text)
{
+ $text = str_replace(' ', ' ', $text);
$text = strip_tags($text);
$text = preg_replace('/\[(\/)?quote\]/', '', $text);
if (ilStr::strLen($text) > 40) {
diff --git a/Modules/Forum/classes/class.ilObjForumGUI.php b/Modules/Forum/classes/class.ilObjForumGUI.php
index dd2d6121906f..e0810466d928 100755
--- a/Modules/Forum/classes/class.ilObjForumGUI.php
+++ b/Modules/Forum/classes/class.ilObjForumGUI.php
@@ -211,7 +211,7 @@ private function isTopLevelReplyCommand() : bool
{
return in_array(
strtolower($this->ctrl->getCmd()),
- array_map('strtolower', array('createTopLevelPost', 'quoteTopLevelPost', 'saveTopLevelPost'))
+ array_map('strtolower', array('createTopLevelPost', 'saveTopLevelPost'))
);
}
@@ -225,7 +225,7 @@ public function executeCommand()
'performPostActivation',
'askForPostActivation', 'askForPostDeactivation',
'toggleThreadNotification', 'toggleThreadNotificationTab',
- 'toggleStickiness', 'cancelPost', 'savePost', 'saveTopLevelPost', 'createTopLevelPost', 'quoteTopLevelPost', 'quotePost', 'getQuotationHTMLAsynch',
+ 'toggleStickiness', 'cancelPost', 'savePost', 'saveTopLevelPost', 'createTopLevelPost', 'quotePost', 'getQuotationHTMLAsynch',
'autosaveDraftAsync', 'autosaveThreadDraftAsync',
'saveAsDraft', 'editDraft', 'updateDraft', 'deliverDraftZipFile', 'deliverZipFile', 'cancelDraft',
'deleteThreadDrafts',
@@ -1672,6 +1672,8 @@ private function initReplyEditForm()
/**
* @var $oFDForum ilFileDataForum
*/
+ $isReply = in_array($this->requestAction, ['showreply', 'ready_showreply']);
+ $isDraft = in_array($this->requestAction, ['publishDraft', 'editdraft']);
// init objects
$oForumObjects = $this->getForumObjects();
@@ -1704,9 +1706,9 @@ private function initReplyEditForm()
}
$this->ctrl->clearParameters($this);
- if (in_array($this->requestAction, ['showreply', 'ready_showreply'])) {
+ if ($isReply) {
$this->replyEditForm->setTitle($this->lng->txt('forums_your_reply'));
- } elseif (in_array($this->requestAction, ['showdraft', 'editdraft'])) {
+ } elseif ($isDraft) {
$this->replyEditForm->setTitle($this->lng->txt('forums_edit_draft'));
} else {
$this->replyEditForm->setTitle($this->lng->txt('forums_edit_post'));
@@ -1714,7 +1716,7 @@ private function initReplyEditForm()
if (
$this->isWritingWithPseudonymAllowed() &&
- in_array($this->requestAction, array('showreply', 'ready_showreply'))
+ in_array($this->requestAction, array('showreply', 'ready_showreply', 'editdraft'))
) {
$oAnonymousNameGUI = new ilTextInputGUI($this->lng->txt('forums_your_name'), 'alias');
$oAnonymousNameGUI->setMaxLength(64);
@@ -1734,9 +1736,7 @@ private function initReplyEditForm()
$this->replyEditForm->addItem($oSubjectGUI);
$oPostGUI = new ilTextAreaInputGUI(
- $this->requestAction == 'showreply' || $this->requestAction == 'ready_showreply' ?
- $this->lng->txt('forums_your_reply') :
- $this->lng->txt('forums_edit_post'),
+ $isReply ? $this->lng->txt('forums_your_reply') : $this->lng->txt('forums_edit_post'),
'message'
);
$oPostGUI->setRequired(true);
@@ -1745,11 +1745,20 @@ private function initReplyEditForm()
$oPostGUI->addPlugin('latex');
$oPostGUI->addButton('latex');
$oPostGUI->addButton('pastelatex');
- $oPostGUI->addPlugin('ilfrmquote');
- if (in_array($this->requestAction, ['showreply', 'showdraft'])) {
+ $quotingAllowed = (
+ !$this->isTopLevelReplyCommand() && (
+ ($isReply && $this->objCurrentPost->getDepth() >= 2) ||
+ (!$isDraft && !$isReply && $this->objCurrentPost->getDepth() > 2) ||
+ ($isDraft && $this->objCurrentPost->getDepth() >= 2)
+ )
+ );
+
+ if ($quotingAllowed) {
$oPostGUI->addButton('ilFrmQuoteAjaxCall');
+ $oPostGUI->addPlugin('ilfrmquote');
}
+
$oPostGUI->removePlugin('advlink');
$oPostGUI->setRTERootBlockElement('');
$oPostGUI->usePurifier(true);
@@ -1867,9 +1876,7 @@ private function initReplyEditForm()
}
if (strtolower($rtestring) != 'iltinymce' || !ilObjAdvancedEditing::_getRichTextEditorUserState()) {
- if ($this->isTopLevelReplyCommand()) {
- $this->replyEditForm->addCommandButton('quoteTopLevelPost', $this->lng->txt('forum_add_quote'));
- } else {
+ if ($quotingAllowed) {
$this->replyEditForm->addCommandButton('quotePost', $this->lng->txt('forum_add_quote'));
}
}
@@ -1885,6 +1892,8 @@ private function initReplyEditForm()
if ($this->requestAction == 'editdraft') {
$this->replyEditForm->addCommandButton('updateDraft', $this->lng->txt('save_message'));
+ } elseif ($this->isTopLevelReplyCommand()) {
+ $this->replyEditForm->addCommandButton('saveTopLevelDraft', $this->lng->txt('save_message'));
} else {
$this->replyEditForm->addCommandButton('saveAsDraft', $this->lng->txt('save_message'));
}
@@ -1940,15 +1949,6 @@ public function saveTopLevelPostObject()
return;
}
- /**
- *
- */
- public function quoteTopLevelPostObject()
- {
- $this->quotePostObject();
- return;
- }
-
public function publishSelectedDraftObject()
{
if (isset($_GET['draft_id']) && (int) $_GET['draft_id'] > 0) {
@@ -1989,7 +1989,8 @@ public function publishDraftObject($use_replyform = true)
if ($use_replyform) {
$oReplyEditForm = $this->getReplyEditForm();
- if (!$oReplyEditForm->checkInput() && !$draft_obj instanceof ilForumPostDraft) {
+ // @Nadia: Why do we need this additional check here (with this check mandatory fields are NOT checked, so I suggest to remove it): && !$draft_obj instanceof ilForumPostDraft
+ if (!$oReplyEditForm->checkInput()) {
$oReplyEditForm->setValuesByPost();
return $this->viewThreadObject();
}
@@ -2766,7 +2767,7 @@ public function viewThreadObject()
if (
$firstNodeInThread instanceof ilForumPost &&
- in_array($this->ctrl->getCmd(), array('createTopLevelPost', 'saveTopLevelPost', 'quoteTopLevelPost')) &&
+ in_array($this->ctrl->getCmd(), array('createTopLevelPost', 'saveTopLevelPost')) &&
!$this->objCurrentTopic->isClosed() &&
$this->access->checkAccess('add_reply', '', (int) $_GET['ref_id'])) {
// Important: Don't separate the following two lines (very fragile code ...)
@@ -2775,28 +2776,7 @@ public function viewThreadObject()
if ($this->ctrl->getCmd() == 'saveTopLevelPost') {
$form->setValuesByPost();
- } elseif ($this->ctrl->getCmd() == 'quoteTopLevelPost') {
- $authorinfo = new ilForumAuthorInformation(
- $firstNodeInThread->getPosAuthorId(),
- $firstNodeInThread->getDisplayUserId(),
- $firstNodeInThread->getUserAlias(),
- $firstNodeInThread->getImportName()
- );
-
- $form->setValuesByPost();
- $form->getItemByPostVar('message')->setValue(
- ilRTE::_replaceMediaObjectImageSrc(
- $frm->prepareText($firstNodeInThread->getMessage(), 1, $authorinfo->getAuthorName()) . "\n" . $form->getInput('message'),
- 1
- )
- );
}
- $this->ctrl->setParameter($this, 'pos_pk', $firstNodeInThread->getId());
- $this->ctrl->setParameter($this, 'thr_pk', $firstNodeInThread->getThreadId());
- $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
- $jsTpl->setVariable('IL_FRM_QUOTE_CALLBACK_SRC', $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true));
- $this->ctrl->clearParameters($this);
- $this->tpl->setVariable('BOTTOM_FORM_ADDITIONAL_JS', $jsTpl->get());
$this->tpl->setVariable('BOTTOM_FORM', $form->getHTML());
}
} else {
@@ -4948,6 +4928,16 @@ private function renderPostingForm(ilForum $frm, ilForumPost $node, string $acti
'del_file' => array()
));
}
+
+ $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getParentId());
+ $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
+ $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
+ $jsTpl->setVariable(
+ 'IL_FRM_QUOTE_CALLBACK_SRC',
+ $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
+ );
+ $this->ctrl->clearParameters($this);
+ $this->tpl->setVariable('FORM_ADDITIONAL_JS', $jsTpl->get());
break;
case 'editdraft':
@@ -4976,6 +4966,17 @@ private function renderPostingForm(ilForum $frm, ilForumPost $node, string $acti
));
}
}
+
+ $this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
+ $this->ctrl->setParameter($this, 'thr_pk', $this->objCurrentPost->getThreadId());
+
+ $jsTpl = new ilTemplate('tpl.forum_post_quoation_ajax_handler.html', true, true, 'Modules/Forum');
+ $jsTpl->setVariable(
+ 'IL_FRM_QUOTE_CALLBACK_SRC',
+ $this->ctrl->getLinkTarget($this, 'getQuotationHTMLAsynch', '', true)
+ );
+ $this->ctrl->clearParameters($this);
+ $this->tpl->setVariable('FORM_ADDITIONAL_JS', $jsTpl->get());
break;
}
$this->ctrl->setParameter($this, 'pos_pk', $this->objCurrentPost->getId());
diff --git a/Modules/Glossary/classes/class.ilGlossaryDataSet.php b/Modules/Glossary/classes/class.ilGlossaryDataSet.php
index 16387df5a730..438179462a9f 100644
--- a/Modules/Glossary/classes/class.ilGlossaryDataSet.php
+++ b/Modules/Glossary/classes/class.ilGlossaryDataSet.php
@@ -11,6 +11,7 @@
* - glo_term: data from glossary_term
* - glo_definition: data from glossary_definition
* - glo_advmd_col_order: ordering md fields
+ * - glo_auto_glossaries: automatically linked glossaries
*
* @author Alex Killing
* @version $Id$
@@ -42,7 +43,7 @@ public function __construct()
*/
public function getSupportedVersions()
{
- return array("5.1.0");
+ return array("5.1.0", "5.4.0");
}
/**
@@ -68,6 +69,7 @@ protected function getTypes($a_entity, $a_version)
if ($a_entity == "glo") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
return array(
"Id" => "integer",
"Title" => "text",
@@ -84,6 +86,7 @@ protected function getTypes($a_entity, $a_version)
if ($a_entity == "glo_term") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
return array(
"Id" => "integer",
"GloId" => "integer",
@@ -97,6 +100,7 @@ protected function getTypes($a_entity, $a_version)
if ($a_entity == "glo_definition") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
return array(
"Id" => "integer",
"TermId" => "integer",
@@ -110,6 +114,7 @@ protected function getTypes($a_entity, $a_version)
if ($a_entity == "glo_advmd_col_order") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
return array(
"GloId" => "integer",
"FieldId" => "text",
@@ -117,6 +122,16 @@ protected function getTypes($a_entity, $a_version)
);
}
}
+
+ if ($a_entity == "glo_auto_glossaries") {
+ switch ($a_version) {
+ case "5.4.0":
+ return array(
+ "GloId" => "integer",
+ "AutoGloId" => "text"
+ );
+ }
+ }
}
/**
@@ -136,6 +151,7 @@ public function readData($a_entity, $a_version, $a_ids, $a_field = "")
if ($a_entity == "glo") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
$this->getDirectDataFromQuery("SELECT o.title, o.description, g.id, g.virtual, pres_mode, snippet_length, show_tax, glo_menu_active" .
" FROM glossary g JOIN object_data o " .
" ON (g.id = o.obj_id) " .
@@ -147,17 +163,35 @@ public function readData($a_entity, $a_version, $a_ids, $a_field = "")
if ($a_entity == "glo_term") {
switch ($a_version) {
case "5.1.0":
- // todo: how does import id needs to be set?
$this->getDirectDataFromQuery("SELECT id, glo_id, term, language" .
" FROM glossary_term " .
" WHERE " . $ilDB->in("glo_id", $a_ids, false, "integer"));
break;
+
+ case "5.4.0":
+ $this->getDirectDataFromQuery("SELECT id, glo_id, term, language" .
+ " FROM glossary_term " .
+ " WHERE " . $ilDB->in("glo_id", $a_ids, false, "integer"));
+
+ $set = $ilDB->query("SELECT r.term_id, r.glo_id, t.term, t.language " .
+ "FROM glo_term_reference r JOIN glossary_term t ON (r.term_id = t.id) " .
+ " WHERE " . $ilDB->in("r.glo_id", $a_ids, false, "integer"));
+ while ($rec = $ilDB->fetchAssoc($set)) {
+ $this->data[] = [
+ "Id" => $rec["term_id"],
+ "GloId" => $rec["glo_id"],
+ "Term" => $rec["term"],
+ "Language" => $rec["language"],
+ ];
+ }
+ break;
}
}
if ($a_entity == "glo_definition") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
$this->getDirectDataFromQuery("SELECT id, term_id, short_text, nr, short_text_dirty" .
" FROM glossary_definition " .
" WHERE " . $ilDB->in("term_id", $a_ids, false, "integer"));
@@ -168,12 +202,29 @@ public function readData($a_entity, $a_version, $a_ids, $a_field = "")
if ($a_entity == "glo_advmd_col_order") {
switch ($a_version) {
case "5.1.0":
+ case "5.4.0":
$this->getDirectDataFromQuery("SELECT glo_id, field_id, order_nr" .
" FROM glo_advmd_col_order " .
" WHERE " . $ilDB->in("glo_id", $a_ids, false, "integer"));
break;
}
}
+
+ if ($a_entity == "glo_auto_glossaries") {
+ switch ($a_version) {
+ case "5.4.0":
+ $set = $ilDB->query("SELECT * FROM glo_glossaries " .
+ " WHERE " . $ilDB->in("id", $a_ids, false, "integer"));
+ $this->data = [];
+ while ($rec = $ilDB->fetchAssoc($set)) {
+ $this->data[] = [
+ "GloId" => $rec["id"],
+ "AutoGloId" => "il_" . IL_INST_ID . "_glo_" . $rec["glo_id"]
+ ];
+ }
+ break;
+ }
+ }
}
/**
@@ -185,7 +236,8 @@ protected function getDependencies($a_entity, $a_version, $a_rec, $a_ids)
case "glo":
return array(
"glo_term" => array("ids" => $a_rec["Id"]),
- "glo_advmd_col_order" => array("ids" => $a_rec["Id"])
+ "glo_advmd_col_order" => array("ids" => $a_rec["Id"]),
+ "glo_auto_glossaries" => array("ids" => $a_rec["Id"])
);
case "glo_term":
@@ -224,6 +276,9 @@ public function importRecord($a_entity, $a_types, $a_rec, $a_mapping, $a_schema_
$newObj->setSnippetLength($a_rec["SnippetLength"]);
$newObj->setActiveGlossaryMenu($a_rec["GloMenuActive"]);
$newObj->setShowTaxonomy($a_rec["ShowTax"]);
+ if ($this->getCurrentInstallationId() > 0) {
+ $newObj->setImportId("il_" . $this->getCurrentInstallationId() . "_glo_" . $a_rec["Id"]);
+ }
$newObj->update(true);
$this->current_obj = $newObj;
@@ -324,6 +379,16 @@ public function importRecord($a_entity, $a_types, $a_rec, $a_mapping, $a_schema_
// processing
$a_mapping->addMapping("Modules/Glossary", "advmd_col_order", $a_rec["GloId"] . ":" . $a_rec["FieldId"], $a_rec["OrderNr"]);
break;
+
+ case "glo_auto_glossaries":
+ $auto_glo_id = ilObject::_lookupObjIdByImportId($a_rec["AutoGloId"]);
+ $glo_id = (int) $a_mapping->getMapping("Modules/Glossary", "glo", $a_rec["GloId"]);
+ if ($glo_id > 0 && $auto_glo_id > 0 && ilObject::_lookupType($auto_glo_id) == "glo") {
+ $glo = new ilObjGlossary($glo_id, false);
+ $glo->addAutoGlossary($auto_glo_id);
+ $glo->updateAutoGlossaries();
+ }
+ break;
}
}
}
diff --git a/Modules/Glossary/classes/class.ilGlossaryExporter.php b/Modules/Glossary/classes/class.ilGlossaryExporter.php
index 4e4cf1f02765..1be0c96b26b8 100644
--- a/Modules/Glossary/classes/class.ilGlossaryExporter.php
+++ b/Modules/Glossary/classes/class.ilGlossaryExporter.php
@@ -52,7 +52,19 @@ public function getXmlExportTailDependencies($a_entity, $a_target_release, $a_id
// workaround for #0023923
$all_refs = ilObject::_getAllReferences($id);
$ref_id = current($all_refs);
- $terms = ilGlossaryTerm::getTermList($ref_id);
+
+ // see #29014, we include referenced terms in the export as well
+ $terms = ilGlossaryTerm::getTermList(
+ $ref_id,
+ "",
+ "",
+ "",
+ 0,
+ false,
+ null,
+ true
+ );
+
foreach ($terms as $t) {
$defs = ilGlossaryDefinition::getDefinitionList($t["id"]);
foreach ($defs as $d) {
@@ -176,8 +188,14 @@ public function getXmlRepresentation($a_entity, $a_schema_version, $a_id)
public function getValidSchemaVersions($a_entity)
{
return array(
+ "5.4.0" => array(
+ "namespace" => "http://www.ilias.de/Modules/Glossary/htlm/5_4",
+ "xsd_file" => "ilias_glo_5_4.xsd",
+ "uses_dataset" => true,
+ "min" => "5.4.0",
+ "max" => ""),
"5.1.0" => array(
- "namespace" => "http://www.ilias.de/Modules/Glossary/htlm/4_1",
+ "namespace" => "http://www.ilias.de/Modules/Glossary/htlm/5_1",
"xsd_file" => "ilias_glo_5_1.xsd",
"uses_dataset" => true,
"min" => "5.1.0",
diff --git a/Modules/Glossary/classes/class.ilObjGlossary.php b/Modules/Glossary/classes/class.ilObjGlossary.php
index 83127ba87137..241b5cf14889 100755
--- a/Modules/Glossary/classes/class.ilObjGlossary.php
+++ b/Modules/Glossary/classes/class.ilObjGlossary.php
@@ -368,15 +368,24 @@ public function setAutoGlossaries($a_val)
$this->auto_glossaries = array();
if (is_array($a_val)) {
foreach ($a_val as $v) {
- $v = (int) $v;
- if ($v > 0 && ilObject::_lookupType($v) == "glo" &&
- !in_array($v, $this->auto_glossaries)) {
- $this->auto_glossaries[] = $v;
- }
+ $this->addAutoGlossary($v);
}
}
}
+ /**
+ * Add auto glossary
+ * @param int $glo_id
+ */
+ public function addAutoGlossary($glo_id)
+ {
+ $glo_id = (int) $glo_id;
+ if ($glo_id > 0 && ilObject::_lookupType($glo_id) == "glo" &&
+ !in_array($glo_id, $this->auto_glossaries)) {
+ $this->auto_glossaries[] = $glo_id;
+ }
+ }
+
/**
* Get auto glossaries
*
diff --git a/Modules/HTMLLearningModule/classes/class.ilObjFileBasedLMGUI.php b/Modules/HTMLLearningModule/classes/class.ilObjFileBasedLMGUI.php
index 653ac1c68145..c27c96c6491f 100755
--- a/Modules/HTMLLearningModule/classes/class.ilObjFileBasedLMGUI.php
+++ b/Modules/HTMLLearningModule/classes/class.ilObjFileBasedLMGUI.php
@@ -343,7 +343,7 @@ public function getSettingsFormValues()
$values["startfile"] = $startfile;
$values["title"] = $this->object->getTitle();
- $values["desc"] = $this->object->getDescription();
+ $values["desc"] = $this->object->getLongDescription();
//$values["lic"] = $this->object->getShowLicense();
$this->form->setValuesByArray($values);
diff --git a/Modules/LearningModule/classes/class.ilLMPresentationGUI.php b/Modules/LearningModule/classes/class.ilLMPresentationGUI.php
index 7eec66237631..2ceec1e8e8b4 100755
--- a/Modules/LearningModule/classes/class.ilLMPresentationGUI.php
+++ b/Modules/LearningModule/classes/class.ilLMPresentationGUI.php
@@ -4,6 +4,8 @@
require_once("./Modules/LearningModule/classes/class.ilObjLearningModule.php");
require_once("./Services/MainMenu/classes/class.ilMainMenuGUI.php");
require_once("./Services/Style/Content/classes/class.ilObjStyleSheet.php");
+require_once 'Modules/LearningModule/classes/class.ilLMPageObject.php';
+
/**
* Class ilLMPresentationGUI
@@ -170,6 +172,7 @@ public function executeCommand()
$lng = $this->lng;
$ilCtrl = $this->ctrl;
$ilUser = $this->user;
+ $ilErr = $this->error;
// check read permission and parent conditions
// todo: replace all this by ilAccess call
@@ -807,7 +810,6 @@ public function ilTOC($a_get_explorer = false)
$exp->setOfflineMode(true);
}
if (!$exp->handleCommand()) {
-
if ($a_get_explorer) {
return $exp;
} else {
diff --git a/Modules/LearningModule/classes/class.ilLMTracker.php b/Modules/LearningModule/classes/class.ilLMTracker.php
index 84cceef44024..52ec6ed14194 100644
--- a/Modules/LearningModule/classes/class.ilLMTracker.php
+++ b/Modules/LearningModule/classes/class.ilLMTracker.php
@@ -182,25 +182,20 @@ public function trackAccess($a_page_id, $user_id)
*/
public function trackLastPageAccess($usr_id, $lm_id, $obj_id)
{
- $ilDB = $this->db;
-
- // first check if an entry for this user and this lm already exist, when so, delete
- $q = "DELETE FROM lo_access " .
- "WHERE usr_id = " . $ilDB->quote((int) $usr_id, "integer") . " " .
- "AND lm_id = " . $ilDB->quote((int) $lm_id, "integer");
- $ilDB->manipulate($q);
-
$title = "";
-
- $q = "INSERT INTO lo_access " .
- "(timestamp,usr_id,lm_id,obj_id,lm_title) " .
- "VALUES " .
- "(" . $ilDB->now() . "," .
- $ilDB->quote((int) $usr_id, "integer") . "," .
- $ilDB->quote((int) $lm_id, "integer") . "," .
- $ilDB->quote((int) $obj_id, "integer") . "," .
- $ilDB->quote($title, "text") . ")";
- $ilDB->manipulate($q);
+ $db = $this->db;
+ $db->replace(
+ "lo_access",
+ [
+ "usr_id" => ["integer", $usr_id],
+ "lm_id" => ["integer", $lm_id]
+ ],
+ [
+ "timestamp" => ["timestamp", ilUtil::now()],
+ "obj_id" => ["integer", $obj_id],
+ "lm_title" => ["text", $title]
+ ]
+ );
}
diff --git a/Modules/LearningModule/classes/class.ilObjContentObjectGUI.php b/Modules/LearningModule/classes/class.ilObjContentObjectGUI.php
index f0875e192b29..9f0e83f349df 100755
--- a/Modules/LearningModule/classes/class.ilObjContentObjectGUI.php
+++ b/Modules/LearningModule/classes/class.ilObjContentObjectGUI.php
@@ -577,7 +577,7 @@ public function getPropertiesFormValues()
$values = array();
$title = $this->object->getTitle();
- $description = $this->object->getDescription();
+ $description = $this->object->getLongDescription();
include_once("./Services/Object/classes/class.ilObjectTranslation.php");
$ot = ilObjectTranslation::getInstance($this->object->getId());
if ($ot->getContentActivated()) {
diff --git a/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLParser.php b/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLParser.php
index 64b5f7cbb0e7..7006049a2612 100644
--- a/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLParser.php
+++ b/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLParser.php
@@ -89,15 +89,15 @@ public function handleEndTag($parser, string $name)
$this->counter++;
break;
case "abstract":
- $this->settings["abstract"] = trim($this->cdata);
+ $this->settings["abstract"] = base64_decode(trim($this->cdata));
break;
case "extro":
- $this->settings["extro"] = trim($this->cdata);
+ $this->settings["extro"] = base64_decode(trim($this->cdata));
break;
case "abstract_img":
$this->settings["abstract_img"] = trim($this->cdata);
break;
- case "extor_img":
+ case "extro_img":
$this->settings["extro_img"] = trim($this->cdata);
break;
case "abstract_img_data":
diff --git a/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLWriter.php b/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLWriter.php
index f49f75081f0e..9b3c59b62ef2 100644
--- a/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLWriter.php
+++ b/Modules/LearningSequence/classes/Xml/class.ilLearningSequenceXMLWriter.php
@@ -109,8 +109,8 @@ protected function writeSettings()
$abstract_img = $this->settings->getAbstractImage();
$extro_img = $this->settings->getExtroImage();
- $this->xmlElement("abstract", null, $this->settings->getAbstract());
- $this->xmlElement("extro", null, $this->settings->getExtro());
+ $this->xmlElement("abstract", null, base64_encode($this->settings->getAbstract()));
+ $this->xmlElement("extro", null, base64_encode($this->settings->getExtro()));
$this->xmlElement("members_gallery", null, $this->settings->getMembersGallery());
$this->xmlElement("abstract_img", null, $abstract_img);
$this->xmlElement("extro_img", null, $extro_img);
diff --git a/Modules/MediaPool/classes/class.ilMediaPoolPageUsagesTableGUI.php b/Modules/MediaPool/classes/class.ilMediaPoolPageUsagesTableGUI.php
index 840d745a4471..f67fe5fbf90a 100644
--- a/Modules/MediaPool/classes/class.ilMediaPoolPageUsagesTableGUI.php
+++ b/Modules/MediaPool/classes/class.ilMediaPoolPageUsagesTableGUI.php
@@ -67,7 +67,7 @@ public function getItems()
$page_obj = ilPageObjectFactory::getInstance($us_arr[0], $usage["id"]);
$usage["page"] = $page_obj;
$repo_tree = $this->repo_tree;
- $ref_ids = array_filter(ilObject::_getAllReferences($page_obj->getRepoObjId()), function($ref_id) use ($repo_tree) {
+ $ref_ids = array_filter(ilObject::_getAllReferences($page_obj->getRepoObjId()), function ($ref_id) use ($repo_tree) {
return $repo_tree->isInTree($ref_id);
});
$usage["ref_ids"] = $ref_ids;
@@ -182,7 +182,7 @@ protected function fillRow($a_set)
}
if ($usage["trash"]) {
- $item["obj_title"].= " (".$lng->txt("trash").")";
+ $item["obj_title"] .= " (" . $lng->txt("trash") . ")";
}
break;
@@ -220,7 +220,7 @@ protected function fillRow($a_set)
}
$ver .= $sep . $version["hist_nr"];
if ($version["lang"] != "") {
- $ver.= "/".$version["lang"];
+ $ver .= "/" . $version["lang"];
}
$sep = ", ";
}
diff --git a/Modules/MediaPool/classes/class.ilObjMediaPoolGUI.php b/Modules/MediaPool/classes/class.ilObjMediaPoolGUI.php
index a6eaf7f2c8a2..157f39029e2e 100755
--- a/Modules/MediaPool/classes/class.ilObjMediaPoolGUI.php
+++ b/Modules/MediaPool/classes/class.ilObjMediaPoolGUI.php
@@ -2011,7 +2011,11 @@ public function initBulkUploadForm()
$form->setFormAction($ctrl->getFormAction($this));
$form->setPreventDoubleSubmission(false);
- $item = new ilFileStandardDropzoneInputGUI($lng->txt("mep_media_files"), 'media_files');
+ $item = new ilFileStandardDropzoneInputGUI(
+ 'cancel',
+ $lng->txt("mep_media_files"),
+ 'media_files'
+ );
$item->setUploadUrl($ctrl->getLinkTarget($this, "performBulkUpload", "", true, true));
$item->setMaxFiles(20);
$form->addItem($item);
diff --git a/Modules/OrgUnit/classes/Positions/class.ilOrgUnitPositionGUI.php b/Modules/OrgUnit/classes/Positions/class.ilOrgUnitPositionGUI.php
index eebe727e1f8e..5efde267fe82 100644
--- a/Modules/OrgUnit/classes/Positions/class.ilOrgUnitPositionGUI.php
+++ b/Modules/OrgUnit/classes/Positions/class.ilOrgUnitPositionGUI.php
@@ -244,7 +244,7 @@ public function addSubTabs()
$this->ctrl()->saveParameter($this, 'arid');
$this->ctrl()->saveParameterByClass(ilOrgUnitDefaultPermissionGUI::class, 'arid');
$this->pushSubTab(self::SUBTAB_SETTINGS, $this->ctrl()
- ->getLinkTarget($this, self::CMD_INDEX));
+ ->getLinkTarget($this, self::CMD_EDIT));
$this->pushSubTab(self::SUBTAB_PERMISSIONS, $this->ctrl()
->getLinkTargetByClass(ilOrgUnitDefaultPermissionGUI::class, self::CMD_INDEX));
}
diff --git a/Modules/OrgUnit/classes/class.ilObjOrgUnit.php b/Modules/OrgUnit/classes/class.ilObjOrgUnit.php
index 81826be39326..cae5449f074a 100644
--- a/Modules/OrgUnit/classes/class.ilObjOrgUnit.php
+++ b/Modules/OrgUnit/classes/class.ilObjOrgUnit.php
@@ -493,15 +493,6 @@ public function delete()
$ilDB = $DIC['ilDB'];
$ilAppEventHandler = $DIC['ilAppEventHandler'];
- //Delete all Childs
- foreach (ilObjOrgUnitTree::_getInstance()->getAllChildren($this->ref_id) as $child_ref_id) {
- if (!ilObjOrgUnit::_exists($child_ref_id, true) || $this->ref_id == $child_ref_id) {
- continue; //already deleted || the current org_unit
- }
- $org_unit = new ilObjOrgUnit($child_ref_id);
- $org_unit->delete();
- }
-
// always call parent delete function first!!
if (!parent::delete()) {
return false;
diff --git a/Modules/OrgUnit/classes/class.ilObjOrgUnitGUI.php b/Modules/OrgUnit/classes/class.ilObjOrgUnitGUI.php
index 22dc5d172faa..265cefe7c552 100644
--- a/Modules/OrgUnit/classes/class.ilObjOrgUnitGUI.php
+++ b/Modules/OrgUnit/classes/class.ilObjOrgUnitGUI.php
@@ -102,7 +102,11 @@ public function __construct()
$this->tpl->addCss('./Modules/OrgUnit/templates/default/orgu.css');
}
-
+ /**
+ * @throws ilCtrlException
+ * @throws ilException
+ * @throws ilRepositoryException
+ */
public function executeCommand()
{
$cmd = $this->ctrl->getCmd();
@@ -741,17 +745,18 @@ public function &__initTableGUI()
return parent::__initTableGUI();
}
-
/**
* confirmed deletion of org units -> org units are deleted immediately, without putting them to the trash
+ * @throws ilRepositoryException
*/
public function confirmedDeleteObject()
{
- if (count($_POST['id']) > 0) {
- foreach ($_POST['id'] as $ref_id) {
- $il_obj_orgunit = new ilObjOrgUnit($ref_id);
- $il_obj_orgunit->delete();
- }
+ global $DIC;
+
+ $ids = filter_input(INPUT_POST, 'id', FILTER_DEFAULT, FILTER_REQUIRE_ARRAY);
+ if (count($ids) > 0) {
+ ilRepUtil::removeObjectsFromSystem($ids);
+ ilUtil::sendSuccess($DIC->language()->txt("info_deleted"), true);
}
$this->ctrl->returnToParent($this);
}
@@ -771,7 +776,7 @@ public function deleteObject($a_error = false)
$arr_ref_ids = [];
//Delete via Manage (more than one)
- if (count($_POST['id']) > 0) {
+ if (is_array($_POST['id']) && count($_POST['id']) > 0) {
$arr_ref_ids = $_POST['id'];
} elseif ($_GET['item_ref_id'] > 0) {
$arr_ref_ids = [$_GET['item_ref_id']];
diff --git a/Modules/Poll/classes/class.ilObjPoll.php b/Modules/Poll/classes/class.ilObjPoll.php
index 7bf1419e5a78..112614c79010 100644
--- a/Modules/Poll/classes/class.ilObjPoll.php
+++ b/Modules/Poll/classes/class.ilObjPoll.php
@@ -479,7 +479,6 @@ public function uploadImage(array $a_upload, $a_clone = false)
} else {
$success = copy($a_upload["tmp_name"], $path . $original);
}
-
if ($success) {
chmod($path . $original, 0770);
@@ -488,9 +487,19 @@ public function uploadImage(array $a_upload, $a_clone = false)
$original_file = ilUtil::escapeShellArg($path . $original);
$thumb_file = ilUtil::escapeShellArg($path . $thumb);
$processed_file = ilUtil::escapeShellArg($path . $processed);
- ilUtil::execConvert($original_file . "[0] -geometry \"100x100>\" -quality 100 PNG:" . $thumb_file);
- ilUtil::execConvert($original_file . "[0] -geometry \"" . self::getImageSize() . ">\" -quality 100 PNG:" . $processed_file);
-
+
+ // -geometry "100x100>" is escaped by -geometry "100x100\>"
+ // re-replace "\>" with ">"
+ $convert_100 = $original_file . "[0] -geometry \"100x100>\" -quality 100 PNG:" . $thumb_file;
+ $escaped_convert_100 = ilUtil::escapeShellCmd($convert_100);
+ $escaped_convert_100 = str_replace('-geometry "100x100\>', '-geometry "100x100>', $escaped_convert_100);
+ ilUtil::execQuoted(PATH_TO_CONVERT, $escaped_convert_100);
+
+ $convert_300 = $original_file . "[0] -geometry \"" . self::getImageSize() . ">\" -quality 100 PNG:" . $processed_file;
+ $escaped_convert_300 = ilUtil::escapeShellCmd($convert_300);
+ $escaped_convert_300 = str_replace('-geometry "' . self::getImageSize() . '\>"', '-geometry "' . self::getImageSize() .'>"', $escaped_convert_300);
+ ilUtil::execQuoted(PATH_TO_CONVERT, $escaped_convert_300);
+
$this->setImage($processed);
return true;
}
diff --git a/Modules/Poll/classes/class.ilObjPollAccess.php b/Modules/Poll/classes/class.ilObjPollAccess.php
index 17f6cb6c195a..abaebc05c4f4 100644
--- a/Modules/Poll/classes/class.ilObjPollAccess.php
+++ b/Modules/Poll/classes/class.ilObjPollAccess.php
@@ -70,6 +70,13 @@ public function _checkAccess($a_cmd, $a_permission, $a_ref_id, $a_obj_id, $a_use
if ($a_user_id == "") {
$a_user_id = $ilUser->getId();
}
+
+ if (
+ $a_cmd == 'preview' &&
+ $a_permission == 'read'
+ ) {
+ return false;
+ }
// check "global" online switch
if (!self::_lookupOnline($a_obj_id) &&
diff --git a/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php b/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php
index c23496375169..ec9369b8edaf 100644
--- a/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php
+++ b/Modules/Portfolio/classes/class.ilObjPortfolioBaseGUI.php
@@ -30,6 +30,21 @@ abstract class ilObjPortfolioBaseGUI extends ilObject2GUI
protected $perma_link; // [string]
protected $page_id; // [int]
protected $page_mode; // [string] preview|edit
+
+ /**
+ * @var int
+ */
+ protected $requested_ppage;
+
+ /**
+ * @var int
+ */
+ protected $requested_user_page;
+
+ /**
+ * @var string
+ */
+ protected $requested_back_url = "";
public function __construct($a_id = 0, $a_id_type = self::REPOSITORY_NODE_ID, $a_parent_node_id = 0)
{
@@ -52,6 +67,20 @@ public function __construct($a_id = 0, $a_id_type = self::REPOSITORY_NODE_ID, $a
$this->lng->loadLanguageModule("prtf");
$this->lng->loadLanguageModule("user");
$this->lng->loadLanguageModule("obj");
+
+ $this->requested_ppage = (int) $_REQUEST["ppage"];
+ $this->requested_user_page = (int) $_REQUEST["user_page"];
+
+ // temp sanitization, should be done smarter in the future
+ $back = str_replace("&", ":::", $_REQUEST["back_url"]);
+ $back = preg_replace(
+ "/[^a-zA-Z0-9_\.\?=:\s]/",
+ "",
+ $back
+ );
+ $this->requested_back_url = str_replace(":::", "&", $back);
+
+ $this->ctrl->setParameterbyClass("ilobjportfoliogui", "back_url", rawurlencode($this->requested_back_url));
}
protected function addLocatorItems()
@@ -82,19 +111,19 @@ protected function addLocatorItems()
protected function determinePageCall()
{
// edit
- if (isset($_REQUEST["ppage"])) {
+ if ($this->requested_ppage > 0) {
if (!$this->checkPermissionBool("write")) {
$this->ctrl->redirect($this, "view");
}
- $this->page_id = $_REQUEST["ppage"];
+ $this->page_id = $this->requested_ppage;
$this->page_mode = "edit";
$this->ctrl->setParameter($this, "ppage", $this->page_id);
return true;
}
// preview
else {
- $this->page_id = $_REQUEST["user_page"];
+ $this->page_id = $this->requested_user_page;
$this->page_mode = "preview";
$this->ctrl->setParameter($this, "user_page", $this->page_id);
return false;
@@ -576,7 +605,7 @@ public function preview($a_return = false, $a_content = false, $a_show_notes = t
$this->tabs_gui->clearTargets();
$pages = ilPortfolioPage::getAllPortfolioPages($portfolio_id);
- $current_page = (int) $_GET["user_page"];
+ $current_page = $this->requested_user_page;
// validate current page
if ($pages && $current_page) {
@@ -608,8 +637,8 @@ public function preview($a_return = false, $a_content = false, $a_show_notes = t
$back_caption = "";
// public profile
- if ($_REQUEST["back_url"]) {
- $back = $_REQUEST["back_url"];
+ if ($this->requested_back_url != "") {
+ $back = $this->requested_back_url;
} elseif ($_GET["baseClass"] != "ilPublicUserProfileGUI" &&
$this->user_id && $this->user_id != ANONYMOUS_USER_ID) {
if (!$this->checkPermissionBool("write")) {
diff --git a/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php b/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php
index acb57eedb060..e5ec10a40150 100644
--- a/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php
+++ b/Modules/Portfolio/classes/class.ilObjPortfolioGUI.php
@@ -74,11 +74,6 @@ public function executeCommand()
$this->checkPermission("read");
- // goto link to portfolio page
- if ($_GET["gtp"]) {
- $_GET["user_page"] = $_GET["gtp"];
- }
-
$this->setTitleAndDescription();
$next_class = $this->ctrl->getNextClass($this);
@@ -1042,16 +1037,19 @@ protected function createFromTemplateDirect($title = "")
public static function _goto($a_target)
{
+ /** @var \ILIAS\DI\Container $DIC */
+ global $DIC;
+
+ $ctrl = $DIC->ctrl();
+
$id = explode("_", $a_target);
$_GET["baseClass"] = "ilsharedresourceGUI";
- $_GET["prt_id"] = $id[0];
+ $ctrl->setParameterByClass("ilobjportfoliogui", "prt_id", $id[0]);
if (sizeof($id) == 2) {
- $_GET["gtp"] = $id[1];
+ $ctrl->setParameterByClass("ilobjportfoliogui", "user_page", $id[1]);
}
-
- include("ilias.php");
- exit;
+ $ctrl->redirectByClass(["ilsharedresourceGUI", "ilobjportfoliogui"], "preview");
}
public function createPortfolioFromAssignment()
@@ -1492,12 +1490,12 @@ public function printView($a_pdf_export = false)
$page_content = '
' . $page_content . '
';
if (!$a_pdf_export) {
- $page_content .= '';
}
diff --git a/Modules/Portfolio/classes/class.ilPortfolioPageGUI.php b/Modules/Portfolio/classes/class.ilPortfolioPageGUI.php
index a46ea16bf3cc..c42a7a653e66 100644
--- a/Modules/Portfolio/classes/class.ilPortfolioPageGUI.php
+++ b/Modules/Portfolio/classes/class.ilPortfolioPageGUI.php
@@ -34,6 +34,11 @@ class ilPortfolioPageGUI extends ilPageObjectGUI
protected $export_material = array("js" => array(), "images" => array(), "files" => array());
protected static $initialized = 0;
+
+ /**
+ * @var int
+ */
+ protected $requested_ppage;
/**
* Constructor
@@ -77,6 +82,8 @@ public function __construct($a_portfolio_id, $a_id = 0, $a_old_nr = 0, $a_enable
ilObjStyleSheet::getPlaceHolderStylePath()
);
$tpl->parseCurrentBlock();
+
+ $this->requested_ppage = (int) $_GET["ppage"];
}
public function getParentType()
@@ -1170,7 +1177,7 @@ public function getViewPageLink()
$ctrl = $DIC->ctrl();
- $ctrl->setParameterByClass("ilobjportfoliogui", "user_page", $_GET["ppage"]);
+ $ctrl->setParameterByClass("ilobjportfoliogui", "user_page", $this->requested_ppage);
return $ctrl->getLinkTargetByClass("ilobjportfoliogui", "preview");
}
diff --git a/Modules/Portfolio/classes/class.ilPortfolioTemplatePageGUI.php b/Modules/Portfolio/classes/class.ilPortfolioTemplatePageGUI.php
index c1265ea55a67..24e07bdfd39a 100644
--- a/Modules/Portfolio/classes/class.ilPortfolioTemplatePageGUI.php
+++ b/Modules/Portfolio/classes/class.ilPortfolioTemplatePageGUI.php
@@ -88,7 +88,7 @@ public function getViewPageLink()
$ctrl = $DIC->ctrl();
- $ctrl->setParameterByClass("ilobjportfoliotemplategui", "user_page", $_GET["ppage"]);
+ $ctrl->setParameterByClass("ilobjportfoliotemplategui", "user_page", $this->requested_ppage);
return $ctrl->getLinkTargetByClass("ilobjportfoliotemplategui", "preview");
}
diff --git a/Modules/RootFolder/classes/class.ilObjRootFolderGUI.php b/Modules/RootFolder/classes/class.ilObjRootFolderGUI.php
index 55a81f2d6a0c..e6e799d07bcb 100755
--- a/Modules/RootFolder/classes/class.ilObjRootFolderGUI.php
+++ b/Modules/RootFolder/classes/class.ilObjRootFolderGUI.php
@@ -182,9 +182,9 @@ public function executeCommand()
if ($cmd == "infoScreen") {
$this->checkPermission("visible");
} else {
- try{
+ try {
$this->checkPermission("read");
- }catch (ilObjectException $exception){
+ } catch (ilObjectException $exception) {
$this->ctrl->redirectToURL("login.php?client_id=" . CLIENT_ID . "&cmd=force_login");
}
}
diff --git a/Modules/Scorm2004/classes/adlparser/SeqActivity.php b/Modules/Scorm2004/classes/adlparser/SeqActivity.php
index 7030a9e96e24..aa689b8bfe6e 100644
--- a/Modules/Scorm2004/classes/adlparser/SeqActivity.php
+++ b/Modules/Scorm2004/classes/adlparser/SeqActivity.php
@@ -55,7 +55,7 @@
define("TIMING_ONCE", "once");
define("TIMING_EACHNEW", "onEachNewAttempt");
define("TER_EXITALL", "_EXITALL_");
-
+ define("TIMING_NEVER", "never");
class SeqActivity
{
diff --git a/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php b/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php
index d0f9f3c73984..8222b78aab34 100755
--- a/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php
+++ b/Modules/Scorm2004/classes/class.ilObjSCORM2004LearningModule.php
@@ -754,6 +754,23 @@ public static function _ISODurationToCentisec($str)
}
return $aV[0] * 3155760000 + $aV[1] * 262980000 + $aV[2] * 8640000 + $aV[3] * 360000 + $aV[4] * 6000 + round($aV[5] * 100);
}
+
+ public static function getQuantityOfSCOs(int $a_slm_id)
+ {
+ global $DIC;
+ $val_set = $DIC->database()->queryF(
+ '
+ SELECT distinct(cp_node.cp_node_id) FROM cp_node,cp_resource,cp_item
+ WHERE cp_item.cp_node_id = cp_node.cp_node_id
+ AND cp_item.resourceid = cp_resource.id
+ AND scormtype = %s
+ AND nodename = %s
+ AND cp_node.slm_id = %s ',
+ array('text','text','integer'),
+ array('sco','item',$a_slm_id)
+ );
+ return $DIC->database()->numRows($val_set);
+ }
public function getCourseCompletionForUser($a_user)
{
@@ -774,7 +791,7 @@ public function getCourseCompletionForUser($a_user)
array('text','text','integer'),
array('sco','item',$this->getId())
);
-
+
while ($val_rec = $ilDB->fetchAssoc($val_set)) {
array_push($scos, $val_rec['cp_node_id']);
}
diff --git a/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php b/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php
index 4cb35707d1d2..6832f83d3967 100755
--- a/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php
+++ b/Modules/Scorm2004/classes/class.ilSCORM2004StoreData.php
@@ -35,8 +35,8 @@ public static function scormPlayerUnload($userId = null, $packageId, $time_from_
if ($data->total_time_sec != "") {
$total_time_sec = $data->total_time_sec;
$ilDB->manipulateF(
- 'UPDATE sahs_user
- SET total_time_sec = %s, last_visited = %s, hash_end =%s, last_access = %s
+ 'UPDATE sahs_user
+ SET total_time_sec = %s, last_visited = %s, hash_end =%s, last_access = %s
WHERE obj_id = %s AND user_id = %s',
array('integer', 'text', 'timestamp', 'timestamp', 'integer', 'integer'),
array($total_time_sec,$last_visited, $endDate, date('Y-m-d H:i:s'), $packageId, $userId)
@@ -53,8 +53,8 @@ public static function scormPlayerUnload($userId = null, $packageId, $time_from_
}
} else {
$ilDB->manipulateF(
- 'UPDATE sahs_user
- SET last_visited = %s, hash_end =%s, last_access = %s
+ 'UPDATE sahs_user
+ SET last_visited = %s, hash_end =%s, last_access = %s
WHERE obj_id = %s AND user_id = %s',
array('text', 'timestamp', 'timestamp', 'integer', 'integer'),
array($last_visited, $endDate, date('Y-m-d H:i:s'), $packageId, $userId)
@@ -102,7 +102,15 @@ public static function persistCMIData($userId = null, $packageId, $defaultLesson
ilSCORM2004StoreData::setGlobalObjectives($userId, $packageId, $data);
$new_global_status = $data->now_global_status;
$return["new_global_status"] = $new_global_status;
-
+
+ // mantis #30293
+ $score_scaled = $data->node[0][35];
+ if ($score_scaled != null) {
+ if (ilObjSCORM2004LearningModule::getQuantityOfSCOs($packageId) == 1) {
+ ilLTIAppEventListener::handleOutcomeWithoutLP($packageId, $userId, $score_scaled * 100);
+ }
+ }
+
ilSCORM2004StoreData::syncGlobalStatus($userId, $packageId, $data, $new_global_status, $time_from_lms);
$ilLog->write("SCORM: return of persistCMIData: " . json_encode($return));
@@ -249,8 +257,8 @@ public static function setCMIData($userId, $packageId, $data, $getComments, $get
if ($i_set > 3) {
$i_set -= 4;
if ($getInteractions) {
- $q = 'DELETE FROM cmi_correct_response
- WHERE cmi_interaction_id IN (
+ $q = 'DELETE FROM cmi_correct_response
+ WHERE cmi_interaction_id IN (
SELECT cmi_interaction.cmi_interaction_id FROM cmi_interaction WHERE cmi_interaction.cmi_node_id = %s)';
$ilDB->manipulateF($q, array('integer'), array($cmi_node_id));
}
@@ -491,10 +499,10 @@ public static function writeGObjective($g_data, $user, $package)
$pkg_id = $package;
$res = $ilDB->queryF(
- '
- SELECT user_id FROM cmi_gobjective
- WHERE objective_id =%s
- AND user_id = %s
+ '
+ SELECT user_id FROM cmi_gobjective
+ WHERE objective_id =%s
+ AND user_id = %s
AND scope_id = %s',
array('text', 'integer', 'integer'),
array($obj, $dbuser, $pkg_id)
@@ -502,9 +510,9 @@ public static function writeGObjective($g_data, $user, $package)
$ilLog->write("SCORM2004 Count is: " . $ilDB->numRows($res));
if (!$ilDB->numRows($res)) {
$ilDB->manipulateF(
- '
- INSERT INTO cmi_gobjective
- (user_id, status, scope_id, measure, satisfied, objective_id)
+ '
+ INSERT INTO cmi_gobjective
+ (user_id, status, scope_id, measure, satisfied, objective_id)
VALUES (%s, %s, %s, %s, %s, %s)',
array('integer', 'text', 'integer', 'text', 'text', 'text'),
array($dbuser, $completed, $pkg_id, $measure, $satisfied, $obj)
@@ -512,13 +520,13 @@ public static function writeGObjective($g_data, $user, $package)
$ilLog->write("SCORM2004 cmi_gobjective Insert status=" . $completed . " scope_id=" . $pkg_id . " measure=" . $measure . " satisfied=" . $satisfied . " objective_id=" . $obj);
} else {
$ilDB->manipulateF(
- '
- UPDATE cmi_gobjective
- SET status = %s,
- measure = %s,
- satisfied = %s
- WHERE objective_id = %s
- AND user_id = %s
+ '
+ UPDATE cmi_gobjective
+ SET status = %s,
+ measure = %s,
+ satisfied = %s
+ WHERE objective_id = %s
+ AND user_id = %s
AND scope_id = %s',
array('text', 'text', 'text', 'text', 'integer', 'integer'),
array($completed, $measure, $satisfied, $obj, $dbuser, $pkg_id)
@@ -537,8 +545,8 @@ public static function writeGObjective($g_data, $user, $package)
//Get the scope for all the global objectives!!!
$res = $ilDB->queryF(
- "SELECT global_to_system
- FROM cp_package
+ "SELECT global_to_system
+ FROM cp_package
WHERE obj_id = %s",
array('text'),
array($package)
@@ -558,10 +566,10 @@ public static function writeGObjective($g_data, $user, $package)
if ($existing_key_template != "") {
//Get the ones that need to be updated in a single query
$res = $ilDB->queryF(
- "SELECT objective_id
- FROM cmi_gobjective
- WHERE user_id = %s
- AND scope_id = %s
+ "SELECT objective_id
+ FROM cmi_gobjective
+ WHERE user_id = %s
+ AND scope_id = %s
AND objective_id IN ($existing_key_template)",
array('integer', 'integer'),
array($dbuser, $scope_id)
@@ -575,16 +583,16 @@ public static function writeGObjective($g_data, $user, $package)
foreach ($rows_to_insert as $obj_id => $vals) {
if (in_array($obj_id, $existing_keys)) {
$ilDB->manipulateF(
- "UPDATE cmi_gobjective
- SET satisfied=%s,
- measure=%s,
- score_raw=%s,
- score_min=%s,
- score_max=%s,
- completion_status=%s,
- progress_measure=%s
- WHERE objective_id = %s
- AND user_id = %s
+ "UPDATE cmi_gobjective
+ SET satisfied=%s,
+ measure=%s,
+ score_raw=%s,
+ score_min=%s,
+ score_max=%s,
+ completion_status=%s,
+ progress_measure=%s
+ WHERE objective_id = %s
+ AND user_id = %s
AND scope_id = %s",
array('text','text', 'text', 'text', 'text', 'text',
'text', 'text', 'integer', 'integer'),
@@ -595,9 +603,9 @@ public static function writeGObjective($g_data, $user, $package)
);
} else {
$ilDB->manipulateF(
- "INSERT INTO cmi_gobjective
- (user_id, satisfied, measure, scope_id, status, objective_id,
- score_raw, score_min, score_max, progress_measure, completion_status)
+ "INSERT INTO cmi_gobjective
+ (user_id, satisfied, measure, scope_id, status, objective_id,
+ score_raw, score_min, score_max, progress_measure, completion_status)
VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
array('integer', 'text', 'text', 'integer', 'text', 'text',
'text', 'text', 'text', 'text', 'text'),
diff --git a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php
old mode 100644
new mode 100755
index 4814e8b3c544..9c8150783de7
--- a/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php
+++ b/Modules/Scorm2004/classes/class.ilSCORM2004TrackingItemsTableGUI.php
@@ -163,7 +163,9 @@ public function getItems()
{
$lng = $this->lng;
- $this->determineOffsetAndOrder();
+ $this->determineOffsetAndOrder(true);
+ $this->determineLimit();
+
$ilSCORM2004TrackingItems = new ilSCORM2004TrackingItems();
switch ($this->report) {
case "exportSelectedCore":
@@ -191,12 +193,12 @@ public function getItems()
$tr_data = $ilSCORM2004TrackingItems->exportSelectedSuccess($this->userSelected, $this->allowExportPrivacy, $this->getObjId(), $this->lmTitle);
break;
}
- $this->setMaxCount($tr_data["cnt"]);
+ // $this->setMaxCount($tr_data["cnt"]);
if (ilUtil::stripSlashes($this->getOrderField()) != "") {
include_once "Services/Utilities/classes/class.ilStr.php";
$tr_data = ilUtil::stableSortArray($tr_data, ilUtil::stripSlashes($this->getOrderField()), ilUtil::stripSlashes($this->getOrderDirection()));
}
-
+
$this->setData($tr_data);
}
protected function parseValue($id, $value, $type)
diff --git a/Modules/Scorm2004/scripts/buildrte/rte-min.js b/Modules/Scorm2004/scripts/buildrte/rte-min.js
index f64ddbe5784a..66521a0bb52f 100644
--- a/Modules/Scorm2004/scripts/buildrte/rte-min.js
+++ b/Modules/Scorm2004/scripts/buildrte/rte-min.js
@@ -1,4 +1,4 @@
-// Build: 2018118230830
+// Build: 2021417225813
function ADLAuxiliaryResource()
{}
@@ -2591,8 +2591,13 @@ if(async)
{xhttp.onreadystatechange=onStateChange;xhttp.send(data?String(data):'');}else
{xhttp.send(data?String(data):'');return onStateChange();}}
function sendJSONRequest(url,data,callback,user,password,headers)
-{if(typeof headers!=="object"){headers={};}
-headers['Accept']='text/javascript';headers['Accept-Charset']='UTF-8';var r=sendAndLoad(url,toJSONString(data),callback,user,password,headers);if(r.content){if(r.content.indexOf("login.php")>-1||r.content.indexOf("formlogin")>-1){var thref=window.location.href;thref=thref.substring(0,thref.indexOf('ilias.php'))+"Modules/Scorm2004/templates/default/session_timeout.html";window.location.href=thref;}}
+{function unloadChrome(){if(navigator.userAgent.indexOf("Chrom")>-1){if((typeof(document.getElementById("res"))!="undefined"&&typeof(document.getElementById("res").contentWindow)!="undefined"&&typeof(document.getElementById("res").contentWindow.event)!="undefined"&&(document.getElementById("res").contentWindow.event.type=="unload"||document.getElementById("res").contentWindow.event.type=="beforeunload"||document.getElementById("res").contentWindow.event.type=="pagehide"))||(typeof(window.event)!="undefined"&&(window.event.type=="unload"||window.event.type=="beforeunload"||window.event.type=="click"))||(typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1])!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow)!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event)!="undefined"&&(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="unload"||document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="beforeunload"))||(typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0])!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow)!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event)!="undefined"&&(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="unload"||document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="beforeunload"))||(typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1])!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow)!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event)!="undefined"&&(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"||document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"))||(typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0])!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1])!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow)!="undefined"&&typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event)!="undefined"&&(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"||document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"))){return true;}}
+return false;}
+if(typeof headers!=="object"){headers={};}
+headers['Accept']='text/javascript';headers['Accept-Charset']='UTF-8';if(url==this.config.store_url&&unloadChrome()){var r=sendAndLoad(url,toJSONString(data),true,user,password,headers);console.log("async request for chrome");try{windowOpenerLoc.reload();}catch(e){}
+return"1";}
+if(url==this.config.scorm_player_unload_url&&navigator.userAgent.indexOf("Chrom")>-1){navigator.sendBeacon(url,toJSONString(data));return"1";}
+var r=sendAndLoad(url,toJSONString(data),callback,user,password,headers);if(r.content){if(r.content.indexOf("login.php")>-1||r.content.indexOf("formlogin")>-1){var thref=window.location.href;thref=thref.substring(0,thref.indexOf('ilias.php'))+"Modules/Scorm2004/templates/default/session_timeout.html";window.location.href=thref;}}
if((r.status===200&&(/^text\/javascript;?.*/i).test(r.type))||r.status===0)
{return parseJSONString(r.content);}
else
@@ -2643,6 +2648,7 @@ var userInteraction=false;function launchTarget(target,isJump){if(userInteractio
onItemUndeliver();mlaunch=msequencer.navigateStr(target,isJump);if(mlaunch.mSeqNonContent==null){onItemDeliver(activities[mlaunch.mActivityID]);}else{loadPage(gConfig.specialpage_url+"&page="+mlaunch.mSeqNonContent);}}
function launchNavType(navType,isUserCurrentlyInteracting){if(!isUserCurrentlyInteracting&&userInteraction){userInteraction=false;return null;}
if(navType=='SuspendAll'){err=currentAPI.SetValueIntern("cmi.exit","suspend");activities[msequencer.mSeqTree.mCurActivity.mActivityID].exit="suspend";}
+if(navType==='ExitAll'||navType==='Exit'||navType==='SuspendAll'){onWindowUnload();}
onItemUndeliver();mlaunch=new ADLLaunch();if(navType==='Start'){mlaunch=msequencer.navigate(NAV_START);}
if(navType==='ResumeAll'){mlaunch=msequencer.navigate(NAV_RESUMEALL);}
if(navType==='Exit'){mlaunch=msequencer.navigate(NAV_EXIT);}
@@ -2960,7 +2966,7 @@ if(mObjStatus.mHasProgressMeasure)
obj="cmi.objectives."+idx+".completion_status";err=currentAPI.SetValueIntern(obj,mObjStatus.mCompletionStatus);}}}}
function syncCMIADLTree(){var mPRIMARY_OBJ_ID=null;var masteryStatus=null;var sessionTime=null;var entry=null;var normalScore=-1.0;var progressMeasure=null;var completionStatus=null;var SCOEntry=null;var suspended=false;SCOEntry=currentAPI.GetValueIntern("cmi.exit");completionStatus=currentAPI.GetValueIntern("cmi.completion_status");var completionSetBySCO=currentAPI.GetValueIntern("cmi.completion_status_SetBySco");if(completionStatus=="not attempted")completionStatus="incomplete";progressMeasure=currentAPI.GetValueIntern("cmi.progress_measure");if(progressMeasure==""||progressMeasure=="unknown")
{progressMeasure=null;}
-masteryStatus=currentAPI.GetValueIntern("cmi.success_status");var masterySetBySCO=currentAPI.GetValueIntern("cmi.success_status_SetBySco");SCOEntry=currentAPI.GetValueIntern("cmi.entry");score=currentAPI.GetValueIntern("cmi.score.scaled");sessionTime=currentAPI.GetValueIntern("cmi.session_time");var act=msequencer.mSeqTree.getActivity(mlaunch.mActivityID);if(act.getIsTracked())
+masteryStatus=currentAPI.GetValueIntern("cmi.success_status");var masterySetBySCO=currentAPI.GetValueIntern("cmi.success_status_SetBySco");SCOEntry=currentAPI.GetValueIntern("cmi.entry");score=currentAPI.GetValueIntern("cmi.score.scaled");sessionTime=currentAPI.GetValueIntern("cmi.session_time");var act=msequencer.mSeqTree.getActivity(mlaunch.mActivityID);if(act&&act.getIsTracked())
{var primaryObjID=null;var foundPrimaryObj=false;var setPrimaryObjSuccess=false;var setPrimaryObjScore=false;objs=act.getObjectives();if(objs!=null){for(var j=0;j -1) {
+ if (
+ (
+ typeof(document.getElementById("res")) != "undefined"
+ && typeof(document.getElementById("res").contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.event) != "undefined"
+ && (document.getElementById("res").contentWindow.event.type=="unload" || document.getElementById("res").contentWindow.event.type=="beforeunload" || document.getElementById("res").contentWindow.event.type=="pagehide")
+ )
+ || (
+ typeof(window.event) != "undefined"
+ && (window.event.type=="unload" || window.event.type=="beforeunload" || window.event.type=="click")
+ )
+ || (//LM in frame 1
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || (//LM in frame 0
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || ( //Articulate Rise
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || ( //Articulate Rise as SCORM 1.2 in 2004 Player
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
if (typeof headers !== "object") {headers = {};}
headers['Accept'] = 'text/javascript';
headers['Accept-Charset'] = 'UTF-8';
+ if (url == this.config.store_url && unloadChrome()) {
+ var r = sendAndLoad(url, toJSONString(data), true, user, password, headers);
+ console.log("async request for chrome");
+ // navigator.sendBeacon(url, toJSONString(data));
+ // console.log('use sendBeacon');
+ try{windowOpenerLoc.reload();} catch(e){}
+ return "1";
+ }
+ if (url == this.config.scorm_player_unload_url && navigator.userAgent.indexOf("Chrom") > -1) {
+ navigator.sendBeacon(url, toJSONString(data));
+ return "1";
+ }
+
var r = sendAndLoad(url, toJSONString(data), callback, user, password, headers);
if (r.content) {
@@ -12362,7 +12432,10 @@ function launchNavType(navType, isUserCurrentlyInteracting) {
//sync
activities[msequencer.mSeqTree.mCurActivity.mActivityID].exit="suspend";
}
-
+ if (navType==='ExitAll' || navType==='Exit' || navType==='SuspendAll') {
+ onWindowUnload();
+ }
+
//throw away API from previous sco and sync CMI and ADLTree, no api...SCO has to care for termination
onItemUndeliver();
@@ -14181,7 +14254,7 @@ function syncCMIADLTree(){
//get current activity
var act = msequencer.mSeqTree.getActivity(mlaunch.mActivityID);
- if (act.getIsTracked())
+ if (act && act.getIsTracked())
{
//alert("main.syncCMIADLTree:\nactivityid: " + mlaunch.mActivityID);
var primaryObjID = null;
@@ -14582,7 +14655,7 @@ function updateNav(ignore) {
var disable=true;
var disabled_str = "";
var test=null;
- if (mlaunch.mNavState.mChoice!=null) {
+ if (mlaunch.mNavState && typeof(mlaunch.mNavState.mChoice)!="undefined" && mlaunch.mNavState.mChoice!=null) {
test=mlaunch.mNavState.mChoice[i];
}
if (test) {
diff --git a/Modules/Scorm2004/scripts/rtemain/main.js b/Modules/Scorm2004/scripts/rtemain/main.js
old mode 100644
new mode 100755
index 233adbce23f6..4c1853c4bb0c
--- a/Modules/Scorm2004/scripts/rtemain/main.js
+++ b/Modules/Scorm2004/scripts/rtemain/main.js
@@ -1353,10 +1353,80 @@ function sendAndLoad(url, data, callback, user, password, headers)
}
function sendJSONRequest (url, data, callback, user, password, headers)
-{
+{
+ function unloadChrome() {
+ if (navigator.userAgent.indexOf("Chrom") > -1) {
+ if (
+ (
+ typeof(document.getElementById("res")) != "undefined"
+ && typeof(document.getElementById("res").contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.event) != "undefined"
+ && (document.getElementById("res").contentWindow.event.type=="unload" || document.getElementById("res").contentWindow.event.type=="beforeunload" || document.getElementById("res").contentWindow.event.type=="pagehide")
+ )
+ || (
+ typeof(window.event) != "undefined"
+ && (window.event.type=="unload" || window.event.type=="beforeunload" || window.event.type=="click")
+ )
+ || (//LM in frame 1
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || (//LM in frame 0
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || ( //Articulate Rise
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ || ( //Articulate Rise as SCORM 1.2 in 2004 Player
+ typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1]) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow) != "undefined"
+ && typeof(document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event) != "undefined"
+ && (
+ document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="unload"
+ || document.getElementById("res").contentWindow.document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type=="beforeunload"
+ )
+ )
+ ) {
+ return true;
+ }
+ }
+ return false;
+ }
+
if (typeof headers !== "object") {headers = {};}
headers['Accept'] = 'text/javascript';
headers['Accept-Charset'] = 'UTF-8';
+ if (url == this.config.store_url && unloadChrome()) {
+ var r = sendAndLoad(url, toJSONString(data), true, user, password, headers);
+ console.log("async request for chrome");
+ // navigator.sendBeacon(url, toJSONString(data));
+ // console.log('use sendBeacon');
+ try{windowOpenerLoc.reload();} catch(e){}
+ return "1";
+ }
+ if (url == this.config.scorm_player_unload_url && navigator.userAgent.indexOf("Chrom") > -1) {
+ navigator.sendBeacon(url, toJSONString(data));
+ return "1";
+ }
+
var r = sendAndLoad(url, toJSONString(data), callback, user, password, headers);
if (r.content) {
@@ -1577,7 +1647,10 @@ function launchNavType(navType, isUserCurrentlyInteracting) {
//sync
activities[msequencer.mSeqTree.mCurActivity.mActivityID].exit="suspend";
}
-
+ if (navType==='ExitAll' || navType==='Exit' || navType==='SuspendAll') {
+ onWindowUnload();
+ }
+
//throw away API from previous sco and sync CMI and ADLTree, no api...SCO has to care for termination
onItemUndeliver();
@@ -3396,7 +3469,7 @@ function syncCMIADLTree(){
//get current activity
var act = msequencer.mSeqTree.getActivity(mlaunch.mActivityID);
- if (act.getIsTracked())
+ if (act && act.getIsTracked())
{
//alert("main.syncCMIADLTree:\nactivityid: " + mlaunch.mActivityID);
var primaryObjID = null;
@@ -3797,7 +3870,7 @@ function updateNav(ignore) {
var disable=true;
var disabled_str = "";
var test=null;
- if (mlaunch.mNavState.mChoice!=null) {
+ if (mlaunch.mNavState && typeof(mlaunch.mNavState.mChoice)!="undefined" && mlaunch.mNavState.mChoice!=null) {
test=mlaunch.mNavState.mChoice[i];
}
if (test) {
diff --git a/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php b/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php
index 5a34e28481b9..d08293c4bab2 100755
--- a/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php
+++ b/Modules/ScormAicc/classes/SCORM/class.ilObjSCORMTracking.php
@@ -182,6 +182,8 @@ public static function storeJsApiCmi($user_id, $obj_id, $data)
$ilDB = $DIC['ilDB'];
$b_updateStatus = false;
+ $i_score_max = 0;
+ $i_score_raw = 0;
$b_messageLog = false;
if ($ilLog->current_log_level == 30) {
@@ -256,6 +258,19 @@ public static function storeJsApiCmi($user_id, $obj_id, $data)
$a_data["right"] . " for obj_id:" . $obj_id . ",sco_id:" . $a_data["sco_id"] . ",user_id:" . $user_id);
}
}
+ if ($a_data["left"] == 'cmi.core.score.max') {
+ $i_score_max = $a_data["right"];
+ }
+ if ($a_data["left"] == 'cmi.core.score.raw') {
+ $i_score_raw = $a_data["right"];
+ }
+ }
+ // mantis #30293
+ if ($i_score_max > 0 && $i_score_raw > 0) {
+ if (count(ilSCORMObject::_lookupPresentableItems($obj_id)) == 1) {
+ ilLTIAppEventListener::handleOutcomeWithoutLP($obj_id, $user_id,
+ ($i_score_raw / $i_score_max) * 100);
+ }
}
}
@@ -277,8 +292,6 @@ public static function syncGlobalStatus($userId, $packageId, $data, $new_global_
$saved_global_status = $data->saved_global_status;
$ilLog->write("saved_global_status=" . $saved_global_status);
- //last_visited!
-
// get attempts
if (!$data->packageAttempts) {
$val_set = $ilDB->queryF(
@@ -299,9 +312,9 @@ public static function syncGlobalStatus($userId, $packageId, $data, $new_global_
$totalTime = (int) $data->totalTimeCentisec;
$totalTime = round($totalTime / 100);
$ilDB->queryF(
- 'UPDATE sahs_user SET sco_total_time_sec=%s, status=%s, percentage_completed=%s, package_attempts=%s WHERE obj_id = %s AND user_id = %s',
- array('integer', 'integer', 'integer', 'integer', 'integer', 'integer'),
- array($totalTime, $new_global_status, $data->percentageCompleted, $attempts, $packageId, $userId)
+ 'UPDATE sahs_user SET last_visited=%s, last_access = %s, sco_total_time_sec=%s, status=%s, percentage_completed=%s, package_attempts=%s WHERE obj_id = %s AND user_id = %s',
+ array('text', 'timestamp', 'integer', 'integer', 'integer', 'integer', 'integer', 'integer'),
+ array($data->last_visited, date('Y-m-d H:i:s'), $totalTime, $new_global_status, $data->percentageCompleted, $attempts, $packageId, $userId)
);
// self::ensureObjectDataCacheExistence();
@@ -741,16 +754,13 @@ public static function scorm12PlayerUnload()
global $DIC;
$ilUser = $DIC['ilUser'];
$ilDB = $DIC['ilDB'];
-
- //$user_id = $ilUser->getID();
$user_id = (int) $_GET["p"];
$ref_id = (int) $_GET["ref_id"];
- // $obj_id = ilObject::_lookupObjId($ref_id);
$obj_id = (int) $_GET["package_id"];
if ($obj_id <= 1) {
$GLOBALS['DIC']['ilLog']->write(__METHOD__ . ' no valid obj_id');
} else {
- $last_visited = $_POST['last_visited'];
+ $last_visited = (string) $_GET['last_visited'];
$endDate = date('Y-m-d H:i:s', mktime(date('H'), date('i') + 5, date('s'), date('m'), date('d'), date('Y')));
$ilDB->manipulateF(
'UPDATE sahs_user
diff --git a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php
index f5c2cb842416..606dd7f32ad1 100755
--- a/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php
+++ b/Modules/ScormAicc/classes/class.ilObjSCORMLearningModule.php
@@ -339,7 +339,7 @@ public function getAttemptsForUsers()
/**
- * get number of atttempts for a certain user and package
+ * get number of attempts for a certain user and package
*/
public function getAttemptsForUser($a_user_id)
{
@@ -348,7 +348,7 @@ public function getAttemptsForUser($a_user_id)
$val_set = $ilDB->queryF(
'SELECT package_attempts FROM sahs_user WHERE obj_id = %s AND user_id = %s',
array('integer','integer'),
- array($this->getId(),$a_user_id,0)
+ array($this->getId(),$a_user_id)
);
$val_rec = $ilDB->fetchAssoc($val_set);
@@ -508,7 +508,7 @@ public function getTrackingDataAggSco($a_sco_id)
AND sco_id = %s',
array('integer','integer'),
array($this->getId(),$a_sco_id)
- );
+ );
$data = array();
while ($user_rec = $ilDB->fetchAssoc($user_set)) {
@@ -528,7 +528,7 @@ public function getTrackingDataAggSco($a_sco_id)
"cmi.core.lesson_status",
"cmi.core.total_time",
"cmi.core.score.raw")
- );
+ );
$score = $time = $status = "";
@@ -786,7 +786,7 @@ public function importSuccessForSahsUser($user_id, $last_access, $status, $attem
'SELECT * FROM sahs_user WHERE obj_id = %s AND user_id = %s',
array('integer','integer'),
array($this->getID(),$user_id)
- );
+ );
if ($ilDB->numRows($statement) > 0) {
$ilDB->update(
'sahs_user',
diff --git a/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php b/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php
old mode 100644
new mode 100755
index 96442e394866..f36bcaa3baa2
--- a/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php
+++ b/Modules/ScormAicc/classes/class.ilSCORMTrackingItemsTableGUI.php
@@ -149,7 +149,9 @@ public function getItems()
global $DIC;
$lng = $DIC['lng'];
- $this->determineOffsetAndOrder();
+ $this->determineOffsetAndOrder(true);
+ $this->determineLimit();
+
$ilSCORMTrackingItems = new ilSCORMTrackingItems();
switch ($this->report) {
case "exportSelectedCore":
@@ -177,7 +179,7 @@ public function getItems()
$tr_data = $ilSCORMTrackingItems->exportSelectedSuccess($this->userSelected, $this->allowExportPrivacy, $this->getObjId(), $this->lmTitle);
break;
}
- $this->setMaxCount($tr_data["cnt"]);
+// $this->setMaxCount($tr_data["cnt"]);
if (ilUtil::stripSlashes($this->getOrderField()) != "") {
include_once "Services/Utilities/classes/class.ilStr.php";
$tr_data = ilUtil::stableSortArray($tr_data, ilUtil::stripSlashes($this->getOrderField()), ilUtil::stripSlashes($this->getOrderDirection()));
diff --git a/Modules/ScormAicc/classes/class.ilSCORMTrackingUsersTableGUI.php b/Modules/ScormAicc/classes/class.ilSCORMTrackingUsersTableGUI.php
old mode 100644
new mode 100755
index 59091e0676ac..a04e455172a0
--- a/Modules/ScormAicc/classes/class.ilSCORMTrackingUsersTableGUI.php
+++ b/Modules/ScormAicc/classes/class.ilSCORMTrackingUsersTableGUI.php
@@ -41,24 +41,15 @@ public function parse()
{
$this->initTable();
- // @TODO add filter
$users = $this->getParentObject()->object->getTrackedUsers($this->filter['lastname']);
$attempts = $this->getParentObject()->object->getAttemptsForUsers();
$versions = $this->getParentObject()->object->getModuleVersionForUsers();
- include_once('./Services/PrivacySecurity/classes/class.ilPrivacySettings.php');
- $privacy = ilPrivacySettings::_getInstance();
- $allowExportPrivacy = $privacy->enabledExportSCORM();
-
$data = array();
foreach ($users as $user) {
$tmp = array();
$tmp['user'] = $user['user_id'];
- if ($allowExportPrivacy == true) {
- $tmp['name'] = $user['lastname'] . ', ' . $user['firstname'];
- } else {
- $tmp['name'] = $user['user_id'];
- }
+ $tmp['name'] = $user['lastname'] . ', ' . $user['firstname'];
$dt = new ilDateTime($user['last_access'], IL_CAL_DATETIME);
$tmp['last_access'] = $dt->get(IL_CAL_UNIX);
$tmp['attempts'] = (int) $attempts[$user['user_id']];
@@ -66,6 +57,18 @@ public function parse()
$data[] = $tmp;
}
+ $this->determineOffsetAndOrder();
+ $orderField = $this->getOrderField();
+ $orderDirection = $this->getOrderDirection();
+ if ( in_array(ilUtil::stripSlashes($orderField), ['user', 'attempts', 'version']) ) {
+ $this->setExternalSorting(true);
+ $data = ilUtil::sortArray(
+ $data,
+ $orderField,
+ $orderDirection,
+ true
+ );
+ }
$this->setData($data);
}
diff --git a/Modules/ScormAicc/classes/class.ilScormLP.php b/Modules/ScormAicc/classes/class.ilScormLP.php
old mode 100644
new mode 100755
index c4bc0d272ef9..826af06ebd8e
--- a/Modules/ScormAicc/classes/class.ilScormLP.php
+++ b/Modules/ScormAicc/classes/class.ilScormLP.php
@@ -13,6 +13,11 @@
*/
class ilScormLP extends ilObjectLP
{
+ /**
+ * @var null | bool
+ */
+ protected $precondition_cache = null;
+
public static function getDefaultModes($a_lp_active)
{
return array(
@@ -61,12 +66,6 @@ public function getValidModes()
}
}
- /**
- * AK, 14Sep2018: This looks strange, the mode is auto-activated if this object is used
- * as a precondition trigger? This is not implemented for any other object type.
- *
- * @return int
- */
public function getCurrentMode()
{
if ($this->checkSCORMPreconditions()) {
@@ -75,13 +74,21 @@ public function getCurrentMode()
return parent::getCurrentMode();
}
+ /**
+ * @return bool
+ * @throws ilDatabaseException
+ */
protected function checkSCORMPreconditions()
{
- include_once('./Services/Conditions/classes/class.ilConditionHandler.php');
- if (count(ilConditionHandler::_getPersistedConditionsOfTrigger('sahs', $this->obj_id))) {
- return true;
+ if (!is_null($this->precondition_cache)) {
+ return $this->precondition_cache;
}
- return false;
+
+ $this->precondition_cache =
+ ilConditionHandler::getNumberOfConditionsOfTrigger('sahs', $this->obj_id) > 0 ?
+ true :
+ false;
+ return $this->precondition_cache;
}
protected static function isLPMember(array &$a_res, $a_usr_id, $a_obj_ids)
diff --git a/Modules/ScormAicc/scripts/basisAPI.js b/Modules/ScormAicc/scripts/basisAPI.js
index e3b0928bd0d1..79e6772ce27f 100755
--- a/Modules/ScormAicc/scripts/basisAPI.js
+++ b/Modules/ScormAicc/scripts/basisAPI.js
@@ -77,13 +77,20 @@ function sendRequest (url, data, callback, user, password, headers) {
}
function useSendBeacon() {
- if (navigator.userAgent.indexOf("Chrome") > -1) {
- if (typeof(window.sahs_content) != "undefined" && typeof(window.sahs_content.event) != "undefined" && (window.sahs_content.event.type=="unload" || window.sahs_content.event.type=="beforeunload")) {
- var raw = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./);
- var version = raw ? parseInt(raw[2], 10) : false;
- if (version === false) return false;
- if (version >= 80) return true;
- }
+ if (navigator.userAgent.indexOf("Chrom") > -1) {
+ var winev = null;
+ if (window.sahs_content && typeof(window.sahs_content.event) != "undefined") winev = window.sahs_content.event.type;
+ else if (typeof(window.event) != "undefined") winev = window.event.type;
+ else if (window.parent && typeof(window.parent.event) != "undefined") winev = window.parent.event.type;
+ else if (window.parent.parent && typeof(window.parent.parent.event) != "undefined") winev = window.parent.parent.event.type;
+ //contentstart
+ try{winev = document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("frame")[1].contentWindow.event.type;} catch(e){}
+ //Articulate Rise
+ try{winev = document.getElementsByTagName("frame")[0].contentWindow.document.getElementsByTagName("iframe")[1].contentWindow.event.type;} catch(e){}
+
+ if (winev == "unload" || winev == "beforeunload" || winev == "click") {
+ return true;
+ }
}
return false;
}
@@ -198,7 +205,9 @@ function message(s_send){
function warning(s_send){
s_send = 'lm_'+iv.objId+': '+s_send;
- sendRequest ('./ilias.php?baseClass=ilSAHSPresentationGUI&ref_id='+iv.refId+'&cmd=logWarning', s_send);
+ if (navigator.userAgent.indexOf("Chrom") < 0) {
+ sendRequest ('./ilias.php?baseClass=ilSAHSPresentationGUI&ref_id='+iv.refId+'&cmd=logWarning', s_send);
+ }
}
// avoid sessionTimeOut
@@ -316,6 +325,8 @@ function IliasCommit() {
}
var s_s="",a_tmp,s_v,a_cmiTmp,i_numCompleted=0,b_statusFailed=false;
var LP_STATUS_IN_PROGRESS_NUM=1, LP_STATUS_COMPLETED_NUM=2,LP_STATUS_FAILED_NUM=3;
+ $last_visited = "";
+ if (iv.b_autoLastVisited==true) $last_visited = iv.launchId;
var o_data={
"cmi":[],
"saved_global_status":iv.status.saved_global_status,
@@ -324,7 +335,8 @@ function IliasCommit() {
"lp_mode":iv.status.lp_mode,
"hash":iv.status.hash,
"p":iv.status.p,
- "totalTimeCentisec":0
+ "totalTimeCentisec":0,
+ "last_visited":$last_visited
};
for (var i=0; isetDisabledObjectTypes(array("itgr", "sess"));
+ $gui->setDisabledObjectTypes(
+ array_merge(
+ [
+ 'itgr', 'sess'
+ ],
+ $objDefinition->getSideBlockTypes()
+ )
+ );
$gui->setAfterCreationCallback($this->ref_id);
$gui->render();
diff --git a/Modules/Session/classes/class.ilSessionMailTemplateParticipantContext.php b/Modules/Session/classes/class.ilSessionMailTemplateParticipantContext.php
index 523fd34c7da7..d666a0aa6525 100644
--- a/Modules/Session/classes/class.ilSessionMailTemplateParticipantContext.php
+++ b/Modules/Session/classes/class.ilSessionMailTemplateParticipantContext.php
@@ -94,18 +94,23 @@ public function getSpecificPlaceholders()
*/
public function resolveSpecificPlaceholder($placeholder_id, array $context_parameters, ilObjUser $recipient = null, $html_markup = false)
{
- /**
- * @var $ilObjDataCache ilObjectDataCache
- */
global $DIC;
$ilObjDataCache = $DIC['ilObjDataCache'];
-
- if ('crs_title' == $placeholder_id) {
- return $ilObjDataCache->lookupTitle($ilObjDataCache->lookupObjId($context_parameters['ref_id']));
- } elseif ('crs_link' == $placeholder_id) {
- require_once './Services/Link/classes/class.ilLink.php';
- return ilLink::_getLink($context_parameters['ref_id'], 'crs');
+ $obj_id = $ilObjDataCache->lookupObjId($context_parameters['ref_id']);
+ $sess_data = ilObjSession::lookupSession($obj_id);
+ $sess_app = ilSessionAppointment::_lookupAppointment($obj_id);
+
+
+ switch ($placeholder_id) {
+ case 'sess_title':
+ return $ilObjDataCache->lookupTitle($obj_id);
+ case 'sess_appointment':
+ return ilSessionAppointment::_appointmentToString($sess_app['start'], $sess_app['end'], $sess_app['fullday']);
+ case 'sess_location':
+ return $sess_data['location'];
+ case 'sess_details':
+ return $sess_data['details'];
}
return '';
diff --git a/Modules/Survey/classes/class.ilObjSurvey.php b/Modules/Survey/classes/class.ilObjSurvey.php
index dc21a9872f39..c8b0678ff124 100755
--- a/Modules/Survey/classes/class.ilObjSurvey.php
+++ b/Modules/Survey/classes/class.ilObjSurvey.php
@@ -1749,14 +1749,21 @@ public function moveQuestions($move_questions, $target_index, $insert_mode)
$part1 = array_slice($this->questions, 0, $array_pos + 1);
$part2 = array_slice($this->questions, $array_pos + 1);
}
+ $found = 0;
foreach ($move_questions as $question_id) {
if (!(array_search($question_id, $part1) === false)) {
unset($part1[array_search($question_id, $part1)]);
+ $found++;
}
if (!(array_search($question_id, $part2) === false)) {
unset($part2[array_search($question_id, $part2)]);
+ $found++;
}
}
+ // sanity check: do not move questions if they have not be found in the array
+ if ($found != count($move_questions)) {
+ return;
+ }
$part1 = array_values($part1);
$part2 = array_values($part2);
$this->questions = array_values(array_merge($part1, $move_questions, $part2));
@@ -3860,10 +3867,12 @@ public function cloneObject($a_target_id, $a_copy_id = 0, $a_omit_tree = false)
include_once "./Modules/SurveyQuestionPool/classes/class.SurveyQuestion.php";
foreach ($this->questions as $key => $question_id) {
+ /** @var $question SurveyQuestion */
$question = self::_instanciateQuestion($question_id);
if ($question) { // #10824
$question->id = -1;
$original_id = SurveyQuestion::_getOriginalId($question_id, false);
+ $question->setObjId($newObj->getId());
$question->saveToDb($original_id);
$newObj->questions[$key] = $question->getId();
$question_pointer[$question_id] = $question->getId();
@@ -6263,7 +6272,7 @@ protected function sentReminderPlaceholders($a_message, $a_user_id, array $a_con
$user = new \ilObjUser($a_user_id);
$processor = new \ilMailTemplatePlaceholderResolver($context, $a_message);
- $a_message = $processor->resolve($user, \ilMailFormCall::getContextParameters());
+ $a_message = $processor->resolve($user, $a_context_params);
} catch (\Exception $e) {
ilLoggerFactory::getLogger('mail')->error(__METHOD__ . ' has been called with invalid context.');
}
diff --git a/Modules/Survey/classes/class.ilSurveyEditorGUI.php b/Modules/Survey/classes/class.ilSurveyEditorGUI.php
index d20390a501db..e061fef43a70 100644
--- a/Modules/Survey/classes/class.ilSurveyEditorGUI.php
+++ b/Modules/Survey/classes/class.ilSurveyEditorGUI.php
@@ -394,6 +394,7 @@ public function moveQuestionsObject()
$this->ctrl->redirect($this, "questions");
} else {
$_SESSION["move_questions"] = $move_questions;
+ $_SESSION["move_questions_survey_id"] = $this->object->getId();
ilUtil::sendInfo($this->lng->txt("select_target_position_for_move_question"));
$this->questionsObject();
}
@@ -443,6 +444,7 @@ protected function insertQuestions($insert_mode)
ilUtil::sendSuccess($this->lng->txt('msg_obj_modified'), true);
$this->object->moveQuestions($_SESSION["move_questions"], $insert_id, $insert_mode);
unset($_SESSION["move_questions"]);
+ unset($_SESSION["move_questions_survey_id"]);
}
$this->ctrl->redirect($this, "questions");
diff --git a/Modules/Survey/classes/class.ilSurveyQuestionTableGUI.php b/Modules/Survey/classes/class.ilSurveyQuestionTableGUI.php
index 1f9c711b4435..f6c47acc9a4a 100644
--- a/Modules/Survey/classes/class.ilSurveyQuestionTableGUI.php
+++ b/Modules/Survey/classes/class.ilSurveyQuestionTableGUI.php
@@ -43,7 +43,8 @@ public function __construct($a_parent_obj, $a_parent_cmd, ilObjSurvey $a_survey_
if (!$this->read_only) {
// command dropdown
- if (!array_key_exists("move_questions", $_SESSION)) {
+ if (!array_key_exists("move_questions", $_SESSION) ||
+ $_SESSION["move_questions_survey_id"] != $this->object->getId()) {
$this->addMultiCommand("createQuestionblock", $lng->txt("define_questionblock"));
$this->addMultiCommand("unfoldQuestionblock", $lng->txt("unfold"));
$this->addMultiCommand("removeQuestions", $lng->txt("remove_question"));
diff --git a/Modules/Survey/classes/forms/FormMailCodesGUI.php b/Modules/Survey/classes/forms/FormMailCodesGUI.php
index c25905d5282f..77bacd189030 100644
--- a/Modules/Survey/classes/forms/FormMailCodesGUI.php
+++ b/Modules/Survey/classes/forms/FormMailCodesGUI.php
@@ -124,14 +124,10 @@ public function __construct($guiclass)
}
}
- if ($ilAccess->checkAccess("write", "", $_GET["ref_id"]) && $rbacsystem->checkAccess('smtp_mail', ilMailGlobalServices::getMailObjectRefId())) {
- if ((int) $ilSetting->get('mail_allow_external')) {
- $this->addCommandButton("sendCodesMail", $this->lng->txt("send"));
- } else {
- ilUtil::sendInfo($lng->txt("cant_send_email_smtp_disabled"));
- }
+ if ((int) $ilSetting->get('mail_allow_external')) {
+ $this->addCommandButton("sendCodesMail", $this->lng->txt("send"));
} else {
- ilUtil::sendInfo($lng->txt("cannot_send_emails"));
+ ilUtil::sendInfo($lng->txt("cant_send_email_smtp_disabled"));
}
}
diff --git a/Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPoolListGUI.php b/Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPoolListGUI.php
index 4ed7551bc52b..a2994d4961cc 100644
--- a/Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPoolListGUI.php
+++ b/Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPoolListGUI.php
@@ -54,7 +54,7 @@ public function init()
// general commands array
include_once("./Modules/SurveyQuestionPool/classes/class.ilObjSurveyQuestionPoolAccess.php");
- $this->commands = ilObjSurveyQUestionPoolAccess::_getCommands();
+ $this->commands = ilObjSurveyQuestionPoolAccess::_getCommands();
}
diff --git a/Modules/Test/classes/class.ilAssQuestionPageCommandForwarder.php b/Modules/Test/classes/class.ilAssQuestionPageCommandForwarder.php
index 9a09e04c78d9..b88e21382bc7 100644
--- a/Modules/Test/classes/class.ilAssQuestionPageCommandForwarder.php
+++ b/Modules/Test/classes/class.ilAssQuestionPageCommandForwarder.php
@@ -71,7 +71,7 @@ public function forward()
$DIC->ctrl()->saveParameter($this, "q_id");
$DIC->language()->loadLanguageModule("content");
$DIC->ctrl()->setReturnByClass("ilAssQuestionPageGUI", "view");
- $DIC->ctrl()->setReturn($this, "questions");
+ $DIC->ctrl()->setReturnByClass("ilObjTestGUI", "questions");
$page_gui = new ilAssQuestionPageGUI($_GET["q_id"]);
$page_gui->setEditPreview(true);
if (strlen($DIC->ctrl()->getCmd()) == 0) {
diff --git a/Modules/Test/classes/class.ilObjTest.php b/Modules/Test/classes/class.ilObjTest.php
index ee2a5db1873c..07a7cbe5fcd3 100755
--- a/Modules/Test/classes/class.ilObjTest.php
+++ b/Modules/Test/classes/class.ilObjTest.php
@@ -7056,7 +7056,14 @@ public static function _getAvailableTests($use_object_id = false)
$ilDB = $DIC['ilDB'];
$result_array = array();
- $tests = ilUtil::_getObjectsByOperations("tst", "write", $ilUser->getId(), -1);
+ $tests = array_slice(
+ array_reverse(
+ ilUtil::_getObjectsByOperations("tst", "write", $ilUser->getId(), PHP_INT_MAX)
+ ),
+ 0,
+ 10000
+ );
+
if (count($tests)) {
$titles = ilObject::_prepareCloneSelection($tests, "tst");
foreach ($tests as $ref_id) {
@@ -10437,7 +10444,7 @@ public function getEvaluationAdditionalFields()
{
include_once "./Modules/Test/classes/class.ilObjTestGUI.php";
include_once "./Modules/Test/classes/tables/class.ilEvaluationAllTableGUI.php";
- $table_gui = new ilEvaluationAllTableGUI(new ilObjTestGUI(''), 'outEvaluation', $this->getAnonymity());
+ $table_gui = new ilEvaluationAllTableGUI(new ilObjTestGUI($this->getRefId()), 'outEvaluation', $this->getAnonymity());
return $table_gui->getSelectedColumns();
}
diff --git a/Modules/Test/classes/class.ilObjTestGUI.php b/Modules/Test/classes/class.ilObjTestGUI.php
index 3ff8c05b1d77..99deed3fda1b 100755
--- a/Modules/Test/classes/class.ilObjTestGUI.php
+++ b/Modules/Test/classes/class.ilObjTestGUI.php
@@ -88,8 +88,9 @@ class ilObjTestGUI extends ilObjectGUI
/**
* Constructor
* @access public
+ * @param mixed|null $refId
*/
- public function __construct()
+ public function __construct($refId = null)
{
global $DIC;
$lng = $DIC['lng'];
@@ -101,7 +102,10 @@ public function __construct()
$this->type = "tst";
$this->ctrl = $ilCtrl;
$this->ctrl->saveParameter($this, array("ref_id", "test_ref_id", "calling_test", "test_express_mode", "q_id"));
- parent::__construct("", $_GET["ref_id"], true, false);
+ if (isset($_GET['ref_id']) && is_numeric($_GET['ref_id'])) {
+ $refId = (int) $_GET['ref_id'];
+ }
+ parent::__construct("", (int) $refId, true, false);
if ($this->object instanceof ilObjTest) {
require_once 'Modules/Test/classes/class.ilTestQuestionSetConfigFactory.php';
diff --git a/Modules/Test/classes/class.ilObjTestSettingsScoringResultsGUI.php b/Modules/Test/classes/class.ilObjTestSettingsScoringResultsGUI.php
index 4e51abf03ebb..2b49230db1b0 100644
--- a/Modules/Test/classes/class.ilObjTestSettingsScoringResultsGUI.php
+++ b/Modules/Test/classes/class.ilObjTestSettingsScoringResultsGUI.php
@@ -169,11 +169,16 @@ private function saveFormCmd($isConfirmedSave = false)
return $this->showConfirmation($form);
}
+ // saving the form leads to isScoreRecalculationRequired($form)
+ // returning false, so remember whether recalculation is needed
+
+ $recalcRequired = $this->isScoreRecalculationRequired($form);
+
// perform save
$this->performSaveForm($form);
- if ($this->isScoreRecalculationRequired($form)) {
+ if ($recalcRequired) {
$this->testOBJ->recalculateScores(true);
}
diff --git a/Modules/Test/classes/class.ilObjTestXMLParser.php b/Modules/Test/classes/class.ilObjTestXMLParser.php
index 32ca4e147976..3f92196a69cc 100644
--- a/Modules/Test/classes/class.ilObjTestXMLParser.php
+++ b/Modules/Test/classes/class.ilObjTestXMLParser.php
@@ -259,11 +259,28 @@ protected function getRandomQuestionSourcePoolDefinitionInstance()
protected function importRandomQuestionSourcePoolDefinition(ilTestRandomQuestionSetSourcePoolDefinition $sourcePoolDefinition, $attr)
{
- $sourcePoolDefinition->setPoolId($this->getImportMapping()->getMapping(
+ $source_pool_id = (int) $attr['poolId'];
+ $effective_pool_id = (int) $this->getImportMapping()->getMapping(
'Modules/Test',
'pool',
- (int) $attr['poolId']
- ));
+ $source_pool_id
+ );
+ $sourcePoolDefinition->setPoolId($effective_pool_id);
+
+ $derive_from_obj_id = true;
+ // The ref_id might not be given in old export files, so we have to check for existence
+ if (isset($attr['ref_id']) && is_numeric($attr['ref_id'])) {
+ if ($source_pool_id === $effective_pool_id) {
+ $derive_from_obj_id = false;
+ $sourcePoolDefinition->setPoolRefId((int) $attr['ref_id']);
+ }
+ }
+
+ if ($derive_from_obj_id) {
+ $ref_ids = ilObject::_getAllReferences($effective_pool_id);
+ $ref_id = current($ref_ids);
+ $sourcePoolDefinition->setPoolRefId($ref_id ? (int) $ref_id : null);
+ }
$sourcePoolDefinition->setPoolQuestionCount((int) $attr['poolQuestCount']);
$sourcePoolDefinition->setQuestionAmount((int) $attr['questAmount']);
diff --git a/Modules/Test/classes/class.ilParticipantsTestResultsGUI.php b/Modules/Test/classes/class.ilParticipantsTestResultsGUI.php
index b9b64b5fdee5..b5a80e68dc36 100644
--- a/Modules/Test/classes/class.ilParticipantsTestResultsGUI.php
+++ b/Modules/Test/classes/class.ilParticipantsTestResultsGUI.php
@@ -486,10 +486,6 @@ public function createUserResults($show_pass_details, $show_answers, $show_reach
$count = 0;
foreach ($show_user_results as $key => $active_id) {
- if ($this->getTestObj()->getFixedParticipants()) {
- $active_id = $this->getTestObj()->getActiveIdOfUser($active_id);
- }
-
if (!in_array($active_id, $participantData->getActiveIds())) {
continue;
}
diff --git a/Modules/Test/classes/class.ilTestCorrectionsGUI.php b/Modules/Test/classes/class.ilTestCorrectionsGUI.php
index 4c816ec18591..2db85ea80464 100644
--- a/Modules/Test/classes/class.ilTestCorrectionsGUI.php
+++ b/Modules/Test/classes/class.ilTestCorrectionsGUI.php
@@ -74,19 +74,32 @@ protected function showQuestionList()
{
$this->DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_CORRECTION);
- $table_gui = new ilTestQuestionsTableGUI(
- $this,
- 'showQuestionList',
- $this->testOBJ->getRefId()
- );
-
- $table_gui->setQuestionTitleLinksEnabled(true);
- $table_gui->setQuestionRemoveRowButtonEnabled(true);
- $table_gui->init();
-
- $table_gui->setData($this->getQuestions());
-
- $this->DIC->ui()->mainTemplate()->setContent($table_gui->getHTML());
+ $ui = $this->DIC->ui();
+
+ if ($this->testOBJ->isFixedTest()) {
+ $table_gui = new ilTestQuestionsTableGUI(
+ $this,
+ 'showQuestionList',
+ $this->testOBJ->getRefId()
+ );
+
+ $table_gui->setQuestionTitleLinksEnabled(true);
+ $table_gui->setQuestionRemoveRowButtonEnabled(true);
+ $table_gui->init();
+
+ $table_gui->setData($this->getQuestions());
+
+ $rendered_gui_component = $table_gui->getHTML();
+ } else {
+ $lng = $this->DIC->language();
+ $txt = $lng->txt('tst_corrections_incompatible_question_set_type');
+
+ $infoBox = $ui->factory()->messageBox()->info($txt);
+
+ $rendered_gui_component = $ui->renderer()->render($infoBox);
+ }
+
+ $ui->mainTemplate()->setContent($rendered_gui_component);
}
protected function showQuestion(ilPropertyFormGUI $form = null)
diff --git a/Modules/Test/classes/class.ilTestEvaluationData.php b/Modules/Test/classes/class.ilTestEvaluationData.php
index 8a9cff6de9ae..542cde83f18d 100755
--- a/Modules/Test/classes/class.ilTestEvaluationData.php
+++ b/Modules/Test/classes/class.ilTestEvaluationData.php
@@ -205,6 +205,7 @@ public function generateOverview()
$this->getParticipant($row["active_fi"])->getPass($row["pass"])->setNrOfAnsweredQuestions($row["answeredquestions"]);
$this->getParticipant($row["active_fi"])->getPass($row["pass"])->setWorkingTime($row["workingtime"]);
+ $this->getParticipant($row["active_fi"])->getPass($row["pass"])->setExamId((string) $row["exam_id"]);
$this->getParticipant($row['active_fi'])->getPass($row['pass'])->setRequestedHintsCount($row['hint_count']);
$this->getParticipant($row['active_fi'])->getPass($row['pass'])->setDeductedHintPoints($row['hint_points']);
diff --git a/Modules/Test/classes/class.ilTestEvaluationGUI.php b/Modules/Test/classes/class.ilTestEvaluationGUI.php
index e8c1f359eaf7..ed0d56dd3879 100644
--- a/Modules/Test/classes/class.ilTestEvaluationGUI.php
+++ b/Modules/Test/classes/class.ilTestEvaluationGUI.php
@@ -274,6 +274,7 @@ public function outEvaluation()
$evaluationrow['reached'] = $userdata->getReached();
$evaluationrow['max'] = $userdata->getMaxpoints();
$evaluationrow['hint_count'] = $userdata->getRequestedHintsCountFromScoredPass();
+ $evaluationrow['exam_id'] = $userdata->getExamIdFromScoredPass();
$percentage = $userdata->getReachedPointsInPercent();
$mark = $this->object->getMarkSchema()->getMatchingMark($percentage);
if (is_object($mark)) {
@@ -1000,6 +1001,13 @@ public function outParticipantsPassDetails()
$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);
@@ -1011,6 +1019,7 @@ public function outParticipantsPassDetails()
$template->setVariable("FORMACTION", $this->ctrl->getFormAction($this));
+ $this->populateExamId($template, (int) $active_id, (int) $pass);
$this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass));
$this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
@@ -1317,6 +1326,13 @@ public function outUserPassDetails()
$overviewTableGUI->setTitle($testResultHeaderLabelBuilder->getPassDetailsHeaderLabel($pass + 1));
$tpl->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()) . " %" . ")";
+ $tpl->setCurrentBlock('total_score');
+ $tpl->setVariable("TOTAL_RESULT_TEXT",$this->lng->txt('tst_stat_result_resultspoints'));
+ $tpl->setVariable("TOTAL_RESULT",$result);
+ $tpl->parseCurrentBlock();
+
if ($this->object->canShowSolutionPrintview()) {
$list_of_answers = $this->getPassListOfAnswers(
$result_array,
@@ -1347,6 +1363,7 @@ public function outUserPassDetails()
}
}
+ $this->populateExamId($tpl, (int) $active_id, (int) $pass);
$this->populatePassFinishDate($tpl, ilObjTest::lookupLastTestPassAccess($active_id, $pass));
$this->tpl->addCss(ilUtil::getStyleSheetLocation("output", "test_print.css", "Modules/Test"), "print");
diff --git a/Modules/Test/classes/class.ilTestEvaluationPassData.php b/Modules/Test/classes/class.ilTestEvaluationPassData.php
index ef0570722434..3570d656da1f 100755
--- a/Modules/Test/classes/class.ilTestEvaluationPassData.php
+++ b/Modules/Test/classes/class.ilTestEvaluationPassData.php
@@ -87,11 +87,14 @@ class ilTestEvaluationPassData
* @var boolean
*/
private $obligationsAnswered = null;
+
+ /** @var string */
+ private $examId = '';
public function __sleep()
{
return array('answeredQuestions', 'pass', 'nrOfAnsweredQuestions', 'reachedpoints',
- 'maxpoints', 'questioncount', 'workingtime');
+ 'maxpoints', 'questioncount', 'workingtime', 'examId');
}
/**
@@ -181,7 +184,7 @@ public function addAnsweredQuestion($question_id, $max_points, $reached_points,
);
}
- public function &getAnsweredQuestion($index)
+ public function getAnsweredQuestion($index)
{
if (array_key_exists($index, $this->answeredQuestions)) {
return $this->answeredQuestions[$index];
@@ -190,7 +193,7 @@ public function &getAnsweredQuestion($index)
}
}
- public function &getAnsweredQuestionByQuestionId($question_id)
+ public function getAnsweredQuestionByQuestionId($question_id)
{
foreach ($this->answeredQuestions as $question) {
if ($question["id"] == $question_id) {
@@ -254,7 +257,23 @@ public function setObligationsAnswered($obligationsAnswered)
{
$this->obligationsAnswered = (bool) $obligationsAnswered;
}
-
+
+ /**
+ * @return string
+ */
+ public function getExamId() : string
+ {
+ return $this->examId;
+ }
+
+ /**
+ * @param string $examId
+ */
+ public function setExamId(string $examId)
+ {
+ $this->examId = $examId;
+ }
+
/**
* getter for property obligationsAnswered.
* if property wasn't set yet the method is trying
diff --git a/Modules/Test/classes/class.ilTestEvaluationUserData.php b/Modules/Test/classes/class.ilTestEvaluationUserData.php
index 571c09087e66..d7780f2c98fb 100755
--- a/Modules/Test/classes/class.ilTestEvaluationUserData.php
+++ b/Modules/Test/classes/class.ilTestEvaluationUserData.php
@@ -123,7 +123,7 @@ class ilTestEvaluationUserData
/**
* Test passes
*
- * @var array
+ * @var array
*/
public $passes;
@@ -340,13 +340,21 @@ public function getPasses()
{
return $this->passes;
}
-
+
+ /**
+ * @param int $pass_nr
+ * @param ilTestEvaluationPassData $pass
+ */
public function addPass($pass_nr, $pass)
{
$this->passes[$pass_nr] = $pass;
}
-
- public function &getPass($pass_nr)
+
+ /**
+ * @param $pass_nr
+ * @return ilTestEvaluationPassData|null
+ */
+ public function getPass($pass_nr)
{
if (array_key_exists($pass_nr, $this->passes)) {
return $this->passes[$pass_nr];
@@ -409,7 +417,7 @@ public function getQuestionTitles()
return $this->questionTitles;
}
- public function &getQuestions($pass = 0)
+ public function getQuestions($pass = 0)
{
if (array_key_exists($pass, $this->questions)) {
return $this->questions[$pass];
@@ -432,7 +440,7 @@ public function addQuestion($original_id, $question_id, $max_points, $sequence =
);
}
- public function &getQuestion($index, $pass = 0)
+ public function getQuestion($index, $pass = 0)
{
if (array_key_exists($index, $this->questions[$pass])) {
return $this->questions[$pass][$index];
@@ -527,6 +535,21 @@ public function getRequestedHintsCountFromScoredPass()
{
return $this->getRequestedHintsCount($this->getScoredPass());
}
+
+ /**
+ * @return string
+ */
+ public function getExamIdFromScoredPass() : string
+ {
+ $examId = '';
+ $scoredPass = $this->getScoredPass();
+
+ if (isset($this->passes[$scoredPass]) && $this->passes[$scoredPass] instanceof ilTestEvaluationPassData) {
+ $examId = $this->passes[$scoredPass]->getExamId();
+ }
+
+ return $examId;
+ }
/**
* returns the count of hints requested by participant for given testpass
diff --git a/Modules/Test/classes/class.ilTestExport.php b/Modules/Test/classes/class.ilTestExport.php
index 4c032aa41776..623a00e3062a 100755
--- a/Modules/Test/classes/class.ilTestExport.php
+++ b/Modules/Test/classes/class.ilTestExport.php
@@ -354,6 +354,10 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
if (count($additionalFields)) {
foreach ($additionalFields as $fieldname) {
+ if (strcmp($fieldname, "exam_id") == 0) {
+ $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('exam_id_label'));
+ continue;
+ }
$worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt($fieldname));
}
}
@@ -411,6 +415,8 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
foreach ($additionalFields as $fieldname) {
if (strcmp($fieldname, 'gender') == 0) {
$worksheet->setCell($row, $col++, $this->lng->txt('gender_' . $userfields[$fieldname]));
+ } elseif (strcmp($fieldname, "exam_id") == 0) {
+ $worksheet->setCell($row, $col++, $userdata->getExamIdFromScoredPass());
} else {
$worksheet->setCell($row, $col++, $userfields[$fieldname]);
}
@@ -547,6 +553,9 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
if (strcmp($fieldname, "matriculation") == 0) {
$worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('matriculation'));
}
+ if (strcmp($fieldname, "exam_id") == 0) {
+ $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('exam_id_label'));
+ }
}
}
$worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('test'));
@@ -577,6 +586,13 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
$col++;
}
}
+ if (strcmp($fieldname, "exam_id") == 0) {
+ if (strlen($userfields[$fieldname])) {
+ $worksheet->setCell($row, $col++, $userdata->getExamIdFromScoredPass());
+ } else {
+ $col++;
+ }
+ }
}
}
$worksheet->setCell($row, $col++, $this->test_obj->getTitle());
@@ -618,6 +634,9 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
if (strcmp($fieldname, "matriculation") == 0) {
$worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('matriculation'));
}
+ if (strcmp($fieldname, "exam_id") == 0) {
+ $worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('exam_id_label'));
+ }
}
}
$worksheet->setFormattedExcelTitle($worksheet->getColumnCoord($col++) . $row, $this->lng->txt('test'));
@@ -648,6 +667,13 @@ public function exportToExcel($deliver = true, $filterby = "", $filtertext = "",
$col++;
}
}
+ if (strcmp($fieldname, "exam_id") == 0) {
+ if (strlen($userfields[$fieldname])) {
+ $worksheet->setCell($row, $col++, $userdata->getExamIdFromScoredPass());
+ } else {
+ $col++;
+ }
+ }
}
}
$worksheet->setCell($row, $col++, $this->test_obj->getTitle());
@@ -764,6 +790,11 @@ public function exportToCSV($deliver = true, $filterby = "", $filtertext = "", $
$additionalFields = $this->test_obj->getEvaluationAdditionalFields();
if (count($additionalFields)) {
foreach ($additionalFields as $fieldname) {
+ if (strcmp($fieldname, "exam_id") == 0) {
+ array_push($datarow, $this->lng->txt('exam_id_label'));
+ $col++;
+ continue;
+ }
array_push($datarow, $this->lng->txt($fieldname));
$col++;
}
@@ -833,6 +864,8 @@ public function exportToCSV($deliver = true, $filterby = "", $filtertext = "", $
foreach ($additionalFields as $fieldname) {
if (strcmp($fieldname, "gender") == 0) {
array_push($datarow2, $this->lng->txt("gender_" . $userfields[$fieldname]));
+ } elseif (strcmp($fieldname, "exam_id") == 0) {
+ array_push($datarow2, $userdata->getExamIdFromScoredPass());
} else {
array_push($datarow2, $userfields[$fieldname]);
}
diff --git a/Modules/Test/classes/class.ilTestExportRandomQuestionSet.php b/Modules/Test/classes/class.ilTestExportRandomQuestionSet.php
index 68e84e56b491..488302c2fb0b 100644
--- a/Modules/Test/classes/class.ilTestExportRandomQuestionSet.php
+++ b/Modules/Test/classes/class.ilTestExportRandomQuestionSet.php
@@ -102,6 +102,7 @@ protected function populateSelectionDefinitions(ilXmlWriter $xmlWriter)
foreach ($this->srcPoolDefList as $definition) {
$attributes = array(
'id' => $definition->getId(),
+ 'ref_id' => $definition->getPoolRefId(),
'poolId' => $definition->getPoolId(),
'poolQuestCount' => $definition->getPoolQuestionCount(),
'questAmount' => $definition->getQuestionAmount(),
diff --git a/Modules/Test/classes/class.ilTestLP.php b/Modules/Test/classes/class.ilTestLP.php
index 4d1a3ed9d3e6..db1b0524744c 100644
--- a/Modules/Test/classes/class.ilTestLP.php
+++ b/Modules/Test/classes/class.ilTestLP.php
@@ -109,7 +109,7 @@ protected static function isLPMember(array &$a_res, $a_usr_id, $a_obj_ids)
$set = $ilDB->query("SELECT tt.obj_fi" .
" FROM tst_active ta" .
" JOIN tst_tests tt ON (ta.test_fi = tt.test_id)" .
- " WHERE " . $ilDB->in("tt.obj_fi", (array) $a_obj_ids, "", "integer") .
+ " WHERE " . $ilDB->in("tt.obj_fi", (array) $a_obj_ids, false, "integer") .
" AND ta.user_fi = " . $ilDB->quote($a_usr_id, "integer"));
while ($row = $ilDB->fetchAssoc($set)) {
$a_res[$row["obj_fi"]] = true;
diff --git a/Modules/Test/classes/class.ilTestOutputGUI.php b/Modules/Test/classes/class.ilTestOutputGUI.php
index 2326da66c401..95e5682a02e7 100755
--- a/Modules/Test/classes/class.ilTestOutputGUI.php
+++ b/Modules/Test/classes/class.ilTestOutputGUI.php
@@ -650,7 +650,7 @@ public function saveQuestionSolution($authorized = true, $force = false)
}
}
- if ($this->saveResult == false) {
+ if ($this->saveResult == false || (!$questionOBJ->validateSolutionSubmit() && $questionOBJ->savePartial()) ) {
$this->ctrl->setParameter($this, "save_error", "1");
$_SESSION["previouspost"] = $_POST;
}
diff --git a/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php b/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php
index d8bce4e494e5..83c8999af1bc 100755
--- a/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php
+++ b/Modules/Test/classes/class.ilTestPlayerAbstractGUI.php
@@ -544,6 +544,10 @@ public function handleUserSettings()
}
}
+ /**
+ * Redirect the user after an automatic save when the time limit is reached
+ * @throws ilTestException
+ */
public function redirectAfterAutosaveCmd()
{
$active_id = $this->testSession->getActiveId();
@@ -582,27 +586,26 @@ public function redirectAfterDashboardCmd()
abstract protected function getCurrentQuestionId();
+ /**
+ * Automatically save a user answer while working on the test
+ * (called repeatedly by asynchronous posts in configured autosave interval)
+ */
public function autosaveCmd()
{
- $canSaveResult = $this->canSaveResult();
- $authorizedSolution = !$canSaveResult;
-
$result = "";
if (is_array($_POST) && count($_POST) > 0) {
- if ($this->isParticipantsAnswerFixed($this->getCurrentQuestionId())) {
+ if (!$this->canSaveResult() || $this->isParticipantsAnswerFixed($this->getCurrentQuestionId())) {
$result = '-IGNORE-';
} else {
- // fau: testNav - delete intermediate solution if answer is unchanged
- // answer is changed, so save the change as intermediate solution
+ // answer is changed from authorized solution, so save the change as intermediate solution
if ($this->getAnswerChangedParameter()) {
- $res = $this->saveQuestionSolution($authorizedSolution, true);
+ $res = $this->saveQuestionSolution(false, true);
}
- // answer is not changed, so delete an intermediate solution
+ // answer is not changed from authorized solution, so delete an intermediate solution
else {
$db_res = $this->removeIntermediateSolution();
$res = is_int($db_res);
}
- // fau.
if ($res) {
$result = $this->lng->txt("autosave_success");
} else {
@@ -610,18 +613,24 @@ public function autosaveCmd()
}
}
}
- // fau: testNav - simplify the redirection if time is reached
- if (!$canSaveResult && !$this->ctrl->isAsynch()) {
- // this was the last action in the test, saving is no longer allowed
- // form was directly submitted in saveOnTimeReached()
- // instead of ajax with autoSave()
- $this->ctrl->redirect($this, ilTestPlayerCommands::REDIRECT_ON_TIME_LIMIT);
- }
- // fau.
echo $result;
exit;
}
-
+
+ /**
+ * Automatically save a user answer when the limited duration of a test run is reached
+ * (called by synchronous form submit when the remaining time count down reaches zero)
+ */
+ public function autosaveOnTimeLimitCmd()
+ {
+ if (!$this->isParticipantsAnswerFixed($this->getCurrentQuestionId())) {
+ // time limit saves the user solution as authorized
+ $this->saveQuestionSolution(true, true);
+ }
+ $this->ctrl->redirect($this, ilTestPlayerCommands::REDIRECT_ON_TIME_LIMIT);
+ }
+
+
// fau: testNav - new function detectChangesCmd()
/**
* Detect changes sent in the background to the server
@@ -1565,13 +1574,19 @@ abstract protected function isQuestionSummaryFinishTestButtonRequired();
/**
* Output of a summary of all test questions for test participants
*/
- public function outQuestionSummaryCmd($fullpage = true, $contextFinishTest = false, $obligationsNotAnswered = false, $obligationsFilter = false)
+ public function outQuestionSummaryCmd($fullpage = true, $contextFinishTest = false, $obligationsInfo = false, $obligationsFilter = false)
{
if ($fullpage) {
$this->tpl->addBlockFile($this->getContentBlockName(), "adm_content", "tpl.il_as_tst_question_summary.html", "Modules/Test");
}
-
- if ($obligationsNotAnswered) {
+
+ $obligationsFulfilled = \ilObjTest::allObligationsAnswered(
+ $this->object->getId(),
+ $this->testSession->getActiveId(),
+ $this->testSession->getPass()
+ );
+
+ if ($obligationsInfo && $this->object->areObligationsEnabled() && !$obligationsFulfilled) {
ilUtil::sendFailure($this->lng->txt('not_all_obligations_answered'));
}
@@ -1596,7 +1611,7 @@ public function outQuestionSummaryCmd($fullpage = true, $contextFinishTest = fal
$table_gui->setShowPointsEnabled(!$this->object->getTitleOutput());
$table_gui->setShowMarkerEnabled($this->object->getShowMarker());
- $table_gui->setObligationsNotAnswered($obligationsNotAnswered);
+ $table_gui->setObligationsNotAnswered(!$obligationsFulfilled);
$table_gui->setShowObligationsEnabled($this->object->areObligationsEnabled());
$table_gui->setObligationsFilterEnabled($obligationsFilter);
$table_gui->setFinishTestButtonEnabled($this->isQuestionSummaryFinishTestButtonRequired());
@@ -1610,6 +1625,17 @@ public function outQuestionSummaryCmd($fullpage = true, $contextFinishTest = fal
if ($this->object->getEnableProcessingTime()) {
$this->outProcessingTime($active_id);
}
+
+ if ($this->object->isShowExamIdInTestPassEnabled()) {
+ $this->tpl->setCurrentBlock('exam_id_footer');
+ $this->tpl->setVariable('EXAM_ID_VAL', ilObjTest::lookupExamId(
+ $this->testSession->getActiveId(),
+ $this->testSession->getPass(),
+ $this->object->getId()
+ ));
+ $this->tpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
+ $this->tpl->parseCurrentBlock();
+ }
}
}
@@ -1968,7 +1994,9 @@ protected function cancelAnswerOptionalQuestionsCmd()
protected function populateHelperGuiContent($helperGui)
{
if ($this->object->getKioskMode()) {
- $this->tpl->addBlockfile($this->getContentBlockName(), 'content', "tpl.il_as_tst_kiosk_mode_content.html", "Modules/Test");
+ $this->tpl->setBodyClass("kiosk");
+ //$this->tpl->hideFooter();
+ $this->tpl->addBlockfile('CONTENT', 'content', "tpl.il_as_tst_kiosk_mode_content.html", "Modules/Test");
$this->tpl->setContent($this->ctrl->getHTML($helperGui));
} else {
$this->tpl->setVariable($this->getContentBlockName(), $this->ctrl->getHTML($helperGui));
@@ -2819,7 +2847,7 @@ protected function populateQuestionEditControl($questionGUI)
// set url to which the for should be submitted when the working time is over
// don't use asynch url because the form is submitted directly
// but use simple '&' because url is copied by javascript into the form action
- $config['saveOnTimeReachedUrl'] = str_replace('&', '&', $this->ctrl->getFormAction($this, ilTestPlayerCommands::AUTO_SAVE));
+ $config['saveOnTimeReachedUrl'] = str_replace('&', '&', $this->ctrl->getFormAction($this, ilTestPlayerCommands::AUTO_SAVE_ON_TIME_LIMIT));
// enable the auto saving function
// the autosave url is asynch because it will be used by an ajax request
diff --git a/Modules/Test/classes/class.ilTestPlayerCommands.php b/Modules/Test/classes/class.ilTestPlayerCommands.php
index 6760e3adbdc5..9843759756fb 100644
--- a/Modules/Test/classes/class.ilTestPlayerCommands.php
+++ b/Modules/Test/classes/class.ilTestPlayerCommands.php
@@ -52,6 +52,7 @@ class ilTestPlayerCommands
const UNFREEZE_ANSWERS = 'unfreezeCheckedQuestionsAnswers';
const AUTO_SAVE = 'autosave';
+ const AUTO_SAVE_ON_TIME_LIMIT = 'autosaveOnTimeLimit';
const REDIRECT_ON_TIME_LIMIT = 'redirectAfterAutosave';
const SUSPEND_TEST = 'suspendTest';
@@ -69,7 +70,7 @@ class ilTestPlayerCommands
// fau: testNav - declare DETECT_CHANGES as non execution command
self::DETECT_CHANGES,
// fau.
- self::AUTO_SAVE, self::REDIRECT_ON_TIME_LIMIT,
+ self::AUTO_SAVE, self::AUTO_SAVE_ON_TIME_LIMIT, self::REDIRECT_ON_TIME_LIMIT,
self::AFTER_TEST_PASS_FINISHED, self::SHOW_FINAL_STATMENT
);
diff --git a/Modules/Test/classes/class.ilTestQuestionSetConfig.php b/Modules/Test/classes/class.ilTestQuestionSetConfig.php
index 4f9e9e9f5b29..0733e974995f 100644
--- a/Modules/Test/classes/class.ilTestQuestionSetConfig.php
+++ b/Modules/Test/classes/class.ilTestQuestionSetConfig.php
@@ -135,30 +135,19 @@ abstract public function cloneQuestionSetRelatedData(ilObjTest $cloneTestOBJ);
*/
public function getQuestionPoolPathString($poolId)
{
- $nodePath = $this->tree->getNodePath(
- current(ilObject::_getAllReferences($poolId))
- );
+ $ref_id = current(ilObject::_getAllReferences($poolId));
- $questionPoolPathString = '';
-
- $i = 0;
- $j = count($nodePath) - 2;
-
- foreach ($nodePath as $node) {
- if ($i > 0) {
- $questionPoolPathString .= ' > ';
- }
-
- $questionPoolPathString .= $node['title'];
-
- if ($i == $j) {
- break;
- }
-
- $i++;
- }
-
- return $questionPoolPathString;
+ $path = new ilPathGUI();
+ $path->enableTextOnly(true);
+ return $path->getPath(ROOT_FOLDER_ID, $ref_id);
+ }
+
+ public function getFirstQuestionPoolRefIdByObjId(int $pool_obj_id) : int
+ {
+ $refs_ids = ilObject::_getAllReferences($pool_obj_id);
+ $refs_id = current($refs_ids);
+
+ return (int) $refs_id;
}
abstract public function isResultTaxonomyFilterSupported();
diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php
index 391aba23243d..81b50d5fb8d0 100644
--- a/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php
+++ b/Modules/Test/classes/class.ilTestRandomQuestionSetConfigGUI.php
@@ -816,6 +816,7 @@ private function getSourcePoolDefinitionByAvailableQuestionPoolId($poolId)
$originalPoolData = $availablePools[$poolId];
$originalPoolData['qpl_path'] = $this->questionSetConfig->getQuestionPoolPathString($poolId);
+ $originalPoolData['qpl_ref_id'] = $this->questionSetConfig->getFirstQuestionPoolRefIdByObjId($poolId);
return $this->sourcePoolDefinitionFactory->getSourcePoolDefinitionByOriginalPoolData($originalPoolData);
}
@@ -891,6 +892,7 @@ private function deriveNewPoolsCmd()
$srcPoolDefinition = $this->sourcePoolDefinitionList->getDefinitionBySourcePoolId($newPool->getId());
$srcPoolDefinition->setPoolTitle($newPool->getTitle());
$srcPoolDefinition->setPoolPath($this->questionSetConfig->getQuestionPoolPathString($newPool->getId()));
+ $srcPoolDefinition->setPoolRefId($this->questionSetConfig->getFirstQuestionPoolRefIdByObjId((int) $newPool->getId()));
$srcPoolDefinition->saveToDb();
ilTestRandomQuestionSetStagingPoolQuestionList::updateSourceQuestionPoolId(
diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetNonAvailablePool.php b/Modules/Test/classes/class.ilTestRandomQuestionSetNonAvailablePool.php
index 69f52d69f57a..88f4b8819e3d 100644
--- a/Modules/Test/classes/class.ilTestRandomQuestionSetNonAvailablePool.php
+++ b/Modules/Test/classes/class.ilTestRandomQuestionSetNonAvailablePool.php
@@ -23,6 +23,9 @@ class ilTestRandomQuestionSetNonAvailablePool
*/
protected $id;
+ /** @var int|null */
+ protected $ref_id = null;
+
/**
* @var string
*/
@@ -97,6 +100,16 @@ public function setUnavailabilityStatus($unavailabilityStatus)
$this->unavailabilityStatus = $unavailabilityStatus;
}
+ public function getRefId() : ?int
+ {
+ return $this->ref_id;
+ }
+
+ public function setRefId(?int $ref_id) : void
+ {
+ $this->ref_id = $ref_id;
+ }
+
/**
* @param array $row
*/
@@ -105,6 +118,7 @@ public function assignDbRow($row)
foreach ($row as $field => $value) {
switch ($field) {
case 'pool_fi': $this->setId($value); break;
+ case 'pool_ref_id': $this->setRefId($value ? (int) $value : null); break;
case 'pool_title': $this->setTitle($value); break;
case 'pool_path': $this->setPath($value); break;
}
diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php
index f63717c4ff32..014f280431aa 100644
--- a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php
+++ b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinition.php
@@ -26,6 +26,9 @@ class ilTestRandomQuestionSetSourcePoolDefinition
private $id = null;
private $poolId = null;
+
+ /** @var null|int */
+ private $poolRefId = null;
private $poolTitle = null;
@@ -88,6 +91,16 @@ public function getPoolId()
{
return $this->poolId;
}
+
+ public function getPoolRefId() : ?int
+ {
+ return $this->poolRefId;
+ }
+
+ public function setPoolRefId(?int $poolRefId) : void
+ {
+ $this->poolRefId = $poolRefId;
+ }
public function setPoolTitle($poolTitle)
{
@@ -312,6 +325,7 @@ public function initFromArray($dataArray)
switch ($field) {
case 'def_id': $this->setId($value); break;
case 'pool_fi': $this->setPoolId($value); break;
+ case 'pool_ref_id': $this->setPoolRefId($value ? (int) $value : null); break;
case 'pool_title': $this->setPoolTitle($value); break;
case 'pool_path': $this->setPoolPath($value); break;
case 'pool_quest_count': $this->setPoolQuestionCount($value); break;
@@ -384,6 +398,7 @@ private function updateDbRecord($testId)
array(
'test_fi' => array('integer', $testId),
'pool_fi' => array('integer', $this->getPoolId()),
+ 'pool_ref_id' => array('integer', $this->getPoolRefId()),
'pool_title' => array('text', $this->getPoolTitle()),
'pool_path' => array('text', $this->getPoolPath()),
'pool_quest_count' => array('integer', $this->getPoolQuestionCount()),
@@ -416,6 +431,7 @@ private function insertDbRecord($testId)
'def_id' => array('integer', $nextId),
'test_fi' => array('integer', $testId),
'pool_fi' => array('integer', $this->getPoolId()),
+ 'pool_ref_id' => array('integer', $this->getPoolRefId()),
'pool_title' => array('text', $this->getPoolTitle()),
'pool_path' => array('text', $this->getPoolPath()),
'pool_quest_count' => array('integer', $this->getPoolQuestionCount()),
@@ -439,10 +455,17 @@ private function insertDbRecord($testId)
public function getPoolInfoLabel(ilLanguage $lng)
{
+ $pool_path = $this->getPoolPath();
+ if (is_int($this->getPoolRefId()) && ilObject::_lookupObjId($this->getPoolRefId())) {
+ $path = new ilPathGUI();
+ $path->enableTextOnly(true);
+ $pool_path = $path->getPath(ROOT_FOLDER_ID, $this->getPoolRefId());
+ }
+
$poolInfoLabel = sprintf(
$lng->txt('tst_dynamic_question_set_source_questionpool_summary_string'),
$this->getPoolTitle(),
- $this->getPoolPath(),
+ $pool_path,
$this->getPoolQuestionCount()
);
diff --git a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php
index bb8a4cd3c67c..5d003c777c06 100644
--- a/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php
+++ b/Modules/Test/classes/class.ilTestRandomQuestionSetSourcePoolDefinitionFactory.php
@@ -39,6 +39,7 @@ public function getSourcePoolDefinitionByOriginalPoolData($originalPoolData)
$sourcePoolDefinition = $this->buildDefinitionInstance();
$sourcePoolDefinition->setPoolId($originalPoolData['qpl_id']);
+ $sourcePoolDefinition->setPoolRefId($originalPoolData['qpl_ref_id']);
$sourcePoolDefinition->setPoolTitle($originalPoolData['qpl_title']);
$sourcePoolDefinition->setPoolPath($originalPoolData['qpl_path']);
$sourcePoolDefinition->setPoolQuestionCount($originalPoolData['count']);
diff --git a/Modules/Test/classes/class.ilTestScoringByQuestionsGUI.php b/Modules/Test/classes/class.ilTestScoringByQuestionsGUI.php
index 3502cdbe86fb..20212a5f7806 100644
--- a/Modules/Test/classes/class.ilTestScoringByQuestionsGUI.php
+++ b/Modules/Test/classes/class.ilTestScoringByQuestionsGUI.php
@@ -47,7 +47,7 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
$tpl = $DIC->ui()->mainTemplate();
$DIC->tabs()->activateTab(ilTestTabsManager::TAB_ID_MANUAL_SCORING);
-
+
include_once 'Services/jQuery/classes/class.iljQueryUtil.php';
iljQueryUtil::initjQuery();
@@ -69,7 +69,7 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
require_once 'Modules/Test/classes/tables/class.ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI.php';
$table = new ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI($this);
-
+
$table->setManualScoringPointsPostData($manPointsPost);
$qst_id = $table->getFilterItemByPostVar('question')->getValue();
@@ -92,18 +92,20 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
if ($selected_questionData && is_numeric($passNr)) {
$data = $this->object->getCompleteEvaluationData(false);
$participants = $data->getParticipants();
-
+
require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
$participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
$participantData->setActiveIdsFilter(array_keys($data->getParticipants()));
-
+
$participantData->setParticipantAccessFilter(
ilTestParticipantAccessFilter::getScoreParticipantsUserFilter($this->ref_id)
);
-
+
$participantData->load($this->object->getTestId());
foreach ($participantData->getActiveIds() as $active_id) {
+
+ /** @var $participant ilTestEvaluationUserData */
$participant = $participants[$active_id];
$testResultData = $this->object->getTestResult($active_id, $passNr - 1);
foreach ($testResultData as $questionData) {
@@ -111,6 +113,7 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
continue;
}
+ $user = ilObjUser::_getUserData(array($participant->user_id));
$table_data[] = array(
'pass_id' => $passNr - 1,
'active_id' => $active_id,
@@ -118,6 +121,9 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
'reached_points' => assQuestion::_getReachedPoints($active_id, $questionData['qid'], $passNr - 1),
'maximum_points' => assQuestion::_getMaximumPoints($questionData['qid']),
'participant' => $participant,
+ 'lastname' => $user[0]['lastname'],
+ 'firstname' => $user[0]['firstname'],
+ 'login' => $participant->getLogin(),
);
}
}
@@ -141,30 +147,30 @@ protected function showManScoringByQuestionParticipantsTable($manPointsPost = ar
$table->setData($table_data);
$tpl->setContent($table->getHTML());
}
-
+
protected function saveManScoringByQuestion()
{
global $DIC; /* @var ILIAS\DI\Container $DIC */
-
+
if (!isset($_POST['scoring']) || !is_array($_POST['scoring'])) {
ilUtil::sendFailure($this->lng->txt('tst_save_manscoring_failed_unknown'));
$this->showManScoringByQuestionParticipantsTable();
return;
}
-
+
$pass = key($_POST['scoring']);
$activeData = current($_POST['scoring']);
-
+
require_once 'Modules/Test/classes/class.ilTestParticipantData.php';
$participantData = new ilTestParticipantData($DIC->database(), $DIC->language());
$participantData->setActiveIdsFilter(array_keys($activeData));
-
+
$participantData->setParticipantAccessFilter(
ilTestParticipantAccessFilter::getScoreParticipantsUserFilter($this->ref_id)
);
-
+
$participantData->load($this->object->getTestId());
-
+
include_once 'Modules/TestQuestionPool/classes/class.assQuestion.php';
include_once 'Modules/Test/classes/class.ilObjTestAccess.php';
include_once 'Services/Tracking/classes/class.ilLPStatusWrapper.php';
@@ -181,7 +187,7 @@ protected function saveManScoringByQuestion()
if (!isset($skipParticipant[$pass])) {
$skipParticipant[$pass] = array();
}
-
+
$skipParticipant[$pass][$active_id] = true;
continue;
@@ -197,11 +203,11 @@ protected function saveManScoringByQuestion()
}
$maxPointsByQuestionId[$qst_id] = assQuestion::_getMaximumPoints($qst_id);
-
+
if ($reached_points > $maxPointsByQuestionId[$qst_id]) {
$oneExceededMaxPoints = true;
}
-
+
$manPointsPost[$pass][$active_id][$qst_id] = $reached_points;
}
}
@@ -260,12 +266,14 @@ protected function saveManScoringByQuestion()
);
ilUtil::sendSuccess($msg, true);
+ /* disabled for Mantis 25850
require_once './Modules/Test/classes/class.ilTestScoring.php';
$scorer = new ilTestScoring($this->object);
$scorer->setPreserveManualScores(true);
$scorer->recalculateSolutions();
+ */
}
-
+
$this->showManScoringByQuestionParticipantsTable();
}
@@ -305,16 +313,27 @@ protected function getAnswerDetail()
$data = $this->object->getCompleteEvaluationData(false);
$participant = $data->getParticipant($active_id);
-
+
$question_gui = $this->object->createQuestionGUI('', $question_id);
$tmp_tpl = new ilTemplate('tpl.il_as_tst_correct_solution_output.html', true, true, 'Modules/Test');
+ if ($question_gui->supportsIntermediateSolutionOutput() && $question_gui->hasIntermediateSolution($active_id, $pass)) {
+ $question_gui->setUseIntermediateSolution(true);
+ $aresult_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, true, false, false, true);
+ $question_gui->setUseIntermediateSolution(false);
+ $tmp_tpl->setVariable('TEXT_ASOLUTION_OUTPUT', $this->lng->txt('autosavecontent'));
+ $tmp_tpl->setVariable('ASOLUTION_OUTPUT', $aresult_output);
+ }
+
$result_output = $question_gui->getSolutionOutput($active_id, $pass, false, false, false, $this->object->getShowSolutionFeedback(), false, true);
$tmp_tpl->setVariable('TEXT_YOUR_SOLUTION', $this->lng->txt('answers_of') . ' ' . $participant->getName());
+
+
+
$maxpoints = $question_gui->object->getMaximumPoints();
$add_title = ' [' . $this->lng->txt('question_id_short') . ': ' . $question_id . ']';
-
+
if ($maxpoints == 1) {
$tmp_tpl->setVariable('QUESTION_TITLE', $this->object->getQuestionTitle($question_gui->object->getTitle()) . ' (' . $maxpoints . ' ' . $this->lng->txt('point') . ')' . $add_title);
} else {
diff --git a/Modules/Test/classes/class.ilTestScoringGUI.php b/Modules/Test/classes/class.ilTestScoringGUI.php
index 88ae49e0898f..74d9cb907803 100755
--- a/Modules/Test/classes/class.ilTestScoringGUI.php
+++ b/Modules/Test/classes/class.ilTestScoringGUI.php
@@ -417,7 +417,8 @@ private function buildManScoringParticipantForm($questionGuiList, $activeId, $pa
$form->setTitle(sprintf($lng->txt('manscoring_results_pass'), $pass + 1));
$form->setTableWidth('100%');
-
+
+ /** @var assQuestionGUI $questionGUI */
foreach ($questionGuiList as $questionId => $questionGUI) {
$questionHeader = sprintf($lng->txt('tst_manscoring_question_section_header'), $questionGUI->object->getTitle());
$questionSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
@@ -431,6 +432,15 @@ private function buildManScoringParticipantForm($questionGuiList, $activeId, $pa
$cust->setHtml($questionSolution);
$form->addItem($cust);
+ if ($questionGUI->supportsIntermediateSolutionOutput() && $questionGUI->hasIntermediateSolution($activeId, $pass)) {
+ $questionGUI->setUseIntermediateSolution(true);
+ $intermediateSolution = $questionGUI->getSolutionOutput($activeId, $pass, false, false, true, false, false, true);
+ $questionGUI->setUseIntermediateSolution(false);
+ $cust = new ilCustomInputGUI($lng->txt('autosavecontent'));
+ $cust->setHtml($intermediateSolution);
+ $form->addItem($cust);
+ }
+
$text = new ilTextInputGUI($lng->txt('tst_change_points_for_question'), "question__{$questionId}__points");
if ($initValues) {
$text->setValue(assQuestion::_getReachedPoints($activeId, $questionId, $pass));
@@ -442,7 +452,7 @@ private function buildManScoringParticipantForm($questionGuiList, $activeId, $pa
$nonedit->setValue(assQuestion::_getMaximumPoints($questionId));
}
$form->addItem($nonedit);
-
+
$area = new ilTextAreaInputGUI($lng->txt('set_manual_feedback'), "question__{$questionId}__feedback");
$area->setUseRTE(true);
if ($initValues) {
diff --git a/Modules/Test/classes/class.ilTestServiceGUI.php b/Modules/Test/classes/class.ilTestServiceGUI.php
index 661bab4b054d..d4b7396798fc 100755
--- a/Modules/Test/classes/class.ilTestServiceGUI.php
+++ b/Modules/Test/classes/class.ilTestServiceGUI.php
@@ -398,7 +398,7 @@ public function getPassListOfAnswers(&$result_array, $active_id, $pass, $show_so
$showFeedback = $this->isContextResultPresentation() && $this->object->getShowSolutionFeedback();
$show_solutions = $this->isContextResultPresentation() && $show_solutions;
-
+
if ($show_solutions) {
$compare_template = new ilTemplate('tpl.il_as_tst_answers_compare.html', true, true, 'Modules/Test');
$compare_template->setVariable("HEADER_PARTICIPANT", $this->lng->txt('tst_header_participant'));
@@ -408,9 +408,23 @@ public function getPassListOfAnswers(&$result_array, $active_id, $pass, $show_so
$compare_template->setVariable('PARTICIPANT', $result_output);
$compare_template->setVariable('SOLUTION', $best_output);
+ if ($question_gui->supportsIntermediateSolutionOutput() && $question_gui->hasIntermediateSolution($active_id, $pass)) {
+ $question_gui->setUseIntermediateSolution(true);
+ $intermediate_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, false, true, $showFeedback);
+ $question_gui->setUseIntermediateSolution(false);
+ $compare_template->setVariable('TXT_INTERMEDIATE', $this->lng->txt('autosavecontent'));
+ $compare_template->setVariable('INTERMEDIATE', $intermediate_output);
+ }
$template->setVariable('SOLUTION_OUTPUT', $compare_template->get());
} else {
$result_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, false, $show_question_only, $showFeedback);
+ if ($question_gui->supportsIntermediateSolutionOutput() && $question_gui->hasIntermediateSolution($active_id, $pass)) {
+ $question_gui->setUseIntermediateSolution(true);
+ $intermediate_output = $question_gui->getSolutionOutput($active_id, $pass, $show_solutions, false, true, $showFeedback);
+ $question_gui->setUseIntermediateSolution(false);
+ $template->setVariable('TXT_INTERMEDIATE', $this->lng->txt('autosavecontent'));
+ $template->setVariable('INTERMEDIATE', $intermediate_output);
+ }
$template->setVariable('SOLUTION_OUTPUT', $result_output);
}
@@ -854,6 +868,7 @@ public function getResultsOfUserOutput($testSession, $active_id, $pass, $targetG
$template->setVariable("TEXT_HEADING", sprintf($this->lng->txt("tst_result_user_name"), $uname));
$template->setVariable("USER_DATA", $user_data);
+ $this->populateExamId($template, (int) $active_id, (int) $pass);
$this->populatePassFinishDate($template, ilObjTest::lookupLastTestPassAccess($active_id, $pass));
return $template->get();
@@ -1197,6 +1212,22 @@ public function populatePassFinishDate($tpl, $passFinishDate)
$tpl->setVariable("PASS_FINISH_DATE_LABEL", $this->lng->txt('tst_pass_finished_on'));
$tpl->setVariable("PASS_FINISH_DATE_VALUE", $passFinishDate);
}
+
+ /**
+ * @param ilTemplate $tpl
+ * @param int $activeId
+ * @param int $pass
+ */
+ public function populateExamId(ilTemplate $tpl, int $activeId, int $pass)
+ {
+ if ($this->object->isShowExamIdInTestResultsEnabled()) {
+ $tpl->setVariable("EXAM_ID_TXT", $this->lng->txt('exam_id'));
+ $tpl->setVariable('EXAM_ID', ilObjTest::lookupExamId(
+ $activeId,
+ $pass
+ ));
+ }
+ }
}
// internal sort function to sort the result array
diff --git a/Modules/Test/classes/class.ilTestSubmissionReviewGUI.php b/Modules/Test/classes/class.ilTestSubmissionReviewGUI.php
index 4bd2b0a2c42f..d0b6fd2cec47 100644
--- a/Modules/Test/classes/class.ilTestSubmissionReviewGUI.php
+++ b/Modules/Test/classes/class.ilTestSubmissionReviewGUI.php
@@ -184,8 +184,21 @@ protected function show()
$html = $this->buildToolbar('review_nav_top')->getHTML();
$html .= $this->buildUserReviewOutput() . ' ';
$html .= $this->buildToolbar('review_nav_bottom')->getHTML();
+
+ if ($this->object->isShowExamIdInTestPassEnabled() && !$this->object->getKioskMode()) {
+ $examIdTpl = new ilTemplate("tpl.exam_id_block.html", true, true, 'Modules/Test');
+ $examIdTpl->setVariable('EXAM_ID_VAL', ilObjTest::lookupExamId(
+ $this->testSession->getActiveId(),
+ $this->testSession->getPass(),
+ $this->object->getId()
+ ));
+ $examIdTpl->setVariable('EXAM_ID_TXT', $this->lng->txt('exam_id'));
+ $html .= $examIdTpl->get();
+ }
- $this->tpl->setVariable($this->getContentBlockName(), $html);
+ $this->tpl->setVariable(
+ $this->getContentBlockName(), $html
+ );
}
protected function pdfDownload()
diff --git a/Modules/Test/classes/tables/class.ilEvaluationAllTableGUI.php b/Modules/Test/classes/tables/class.ilEvaluationAllTableGUI.php
index c791dca90308..2f8b71565d92 100644
--- a/Modules/Test/classes/tables/class.ilEvaluationAllTableGUI.php
+++ b/Modules/Test/classes/tables/class.ilEvaluationAllTableGUI.php
@@ -51,6 +51,9 @@ public function __construct($a_parent_obj, $a_parent_cmd, $anonymity = false, $o
if (strcmp($c, 'email') == 0) {
$this->addColumn($this->lng->txt("email"), 'email', '');
}
+ if (strcmp($c, 'exam_id') == 0 && $this->parent_obj->object->isShowExamIdInTestResultsEnabled()) {
+ $this->addColumn($this->lng->txt("exam_id_label"), 'exam_id', '');
+ }
if (strcmp($c, 'institution') == 0) {
$this->addColumn($this->lng->txt("institution"), 'institution', '');
}
@@ -133,6 +136,7 @@ public function numericOrdering($a_field)
break;
case 'reached':
case 'hint_count':
+ case 'exam_id':
case 'answered':
return true;
break;
@@ -191,6 +195,12 @@ public function getSelectableColumns()
"txt" => $lng->txt("matriculation"),
"default" => false
);
+ if ($this->parent_obj->object->isShowExamIdInTestResultsEnabled()) {
+ $cols["exam_id"] = array(
+ "txt" => $lng->txt("exam_id_label"),
+ "default" => false
+ );
+ }
}
if ($this->parent_obj->object->getECTSOutput()) {
$cols["ects_grade"] = array(
@@ -308,6 +318,12 @@ protected function fillRow($data)
$this->tpl->setVariable("MATRICULATION", strlen($data['matriculation']) ? $data['matriculation'] : ' ');
$this->tpl->parseCurrentBlock();
}
+ if (strcmp($c, 'exam_id') == 0 && $this->parent_obj->object->isShowExamIdInTestResultsEnabled()) {
+ $this->tpl->setCurrentBlock('exam_id');
+ $examId = is_string($data['exam_id']) && strlen($data['exam_id']) ? $data['exam_id'] : ' ';
+ $this->tpl->setVariable('EXAM_ID', $examId);
+ $this->tpl->parseCurrentBlock();
+ }
}
if ($this->parent_obj->object->getECTSOutput()) {
if (strcmp($c, 'ects_grade') == 0) {
diff --git a/Modules/Test/classes/tables/class.ilParticipantsTestResultsTableGUI.php b/Modules/Test/classes/tables/class.ilParticipantsTestResultsTableGUI.php
index 03ea12c5381e..0efb5f692883 100644
--- a/Modules/Test/classes/tables/class.ilParticipantsTestResultsTableGUI.php
+++ b/Modules/Test/classes/tables/class.ilParticipantsTestResultsTableGUI.php
@@ -100,7 +100,7 @@ public function setAnonymity($anonymity)
public function numericOrdering($field)
{
return in_array($field, array(
- 'scored_pass', 'answered_questions', 'points', 'percent_result'
+ 'scored_pass', 'answered_questions', 'reached_points', 'percent_result'
));
}
diff --git a/Modules/Test/classes/tables/class.ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI.php b/Modules/Test/classes/tables/class.ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI.php
index 3eb14b058dda..0c4248e137ea 100644
--- a/Modules/Test/classes/tables/class.ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI.php
+++ b/Modules/Test/classes/tables/class.ilTestManScoringParticipantsBySelectedQuestionAndPassTableGUI.php
@@ -41,8 +41,6 @@ public function __construct($parentObj)
parent::__construct($parentObj, self::PARENT_DEFAULT_CMD);
- $this->disable('sort');
-
$this->setFormAction($ilCtrl->getFormAction($parentObj, self::PARENT_DEFAULT_CMD));
$this->setRowTemplate("tpl.il_as_tst_man_scoring_by_question_tblrow.html", "Modules/Test");
@@ -51,17 +49,28 @@ public function __construct($parentObj)
$this->addCommandButton(self::PARENT_SAVE_SCORING_CMD, $this->lng->txt('save'));
+ $this->initOrdering();
$this->initColumns();
$this->initFilter();
}
private function initColumns()
{
- $this->addColumn($this->lng->txt('name'), 'lastname', '40%');
- $this->addColumn($this->lng->txt('tst_reached_points'), 'lastname', '40%');
+ $this->addColumn($this->lng->txt('lastname'), 'lastname', '20%');
+ $this->addColumn($this->lng->txt('firstname'), 'firstname', '20%');
+ $this->addColumn($this->lng->txt('login'), 'login', '20%');
+ $this->addColumn($this->lng->txt('tst_reached_points'), 'reached_points', '20%');
$this->addColumn('', '', '20%');
}
+ private function initOrdering()
+ {
+ $this->enable('sort');
+
+ $this->setDefaultOrderField("lastname");
+ $this->setDefaultOrderDirection("asc");
+ }
+
public function initFilter()
{
$this->setDisableFilterHiding(true);
@@ -128,7 +137,10 @@ public function fillRow($row)
$this->tpl->touchBlock('row_js');
}
- $this->tpl->setVariable('VAL_NAME', $row['participant']->getName());
+ $this->tpl->setVariable('PARTICIPANT_LASTNAME', $row['lastname']);
+ $this->tpl->setVariable('PARTICIPANT_FIRSTNAME', $row['firstname']);
+ $this->tpl->setVariable('PARTICIPANT_LOGIN', $row['login']);
+
$reached_points = new ilNumberInputGUI('', 'scoring[' . $row['pass_id'] . '][' . $row['active_id'] . '][' . $row['qst_id'] . ']');
$reached_points->allowDecimals(true);
$reached_points->setSize(5);
diff --git a/Modules/Test/classes/tables/class.ilTestQuestionBrowserTableGUI.php b/Modules/Test/classes/tables/class.ilTestQuestionBrowserTableGUI.php
index 4d00e6ac9209..3948b6e478e0 100644
--- a/Modules/Test/classes/tables/class.ilTestQuestionBrowserTableGUI.php
+++ b/Modules/Test/classes/tables/class.ilTestQuestionBrowserTableGUI.php
@@ -415,6 +415,7 @@ public function initFilter()
require_once 'Services/Form/classes/class.ilRepositorySelectorInputGUI.php';
$ri = new ilRepositorySelectorInputGUI($this->lng->txt('repository'), 'repository_root_node');
$ri->setHeaderMessage($this->lng->txt('question_browse_area_info'));
+ $ri->setClickableTypes(array('qpl'));
$this->addFilterItem($ri);
$ri->readFromSession();
$this->filter['repository_root_node'] = $ri->getValue();
diff --git a/Modules/Test/classes/tables/class.ilTestQuestionsTableGUI.php b/Modules/Test/classes/tables/class.ilTestQuestionsTableGUI.php
index 1812a667e143..110b153fa415 100644
--- a/Modules/Test/classes/tables/class.ilTestQuestionsTableGUI.php
+++ b/Modules/Test/classes/tables/class.ilTestQuestionsTableGUI.php
@@ -46,7 +46,7 @@ class ilTestQuestionsTableGUI extends ilTable2GUI
protected $obligatoryQuestionsHandlingEnabled = false;
/**
- * @var int
+ * @var float
*/
protected $totalPoints = 0;
@@ -450,17 +450,17 @@ public function setObligatoryQuestionsHandlingEnabled(bool $obligatoryQuestionsH
}
/**
- * @return int
+ * @return float
*/
- public function getTotalPoints() : int
+ public function getTotalPoints() : float
{
return $this->totalPoints;
}
/**
- * @param int $totalPoints
+ * @param float $totalPoints
*/
- public function setTotalPoints(int $totalPoints)
+ public function setTotalPoints(float $totalPoints)
{
$this->totalPoints = $totalPoints;
}
diff --git a/Modules/Test/templates/default/tpl.exam_id_block.html b/Modules/Test/templates/default/tpl.exam_id_block.html
new file mode 100644
index 000000000000..8dd2564e5c28
--- /dev/null
+++ b/Modules/Test/templates/default/tpl.exam_id_block.html
@@ -0,0 +1 @@
+
{EXAM_ID_TXT} {EXAM_ID_VAL}
\ No newline at end of file
diff --git a/Modules/Test/templates/default/tpl.il_as_tst_answers_compare.html b/Modules/Test/templates/default/tpl.il_as_tst_answers_compare.html
index a3f9b046b1ff..84ed35953e19 100644
--- a/Modules/Test/templates/default/tpl.il_as_tst_answers_compare.html
+++ b/Modules/Test/templates/default/tpl.il_as_tst_answers_compare.html
@@ -2,6 +2,10 @@