AutorÃa | Ultima modificación | Ver Log |
<?php
// This file is part of local_downloadcenter for 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/>.
/**
* Download center plugin
*
* @package local_downloadcenter
* @author Simeon Naydenov (moniNaydenov@gmail.com)
* @copyright 2020 Academic Moodle Cooperation {@link http://www.academic-moodle-cooperation.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
class local_downloadcenter_factory {
/**
* @var
*/
private $course;
/**
* @var
*/
private $user;
/**
* @var
*/
private $sortedresources;
/**
* @var
*/
private $filteredresources;
private $_downloadoptions;
/**
* @var array
*/
private $availableresources = [
'resource',
'folder',
'publication',
'page',
'book',
'lightboxgallery',
'assign',
'glossary',
'etherpadlite',
];
/**
* @var array
*/
private $jsnames = [];
/**
* @var
*/
private $progress;
/**
* local_downloadcenter_factory constructor.
* @param $course
* @param $user
*/
public function __construct($course, $user) {
$this->course = $course;
$this->user = $user;
$this->_downloadoptions = [
'filesrealnames' => false,
'addnumbering' => false,
];
}
/**
* @return array
* @throws coding_exception
* @throws dml_exception
* @throws moodle_exception
*/
public function get_resources_for_user() {
global $DB, $CFG;
// Only downloadable resources should be shown!
if (!empty($this->sortedresources)) {
return $this->sortedresources;
}
$modinfo = get_fast_modinfo($this->course);
$usesections = course_format_uses_sections($this->course->format);
$sorted = [];
if ($usesections) {
$sections = $DB->get_records('course_sections', array('course' => $this->course->id), 'section');
// Thanks to https://github.com/marinaglancy for the fix!
$max = course_get_format($this->course)->get_format_options()['numsections'] ?? count($sections);
$unnamedsections = [];
$namedsections = [];
foreach ($sections as $section) {
if (intval($section->section) > $max) {
break;
}
if (!isset($sorted[$section->section]) && $section->visible) {
$sorted[$section->section] = new stdClass;
$title = trim(get_section_name($this->course, $section->section));
$title = self::shorten_filename($title);
$sorted[$section->section]->title = $title;
if (empty($title)) {
$unnamedsections[] = $section->section;
} else {
$namedsections[$title] = true;
}
$sorted[$section->section]->res = []; // TODO: fix empty names here!!!
}
}
foreach ($unnamedsections as $sectionid) {
$untitled = get_string('untitled', 'local_downloadcenter');
$title = $untitled;
$i = 1;
while (isset($namedsections[$title])) {
$title = $untitled . ' ' . strval($i);
$i++;
}
$namedsections[$title] = true;
$sorted[$sectionid]->title = $title;
}
} else {
$sorted['default'] = new stdClass;// TODO: fix here if needed!
$sorted['default']->title = '0';
$sorted['default']->res = [];
}
$cms = [];
$resources = [];
foreach ($modinfo->cms as $cm) {
if (!in_array($cm->modname, $this->availableresources)) {
continue;
}
if (!$cm->uservisible) {
continue;
}
if (!$cm->has_view() && $cm->modname != 'folder') {
// Exclude label and similar!
continue;
}
$cms[$cm->id] = $cm;
$resources[$cm->modname][] = $cm->instance;
}
// Preload instances!
foreach ($resources as $modname => $instances) {
$resources[$modname] = $DB->get_records_list($modname, 'id', $instances, 'id');
}
$availablesections = array_keys($sorted);
$currentsection = '';
foreach ($cms as $cm) {
if (!isset($resources[$cm->modname][$cm->instance])) {
continue;
}
$resource = $resources[$cm->modname][$cm->instance];
if ($usesections) {
if ($cm->sectionnum !== $currentsection) {
$currentsection = $cm->sectionnum;
}
if (!in_array($currentsection, $availablesections)) {
continue;
}
} else {
$currentsection = 'default';
}
$cmcontext = context_module::instance($cm->id);
if ($cm->modname == 'glossary') {
if ( !has_capability('mod/glossary:manageentries', $cmcontext) && !$resource->allowprintview) {
continue;
}
}
if (!isset($this->jsnames[$cm->modname])) {
$this->jsnames[$cm->modname] = get_string('modulenameplural', 'mod_' . $cm->modname);
}
$icon = '<img src="'.$cm->get_icon_url().'" class="activityicon" alt="'.$cm->get_module_type_name().'" /> ';
// TODO: $cm->visible..
$res = new stdClass;
$res->icon = $icon;
$res->cmid = $cm->id;
$res->name = $cm->get_formatted_name();
$res->modname = $cm->modname;
$res->instanceid = $cm->instance;
$res->resource = $resource;
$res->cm = $cm;
$res->context = $cmcontext;
$sorted[$currentsection]->res[] = $res;
}
$this->sortedresources = $sorted;
return $sorted;
}
/**
* @return array
*/
public function get_js_modnames() {
return array($this->jsnames);
}
/**
* @return string
* @throws coding_exception
* @throws dml_exception
*/
public function create_zip() {
global $DB, $CFG, $USER, $OUTPUT, $PAGE, $SITE;
if (file_exists($CFG->dirroot . '/mod/publication/locallib.php')) {
require_once($CFG->dirroot . '/mod/publication/locallib.php');
} else {
define('PUBLICATION_MODE_UPLOAD', 0);
define('PUBLICATION_MODE_IMPORT', 1);
}
$modbookmissing = true;
if (file_exists($CFG->dirroot . '/mod/book/tool/print/locallib.php')) {
require_once($CFG->dirroot . '/mod/book/tool/print/locallib.php');
$modbookmissing = false;
}
$bookrenderer = $PAGE->get_renderer('booktool_print');
// Zip files and sent them to a user.
$fs = get_file_storage();
$filelist = [];
$filteredresources = $this->filteredresources;
// Needed for mod_publication!
$userfields = \core_user\fields::for_userpic();
$ufields = $userfields->get_sql('u', false, '', 'id', false)->selects;
$useridentityfields = $CFG->showuseridentity != '' ? 'u.'.str_replace(', ', ', u.', $CFG->showuseridentity) . ', ' : '';
$topicprefixid = 1;
$topicscount = count($filteredresources);
$topicprefixformat = '%0' . strlen($topicscount) . 'd';
$filesrealnames = $this->_downloadoptions['filesrealnames'];
$addnumbering = $this->_downloadoptions['addnumbering'];
foreach ($filteredresources as $topicid => $info) {
$info->title = html_entity_decode($info->title);
$basedir = clean_filename($info->title);
if ($addnumbering) {
$basedir = sprintf($topicprefixformat, $topicprefixid) . '_' . $basedir;
}
$topicprefixid++;
$basedir = self::shorten_filename($basedir);
$filelist[$basedir] = null;
$resprefixid = 1;
$rescount = count($info->res);
$resprefixformat = '%0' . strlen($rescount) . 'd';
foreach ($info->res as $res) {
$res->name = html_entity_decode($res->name);
if ($addnumbering) {
$res->name = sprintf($resprefixformat, $resprefixid) . '_' . $res->name;
}
$resdir = $basedir . '/' . self::shorten_filename(clean_filename($res->name));
$filelist[$resdir] = null;
$context = $res->context;
if ($res->modname == 'resource') {
$files = $fs->get_area_files($context->id, 'mod_resource', 'content', 0, 'sortorder DESC, id ASC', false);
$file = array_shift($files); // Get only the first file - such are the requirements!
if ($filesrealnames) {
$realfilename = $file->get_filename();
if ($addnumbering) {
$realfilename = sprintf($resprefixformat, $resprefixid) . '_' . $realfilename;
}
$filename = $basedir . '/' . self::shorten_filename($realfilename);
} else {
$filename = $basedir . '/' . self::shorten_filename(clean_filename($res->name));
}
unset($filelist[$resdir]);
$extension = mimeinfo_from_type('extension', $file->get_mimetype());
$currentextension = strtolower(pathinfo($filename, PATHINFO_EXTENSION));
if (!empty($currentextension)) {
$filename = mb_substr($filename, 0, -mb_strlen($currentextension) - 1);
}
$fullfilename = $filename . $extension;
$filei = 1;
while (isset($filelist[$fullfilename]) && $filei < 200) {
$fullfilename = $filename . '_' . $filei . $extension;
$filei++;
}
$filelist[$fullfilename] = $file;
} else if ($res->modname == 'folder') {
$folder = $fs->get_area_tree($context->id, 'mod_folder', 'content', 0);
$this->add_folder_contents($filelist, $folder, $resdir);
} else if ($res->modname == 'publication') {
$cm = $res->cm;
$conditions = [];
$conditions['publication'] = $res->instanceid;
$filesforzipping = [];
$filearea = 'attachment';
// Find out current groups mode.
$groupmode = groups_get_activity_groupmode($cm);
$currentgroup = groups_get_activity_group($cm, true);
// Get group name for filename.
$groupname = '';
// Get all ppl that are allowed to submit assignments.
list($esql, $params) = get_enrolled_sql($context, 'mod/publication:view', $currentgroup);
$showall = false;
if (has_capability('mod/publication:approve', $context) ||
has_capability('mod/publication:grantextension', $context)) {
$showall = true;
}
if ($showall) {
$sql = 'SELECT u.id FROM {user} u '.
'LEFT JOIN ('.$esql.') eu ON eu.id=u.id '.
'WHERE u.deleted = 0 AND eu.id=u.id';
} else {
$sql = 'SELECT u.id FROM {user} u '.
'LEFT JOIN ('.$esql.') eu ON eu.id=u.id '.
'LEFT JOIN {publication_file} files ON (u.id = files.userid) '.
'WHERE u.deleted = 0 AND eu.id=u.id '.
'AND files.publication = '. $res->instanceid . ' ';
if ($res->resource->mode == PUBLICATION_MODE_UPLOAD) {
// Mode upload.
// SN 11.07.2016 - feature #2738:
// in mod/publication/locallib : line 81, publication::__construct() { ...
// .....$this->instance->obtainteacherapproval = !$this->obtainteacherapproval ...
// ..} ...
// So flag has to be actually inverted!
if (!$res->resource->obtainteacherapproval) {
// Need teacher approval.
$where = 'files.teacherapproval = 1';
} else {
// No need for teacher approval.
// Teacher only hasnt rejected.
$where = '(files.teacherapproval = 1 OR files.teacherapproval IS NULL)';
}
} else {
// Mode import.
if (!$res->resource->obtainstudentapproval) {
// No need to ask student and teacher has approved.
$where = 'files.teacherapproval = 1';
} else {
// Student and teacher have approved.
$where = 'files.teacherapproval = 1 AND files.studentapproval = 1';
}
}
$sql .= 'AND ' . $where . ' ';
$sql .= 'GROUP BY u.id';
}
$users = $DB->get_records_sql($sql, $params);
if (!empty($users)) {
$users = array_keys($users);
}
// If groupmembersonly used, remove users who are not in any group.
if ($users && !empty($CFG->enablegroupmembersonly) && $cm->groupmembersonly) {
if ($groupingusers = groups_get_grouping_members($cm->groupingid, 'u.id', 'u.id')) {
$users = array_intersect($users, array_keys($groupingusers));
}
}
$userfields = [];
foreach (\core_user\fields::get_name_fields() as $field) {
$userfields[$field] = $field;
}
$userfields['id'] = 'id';
$userfields['username'] = 'username';
$userfields = implode(', ', $userfields);
$viewfullnames = has_capability('moodle/site:viewfullnames', $context);
// Get all files from each user.
foreach ($users as $uploader) {
$auserid = $uploader;
$conditions['userid'] = $uploader;
$records = $DB->get_records('publication_file', $conditions);
// Get user firstname/lastname.
$auser = $DB->get_record('user', array('id' => $auserid), $userfields);
foreach ($records as $record) {
$haspermission = false;
if ($res->resource->mode == PUBLICATION_MODE_UPLOAD) {
// Mode upload.
// SN 11.07.2016 - feature #2738 - check comment above!
if (!$res->resource->obtainteacherapproval) {
// Need teacher approval.
if ($record->teacherapproval == 1) {
// Teacher has approved.
$haspermission = true;
}
} else {
// No need for teacher approval.
if (is_null($record->teacherapproval) || $record->teacherapproval == 1) {
// Teacher only hasnt rejected.
$haspermission = true;
}
}
} else {
// Mode import.
if (!$res->resource->obtainstudentapproval && $record->teacherapproval == 1) {
// No need to ask student and teacher has approved.
$haspermission = true;
} else if ($res->resource->obtainstudentapproval &&
$record->teacherapproval == 1 &&
$record->studentapproval == 1) {
// Student and teacher have approved.
$haspermission = true;
}
}
if (has_capability('mod/publication:approve', $context) || $haspermission) {
// Is teacher or file is public.
$file = $fs->get_file_by_id($record->fileid);
// Get files new name.
$fileext = strstr($file->get_filename(), '.');
$fileoriginal = str_replace($fileext, '', $file->get_filename());
$fileforzipname = clean_filename(($viewfullnames ? (fullname($auser) . '_') : '') .
$fileoriginal.'_' . $auserid . $fileext);
$fileforzipname = $resdir . '/' . self::shorten_filename($fileforzipname);
// Save file name to array for zipping.
$filelist[$fileforzipname] = $file;
}
}
} // End of foreach.
} else if ($res->modname == 'page') {
$fsfiles = $fs->get_area_files($context->id,
'mod_page',
'content');
if (count($fsfiles) > 0) {
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/data' . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
}
if (count($fsfiles) == 0) {
unset($filelist[$resdir]);
$filename = $basedir . '/' . self::shorten_filename($res->name . '.html');
} else {
$filename = $resdir . '/' . self::shorten_filename($res->name . '.html');
}
$content = str_replace('@@PLUGINFILE@@', 'data', $res->resource->content);
$content = self::convert_content_to_html_doc($res->name, $content);
$filelist[$filename] = array($content); // Needs to be array to be saved as file.
} else if ($res->modname == 'book' && !$modbookmissing) {
$book = $res->resource;
$cm = $res->cm;
$chapters = book_preload_chapters($book);
$fsfiles = $fs->get_area_files($context->id,
'mod_book',
'chapter');
if (count($fsfiles) > 0) {
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/data' . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
}
if (count($fsfiles) == 0) {
unset($filelist[$resdir]);
$filename = $basedir . '/' . self::shorten_filename($res->name . '.html');
} else {
$filename = $resdir . '/' . self::shorten_filename($res->name . '.html');
}
// Taken from mod/book/tool/print/index.php!
$allchapters = $DB->get_records('book_chapters', array('bookid' => $book->id), 'pagenum');
$book->intro = str_replace('@@PLUGINFILE@@', 'data', $book->intro);
$content = '<a name="top"></a>';
$content .= $OUTPUT->heading(format_string($book->name, true, array('context' => $context)), 1);
$content .= '<p class="book_summary">' .
format_text($book->intro, $book->introformat, array('noclean' => true, 'context' => $context)) .
'</p>';
$toc = $bookrenderer->render_print_book_toc($chapters, $book, $cm);
$content .= $toc;
// Chapters!
$link1 = $CFG->wwwroot.'/mod/book/view.php?id='.$this->course->id.'&chapterid=';
$link2 = $CFG->wwwroot.'/mod/book/view.php?id='.$this->course->id;
foreach ($chapters as $ch) {
$chapter = $allchapters[$ch->id];
if ($chapter->hidden) {
continue;
}
$content .= '<div class="book_chapter"><a name="ch'.$ch->id.'"></a>';
$title = book_get_chapter_title($chapter->id, $chapters, $book, $context);
if (!$book->customtitles) {
if (!$chapter->subchapter) {
$content .= $OUTPUT->heading($title);
} else {
$content .= $OUTPUT->heading($title, 3);
}
}
$chaptercontent = str_replace($link1, '#ch', $chapter->content);
$chaptercontent = str_replace($link2, '#top', $chaptercontent);
$chaptercontent = str_replace('@@PLUGINFILE@@', 'data', $chaptercontent);
$content .= format_text($chaptercontent,
$chapter->contentformat,
array('noclean' => true, 'context' => $context));
$content .= '</div>';
$content .= '<a href="#toc">↑ ' . get_string('top', 'mod_book') . '</a>';
}
$content = self::convert_content_to_html_doc($res->name, $content);
$filelist[$filename] = array($content); // Needs to be array to be saved as file.
} else if ($res->modname == 'lightboxgallery') {
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_lightboxgallery', 'gallery_images');
foreach ($files as $storedfile) {
if (!$storedfile->is_valid_image()) {
continue;
}
$filename = $resdir . '/' . self::shorten_filename($storedfile->get_filename());
$filelist[$filename] = $storedfile;
}
} else if ($res->modname == 'assign') {
require_once($CFG->dirroot . '/mod/assign/locallib.php');
require_once($CFG->dirroot . '/mod/assign/externallib.php');
if ($res->resource->allowsubmissionsfromdate < time() || $res->resource->alwaysshowdescription) {
$fsfiles = $fs->get_area_files($context->id, 'mod_assign', 'introattachment', 0, 'id', false);
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/intro' . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
$fsfiles = $fs->get_area_files($context->id, 'mod_assign', 'intro', 0, 'id', false);
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/intro/files' . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
$introtitle = get_string('description') . ' ' . $res->name;
$introcontent = str_replace('@@PLUGINFILE@@', 'files', $res->resource->intro);
$introcontent = self::convert_content_to_html_doc($introtitle, $introcontent);
$filelist[$resdir . '/intro/intro.html'] = [$introcontent];
}
$submissionsstr = get_string('gradeitem:submissions', 'assign');
$assign = new assign($context, null, null);
$assignplugins = $assign->get_submission_plugins();
$feedbackplugins = $assign->get_feedback_plugins();
$params = ['assignment' => $res->instanceid];
$isstudent = !has_capability('mod/assign:viewgrades', $context);
if ($isstudent) {
// When student, fetch only own submissions!
$submissions = $assign->get_all_submissions($USER->id);
} else {
$submissions = $DB->get_records('assign_submission', $params, 'attemptnumber ASC');
}
foreach ($submissions as $submission) {
$user = null;
$group = null;
if ($submission->userid != 0) {
$user = $DB->get_record('user', ['id' => $submission->userid]);
$fullname = $resdir. '/' . $submissionsstr . '/' . self::shorten_filename(fullname($user));
} else if ($submission->groupid != 0) {
$group = $DB->get_record('groups', ['id' => $submission->groupid]);
$groupname = get_string('group', 'group') . ': ' . $group->name;
$fullname = $resdir. '/' . $submissionsstr . '/' . self::shorten_filename($groupname);
} else {
$groupname = get_string('group', 'group') . ': ' . get_string('defaultteam', 'assign');
$fullname = $resdir. '/' . $submissionsstr . '/' . self::shorten_filename($groupname);
}
// Submission!
foreach ($assignplugins as $assignplugin) {
if (!$assignplugin->is_enabled() || !$assignplugin->is_visible()) {
continue;
}
// Subtype is 'assignsubmission', type is currently 'file' or 'onlinetext'.
$component = $assignplugin->get_subtype().'_'.$assignplugin->get_type();
$fileareas = $assignplugin->get_file_areas();
foreach ($fileareas as $filearea => $name) {
if ($areafiles = $fs->get_area_files($context->id, $component, $filearea, $submission->id, 'itemid, filepath, filename', false)) {
foreach ($areafiles as $file) {
$filename = $fullname . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
}
}
if ($assignplugin->get_type() == 'onlinetext') {
$onlinetext = $assignplugin->get_editor_text('onlinetext', $submission->id);
$onlinetext = str_replace('@@PLUGINFILE@@/', '', $onlinetext);
if (mb_strlen(trim($onlinetext)) > 0) {
$onlinetext = self::convert_content_to_html_doc($assignplugin->get_name(), $onlinetext);
$filename = $fullname . '/' . self::shorten_filename($assignplugin->get_name() . '.html');
$filelist[$filename] = [$onlinetext];
}
}
}
// Feedback!
if (empty($user)) {
if ($isstudent) {
$user = $USER; // Applicable with group submissions!
} else {
continue; // There is no feedback per group AFAIK.
}
}
$feedback = $assign->get_assign_feedback_status_renderable($user);
// The feedback for our latest submission.
if ($feedback && $feedback->grade) {
$fullname .= '/' . get_string('feedback', 'grades');
foreach ($feedbackplugins as $feedbackplugin) {
if (!$feedbackplugin->is_enabled() || !$feedbackplugin->is_visible()) {
continue;
}
$component = $feedbackplugin->get_subtype().'_'.$feedbackplugin->get_type();
$fileareas = $feedbackplugin->get_file_areas();
foreach ($fileareas as $filearea => $name) {
if ($areafiles = $fs->get_area_files($context->id, $component, $filearea, $feedback->grade->id, 'itemid, filepath, filename', false)) {
foreach ($areafiles as $file) {
$filename = $fullname . $file->get_filepath() . self::shorten_filename($file->get_filename());
$filelist[$filename] = $file;
}
}
}
if ($feedbackplugin->get_type() == 'comments') {
$comments = $feedbackplugin->get_editor_text('comments', $feedback->grade->id);
$comments = str_replace('@@PLUGINFILE@@/', '', $comments);
if (mb_strlen(trim($comments)) > 0) {
$comments = self::convert_content_to_html_doc($feedbackplugin->get_name(), $comments);
$filename = $fullname . '/' . self::shorten_filename($feedbackplugin->get_name() . '.html');
$filelist[$filename] = [$comments];
}
}
}
}
}
} else if ($res->modname == 'glossary') {
$hook = 'ALL'; // Setting up default values as taken from mod/glossary/print.php!
$pivotkey = 'concept';
$fullpivot = false;
$currentpivot = '';
$mode = '';
$fmtoptions = ['context' => $context];
$glossary = $res->resource;
$displayformat = $glossary->displayformat;
$course = $this->course;
$cm = $res->cm;
$content = '';
ob_start();
$sitename = get_string("site") . ': <span class="strong">' . format_string($SITE->fullname) . '</span>';
echo html_writer::tag('div', $sitename, array('class' => 'sitename'));
$coursename = get_string("course") . ': <span class="strong">' . format_string($course->fullname) . ' ('. format_string($course->shortname) . ')</span>';
echo html_writer::tag('div', $coursename, array('class' => 'coursename'));
$modname = get_string("modulename", "glossary") . ': <span class="strong">' . format_string($glossary->name, true) . '</span>';
echo html_writer::tag('div', $modname, array('class' => 'modname'));
list($allentries, $count) = glossary_get_entries_by_letter($glossary, $context, 'ALL', 0, 0);
if ( $allentries ) {
foreach ($allentries as $entry) {
$pivot = $entry->{$pivotkey};
$upperpivot = core_text::strtoupper($pivot);
$pivottoshow = core_text::strtoupper(format_string($pivot, true, $fmtoptions));
// Reduce pivot to 1cc if necessary.
if (!$fullpivot) {
$upperpivot = core_text::substr($upperpivot, 0, 1);
$pivottoshow = core_text::substr($pivottoshow, 0, 1);
}
// If there's a group break.
if ($currentpivot != $upperpivot) {
$currentpivot = $upperpivot;
echo html_writer::tag('div', clean_text($pivottoshow), array('class' => 'mdl-align strong'));
}
glossary_print_entry($course, $cm, $glossary, $entry, $mode, $hook, 1, $displayformat, true);
}
// The all entries value may be a recordset or an array.
if ($allentries instanceof moodle_recordset) {
$allentries->close();
}
}
$content .= ob_get_contents();
ob_end_clean();
$fileurl = $CFG->wwwroot . '/pluginfile.php/' . $context->id . '/mod_glossary/';
$content = str_replace($fileurl, 'data/', $content);
$filename = $resdir . '/' . self::shorten_filename($res->name . '.html');
$linkrel = '<link href="css/styles.css" rel="stylesheet">';
$linkrel .= '<style> .img-fluid { max-width: 100%; height: auto;}</style>';
$content = '<div class="path-mod-glossary" id="#page-mod-glossary-print">' . $content . '</div>';
$content = self::convert_content_to_html_doc($res->name, $content, $linkrel);
$filelist[$filename] = [$content];
$filelist[$resdir . '/css/styles.css'] = $CFG->dirroot . '/mod/glossary/styles.css';
// Handle attachments.
$fsfiles = $fs->get_area_files($context->id,
'mod_glossary',
'attachment');
if (count($fsfiles) > 0) {
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/data/attachment/' . $file->get_itemid() . '/' . $file->get_filename();
$filelist[$filename] = $file;
}
}
// Handle entries.
$fsfiles = $fs->get_area_files($context->id,
'mod_glossary',
'entry');
if (count($fsfiles) > 0) {
foreach ($fsfiles as $file) {
if ($file->get_filesize() == 0) {
continue;
}
$filename = $resdir . '/data/entry/' . $file->get_itemid() . '/' . $file->get_filename();
$filelist[$filename] = $file;
}
}
} else if ($res->modname == 'etherpadlite') {
require_once($CFG->dirroot . '/mod/etherpadlite/lib.php');
$etherpadconfig = get_config('etherpadlite');
$domain = $etherpadconfig->url;
$padid = $res->resource->uri;
$etherpadclient = \mod_etherpadlite\api\client::get_instance($etherpadconfig->apikey, $domain); // If not working, try $domain.'api' instead.
// Handle groups here.
$groupmode = groups_get_activity_groupmode($res->cm);
if ($groupmode) {
if ($groupmode == VISIBLEGROUPS || has_capability('moodle/course:managegroups', $res->context)) {
$htmlcontent = $etherpadclient->get_html($padid);
if (!empty($htmlcontent)) {
$htmlcontent = self::append_etherpadlite_css($htmlcontent->html);
$filename = $resdir . '/' . self::shorten_filename($res->name . '_' . get_string('allparticipants') . '.html');
$filelist[$filename] = array($htmlcontent); // Needs to be array to be saved as file.
}
}
$allgroups = groups_get_activity_allowed_groups($res->cm);
foreach ($allgroups as $group) {
$htmlcontent = $etherpadclient->get_html($padid . $group->id);
if (!empty($htmlcontent)) {
$htmlcontent = self::append_etherpadlite_css($htmlcontent->html);
$filename = $resdir . '/' . self::shorten_filename($res->name . '_' . $group->name . '.html');
$filelist[$filename] = array($htmlcontent); // Needs to be array to be saved as file.
}
}
} else {
$htmlcontent = $etherpadclient->get_html($padid);
if (!empty($htmlcontent)) {
$htmlcontent = self::append_etherpadlite_css($htmlcontent->html);
$filename = $resdir . '/' . self::shorten_filename($res->name . '.html');
$filelist[$filename] = array($htmlcontent); // Needs to be array to be saved as file.
}
}
}
$resprefixid++;
}
}
\core\session\manager::write_close();
$filename = sprintf('%s_%s.zip', $this->course->shortname, userdate(time(), '%Y%m%d_%H%M'));
$zipwriter = \core_files\archive_writer::get_stream_writer($filename, \core_files\archive_writer::ZIP_WRITER);
// Stream the files into the zip.
foreach ($filelist as $pathinzip => $file) {
if ($file instanceof \stored_file) {
// Most of cases are \stored_file.
$zipwriter->add_file_from_stored_file($pathinzip, $file);
} else if (is_array($file)) {
// Save $file as contents, from onlinetext subplugin.
$content = reset($file);
$zipwriter->add_file_from_string($pathinzip, $content);
} else if (is_string($file)) {
$zipwriter->add_file_from_filepath($pathinzip, $file);
}
}
// Finish the archive.
$zipwriter->finish();
die;
}
/**
* @param $filelist
* @param $folder
* @param $path
*/
private function add_folder_contents(&$filelist, $folder, $path) {
if (!empty($folder['subdirs'])) {
foreach ($folder['subdirs'] as $foldername => $subfolder) {
$foldername = self::shorten_filename($foldername);
$this->add_folder_contents($filelist, $subfolder, $path . '/' . $foldername);
}
}
foreach ($folder['files'] as $filename => $file) {
$filelist[$path . '/' . self::shorten_filename($filename)] = $file;
}
}
/**
* @param $data
* @throws coding_exception
* @throws dml_exception
* @throws moodle_exception
*/
public function parse_form_data($data) {
$data = (array)$data;
$filtered = [];
$sortedresources = $this->get_resources_for_user();
$excludeempty = get_config('local_downloadcenter', 'exclude_empty_topics');
foreach ($sortedresources as $sectionid => $info) {
if (!isset($data['item_topic_' . $sectionid])) {
continue;
}
$filtered[$sectionid] = new stdClass;
$filtered[$sectionid]->title = $info->title;
$filtered[$sectionid]->res = [];
foreach ($info->res as $res) {
$name = 'item_' . $res->modname . '_' . $res->instanceid;
if (!isset($data[$name])) {
continue;
}
$filtered[$sectionid]->res[] = $res;
}
if ($excludeempty && empty($filtered[$sectionid]->res)) {
unset($filtered[$sectionid]);
}
}
$this->filteredresources = $filtered;
$this->_downloadoptions['filesrealnames'] = isset($data['filesrealnames']);
$this->_downloadoptions['addnumbering'] = isset($data['addnumbering']);
}
/**
* @param $filename
* @param int $maxlength
* @return string
*/
public static function shorten_filename($filename, $maxlength = 64) {
$filename = (string)$filename;
$filename = str_replace('/', '_', $filename);
if (strlen($filename) <= $maxlength) {
return $filename;
}
$limit = round($maxlength / 2) - 1;
return substr($filename, 0, $limit) . '___' . substr($filename, (1 - $limit));
}
public static function convert_content_to_html_doc($title, $content, $additionalhead = '') {
return <<<HTML
<!doctype html>
<html>
<head>
<title>$title</title>
<meta charset="utf-8">
$additionalhead
</head>
<body>
$content
</body>
</html>
HTML;
}
public static function append_etherpadlite_css($htmlcontent) {
$csscontent = <<<CSS
<style>
ol {
counter-reset: item;
}
ol > li {
counter-increment: item;
}
ol ol > li {
display: block;
}
ol > li {
display: block;
}
ol > li:before {
content: counters(item, ".") ". ";
}
ol ol > li:before {
content: counters(item, ".") ". ";
margin-left: -20px;
}
ul.indent {
list-style-type: none;
}
</style>
</body>
CSS;
return str_replace('</body>', $csscontent, $htmlcontent);
}
}