You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
208 lines
9.9 KiB
208 lines
9.9 KiB
2 years ago
|
<?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/>.
|
||
|
|
||
|
/**
|
||
|
* This file contains local methods for the course format Tiles (not included in lib.php as that's widely called)
|
||
|
* @since Moodle 2.7
|
||
|
* @package format_tiles
|
||
|
* @copyright 2018 David Watson {@link http://evolutioncode.uk}
|
||
|
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||
|
*/
|
||
|
|
||
|
defined('MOODLE_INTERNAL') || die();
|
||
|
|
||
|
/**
|
||
|
* Experimental feature allowing a teacher to click and convert any label into a page
|
||
|
* @param int $cmid the course module id of the label (which is recycled)
|
||
|
* @param stdClass $course
|
||
|
* @throws dml_exception
|
||
|
* @throws required_capability_exception
|
||
|
* @throws coding_exception
|
||
|
*/
|
||
|
function format_tiles_convert_label_to_page($cmid, $course) {
|
||
|
global $DB;
|
||
|
$cm = $DB->get_record('course_modules', array('id' => $cmid), '*', MUST_EXIST);
|
||
|
$labelmoduleid = $DB->get_record('modules', array('name' => 'label'), 'id', MUST_EXIST)->id;
|
||
|
if ($cm->module != $labelmoduleid) {
|
||
|
debugging("Cannot convert a non label - course module id " . $cmid, DEBUG_DEVELOPER);
|
||
|
return;
|
||
|
}
|
||
|
$label = $DB->get_record('label', array('id' => $cm->instance), '*', MUST_EXIST);
|
||
|
if ($label->course !== $course->id || $cm->course !== $course->id) {
|
||
|
debugging("Cannot convert label - incorrect course id " . $course->id, DEBUG_DEVELOPER);
|
||
|
return;
|
||
|
}
|
||
|
$coursecontext = context_course::instance($course->id);
|
||
|
require_capability('mod/page:addinstance', $coursecontext);
|
||
|
require_capability('moodle/course:manageactivities', $coursecontext);
|
||
|
|
||
|
// Prepare the new page database object using the label as a basis.
|
||
|
$newpage = $label;
|
||
|
|
||
|
// New page display name - label names may be multi line but we only want first line.
|
||
|
$newpage->name = format_tiles_get_first_line($label->name);
|
||
|
|
||
|
// Now the content - if the first line contains a repetition of the 'name', remove the repetition.
|
||
|
$newpage->content = $label->intro;
|
||
|
$firstline = format_tiles_get_first_line($newpage->content);
|
||
|
if (strpos($firstline, $newpage->name) !== false && strpos($firstline, 'PLUGINFILE') === false) {
|
||
|
// The first line seems to include what we are using for the name.
|
||
|
// Also it does not seem to contain a file link so is not adding anything - remove it.
|
||
|
$remainder = substr($newpage->content, strpos($newpage->content, $firstline) + strlen($firstline));
|
||
|
$newfirstline = str_replace($newpage->name, '', $firstline);
|
||
|
$newpage->content = $newfirstline . $remainder;
|
||
|
}
|
||
|
$newpage->intro = '';
|
||
|
$newpage->contentformat = FORMAT_HTML;
|
||
|
$newpage->display = 0;
|
||
|
$newpage->displayoptions = serialize(array(
|
||
|
'printheading' => get_config('page', 'printheading'),
|
||
|
'printintro' => get_config('page', 'printintro')
|
||
|
));
|
||
|
$newpage->timemodified = time();
|
||
|
$newpage->revision = 0;
|
||
|
// Vars $newpage->legacyfiles and $newpage->legacyfileslast are left null.
|
||
|
|
||
|
// Now add new record to the page table.
|
||
|
$newpageid = $DB->insert_record('page', $newpage, true);
|
||
|
|
||
|
// Make necessary changes to the course modules table.
|
||
|
$cm->module = $DB->get_record('modules', array('name' => 'page'), 'id', MUST_EXIST)->id;
|
||
|
$cm->instance = $newpageid;
|
||
|
$cm->timemodified = time();
|
||
|
$DB->update_record('course_modules', $cm);
|
||
|
|
||
|
// If label contained embedded images etc, update files table to show they now relate to page not label.
|
||
|
$contextid = $DB->get_record('context', array('contextlevel' => CONTEXT_MODULE, 'instanceid' => $cmid), 'id', MUST_EXIST)->id;
|
||
|
$files = $DB->get_records('files', array('component' => 'mod_label', 'contextid' => $contextid));
|
||
|
if (count($files) > 0) {
|
||
|
$fs = get_file_storage();
|
||
|
foreach ($files as $file) {
|
||
|
// We modify only the fields we need to in order to convert label to page i.e. component and filearea.
|
||
|
// We ensure that we leave the others including contextid unchanged as they are needed to generate the file URL.
|
||
|
// They are contextid, filepath ('/') and itemid ('0').
|
||
|
// We do change the pathnamehash as it is a hash of the other values so needs recalculating.
|
||
|
// The embedded URL is like [wwwroot]/pluginfile.php/[contextid]/[component]/[filearea]/[itemid][filepath][filename].
|
||
|
// e.g. [wwwroot]/pluginfile.php/7577/mod_page/content/0/an_image.png.
|
||
|
|
||
|
$pathnamehash = $fs->get_pathname_hash(
|
||
|
$file->contextid,
|
||
|
'mod_page', // New component.
|
||
|
'content', // New filearea.
|
||
|
$file->itemid,
|
||
|
$file->filepath,
|
||
|
$file->filename
|
||
|
);
|
||
|
$params = array(
|
||
|
'pathnamehash' => $pathnamehash,
|
||
|
'timemodified' => time(),
|
||
|
'id' => $file->id
|
||
|
);
|
||
|
$DB->execute(
|
||
|
"UPDATE {files}
|
||
|
SET pathnamehash = :pathnamehash, component = 'mod_page', filearea='content', timemodified = :timemodified
|
||
|
WHERE id = :id",
|
||
|
$params
|
||
|
);
|
||
|
}
|
||
|
}
|
||
|
// Finally remove the old label.
|
||
|
$DB->delete_records('label', array('id' => $label->id));
|
||
|
rebuild_course_cache($course->id, true);
|
||
|
\core\notification::info(get_string('labelconverted', 'format_tiles'));
|
||
|
$cm->modname = "page";
|
||
|
$cm->name = $newpage->name;
|
||
|
$event = \format_tiles\event\label_converted::create_from_cm($cm);
|
||
|
$event->trigger();
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Get the first line of some text, i.e. all the text
|
||
|
* before char with ASCII code 10 or 13
|
||
|
* @param string $text the text to search
|
||
|
* @return string the resulting text
|
||
|
*/
|
||
|
function format_tiles_get_first_line($text) {
|
||
|
$text = explode(chr(13), $text)[0]; // Newline char \n.
|
||
|
if (strpos($text, chr(10))) { // Return char \r in case it is used instead.
|
||
|
$text = explode(chr(10), $text)[0];
|
||
|
}
|
||
|
return $text;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Which course modules is the site administrator allowing to be displayed in a modal?
|
||
|
* @return array the permitted modules including resource types e.g. page, pdf, HTML
|
||
|
* @throws dml_exception
|
||
|
*/
|
||
|
function format_tiles_allowed_modal_modules() {
|
||
|
$devicetype = \core_useragent::get_device_type();
|
||
|
if ($devicetype != \core_useragent::DEVICETYPE_TABLET && $devicetype != \core_useragent::DEVICETYPE_MOBILE
|
||
|
&& !(\core_useragent::is_ie())) {
|
||
|
// JS navigation and modals in Internet Explorer are not supported by this plugin so we disable modals here.
|
||
|
return array(
|
||
|
'resources' => explode(",", get_config('format_tiles', 'modalresources')),
|
||
|
'modules' => explode(",", get_config('format_tiles', 'modalmodules'))
|
||
|
);
|
||
|
} else {
|
||
|
return array('resources' => [], 'modules' => []);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* If we are not on a mobile device we may want to ensure that tiles are nicely fitted depending on our screen width.
|
||
|
* E.g. avoid a row with one tile, centre the tiles on screen. JS will handle this post page load.
|
||
|
* However we want to handle it pre-page load if we can to avoid tiles moving around once page is loaded.
|
||
|
* So we have JS send the width via AJAX on first load, and we remember the value and apply it next time using inline CSS.
|
||
|
* This function gets the data to enable us to add the inline CSS.
|
||
|
* This will hide the main tiles window on page load and display a loading icon instead.
|
||
|
* Then post page load, JS will get the screen width, re-arrange the tiles, then hide the loading icon and show the tiles.
|
||
|
* If session width var has already been set (because JS already ran), we set that width initially.
|
||
|
* Then we can load the page immediately at that width without hiding anything.
|
||
|
* The skipcheck URL param is there in case anyone gets stuck at loading icon and clicks it - they escape it for session.
|
||
|
* @param int $courseid the course ID we are in.
|
||
|
* @see format_tiles_external::set_session_width() for where the session vars are set from JS.
|
||
|
* @return array the data to add to our mustache templates.
|
||
|
* @throws coding_exception
|
||
|
* @throws dml_exception
|
||
|
*/
|
||
|
function format_tiles_width_template_data($courseid) {
|
||
|
global $SESSION, $PAGE;
|
||
|
$data = [];
|
||
|
if (get_config('format_tiles', 'fittilestowidth')) {
|
||
|
if (optional_param('skipcheck', 0, PARAM_INT) || isset($SESSION->format_tiles_skip_width_check)) {
|
||
|
$SESSION->format_tiles_skip_width_check = 1;
|
||
|
return array('hidetilesinitially' => 0);
|
||
|
} else if ($PAGE->user_is_editing()
|
||
|
|| !get_config('format_tiles', 'usejavascriptnav')
|
||
|
|| get_user_preferences('format_tiles_stopjsnav', 0)) {
|
||
|
// Here we may don't tiles initially or restrict screen width.
|
||
|
return array('hidetilesinitially' => 0);
|
||
|
} else {
|
||
|
// If session screen width has been set, send it to template so we can include in inline CSS.
|
||
|
$sessionvar = 'format_tiles_width_' . $courseid;
|
||
|
$sessionvarvalue = isset($SESSION->$sessionvar) ? $SESSION->$sessionvar : 0;
|
||
|
$data['defaultscreenwidthsession'] = $sessionvarvalue;
|
||
|
|
||
|
// If no session screen width has yet been set, we hide the tiles initally so we can calculate correct width.
|
||
|
$data['hidetilesinitially'] = $sessionvarvalue == 0 ? 1 : 0;
|
||
|
}
|
||
|
return $data;
|
||
|
} else {
|
||
|
// Feature is disabled by site admin.
|
||
|
return array('hidetilesinitially' => 0);
|
||
|
}
|
||
|
}
|