Skip to content

Commit

Permalink
Version 1.2
Browse files Browse the repository at this point in the history
  • Loading branch information
fneumann committed Jan 21, 2024
2 parents fa0a481 + f4b7aaa commit 3c6b241
Show file tree
Hide file tree
Showing 26 changed files with 801 additions and 192 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Change log

## Version 1.2 (2042-01-21)
- fixed error with ascii control characters when written text is processed
- fixed juristic headline scheme
- added settings for processing written text (paragraph numbers, correction margins)
- added settings for pdf generation (heqader, footer, margins)
- improved pdf layout for written text and correction
- check existence of corrector comments for pdf upload and editor settings
- removed "Pilot" from language variables

## Version 1.1 (2023-12-20)

- First published version of the plugin for ILIAS 7
27 changes: 21 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# LongEssayAssessment (Pilot Version)
# LongEssayAssessment
Plugin for the LMS ILIAS open source to realize exams with writing of long texts.

This pilot version is currently **under development** to complete the functionality required by the [EDUTIEK project](https://www.edutiek.de).
The EDUTIEK project (acronym for "Einfache Durchführung textintensiver E-Klausuren") is developing a comprehensive software solution for online exams in subjects in which longer texts have to be submitted as exam solutions. These include law, history, linguistics, philosophy, sociology and many more.

An initial set of features is available in the **pre-test version** named LongEssayTask which is maintained in a different [GitHub repository](https://github.com/fneumann/LongEssayTask).
The "Long Essay Assessment" is a repository object and bundles all functions for the realisation of a text exam. Responsibilities for creating, carrying out and correcting tasks are assigned to different people via the authorisation system. Support material can be provided for editing and correction is supported by an evaluation scheme. All results can be output in PDF/A format for documentation purposes.

The integrated "Writer" is a specialised editing page for examinees during the exam. The text editor and the task or additional material can be displayed side by side or on a full page. All editing steps are logged and are reversible. Even if the network is interrupted, you can continue writing and the editing steps will be saved afterwards. At the end of the editing time, the written text is displayed for review and its submission is finally confirmed.

The integrated "Corrector" is a specialised editing page for the proofreaders. In the submitted text, passages are marked and provided with comments. With each comment, partial points can be awarded based on the evaluation scheme. The text and comments are clearly displayed next to each other, optionally also with the comments from the first correction in the case of a second correction. To create the overall vote, a proposal for the final grade is calculated from the sum of the partial points, which can be accepted or changed. The vote can be used to create a textual overall assessment.

## Installation

Expand All @@ -22,8 +26,19 @@ An initial set of features is available in the **pre-test version** named LongEs
composer install --no-dev
````

## History
Please clear your browser cache after an update before you start the writing and ccorrection screens.

## Branches and Versions

The plugin is published for ILIAS in different branches:

* **release1_ilias7** will receive bug fixes only
* **release2_ilias8** will be created by March 2024
* **main** is the current development branch. Please do not use it for production.

Versions 2.x will receive bug fixes as well as new features without breaking existing functionality and data.
Please consult the [CHANGELOG](CHANGELOG.md) to see the different versions.

### Version 1.1 (2023-12-20)
## Known Issues

- First published version of the plugin for ILIAS 7
The writing and correction of exams is tested with Firefox and Chrome, so modern Chromium based browser should work. We know about issues with older Safari browsers. Please test with you local system before writing an exam and offer a tryout service for students who should write on their own device.
5 changes: 2 additions & 3 deletions classes/Corrector/class.CorrectorContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
use ILIAS\Plugin\LongEssayAssessment\Data\Essay\CorrectorComment;
use ILIAS\Plugin\LongEssayAssessment\Data\Essay\CriterionPoints;
use ILIAS\Plugin\LongEssayAssessment\Data\Task\CorrectionSettings as PluginCorrectionSettings;
use Edutiek\LongEssayAssessmentService\Data\CorrectionPage;
use Edutiek\LongEssayAssessmentService\Data\PageData;
use Edutiek\LongEssayAssessmentService\Data\CorrectionMark;
use Edutiek\LongEssayAssessmentService\Data\CorrectionPreferences;
use ILIAS\Plugin\LongEssayAssessment\Data\Corrector\CorrectorPreferences;
Expand Down Expand Up @@ -518,9 +518,8 @@ public function getPagesOfItem(string $item_key): array
(int) $item_key, $this->task->getTaskId()))
) {
foreach ($essay_repo->getEssayImagesByEssayID($repoEssay->getId()) as $repoImage) {
$pages[] = new CorrectionPage(
$pages[] = new PageData(
(string) $repoImage->getId(),
$item_key,
$repoImage->getPageNo(),
$repoImage->getWidth(),
$repoImage->getHeight(),
Expand Down
2 changes: 1 addition & 1 deletion classes/Corrector/class.CorrectorStartGUI.php
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ protected function downloadWrittenPdf()
$params = $this->request->getQueryParams();
$writer_id = (int) ($params['writer_id'] ?? 0);

$service = $this->localDI->getCorrectorAdminService($this->object->getId());
$service = $this->localDI->getWriterAdminService($this->object->getId());
$repoWriter = $this->localDI->getWriterRepo()->getWriterById($writer_id);

$filename = 'task' . $this->object->getId() . '_writer' . $repoWriter->getId(). '-writing.pdf';
Expand Down
2 changes: 1 addition & 1 deletion classes/CorrectorAdmin/class.CorrectorAdminGUI.php
Original file line number Diff line number Diff line change
Expand Up @@ -434,7 +434,7 @@ protected function downloadWrittenPdf()
$params = $this->request->getQueryParams();
$writer_id = (int) ($params['writer_id'] ?? 0);

$service = $this->localDI->getCorrectorAdminService($this->object->getId());
$service = $this->localDI->getWriterAdminService($this->object->getId());
$repoWriter = $this->localDI->getWriterRepo()->getWriterById($writer_id);

$filename = 'task' . $this->object->getId() . '_writer' . $repoWriter->getId(). '-writing.pdf';
Expand Down
31 changes: 2 additions & 29 deletions classes/CorrectorAdmin/class.CorrectorAdminService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,14 @@
use ILIAS\Plugin\LongEssayAssessment\Data\Task\CorrectionSettings;
use ILIAS\Plugin\LongEssayAssessment\Data\Corrector\Corrector;
use ILIAS\Plugin\LongEssayAssessment\Data\Corrector\CorrectorAssignment;
use ILIAS\Plugin\LongEssayAssessment\Data\Corrector\CorrectorRepository;
use ILIAS\Plugin\LongEssayAssessment\Data\Essay\CorrectorSummary;
use ILIAS\Plugin\LongEssayAssessment\Data\DataService;
use ILIAS\Plugin\LongEssayAssessment\Data\Essay\Essay;
use ILIAS\Plugin\LongEssayAssessment\Data\Essay\EssayRepository;
use ILIAS\Plugin\LongEssayAssessment\Data\Object\GradeLevel;
use ILIAS\Plugin\LongEssayAssessment\Data\Task\LogEntry;
use ILIAS\Plugin\LongEssayAssessment\Data\Task\TaskRepository;
use ILIAS\Plugin\LongEssayAssessment\Data\Task\TaskSettings;
use ILIAS\Plugin\LongEssayAssessment\Data\Writer\Writer;
use ILIAS\Plugin\LongEssayAssessment\Data\Writer\WriterRepository;
use ILIAS\Data\UUID\Factory as UUID;
use ilObjUser;

Expand Down Expand Up @@ -429,14 +426,15 @@ public function createCorrectionsExport(\ilObjLongEssayAssessment $object) : str
$storage->createDir($zipdir);

$repoTask = $this->taskRepo->getTaskSettingsById($object->getId());
$writerAdminService = $this->localDI->getWriterAdminService($repoTask->getTaskId());
foreach ($this->essayRepo->getEssaysByTaskId($repoTask->getTaskId()) as $repoEssay) {
$repoWriter = $this->writerRepo->getWriterById($repoEssay->getWriterId());

$subdir = \ilUtil::getASCIIFilename(\ilObjUser::_lookupFullname($repoWriter->getUserId()) . ' (' . \ilObjUser::_lookupLogin($repoWriter->getUserId()) . ')');
$storage->createDir($zipdir . '/' . $subdir);

$filename = $subdir . '-writing.pdf';
$storage->write($zipdir . '/' . $subdir. '/'. $filename, $this->getWritingAsPdf($object, $repoWriter));
$storage->write($zipdir . '/' . $subdir. '/'. $filename, $writerAdminService->getWritingAsPdf($object, $repoWriter));

$filename = $subdir . '-correction.pdf';
$storage->write($zipdir . '/' . $subdir. '/'. $filename, $this->getCorrectionAsPdf($object, $repoWriter));
Expand All @@ -453,32 +451,7 @@ public function createCorrectionsExport(\ilObjLongEssayAssessment $object) : str
//$delivery = new \ilFileDelivery()
}

/**
* Get the writing of an essay as PDF string
*/
public function getWritingAsPdf(\ilObjLongEssayAssessment $object, Writer $repoWriter, $anonymous = false)
{
$context = new CorrectorContext();
$context->init((string) $this->dic->user()->getId(), (string) $object->getRefId());

$writingTask = $context->getWritingTaskByWriterId($repoWriter->getId());
if ($anonymous) {
$writingTask = $writingTask->withWriterName($repoWriter->getPseudonym());
}
$writtenEssay = $context->getEssayOfItem((string) $repoWriter->getId());

$item = new DocuItem(
(string) $repoWriter->getId(),
$writingTask,
$writtenEssay,
[],
[],
);

$service = new Service($context);
return $service->getWritingAsPdf($item);
}

/**
* Get the correction of an essay as PDF string
* if a repo corrector is given as parameter, then only this correction is included, not other correctors
Expand Down
18 changes: 14 additions & 4 deletions classes/Data/Essay/class.EssayRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -229,16 +229,26 @@ public function getCorrectorCommentById(int $id) : ?RecordData

/**
* @param int $essay_id
* @param int $corrector_id
* @param int|null $corrector_id
* @return CorrectorComment[]
*/
public function getCorrectorCommentsByEssayIdAndCorrectorId(int $essay_id, int $corrector_id): array
public function getCorrectorCommentsByEssayIdAndCorrectorId(int $essay_id, ?int $corrector_id = null): array
{
$query = "SELECT * FROM " . CorrectorComment::tableName() . " WHERE essay_id = " . $this->db->quote($essay_id, 'integer') .
" AND corrector_id = ". $this->db->quote($corrector_id, 'integer');
$query = "SELECT * FROM " . CorrectorComment::tableName() . " WHERE essay_id = " . $this->db->quote($essay_id, 'integer');
if (isset($corrector_id)) {
$query .= " AND corrector_id = ". $this->db->quote($corrector_id, 'integer');;
}
return $this->queryRecords($query, CorrectorComment::model());
}

public function hasCorrectorCommentsByTaskId(int $task_id)
{
$query = "SELECT c.id FROM xlas_corrector_comment m JOIN xlas_corrector c ON m.corrector_id = c.id WHERE c.task_id = "
. $this->db->quote($task_id, 'integer') . ' LIMIT 1';

return !empty($this->getIntegerList($query, 'id'));
}

/**
* @param int $id
* @return CriterionPoints|null
Expand Down
6 changes: 3 additions & 3 deletions classes/Data/Object/class.ObjectRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ public function __construct(
}

/**
* @return ObjectSettings|null
* @return ObjectSettings
*/
public function getObjectSettingsById(int $a_id): ?RecordData
public function getObjectSettingsById(int $a_id): RecordData
{
$query = "SELECT * FROM xlas_object_settings WHERE obj_id = " . $this->db->quote($a_id, 'integer');
return $this->getSingleRecord($query, ObjectSettings::model());
return $this->getSingleRecord($query, ObjectSettings::model(), new ObjectSettings($a_id));
}

public function ifGradeLevelExistsById(int $a_id): bool
Expand Down
108 changes: 68 additions & 40 deletions classes/Data/Task/class.EditorSettings.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,14 +29,22 @@ class EditorSettings extends RecordData
'headline_scheme'=> 'text',
'formatting_options' => 'text',
'notice_boards' => 'integer',
'copy_allowed' => 'integer'
'copy_allowed' => 'integer',
'add_paragraph_numbers' => 'integer',
'add_correction_margin' => 'integer',
'left_correction_margin' => 'integer',
'right_correction_margin' => 'integer'
];

protected int $task_id;
protected string $headline_scheme = self::HEADLINE_SCHEME_NONE;
protected string $formatting_options = self::FORMATTING_OPTIONS_MEDIUM;
protected int $notice_boards = 0;
protected int $copy_allowed = 0;
protected int $add_paragraph_numbers = 1;
protected int $add_correction_margin = 0;
protected int $left_correction_margin = 0;
protected int $right_correction_margin = 0;

public function __construct(int $task_id)
{
Expand All @@ -47,68 +55,48 @@ public static function model() {
return new self(0);
}

/**
* @return string
*/
public function getHeadlineScheme(): string
{
return (string)$this->headline_scheme;
return $this->headline_scheme;
}

/**
* @param ?string $headline_scheme
*/
public function setHeadlineScheme(?string $headline_scheme): void
public function setHeadlineScheme(?string $headline_scheme): self
{
$this->headline_scheme = (string)$headline_scheme;
return $this;
}

/**
* @return string
*/
public function getFormattingOptions(): string
{
return (string)$this->formatting_options;
return $this->formatting_options;
}

/**
* @param ?string $formatting_options
*/
public function setFormattingOptions(?string $formatting_options): void
public function setFormattingOptions(?string $formatting_options): self
{
$this->formatting_options = (string)$formatting_options;
$this->formatting_options = (string) $formatting_options;
return $this;
}

/**
* @return int
*/
public function getNoticeBoards(): int
{
return (int)$this->notice_boards;
return $this->notice_boards;
}

/**
* @param ?int $notice_boards
*/
public function setNoticeBoards(?int $notice_boards): void
public function setNoticeBoards(?int $notice_boards): self
{
$this->notice_boards = $notice_boards;
return $this;
}

/**
* @return bool
*/
public function isCopyAllowed(): bool
{
return (bool)$this->copy_allowed;
return (bool )$this->copy_allowed;
}

/**
* @param ?bool $copy_allowed
*/
public function setCopyAllowed(?bool $copy_allowed): void
public function setCopyAllowed(?bool $copy_allowed): self
{
$this->copy_allowed = (int)$copy_allowed;
$this->copy_allowed = (int) $copy_allowed;
return $this;
}

/**
Expand All @@ -119,13 +107,53 @@ public function getTaskId(): int
return $this->task_id;
}

/**
* @param int $task_id
* @return EditorSettings
*/
public function setTaskId(int $task_id): EditorSettings
public function setTaskId(int $task_id): self
{
$this->task_id = $task_id;
return $this;
}

public function getAddParagraphNumbers() : bool
{
return (bool) $this->add_paragraph_numbers;
}

public function setAddParagraphNumbers(bool $add_paragraph_numbers) : self
{
$this->add_paragraph_numbers = (int) $add_paragraph_numbers;
return $this;
}

public function getAddCorrectionMargin() : bool
{
return (bool) $this->add_correction_margin;
}

public function setAddCorrectionMargin(bool $add_correction_margin) : self
{
$this->add_correction_margin = (int) $add_correction_margin;
return $this;
}

public function getLeftCorrectionMargin() : int
{
return $this->left_correction_margin;
}

public function setLeftCorrectionMargin(int $left_correction_margin) : self
{
$this->left_correction_margin = $left_correction_margin;
return $this;
}

public function getRightCorrectionMargin() : int
{
return $this->right_correction_margin;
}

public function setRightCorrectionMargin(int $right_correction_margin) : self
{
$this->right_correction_margin = $right_correction_margin;
return $this;
}
}
Loading

0 comments on commit 3c6b241

Please sign in to comment.