aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/controllers/file.php60
-rw-r--r--app/controllers/oer/mymaterial.php20
-rw-r--r--app/views/file/oer_post_upload.php78
-rw-r--r--db/migrations/5.3.12_add_oer_post_upload_table.php101
-rw-r--r--lib/cronjobs/remind_oer_upload.class.php76
-rw-r--r--lib/models/OERPostUpload.php35
-rw-r--r--resources/assets/stylesheets/less/files.less125
7 files changed, 431 insertions, 64 deletions
diff --git a/app/controllers/file.php b/app/controllers/file.php
index b1ed35a..c53a219 100644
--- a/app/controllers/file.php
+++ b/app/controllers/file.php
@@ -461,11 +461,43 @@ class FileController extends AuthenticatedController
$this->content_terms_of_use = $this->file->getTermsOfUse();
}
+ public function oer_post_upload_action($file_ref_id)
+ {
+ $this->file_ref_id = $file_ref_id;
+ PageLayout::setTitle(_('Datei für OER-Campus bereitstellen'));
+
+ $this->semester_ende = date('d.m.Y', Semester::findCurrent()->ende);
+
+ if (Request::isPost()) {
+ CSRFProtection::verifyUnsafeRequest();
+ $oer_share = Request::int('oer_upload');
+ $redirect = Request::get('redirect_to_files');
+
+ if ($oer_share === 1) {
+ // share now
+ return $this->share_oer_action($this->file_ref_id, $redirect);
+ } else if ($oer_share === 2) {
+ // save and send a reminder to share later
+ $oer_post_upload = new OERPostUpload();
+ $oer_post_upload->file_ref_id = $this->file_ref_id;
+ $oer_post_upload->user_id = $GLOBALS['user']->id;
+ $oer_post_upload->reminder_date = Semester::findCurrent()->ende;
+ $oer_post_upload->store();
+ $this->response->add_header('X-Dialog-Close', '1');
+ $this->render_nothing();
+ PageLayout::postSuccess(_('Erinnerung wurde gespeichert.'));
+ } else {
+ $this->response->add_header('X-Dialog-Close', '1');
+ }
+ }
+ }
+
/**
* The action for sharing a file on the oer campus
*/
- public function share_oer_action($file_ref_id)
+ public function share_oer_action($file_ref_id, $redirect = null)
{
+ $this->redirect = $redirect;
$this->file_ref = FileRef::find($file_ref_id);
$this->file = $this->file_ref->getFileType();
@@ -486,9 +518,19 @@ class FileController extends AuthenticatedController
'image_tmp_name' => null
];
- $this->redirect("oer/mymaterial/edit");
+ // only if you were in Dateibereich
+ if ($this->redirect === 'redirect_to_files') {
+ $_SESSION['NEW_OER']['redirect_url'] = 'files';
+ $_SESSION['NEW_OER']['dir'] = $this->folder->getId();
+ $_SESSION['NEW_OER']['cid'] = $this->folder->range_id;
+ }
+
+ $this->redirect('oer/mymaterial/edit');
}
+ /**
+ * The action for suggesting a file for the oer campus to the file owner
+ */
public function suggest_oer_action($file_ref_id)
{
$this->file_ref_id = $file_ref_id;
@@ -1611,6 +1653,20 @@ class FileController extends AuthenticatedController
}
}
+ if (count($file_ref_ids) === 1) {
+ if (Config::get()->OERCAMPUS_ENABLED
+ && Config::get()->OER_ENABLE_POST_UPLOAD
+ && $GLOBALS['perm']->have_perm('tutor')
+ ) {
+ if ($file_ref['content_terms_of_use_id'] === 'SELFMADE_NONPUB'
+ || $file_ref['content_terms_of_use_id'] === 'FREE_LICENSE'
+ ) {
+ $this->redirect('file/oer_post_upload/' . $file_ref['id']);
+ return;
+ }
+ }
+ }
+
if ($redirect) {
$this->redirect($redirect);
return;
diff --git a/app/controllers/oer/mymaterial.php b/app/controllers/oer/mymaterial.php
index 93b0cd4..a240645 100644
--- a/app/controllers/oer/mymaterial.php
+++ b/app/controllers/oer/mymaterial.php
@@ -145,17 +145,27 @@ class Oer_MymaterialController extends AuthenticatedController
}
unset($_SESSION['NEW_OER']);
-
PageLayout::postSuccess(_('Lernmaterial erfolgreich gespeichert.'));
if (Request::get('redirect_url')) {
- $this->redirect(URLHelper::getURL(Request::get('redirect_url'), [
- 'material_id' => $material->getId(),
- 'url' => $this->url_for('oer/market/details/' . $material->id)
- ]));
+ if (Request::get('redirect_url') === 'files') {
+ $this->redirect(
+ URLHelper::getURL(
+ 'dispatch.php/course/files/index/' . Request::get('dir'),
+ ['cid' => Request::get('cid')]
+ )
+ );
+ } else {
+ $this->redirect(URLHelper::getURL(Request::get('redirect_url'), [
+ 'material_id' => $material->getId(),
+ 'url' => $this->url_for('oer/market/details/' . $material->id)
+ ]));
+ }
} else {
$this->redirect('oer/market/details/' . $material->id);
}
+
+
}
if (isset($_SESSION['NEW_OER'])) {
$this->template = $_SESSION['NEW_OER'];
diff --git a/app/views/file/oer_post_upload.php b/app/views/file/oer_post_upload.php
new file mode 100644
index 0000000..8e5ca55
--- /dev/null
+++ b/app/views/file/oer_post_upload.php
@@ -0,0 +1,78 @@
+<?php
+if (!isset($selected_oer_upload)) {
+ $selected_oer_upload = 0;
+}
+?>
+<form action="<?= $controller->link_for('file/oer_post_upload/', $file_ref_id)?>"
+ method="post" class="default" data-dialog="reload-on-close">
+ <?= CSRFProtection::tokenTag() ?>
+
+ <div id="select_oer_upload_info">
+ <span><?= _('Wenn Sie möchten, können Sie die hochgeladene Datei für den OER-Campus bereitstellen.') ?></span>
+ <span><?= sprintf(_('Falls Sie die Datei zu einem späteren Zeitpunkt bereitstellen möchten,
+ wird Ihnen am Ende des Semesters (%s) eine Nachricht zugeschickt.'), $semester_ende) ?></span>
+ </div>
+ <fieldset class="select_oer_upload">
+ <input type="radio" name="oer_upload" id="oer-upload-no" value="0"
+ <? if (0 == $selected_oer_upload) echo 'checked'; ?>>
+ <label for="oer-upload-no">
+ <div class="icon">
+ <?= Icon::create('decline')->asImg(32) ?>
+ </div>
+ <div class="text">
+ <?= _('Nicht für den OER-Campus bereitstellen.') ?>
+ </div>
+ <?= Icon::create('arr_1down')->asImg(24, ['class' => 'arrow']) ?>
+ <?= Icon::create('check-circle')->asImg(32, ['class' => 'check']) ?>
+ </label>
+ <div class="oer_upload_description">
+ <div class="description">
+ <?= _('Ich möchte die hochgeladene Datei jetzt nicht im OER-Campus bereitstellen.
+ Ich habe jedoch später jederzeit die Möglichkeit dazu.') ?>
+ </div>
+ </div>
+
+ <input type="radio" name="oer_upload" id="oer-upload-yes" value="1"
+ <? if (1 == $selected_oer_upload) echo 'checked'; ?>>
+ <label for="oer-upload-yes">
+ <div class="icon">
+ <?= Icon::create('accept')->asImg(32) ?>
+ </div>
+ <div class="text">
+ <?= _('Jetzt für den OER-Campus bereitstellen.') ?>
+ </div>
+ <?= Icon::create('arr_1down')->asImg(24, ['class' => 'arrow']) ?>
+ <?= Icon::create('check-circle')->asImg(32, ['class' => 'check']) ?>
+ </label>
+ <div class="oer_upload_description">
+ <div class="description">
+ <?= _('Die Datei wird direkt im OER-Campus bereitgestellt. Sie ist dann neben vielen weiteren freien Lernmaterialien an allen Stud.IP-Standorten mit aktiviertem OER-Campus sichtbar.') ?>
+ </div>
+ </div>
+
+ <input type="radio" name="oer_upload" id="oer-upload-later" value="2"
+ <? if (2 == $selected_oer_upload) echo 'checked'; ?>>
+ <label for="oer-upload-later">
+ <div class="icon">
+ <?= Icon::create('date')->asImg(32) ?>
+ </div>
+ <div class="text">
+ <?= _('Zu einem späteren Zeitpunkt für den OER-Campus bereitstellen.') ?>
+ </div>
+ <?= Icon::create('arr_1down')->asImg(24, ['class' => 'arrow']) ?>
+ <?= Icon::create('check-circle')->asImg(32, ['class' => 'check']) ?>
+ </label>
+ <div class="oer_upload_description">
+ <div class="description">
+ <?= sprintf(_('Ich möchte am Semesterende (%s) daran erinnert werden, diese Datei gegebenenfalls im OER-Campus bereitzustellen.'), $semester_ende) ?>
+ </div>
+ </div>
+ </fieldset>
+
+ <input type="hidden" name="redirect_to_files" value="redirect_to_files">
+ <footer data-dialog-button>
+ <?= Studip\Button::createAccept(_('Speichern'))?>
+ <?= Studip\Button::createCancel(_('Abbrechen'))?>
+
+ </footer>
+</form>
diff --git a/db/migrations/5.3.12_add_oer_post_upload_table.php b/db/migrations/5.3.12_add_oer_post_upload_table.php
new file mode 100644
index 0000000..1a2c88e
--- /dev/null
+++ b/db/migrations/5.3.12_add_oer_post_upload_table.php
@@ -0,0 +1,101 @@
+<?php
+class AddOerPostUploadTable extends Migration
+{
+ public function description()
+ {
+ return "Adds table to create oer upload reminders and entry to cronjob schedule and task and config option";
+ }
+
+ public function up()
+ {
+ $db = DBmanager::Get();
+
+ $db->exec("CREATE TABLE IF NOT EXISTS `oer_post_upload` (
+ `file_ref_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin,
+ `user_id` char(32) CHARACTER SET latin1 COLLATE latin1_bin,
+ `reminder_date` int unsigned,
+ `mkdate` int(11) NOT NULL,
+ `chdate` int(11) NOT NULL,
+ PRIMARY KEY (`user_id`, `file_ref_id`)
+ )");
+
+ // Add default cron tasks and schedules
+ $new_job = [
+ 'filename' => 'lib/cronjobs/remind_oer_upload.class.php',
+ 'class' => RemindOerUpload::class,
+ 'priority' => 'normal',
+ 'minute' => '0',
+ 'hour' => '1',
+ 'active' => '1'
+ ];
+
+ $query = "INSERT IGNORE INTO `cronjobs_tasks`
+ (`task_id`, `filename`, `class`, `active`)
+ VALUES (:task_id, :filename, :class, 1)";
+ $task_statement = DBManager::get()->prepare($query);
+
+ $query = "INSERT IGNORE INTO `cronjobs_schedules`
+ (`schedule_id`, `task_id`, `parameters`, `priority`,
+ `type`, `minute`, `hour`, `mkdate`, `chdate`,
+ `last_result`, `active`)
+ VALUES (:schedule_id, :task_id, '[]', :priority, 'periodic',
+ :minute, :hour, UNIX_TIMESTAMP(), UNIX_TIMESTAMP(),
+ NULL, :active)";
+ $schedule_statement = DBManager::get()->prepare($query);
+
+
+ $task_id = md5(uniqid('task', true));
+
+ $task_statement->execute([
+ ':task_id' => $task_id,
+ ':filename' => $new_job['filename'],
+ ':class' => $new_job['class'],
+ ]);
+
+ $schedule_id = md5(uniqid('schedule', true));
+ $schedule_statement->execute([
+ ':schedule_id' => $schedule_id,
+ ':task_id' => $task_id,
+ ':priority' => $new_job['priority'],
+ ':hour' => $new_job['hour'],
+ ':minute' => $new_job['minute'],
+ ':active' => $new_job['active']
+ ]);
+
+ $query = "INSERT IGNORE INTO `config`
+ SET `field` = :field,
+ `value` = :value,
+ `type` = :type,
+ `range` = :range,
+ `section` = :section,
+ `mkdate` = UNIX_TIMESTAMP(),
+ `chdate` = UNIX_TIMESTAMP(),
+ `description` = :description";
+ $config_statement = DBManager::get()->prepare($query);
+
+ $config_statement->execute([
+ ':field' => 'OER_ENABLE_POST_UPLOAD',
+ ':value' => '1',
+ ':type' => 'boolean',
+ ':range' => 'global',
+ ':section' => 'OERCampus',
+ ':description' => 'Post-Upload-Dialog nach Hochladen einer Datei erlauben?',
+ ]);
+
+ }
+
+ public function down()
+ {
+ CronjobTask::deleteBySQL('class = ?', [RemindOerUpload::class]);
+
+ $query = "DROP TABLE `oer_post_upload`";
+ DBManager::get()->exec($query);
+
+ $query = "DELETE `config`, `config_values`
+ FROM `config`
+ LEFT JOIN `config_values` USING (`field`)
+ WHERE `field` = 'OER_ENABLE_POST_UPLOAD'";
+ DBManager::get()->exec($query);
+ }
+
+}
diff --git a/lib/cronjobs/remind_oer_upload.class.php b/lib/cronjobs/remind_oer_upload.class.php
new file mode 100644
index 0000000..9ac20e7
--- /dev/null
+++ b/lib/cronjobs/remind_oer_upload.class.php
@@ -0,0 +1,76 @@
+<?php
+/**
+ * remind_oer_upload.class.php - Sends reminder emails for uploading files to OER Campus.
+ *
+ * @author Michaela Brückner <brueckner@data-quest.de>, Suchi & Berg GmbH <info@data-quest.de>
+ * @access public
+ * @since 5.2
+ */
+
+require_once 'lib/classes/CronJob.class.php';
+
+class RemindOerUpload extends CronJob
+{
+
+ public static function getName()
+ {
+ return _('An OER-Campus Upload erinnern');
+ }
+
+ public static function getDescription()
+ {
+ return _('Erinnert den Autor am Ende des Semesters an eine Datei, die in den OER-Campus hochgeladen werden soll.');
+ }
+
+ public function execute($last_result, $parameters = [])
+ {
+ // check the reminder date, which now is in past
+ $query = "SELECT `file_ref_id` FROM `oer_post_upload`
+ WHERE `reminder_date` < UNIX_TIMESTAMP()";
+ $results = DBManager::get()->fetchAll($query);
+
+ // get file information from file_ref_id
+ foreach ($results as $result) {
+ $file_ref = FileRef::find($result['file_ref_id']);
+
+ if (!FileRef::countBySql('id = ?', [$result['file_ref_id']])) {
+ // file might be deleted meanwhile, so do not try to send a reminder for it
+ } else {
+ $filetype = $file_ref->getFileType();
+ $file_to_suggest = $filetype->convertToStandardFile();
+
+ $this->author = $file_ref->owner->username;
+ $this->link_to_share = URLHelper::getURL('dispatch.php/file/share_oer/' . $result['file_ref_id']);
+ $this->linktext = _('Klicken Sie hier, um das Material im OER-Campus zu veröffentlichen.');
+ $this->formatted_link = '['. $this->linktext .']' . $this->link_to_share;
+
+ $oer_reminder_message = sprintf(_("Sie wollten daran erinnert werden, die folgende Datei im OER-Campus zu veröffentlichen:\n\n"
+ . "Dateiname: %s \n"
+ . "Beschreibung: %s \n"
+ . "%s \n\n"),
+ $file_to_suggest->getFilename(),
+ $file_to_suggest->getDescription(),
+ $this->formatted_link
+ );
+
+ $messaging = new messaging();
+
+ $messaging->insert_message(
+ $oer_reminder_message,
+ $this->author,
+ '____%system%____',
+ '',
+ Request::option('message_id'),
+ '',
+ null,
+ _('Erinnerung zur Veröffentlichung einer Datei im OER-Campus')
+ );
+
+ OERPostUpload::deleteBySQL("file_ref_id = ?", [$result['file_ref_id']]);
+
+ }
+
+ }
+
+ }
+}
diff --git a/lib/models/OERPostUpload.php b/lib/models/OERPostUpload.php
new file mode 100644
index 0000000..8bf7386
--- /dev/null
+++ b/lib/models/OERPostUpload.php
@@ -0,0 +1,35 @@
+<?php
+
+/**
+ * Model class to handle reminder for possible OER upload files
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * @author Michaela Brückner <brueckner@data-quest.de>
+ * @license http://www.gnu.org/licenses/gpl-2.0.html GPL version 2
+ * @category Stud.IP
+ * @since 5.3
+ * @property string file_ref_id database column
+ * @property string user_id database column
+ * @property int reminder_date database column
+ * @property string mkdate database column
+ * @property string chdate database column
+ */
+class OERPostUpload extends SimpleORMap
+{
+ protected static function configure($config = [])
+ {
+ $config['db_table'] = 'oer_post_upload';
+ $config['belongs_to']['file'] = [
+ 'class_name' => File::class,
+ 'foreign_key' => 'id',
+ 'on_delete' => 'delete'
+ ];
+
+ parent::configure($config);
+ }
+
+}
diff --git a/resources/assets/stylesheets/less/files.less b/resources/assets/stylesheets/less/files.less
index 9f9ae16..0b40c0b 100644
--- a/resources/assets/stylesheets/less/files.less
+++ b/resources/assets/stylesheets/less/files.less
@@ -193,11 +193,13 @@ div.file_select_possibilities, .folder_type_select_possibilities {
/* for file/edit view only: */
- input[name=content_terms_of_use_id] {
+ input[name=content_terms_of_use_id],
+ input[name=oer_upload] {
display: none;
}
- input[name=content_terms_of_use_id]:checked + label {
+ input[name=content_terms_of_use_id]:checked + label,
+ input[name=oer_upload]:checked + label {
background-color: @brand-color-darker;
color: @contrast-content-white;
@@ -400,72 +402,81 @@ table.documents {
}
-form.default fieldset.select_terms_of_use {
- > legend {
- margin: 0px;
- width: 100%;
+form.default {
+ #select_oer_upload_info {
+ padding-top: 15px;
+ padding-bottom: 15px;
}
- border: none;
- padding: 0px;
- margin-left: 0px;
- margin-right: 0px;
- > input[type=radio] {
- opacity: 0;
- position: absolute;
- &:focus + label {
- outline: auto;
- }
- }
- > label {
- cursor: pointer;
- border: 1px solid @content-color-40;
- transition: background-color 200ms;
- display: flex;
- justify-content: space-between;
- align-items: center;
- padding: 6px;
- padding-bottom: 2px;
- margin-bottom: 0;
- border-top: none;
- > .text {
+ fieldset.select_terms_of_use,
+ fieldset.select_oer_upload {
+ > legend {
+ margin: 0px;
width: 100%;
- margin-left: 10px;
}
- > .arrow {
- margin-right: 5px;
+ border: none;
+ padding: 0px;
+ margin-left: 0px;
+ margin-right: 0px;
+
+ > input[type=radio] {
+ opacity: 0;
+ position: absolute;
+ &:focus + label {
+ outline: auto;
+ }
}
- > .check {
- display: none;
+ > label {
+ cursor: pointer;
+ border: 1px solid @content-color-40;
+ transition: background-color 200ms;
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ padding: 6px;
+ padding-bottom: 2px;
+ margin-bottom: 0;
+ border-top: none;
+ > .text {
+ width: 100%;
+ margin-left: 10px;
+ }
+ > .arrow {
+ margin-right: 5px;
+ }
+ > .check {
+ display: none;
+ }
}
- }
- > label:first-of-type {
- border-top: 1px solid @content-color-40;
- }
- > div {
- border: 1px solid @content-color-40;
- border-top: none;
- display: none;
- padding: 10px;
-
- }
- > input[type=radio]:checked + label {
- background-color: @content-color-20;
- transition: background-color 200ms;
- > .arrow {
+ > label:first-of-type {
+ border-top: 1px solid @content-color-40;
+ }
+ > div {
+ border: 1px solid @content-color-40;
+ border-top: none;
display: none;
+ padding: 10px;
+
}
- > .check {
- display: inline-block;
+ > input[type=radio]:checked + label {
+ background-color: @content-color-20;
+ transition: background-color 200ms;
+ > .arrow {
+ display: none;
+ }
+ > .check {
+ display: inline-block;
+ }
}
- }
- > input[type=radio]:checked + label + div {
- display: block;
- .description {
- animation-duration: 400ms;
- animation-name: terms_of_use_fadein;
+ > input[type=radio]:checked + label + div {
+ display: block;
+ .description {
+ animation-duration: 400ms;
+ animation-name: terms_of_use_fadein;
+ }
}
}
+
}
@keyframes terms_of_use_fadein {