Skip to content
Snippets Groups Projects
Commit 3d8cb20a authored by Thomas Hackl's avatar Thomas Hackl
Browse files

Resolve "Erweiterung Courseware: Zertifikate, Erinnerungen und Rücksetzen des Fortschritts"

Closes #1660

Merge request studip/studip!1172
parent d22c048e
No related branches found
No related tags found
No related merge requests found
<?php
require_once('lib/cronjobs/courseware.php');
class CoursewareCronEvents extends Migration
{
public function description()
{
return 'Prepares database tables for storing timestamps of courseware cron events, ' .
'like certificate sending and reminders.';
}
public function up()
{
// Create a table for certificates
DBManager::get()->exec("CREATE TABLE IF NOT EXISTS `cw_certificates` (
`id` CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`user_id` CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`course_id` CHAR(32) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL,
`mkdate` INT(11) NOT NULL,
PRIMARY KEY (`id`),
INDEX index_user_id (`user_id`),
INDEX index_course_id (`course_id`),
INDEX index_user_ourse (`user_id`, `course_id`)
)");
CoursewareCronjob::register()->schedulePeriodic(41, 1)->activate();
}
public function down()
{
CoursewareCronjob::unregister();
DBManager::get()->exec("DROP TABLE IF EXISTS `cw_certificates`");
$fields = [
'COURSEWARE_CERTIFICATE_SETTINGS',
'COURSEWARE_REMINDER_SETTINGS',
'COURSEWARE_RESET_PROGRESS_SETTINGS',
'COURSEWARE_LAST_REMINDER',
'COURSEWARE_LAST_PROGRESS_RESET'
];
DBManager::get()->execute("DELETE FROM `config` WHERE `field` IN (:fields)",
['fields' => $fields]);
DBManager::get()->execute("DELETE FROM `config_values` WHERE `field` IN (:fields)",
['fields' => $fields]);
}
}
<?php
class CoursewarePDFCertificate extends TCPDF
{
public function __construct($background = false, $orientation = 'P', $unit = 'mm', $format = 'A4', $unicode = true, $encoding = 'UTF-8')
{
$this->config = Config::get();
if ($this->config->getValue('LOAD_EXTERNAL_MEDIA') === 'proxy') {
$this->media_proxy = new MediaProxy();
}
parent::__construct($orientation, $unit, $format, $unicode, $encoding, false);
if ($background) {
$fileRef = FileRef::find($background);
$this->background = $fileRef->file->getPath();
} else {
$this->background = $GLOBALS['STUDIP_BASE_PATH'] . '/public/assets/images/pdf/pdf_default_background.jpg';
}
$this->setDefaults();
}
public function Header()
{
$bMargin = $this->getBreakMargin();
$auto_page_break = $this->AutoPageBreak;
$this->SetAutoPageBreak(false, 0);
$this->Image($this->background, 0, 0, 210, 297, '', '', '', false, 300, '', false, false, 0);
$this->setFont('helvetica', 'B', 50);
$this->Cell(0, 160, 'Z E R T I F I K A T', 0, false, 'C', 0, '', 0, false, 'T', 'M');
$this->SetAutoPageBreak($auto_page_break, $bMargin);
$this->setPageMark();
}
private function setDefaults()
{
$this->SetTopMargin(110);
$this->SetLeftMargin(20);
$this->SetRightMargin(20);
}
}
......@@ -78,6 +78,30 @@ class CoursewareInstancesUpdate extends JsonApiController
return 'Attribute `editing-permission-level` contains an invalid value.';
}
}
if (self::arrayHas($json, 'data.attributes.certificate-settings')) {
$certificateSettings = self::arrayGet($json, 'data.attributes.certificate-settings');
if (!$resource->isValidCertificateSettings($certificateSettings)) {
return 'Attribute `certificate-settings` contains an invalid value.';
}
}
if (self::arrayHas($json, 'data.attributes.reminder-settings')) {
$reminderSettings = self::arrayGet($json, 'data.attributes.reminder-settings');
if (!$resource->isValidReminderSettings($reminderSettings)) {
return 'Attribute `reminder-settings` contains an invalid value.';
}
}
if (self::arrayHas($json, 'data.attributes.reset-progress-settings')) {
$resetProgressSettings = self::arrayGet($json, 'data.attributes.reset-progress-settings');
if (!$resource->isValidResetProgressSettings($resetProgressSettings)) {
return 'Attribute `reset-progress-settings` contains an invalid value.';
}
}
}
private function updateInstance(\User $user, Instance $instance, array $json): Instance
......@@ -95,6 +119,15 @@ class CoursewareInstancesUpdate extends JsonApiController
$editingPermissionLevel = $get('data.attributes.editing-permission-level');
$instance->setEditingPermissionLevel($editingPermissionLevel);
$certificateSettings = $get('data.attributes.certificate-settings');
$instance->setCertificateSettings($certificateSettings);
$reminderSettings = $get('data.attributes.reminder-settings');
$instance->setReminderSettings($reminderSettings);
$resetProgressSettings = $get('data.attributes.reset-progress-settings');
$instance->setResetProgressSettings($resetProgressSettings);
return $instance;
}
}
......@@ -36,6 +36,9 @@ class Instance extends SchemaProvider
'favorite-block-types' => $resource->getFavoriteBlockTypes($user),
'sequential-progression' => (bool) $resource->getSequentialProgression(),
'editing-permission-level' => $resource->getEditingPermissionLevel(),
'certificate-settings' => $resource->getCertificateSettings(),
'reminder-settings' => $resource->getReminderSettings(),
'reset-progress-settings' => $resource->getResetProgressSettings()
];
}
......
<?php
/**
* courseware.php
*
* @author Thomas Hackl <hackl@data-quest.de>
* @access public
* @since 5.3
*/
class CoursewareCronjob extends CronJob
{
public static function getName()
{
return _('Courseware-Erinnerungen und -zertifikate verschicken sowie Fortschritt zurücksetzen');
}
public static function getDescription()
{
return _('Versendet Erinnerungen, Zertifikate bei Erreichen eines bestimmten Fortschritts und setzt ' .
'Fortschritt bei derartig konfigurierten Coursewares zurück.');
}
public static function getParameters()
{
return [
'verbose' => [
'type' => 'boolean',
'default' => false,
'status' => 'optional',
'description' => _('Sollen Ausgaben erzeugt werden (sind später im Log des Cronjobs sichtbar)'),
]
];
}
public function setUp()
{
}
public function execute($last_result, $parameters = [])
{
$verbose = $parameters['verbose'];
/*
* Fetch all courses that have some relevant settings.
*/
$todo = DBManager::get()->fetchAll(
"SELECT c.`range_id`, c. `field`, c.`value`
FROM `config_values` c
JOIN `seminare` s ON (s.`Seminar_id` = c.`range_id`)
WHERE c.`field` IN (:fields)",
['fields' => [
// Send certificate when this progress is reached
'COURSEWARE_CERTIFICATE_SETTINGS',
// Remind all users about courseware
'COURSEWARE_REMINDER_SETTINGS',
// Reset user progress to 0
'COURSEWARE_RESET_PROGRESS_SETTINGS'
]
]
);
if (count($todo) > 0) {
if ($verbose) {
echo sprintf("Found %u courses to process.\n", count($todo));
}
$timezone = Config::get()->DEFAULT_TIMEZONE;
// Process all found entries...
foreach ($todo as $one) {
// Fetch all courseware blocks belonging to the current course.
$blocks = DBManager::get()->fetchFirst(
"SELECT DISTINCT b.`id`
FROM `cw_blocks` b
JOIN `cw_containers` c ON (c.`id` = b.`container_id`)
JOIN `cw_structural_elements` e ON (e.`id` = c.`structural_element_id`)
WHERE e.`range_id` = :course",
['course' => $one['range_id']]
);
// extract details from JSON
$settings = json_decode($one['value'], true);
// differentiate by setting type
switch ($one['field']) {
// Send certificates to those who have progressed far enough and have not yet gotten one.
case 'COURSEWARE_CERTIFICATE_SETTINGS':
if ($verbose) {
echo sprintf("Generating certificates for course %s.\n",
$one['range_id']);
}
// Fetch accumulated progress values for all users in this course.
$progresses = DBManager::get()->fetchAll(
"SELECT DISTINCT p.`user_id`, SUM(p.`grade`) AS progress
FROM `cw_user_progresses` p
WHERE `block_id` IN (:blocks)
AND NOT EXISTS (
SELECT `id` FROM `cw_certificates` WHERE `user_id` = p.`user_id` AND `course_id` = :course
)
GROUP BY `user_id`",
['blocks' => $blocks, 'course' => $one['range_id']]
);
// Calculate percentual progress and send certificates if necessary.
foreach ($progresses as $progress) {
$percent = ($progress['progress'] / count($blocks)) * 100;
if ($percent >= $settings['threshold']) {
if ($verbose) {
echo sprintf("User %s will get a certificate for course %s.\n",
$progress['user_id'], $one['range_id']);
}
$this->sendCertificate($one['range_id'], $progress['user_id'],
$percent, $settings);
/*
* Insert a new entry into database for tracking who already got a certificate.
* This can be useful if certificates get a validity time or such.
*/
$entry = new Courseware\Certificate();
$entry->user_id = $progress['user_id'];
$entry->course_id = $one['range_id'];
$entry->store();
}
}
break;
// Send reminders to all course participants.
case 'COURSEWARE_REMINDER_SETTINGS':
// Check when the last reminder was sent...
$now = new DateTime('', new DateTimeZone($timezone));
// What would be the minimum date for the last reminder?
$minReminder = clone $now;
// The last reminder has been sent at?
$lastReminder = new DateTime('', new DateTimeZone($timezone));
$lastReminder->setTimestamp(
UserConfig::get($one['range_id'])->COURSEWARE_LAST_REMINDER ?: 0
);
// Check if the settings specify a start and/or end date for reminders
$start = new DateTime($settings['startDate'] ?: '1970-01-01',
new DateTimeZone($timezone));
$end = new DateTime($settings['endDate'] ?: '2199-12-31',
new DateTimeZone($timezone));
$interval = new DateInterval('P1D');
switch ($settings['interval']) {
case 7:
$interval = new DateInterval('P7D');
break;
case 14:
$interval = new DateInterval('P14D');
break;
case 30:
$interval = new DateInterval('P1M');
break;
case 90:
$interval = new DateInterval('P3M');
break;
case 180:
$interval = new DateInterval('P6M');
break;
case 365:
$interval = new DateInterval('P1Y');
break;
}
$minReminder->sub($interval);
// ... and send a new one if necessary.
if ($lastReminder <= $minReminder && $now >= $start && $now <= $end) {
if ($verbose) {
echo sprintf("Sending reminders for course %s.\n",
$one['range_id']);
}
if ($this->sendReminders($one['range_id'], $settings)) {
UserConfig::get($one['range_id'])->store('COURSEWARE_LAST_REMINDER',
$now->getTimestamp()
);
}
}
break;
// Reset courseware progress to 0 for all course participants.
case 'COURSEWARE_RESET_PROGRESS_SETTINGS':
// Check when the last reset was performed...
$now = new DateTime('', new DateTimeZone($timezone));
$checkLast = clone $now;
$lastReset = new DateTime('', new DateTimeZone($timezone));
$lastReset->setTimestamp(
UserConfig::get($one['range_id'])->COURSEWARE_LAST_PROGRESS_RESET ?: 0
);
$interval = new DateInterval('P1D');
switch ($one['value']) {
case 14:
$interval = new DateInterval('P14D');
break;
case 30:
$interval = new DateInterval('P1M');
break;
case 90:
$interval = new DateInterval('P3M');
break;
case 180:
$interval = new DateInterval('P6M');
break;
case 365:
$interval = new DateInterval('P1Y');
break;
}
// ... and reset again if necessary.
if ($lastReset <= $checkLast->sub($interval)) {
if ($verbose) {
echo sprintf("Resetting all progress for courseware in course %s.\n",
$one['range_id']);
}
// Remove all progress in the given blocks.
$this->resetProgress($one['range_id'], $blocks, $settings);
UserConfig::get($one['range_id'])->store('COURSEWARE_LAST_PROGRESS_RESET',
$now->getTimestamp()
);
}
}
}
} else if ($verbose) {
echo "Nothing to do.\n";
}
}
private function sendCertificate($course_id, $user_id, $progress, $settings)
{
$user = User::find($user_id);
$course = Course::find($course_id);
$template = $GLOBALS['template_factory']->open('courseware/mails/certificate');
$html = $template->render(
compact('user', 'course')
);
// Generate the PDF.
$pdf = new CoursewarePDFCertificate($settings['image']);
$pdf->AddPage();
$pdf->writeHTML($html, true, false, true, false, '');
$pdf_file_name = $user->nachname . '_' . $course->name . '_' . _('Zertifikat') . '.pdf';
$filename = $GLOBALS['TMP_PATH'] . '/' . $pdf_file_name;
$pdf->Output($filename, 'F');
// Send the mail with PDF attached.
$mail = new StudipMail();
$message = sprintf(
_('Anbei erhalten Sie Ihr Courseware-Zertifikat zur Veranstaltung %1$s, in der Sie einen Fortschritt ' .
'von %2$u %% erreicht haben.'), $course->getFullname(), $progress);
$message .= "\n\n" . _('Über folgenden Link kommen Sie direkt zur Courseware') . ': ' .
URLHelper::getURL('seminar_main.php', ['auswahl' => $course->id,
'redirect_to' => 'dispatch.php/course/courseware']);
$mail->addRecipient($user->email, $user->getFullname())
->setSubject(_('Courseware: Zertifikat') . ' - ' . $course->getFullname())
->setBodyText($message)
->addFileAttachment($filename, $pdf_file_name)
->send();
@unlink($filename);
// Add database entry for the certificate.
}
private function sendReminders($course_id, $settings)
{
$course = Course::find($course_id);
$recipients = $course->getMembersWithStatus('autor', true);
$mail = new StudipMail();
foreach ($recipients as $rec) {
$mail->addRecipient(
$rec->email,
$rec->getUserFullname(),
'bcc'
);
}
$message = $settings['mailText'] . "\n\n" . _('Über folgenden Link kommen Sie direkt zur Courseware') . ': ' .
URLHelper::getURL('seminar_main.php', ['auswahl' => $course->id,
'redirect_to' => 'dispatch.php/course/courseware']);
$mail->setSubject(_('Courseware: Erinnerung') . ' - ' . $course->getFullname())
->setBodyText($message);
return $mail->send();
}
private function resetProgress($course_id, $block_ids, $settings)
{
$course = Course::find($course_id);
DBManager::get()->execute(
"DELETE FROM `cw_user_progresses` WHERE `block_id` IN (:blocks)",
['blocks' => $block_ids]
);
$recipients = $course->getMembersWithStatus('autor', true);
$mail = new StudipMail();
foreach ($recipients as $rec) {
$mail->addRecipient(
$rec->email,
$rec->getUserFullname(),
'bcc'
);
}
$message = $settings['mailText'] . "\n\n" . _('Über folgenden Link kommen Sie direkt zur Courseware') . ': ' .
URLHelper::getURL('seminar_main.php', ['auswahl' => $course->id,
'redirect_to' => 'dispatch.php/course/courseware']);
$mail->setSubject(_('Courseware: Fortschritt zurückgesetzt') . ' - ' . $course->getFullname())
->setBodyText($message);
return $mail->send();
}
}
<?php
namespace Courseware;
use \User, \Course;
/**
* Courseware's certificates.
*
* @author Thomas Hackl <hackl@data-quest.de>
* @license GPL2 or any later version
*
* @since Stud.IP 5.3
*
* @property string $id database column
* @property string $user_id database column
* @property string $course_id database column
* @property int $mkdate database column
*/
class Certificate extends \SimpleORMap
{
protected static function configure($config = [])
{
$config['db_table'] = 'cw_certificates';
$config['belongs_to']['user'] = [
'class_name' => User::class,
'foreign_key' => 'user_id',
];
$config['belongs_to']['course'] = [
'class_name' => Course::class,
'foreign_key' => 'course_id',
];
parent::configure($config);
}
}
......@@ -231,6 +231,161 @@ class Instance
}
}
/**
* Returns the certificate creation settings.
*
* @return array
*/
public function getCertificateSettings(): array
{
$range = $this->getRange();
/** @var array $certificateSettings */
$certificateSettings = json_decode(
$range->getConfiguration()->getValue('COURSEWARE_CERTIFICATE_SETTINGS'),
true
)?: [];
$this->validateCertificateSettings($certificateSettings);
return $certificateSettings;
}
/**
* Sets the certificate settings for this courseware instance.
*
* @param array $certificateSettings an array of parameters
*/
public function setCertificateSettings(array $certificateSettings): void
{
$this->validateCertificateSettings($certificateSettings);
$range = $this->getRange();
$range->getConfiguration()->store('COURSEWARE_CERTIFICATE_SETTINGS',
count($certificateSettings) > 0 ? json_encode($certificateSettings) : null);
}
/**
* Validates certificate settings.
*
* @param array $certificateSettings settings for certificate creation
*
* @return bool true if all given values are valid, false otherwise
*/
public function isValidCertificateSettings(array $certificateSettings): bool
{
return (int) $certificateSettings['threshold'] >= 0 && (int) $certificateSettings['threshold'] <= 100;
}
private function validateCertificateSettings(array $certificateSettings): void
{
if (!$this->isValidCertificateSettings($certificateSettings)) {
throw new \InvalidArgumentException('Invalid certificate settings given.');
}
}
/**
* Returns the reminder message sending settings.
*
* @return array
*/
public function getReminderSettings(): array
{
$range = $this->getRange();
/** @var int $reminderInterval */
$reminderSettings = json_decode(
$range->getConfiguration()->getValue('COURSEWARE_REMINDER_SETTINGS'),
true
)?: [];
$this->validateReminderSettings($reminderSettings);
return $reminderSettings;
}
/**
* Sets the reminder message settings this courseware instance.
*
* @param array $reminderSettings an array of parameters
*/
public function setReminderSettings(array $reminderSettings): void
{
$this->validateReminderSettings($reminderSettings);
$range = $this->getRange();
$range->getConfiguration()->store('COURSEWARE_REMINDER_SETTINGS',
count($reminderSettings) > 0 ? json_encode($reminderSettings) : null);
}
/**
* Validates reminder message settings.
*
* @param array $reminderSettings settings for reminder mail sending
*
* @return bool true if all given values are valid, false otherwise
*/
public function isValidReminderSettings(array $reminderSettings): bool
{
$valid = in_array($reminderSettings['interval'], [0, 7, 14, 30, 90, 180, 365]);
return $valid;
}
private function validateReminderSettings(array $reminderSettings): void
{
if (!$this->isValidReminderSettings($reminderSettings)) {
throw new \InvalidArgumentException('Invalid reminder settings given.');
}
}
/**
* Returns the progress resetting settings.
*
* @return array
*/
public function getResetProgressSettings(): array
{
$range = $this->getRange();
/** @var int $reminderInterval */
$resetProgressSettings = json_decode(
$range->getConfiguration()->getValue('COURSEWARE_RESET_PROGRESS_SETTINGS'),
true
)?: [];
$this->validateResetProgressSettings($resetProgressSettings);
return $resetProgressSettings;
}
/**
* Sets the progress resetting settings this courseware instance.
*
* @param array $reminderSettings an array of parameters
*/
public function setResetProgressSettings(array $resetProgressSettings): void
{
$this->validateResetProgressSettings($resetProgressSettings);
$range = $this->getRange();
$range->getConfiguration()->store('COURSEWARE_RESET_PROGRESS_SETTINGS',
count($resetProgressSettings) > 0 ? json_encode($resetProgressSettings) : null);
}
/**
* Validates progress resetting settings.
*
* @param array $resetProgressSettings settings for progress resetting
*
* @return bool true if all given values are valid, false otherwise
*/
public function isValidResetProgressSettings(array $resetProgressSettings): bool
{
$valid = in_array($resetProgressSettings['interval'], [0, 14, 30, 90, 180, 365]);
return $valid;
}
private function validateResetProgressSettings(array $resetProgressSettings): void
{
if (!$this->isValidResetProgressSettings($resetProgressSettings)) {
throw new \InvalidArgumentException('Invalid progress resetting settings given.');
}
}
/**
* Returns all bookmarks of a user associated to this courseware instance.
*
......
public/assets/images/pdf/pdf_default_background.jpg

133 KiB

......@@ -2,37 +2,195 @@
<div class="cw-tools cw-tools-admin">
<form class="default" @submit.prevent="">
<fieldset>
<legend><translate>Allgemeine Einstellungen</translate></legend>
<legend>{{ $gettext('Allgemeine Einstellungen') }}</legend>
<label>
<span><translate>Art der Inhaltsabfolge</translate></span>
<span>{{ $gettext('Art der Inhaltsabfolge') }}</span>
<select class="size-s" v-model="currentProgression">
<option value="0"><translate>Frei</translate></option>
<option value="1"><translate>Sequentiell</translate></option>
<option value="0">{{ $gettext('Frei') }}</option>
<option value="1">{{ $gettext('Sequentiell') }}</option>
</select>
</label>
<label>
<span><translate>Editierberechtigung für Tutor/-innen</translate></span>
<span>{{ $gettext('Editierberechtigung für Tutor/-innen') }}</span>
<select class="size-s" v-model="currentPermissionLevel">
<option value="dozent"><translate>Nein</translate></option>
<option value="tutor"><translate>Ja</translate></option>
<option value="dozent">{{ $gettext('Nein') }}</option>
<option value="tutor">{{ $gettext('Ja') }}</option>
</select>
</label>
</fieldset>
<fieldset>
<legend>
{{ $gettext('Zertifikate') }}
</legend>
<label>
<input type="checkbox" name="makecert" v-model="makeCert">
<span>
{{ $gettext('Zertifikat bei Erreichen einer Fortschrittsgrenze versenden') }}
</span>
<studip-tooltip-icon :text="$gettext('Erreicht eine Person in diesem Lernmaterial den ' +
'hier eingestellten Fortschritt, so erhält Sie ein PDF-Zertifikat per E-Mail.')"/>
</label>
<label v-if="makeCert">
<span>
{{ $gettext('Erforderlicher Fortschritt (in Prozent), um ein Zertifikat zu erhalten') }}
</span>
<input type="number" min="1" max="100" name="threshold" v-model="certThreshold">
</label>
<label v-if="makeCert">
<span>
{{ $gettext('Hintergrundbild des Zertifikats wählen') }}
</span>
<courseware-file-chooser :isImage="true" v-model="certImage"
@selectFile="updateCertImage"></courseware-file-chooser>
</label>
</fieldset>
<fieldset>
<legend>
{{ $gettext('Erinnerungen') }}
</legend>
<label>
<input type="checkbox" name="sendreminders" v-model="sendReminders">
<span>
{{ $gettext('Erinnerungsnachrichten an alle Teilnehmenden schicken') }}
</span>
<studip-tooltip-icon :text="$gettext('Hier können periodisch Nachrichten an alle ' +
'Teilnehmenden verschickt werden, um z.B. an die Bearbeitung dieses Lernmaterials zu erinnern.')"/>
</label>
<label v-if="sendReminders">
<span>
{{ $gettext('Zeitraum zwischen Erinnerungen') }}
</span>
<select name="reminder_interval" v-model="reminderInterval">
<option value="7">
{{ $gettext('wöchentlich') }}
</option>
<option value="14">
{{ $gettext('14-tägig') }}
</option>
<option value="30">
{{ $gettext('monatlich') }}
</option>
<option value="90">
{{ $gettext('vierteljährlich') }}
</option>
<option value="180">
{{ $gettext('halbjährlich') }}
</option>
<option value="365">
{{ $gettext('jährlich') }}
</option>
</select>
</label>
<label v-if="sendReminders" class="col-3">
<span>
{{ $gettext('Erstmalige Erinnerung am') }}
<input type="date" name="reminder_start_date"
v-model="reminderStartDate">
</span>
</label>
<label v-if="sendReminders" class="col-3">
<span>
{{ $gettext('Letztmalige Erinnerung am') }}
<input type="date" name="reminder_end_date"
v-model="reminderEndDate">
</span>
</label>
<label v-if="sendReminders">
<span>
{{ $gettext('Text der Erinnerungsmail') }}
<textarea cols="70" rows="4" name="reminder_mail_text" data-editor="minimal"
v-model="reminderMailText"></textarea>
</span>
</label>
</fieldset>
<fieldset>
<legend>
{{ $gettext('Fortschritt') }}
</legend>
<label>
<input type="checkbox" name="resetprogress" v-model="resetProgress">
<span>
{{ $gettext('Fortschritt periodisch auf 0 zurücksetzen') }}
</span>
<studip-tooltip-icon :text="$gettext('Hier kann eingestellt werden, den Fortschritt ' +
'aller Teilnehmenden periodisch auf 0 zurückzusetzen.')"/>
</label>
<label v-if="resetProgress">
<span>
{{ $gettext('Zeitraum zum Rücksetzen des Fortschritts') }}
</span>
<select name="reset_progress_interval" v-model="resetProgressInterval">
<option value="14">
{{ $gettext('14-tägig') }}
</option>
<option value="30">
{{ $gettext('monatlich') }}
</option>
<option value="90">
{{ $gettext('vierteljährlich') }}
</option>
<option value="180">
{{ $gettext('halbjährlich') }}
</option>
<option value="365">
{{ $gettext('jährlich') }}
</option>
</select>
</label>
<label v-if="resetProgress" class="col-3">
<span>
{{ $gettext('Erstmaliges Zurücksetzen am') }}
<input type="date" dataformatas="" name="reset_progress_start_date"
v-model="resetProgressStartDate">
</span>
</label>
<label v-if="resetProgress" class="col-3">
<span>
{{ $gettext('Letztmaliges Zurücksetzen am') }}
<input type="date" name="reset_progress_end_date"
v-model="resetProgressEndDate">
</span>
</label>
<label v-if="resetProgress">
<span>
{{ $gettext('Text der Rücksetzungsmail') }}
<textarea cols="70" rows="4" name="reset_progress_mail_text" data-editor="minimal"
v-model="resetProgressMailText"></textarea>
</span>
</label>
</fieldset>
</form>
<button class="button" @click="store"><translate>Übernehmen</translate></button>
<button class="button" @click="store">{{ $gettext('Übernehmen') }}</button>
</div>
</template>
<script>
import { mapActions, mapGetters } from 'vuex';
import CoursewareFileChooser from "./CoursewareFileChooser.vue";
import StudipTooltipIcon from '../StudipTooltipIcon.vue';
export default {
name: 'cw-tools-admin',
components: { StudipTooltipIcon, CoursewareFileChooser },
data() {
return {
currentPermissionLevel: '',
currentProgression: '',
makeCert: false,
certThreshold: 0,
certImage: '',
sendReminders: false,
reminderInterval: 7,
reminderStartDate: '',
reminderEndDate: '',
reminderMailText: '',
resetProgress: false,
resetProgressInterval: 180,
resetProgressStartDate: '',
resetProgressEndDate: '',
resetProgressMailText: ''
};
},
computed: {
......@@ -46,8 +204,28 @@ export default {
companionSuccess: 'companionSuccess',
}),
initData() {
console.log(this.courseware.attributes);
this.currentPermissionLevel = this.courseware.attributes['editing-permission-level'];
this.currentProgression = this.courseware.attributes['sequential-progression'] ? '1' : '0';
this.certSettings = this.courseware.attributes['certificate-settings'];
this.makeCert = typeof(this.certSettings) === 'object' &&
Object.keys(this.certSettings).length > 0;
this.certThreshold = this.certSettings.threshold;
this.certImage = this.certSettings.image;
this.reminderSettings = this.courseware.attributes['reminder-settings'];
this.sendReminders = typeof(this.reminderSettings) === 'object' &&
Object.keys(this.reminderSettings).length > 0;
this.reminderInterval = this.reminderSettings.interval;
this.reminderStartDate = this.reminderSettings.startDate;
this.reminderEndDate = this.reminderSettings.endDate;
this.reminderMailText = this.reminderSettings.mailText;
this.resetProgressSettings = this.courseware.attributes['reset-progress-settings'];
this.resetProgress = typeof(this.resetProgressSettings) === 'object' &&
Object.keys(this.resetProgressSettings).length > 0;
this.resetProgressInterval = this.resetProgressSettings.interval;
this.resetProgressStartDate = this.resetProgressSettings.startDate;
this.resetProgressEndDate = this.resetProgressSettings.endDate;
this.resetProgressMailText = this.resetProgressSettings.mailText;
},
store() {
this.companionSuccess({
......@@ -56,8 +234,36 @@ export default {
this.storeCoursewareSettings({
permission: this.currentPermissionLevel,
progression: this.currentProgression,
certificateSettings: this.generateCertificateSettings(),
reminderSettings: this.generateReminderSettings(),
resetProgressSettings: this.generateResetProgressSettings()
});
},
generateCertificateSettings() {
return this.makeCert ? {
threshold: this.certThreshold,
image: this.certImage
} : {};
},
generateReminderSettings() {
return this.sendReminders ? {
interval: this.reminderInterval,
startDate: this.reminderStartDate,
endDate: this.reminderEndDate,
mailText: this.reminderMailText
} : {};
},
generateResetProgressSettings() {
return this.resetProgress ? {
interval: this.resetProgressInterval,
startDate: this.resetProgressStartDate,
endDate: this.resetProgressEndDate,
mailText: this.resetProgressMailText
} : {};
},
updateCertImage(file) {
this.certImage = file.id;
}
},
mounted() {
this.initData();
......
......@@ -536,10 +536,15 @@ export const actions = {
return dispatch('loadContainer', containerId);
},
async storeCoursewareSettings({ dispatch, getters }, { permission, progression }) {
async storeCoursewareSettings({ dispatch, getters },
{ permission, progression, certificateSettings, reminderSettings,
resetProgressSettings }) {
const courseware = getters.courseware;
courseware.attributes['editing-permission-level'] = permission;
courseware.attributes['sequential-progression'] = progression;
courseware.attributes['certificate-settings'] = certificateSettings;
courseware.attributes['reminder-settings'] = reminderSettings;
courseware.attributes['reset-progress-settings'] = resetProgressSettings;
return dispatch('courseware-instances/update', courseware, { root: true });
},
......
<?php
$p = '<p style="font-size: 20px; text-align: center;">';
$span_bold = '<br /><br /><span style="font-size: 20px; text-align: center; font-weight: bold">';
$span_close = '</span><br /><br />';
switch($user->geschlecht) {
case 1:
$anrede = _('Herr');
break;
case 2:
$anrede = _('Frau');
break;
default:
$anrede= '';
}
echo $p;
printf(
_("Hiermit wird bescheinigt, dass %s am %s erfolgreich am Seminar %s teilgenommen hat."),
$span_bold . $anrede . ' ' . $user->getFullname() . $span_close,
$span_bold . date('d.m.Y', time()) . $span_close,
$span_bold . $course->name . $span_close
);
echo '</p>';
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment