Autoría | Ultima modificación | Ver Log |
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle 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 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
namespace local_listcoursefiles;
/**
* Class course_file
* @package local_listcoursefiles
* @copyright 2017 Martin Gauk (@innoCampus, TU Berlin)
* @author Jeremy FitzPatrick
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_file {
/**
* @var \stdClass
*/
protected $file;
/**
* @var int
*/
protected $courseid = 0;
/* Properties used by the template. */
/**
* @var int
*/
public $fileid = 0;
/**
* @var string
*/
public $filelicense = '';
/**
* @var string Friendly readable size of the file (MB or kB as appropriate)
*/
public $filesize = '';
/**
* @var string
*/
public $filetype = '';
/**
* @var string The name of the person who uploaded the file.
*/
public $fileuploader = '';
/**
* @var bool Is the license expired?
*/
public $fileexpired = false;
/**
* @var false|string
*/
public $fileurl = false;
/**
* @var string
*/
public $filename = '';
/**
* @var false|string A link to the page where the file is used.
*/
public $filecomponenturl = false;
/**
* @var string
*/
public $filecomponent;
/**
* @var string|false A link to the page with the editor where the file was added.
*/
public $fileediturl = false;
/**
* @var string A message stating if the file is used or unknown.
*/
public $fileused;
/**
* Creates an object of this class or an appropriate subclass.
* @param \stdClass $file
* @return course_file
* @throws \coding_exception
* @throws \dml_exception
* @throws \moodle_exception
*/
public static function create(\stdClass $file): course_file {
$classname = '\local_listcoursefiles\components\\' . $file->component;
if (class_exists($classname)) {
return new $classname($file);
}
return new course_file($file);
}
/**
* course_file constructor.
* @param \stdClass $file
* @throws \coding_exception
* @throws \dml_exception
* @throws \moodle_exception
*/
public function __construct(\stdClass $file) {
global $COURSE;
$this->courseid = $COURSE->id;
$this->file = $file;
$this->filelicense = licences::get_license_name_color($file->license ?? '');
$this->fileid = $file->id;
$this->filesize = display_size($file->filesize);
$this->filetype = mimetypes::get_file_type_translation($file->mimetype);
$this->fileuploader = fullname($file);
$this->fileexpired = !$this->check_mimetype_license_expiry_date();
$fileurl = $this->get_file_download_url();
$this->fileurl = ($fileurl) ? $fileurl->out() : false;
$this->filename = $this->get_displayed_filename();
$componenturl = $this->get_component_url();
$this->filecomponenturl = ($componenturl) ? $componenturl->out() : false;
$this->filecomponent = course_files::get_component_translation($file->component);
$isused = $this->is_file_used();
if ($isused === true) {
$this->fileused = get_string('yes', 'core');
} else if ($isused === false) {
$this->fileused = get_string('no', 'core');
} else {
$this->fileused = get_string('nottested', 'local_listcoursefiles');
}
$editurl = $this->get_edit_url();
$this->fileediturl = ($editurl) ? $editurl->out(false) : false;
}
/**
* Getter for filename
* @return string
*/
protected function get_displayed_filename(): string {
return $this->file->filename;
}
/**
* Check if a file with a specific license has expired.
*
* This checks if a file has been expired because:
* - it is a document (has a particular mimetype),
* - has been provided under a specific license
* - and the expiry date is exceed (in respect of the course start date and the file creation time).
*
* The following settings need to be defined in the config.php:
* array $CFG->fileexpirylicenses which licenses (shortnames) expire
* int $CFG->fileexpirydate when do files expire (unix time)
* array $CFG->filemimetypes['document'] mime types of documents
*
* These adjustments were made by Technische Universität Berlin in order to conform to § 52a UrhG.
*
* @return boolean whether file is allowed to be delivered to students
*/
protected function check_mimetype_license_expiry_date(): bool {
global $CFG, $COURSE;
// Check if enabled/configured.
if (!isset($CFG->fileexpirydate, $CFG->fileexpirylicenses, $CFG->filemimetypes['document'])) {
return true;
}
if (in_array($this->file->license, $CFG->fileexpirylicenses)) {
$isdoc = false;
$fmimetype = $this->file->mimetype;
foreach ($CFG->filemimetypes['document'] as $mime) {
if ($mime === $fmimetype || (substr($mime, -1) === '%' && strncmp($mime, $fmimetype, strlen($mime) - 1) === 0)) {
$isdoc = true;
break;
}
}
$coursestart = $COURSE->startdate ?? 0;
if ($isdoc && $CFG->fileexpirydate > max($coursestart, $this->file->timecreated)) {
return false;
}
}
return true;
}
/**
* Try to get the download url for a file.
*
* @return null|\moodle_url
* @throws \moodle_exception
*/
protected function get_file_download_url(): ?\moodle_url {
if ($this->file->filearea == 'intro') {
return $this->get_standard_file_download_url();
}
return null;
}
/**
* Get the standard download url for a file.
*
* Most pluginfile urls are constructed the same way.
*
* @param bool $insertitemid
* @return \moodle_url
* @throws \moodle_exception
*/
protected function get_standard_file_download_url(bool $insertitemid = true): \moodle_url {
$url = '/pluginfile.php/' . $this->file->contextid . '/' . $this->file->component . '/' . $this->file->filearea;
if ($insertitemid) {
$url .= '/' . $this->file->itemid;
}
$url .= $this->file->filepath . $this->file->filename;
return new \moodle_url($url);
}
/**
* Try to get the url for the component (module or course).
*
* @return null|\moodle_url
* @throws \moodle_exception
*/
protected function get_component_url(): ?\moodle_url {
if ($this->file->contextlevel == CONTEXT_MODULE) {
$coursemodinfo = get_fast_modinfo($this->courseid);
if (!empty($coursemodinfo->cms[$this->file->instanceid])) {
return $coursemodinfo->cms[$this->file->instanceid]->url;
}
}
return null;
}
/**
* Checks if embedded files have been used
*
* @return bool|null
* @throws \dml_exception
*/
protected function is_file_used(): ?bool {
global $DB;
$component = strpos($this->file->component, 'mod_') === 0 ? 'mod' : $this->file->component;
switch ($component) {
case 'mod': // Course module.
$modname = str_replace('mod_', '', $this->file->component);
if (!array_key_exists($modname, \core_component::get_plugin_list('mod'))) {
return null;
}
if ($this->file->filearea === 'intro') {
$sql = "SELECT m.*
FROM {context} ctx
JOIN {course_modules} cm ON cm.id = ctx.instanceid
JOIN {{$modname}} m ON m.id = cm.instance
WHERE ctx.id = ?";
$mod = $DB->get_record_sql($sql, [$this->file->contextid]);
return $this->is_embedded_file_used($mod, 'intro', $this->file->filename);
}
break;
case 'question':
$question = $DB->get_record('question', ['id' => $this->file->itemid]);
return $this->is_embedded_file_used($question, $this->file->filearea, $this->file->filename);
case 'qtype_essay':
$question = $DB->get_record('qtype_essay_options', ['questionid' => $this->file->itemid]);
return $this->is_embedded_file_used($question, 'graderinfo', $this->file->filename);
}
return null;
}
/**
* Test if a file is embedded in text
*
* @param \stdClass|false $record
* @param string $field
* @param string $filename
* @return bool|null
*/
protected function is_embedded_file_used($record, string $field, string $filename): ?bool {
if ($record && property_exists($record, $field)) {
return is_int(strpos($record->$field, '@@PLUGINFILE@@/' . rawurlencode($filename)));
}
return null;
}
/**
* Creates the URL for the editor where the file is added
*
* @return \moodle_url|null
* @throws \dml_exception
* @throws \moodle_exception
*/
protected function get_edit_url(): ?\moodle_url {
global $DB;
$component = strpos($this->file->component, 'mod_') === 0 ? 'mod' : $this->file->component;
switch ($component) {
case 'mod':
if ($this->file->filearea === 'intro') { // Just checking description for now.
$sql = "SELECT cm.*
FROM {context} ctx
JOIN {course_modules} cm ON cm.id = ctx.instanceid
WHERE ctx.id = ?";
$mod = $DB->get_record_sql($sql, [$this->file->contextid]);
return new \moodle_url('/course/modedit.php?', ['update' => $mod->id]);
}
break;
case 'question':
case 'qtype_essay':
return new \moodle_url('/question/question.php?', ['courseid' => $this->courseid, 'id' => $this->file->itemid]);
}
return null;
}
}