Skip to content
Snippets Groups Projects
Commit e4fc6d02 authored by Michaela Brückner's avatar Michaela Brückner :unicorn: Committed by David Siegfried
Browse files

resolves #853

Closes #853

Merge request studip/studip!1191
parent 5e590653
No related branches found
No related tags found
No related merge requests found
......@@ -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;
......
......@@ -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'];
......
<?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>
<?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);
}
}
<?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']]);
}
}
}
}
<?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);
}
}
......@@ -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 {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment