first commit

This commit is contained in:
CHIEFSOFT\ameye
2024-09-30 18:11:26 -04:00
commit e592ca6823
27270 changed files with 5002257 additions and 0 deletions
+10
View File
@@ -0,0 +1,10 @@
define("mod_folder/folder",["exports","core/yui"],(function(_exports,_yui){var obj;
/**
* Javascript helper function for Folder module
*
* @module mod_folder/folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/Object.defineProperty(_exports,"__esModule",{value:!0}),_exports.initTree=void 0,_yui=(obj=_yui)&&obj.__esModule?obj:{default:obj};_exports.initTree=(id,expandAll)=>{_yui.default.use("yui2-treeview","node-event-simulate",(function(Y){var tree=new Y.YUI2.widget.TreeView(id);tree.subscribe("clickEvent",(function(){return!1})),tree.subscribe("enterKeyPressed",(function(node){return Y.one(node.getContentEl()).one("a").simulate("click"),!1})),expandAll?tree.expandAll():tree.getRoot().children[0].expand(),tree.render()}))}}));
//# sourceMappingURL=folder.min.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"folder.min.js","sources":["../src/folder.js"],"sourcesContent":["// This file is part of Moodle - http://moodle.org/\n//\n// Moodle is free software: you can redistribute it and/or modify\n// it under the terms of the GNU General Public License as published by\n// the Free Software Foundation, either version 3 of the License, or\n// (at your option) any later version.\n//\n// Moodle is distributed in the hope that it will be useful,\n// but WITHOUT ANY WARRANTY; without even the implied warranty of\n// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n// GNU General Public License for more details.\n//\n// You should have received a copy of the GNU General Public License\n// along with Moodle. If not, see <http://www.gnu.org/licenses/>.\n\n/**\n * Javascript helper function for Folder module\n *\n * @module mod_folder/folder\n * @copyright 2009 Petr Skoda {@link http://skodak.org}\n * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later\n */\n\nimport YUI from 'core/yui';\n\nexport const initTree = (id, expandAll) => {\n YUI.use('yui2-treeview', 'node-event-simulate', function(Y) {\n var tree = new Y.YUI2.widget.TreeView(id);\n\n tree.subscribe(\"clickEvent\", function() {\n // we want normal clicking which redirects to url\n return false;\n });\n\n tree.subscribe(\"enterKeyPressed\", function(node) {\n // We want keyboard activation to trigger a click on the first link.\n Y.one(node.getContentEl()).one('a').simulate('click');\n return false;\n });\n\n if (expandAll) {\n tree.expandAll();\n } else {\n // Else just expand the top node.\n tree.getRoot().children[0].expand();\n }\n\n tree.render();\n });\n};\n"],"names":["id","expandAll","use","Y","tree","YUI2","widget","TreeView","subscribe","node","one","getContentEl","simulate","getRoot","children","expand","render"],"mappings":";;;;;;;0JAyBwB,CAACA,GAAIC,0BACrBC,IAAI,gBAAiB,uBAAuB,SAASC,OACjDC,KAAO,IAAID,EAAEE,KAAKC,OAAOC,SAASP,IAEtCI,KAAKI,UAAU,cAAc,kBAElB,KAGXJ,KAAKI,UAAU,mBAAmB,SAASC,aAEvCN,EAAEO,IAAID,KAAKE,gBAAgBD,IAAI,KAAKE,SAAS,UACtC,KAGPX,UACAG,KAAKH,YAGLG,KAAKS,UAAUC,SAAS,GAAGC,SAG/BX,KAAKY"}
+50
View File
@@ -0,0 +1,50 @@
// 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/>.
/**
* Javascript helper function for Folder module
*
* @module mod_folder/folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
import YUI from 'core/yui';
export const initTree = (id, expandAll) => {
YUI.use('yui2-treeview', 'node-event-simulate', function(Y) {
var tree = new Y.YUI2.widget.TreeView(id);
tree.subscribe("clickEvent", function() {
// we want normal clicking which redirects to url
return false;
});
tree.subscribe("enterKeyPressed", function(node) {
// We want keyboard activation to trigger a click on the first link.
Y.one(node.getContentEl()).one('a').simulate('click');
return false;
});
if (expandAll) {
tree.expandAll();
} else {
// Else just expand the top node.
tree.getRoot().children[0].expand();
}
tree.render();
});
};
+92
View File
@@ -0,0 +1,92 @@
<?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/>.
/**
* Provides support for the conversion of moodle1 backup to the moodle2 format
*
* @package mod_folder
* @copyright 2011 Andrew Davis <andrew@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Folder conversion handler. This resource handler is called by moodle1_mod_resource_handler
*/
class moodle1_mod_folder_handler extends moodle1_resource_successor_handler {
/** @var moodle1_file_manager instance */
protected $fileman = null;
/**
* Converts /MOODLE_BACKUP/COURSE/MODULES/MOD/RESOURCE data
* Called by moodle1_mod_resource_handler::process_resource()
*/
public function process_legacy_resource(array $data, array $raw = null) {
// get the course module id and context id
$instanceid = $data['id'];
$currentcminfo = $this->get_cminfo($instanceid);
$moduleid = $currentcminfo['id'];
$contextid = $this->converter->get_contextid(CONTEXT_MODULE, $moduleid);
// convert legacy data into the new folder record
$folder = array();
$folder['id'] = $data['id'];
$folder['name'] = $data['name'];
$folder['intro'] = $data['intro'];
$folder['introformat'] = $data['introformat'];
$folder['revision'] = 1;
$folder['timemodified'] = $data['timemodified'];
// get a fresh new file manager for this instance
$this->fileman = $this->converter->get_file_manager($contextid, 'mod_folder');
// migrate the files embedded into the intro field
$this->fileman->filearea = 'intro';
$this->fileman->itemid = 0;
$folder['intro'] = moodle1_converter::migrate_referenced_files($folder['intro'], $this->fileman);
// migrate the folder files
$this->fileman->filearea = 'content';
$this->fileman->itemid = 0;
if (empty($data['reference'])) {
$this->fileman->migrate_directory('course_files');
} else {
$this->fileman->migrate_directory('course_files/'.$data['reference']);
}
// write folder.xml
$this->open_xml_writer("activities/folder_{$moduleid}/folder.xml");
$this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $moduleid,
'modulename' => 'folder', 'contextid' => $contextid));
$this->write_xml('folder', $folder, array('/folder/id'));
$this->xmlwriter->end_tag('activity');
$this->close_xml_writer();
// write inforef.xml
$this->open_xml_writer("activities/folder_{$moduleid}/inforef.xml");
$this->xmlwriter->begin_tag('inforef');
$this->xmlwriter->begin_tag('fileref');
foreach ($this->fileman->get_fileids() as $fileid) {
$this->write_xml('file', array('id' => $fileid));
}
$this->xmlwriter->end_tag('fileref');
$this->xmlwriter->end_tag('inforef');
$this->close_xml_writer();
}
}
@@ -0,0 +1,70 @@
<?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/>.
/**
* Defines backup_folder_activity_task class
*
* @package mod_folder
* @category backup
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/folder/backup/moodle2/backup_folder_stepslib.php');
/**
* Provides the steps to perform one complete backup of the Folder instance
*/
class backup_folder_activity_task extends backup_activity_task {
/**
* No specific settings for this activity
*/
protected function define_my_settings() {
}
/**
* Defines a backup step to store the instance data in the folder.xml file
*/
protected function define_my_steps() {
$this->add_step(new backup_folder_activity_structure_step('folder_structure', 'folder.xml'));
}
/**
* Encodes URLs to the index.php and view.php scripts
*
* @param string $content some HTML text that eventually contains URLs to the activity instance scripts
* @return string the content with the URLs encoded
*/
public static function encode_content_links($content) {
global $CFG;
$base = preg_quote($CFG->wwwroot,"/");
// Link to the list of folder
$search="/(".$base."\/mod\/folder\/index.php\?id\=)([0-9]+)/";
$content= preg_replace($search, '$@FOLDERINDEX*$2@$', $content);
// Link to choice view by moduleid
$search="/(".$base."\/mod\/folder\/view.php\?id\=)([0-9]+)/";
$content= preg_replace($search, '$@FOLDERVIEWBYID*$2@$', $content);
return $content;
}
}
@@ -0,0 +1,59 @@
<?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/>.
/**
* Define all the backup steps that will be used by the backup_folder_activity_task
*
* @package mod_folder
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* Define the complete folder structure for backup, with file and id annotations
*/
class backup_folder_activity_structure_step extends backup_activity_structure_step {
protected function define_structure() {
// To know if we are including userinfo
$userinfo = $this->get_setting_value('userinfo');
// Define each element separated
$folder = new backup_nested_element('folder', array('id'), array(
'name', 'intro', 'introformat', 'revision',
'timemodified', 'display', 'showexpanded', 'showdownloadfolder', 'forcedownload'));
// Build the tree
// (nice mono-tree, lol)
// Define sources
$folder->set_source_table('folder', array('id' => backup::VAR_ACTIVITYID));
// Define id annotations
// (none)
// Define file annotations
$folder->annotate_files('mod_folder', 'intro', null);
$folder->annotate_files('mod_folder', 'content', null);
// Return the root element (folder), wrapped into standard activity structure
return $this->prepare_activity_structure($folder);
}
}
@@ -0,0 +1,109 @@
<?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/>.
/**
* @package mod_folder
* @subpackage backup-moodle2
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once($CFG->dirroot . '/mod/folder/backup/moodle2/restore_folder_stepslib.php'); // Because it exists (must)
/**
* folder restore task that provides all the settings and steps to perform one
* complete restore of the activity
*/
class restore_folder_activity_task extends restore_activity_task {
/**
* Define (add) particular settings this activity can have
*/
protected function define_my_settings() {
// No particular settings for this activity
}
/**
* Define (add) particular steps this activity can have
*/
protected function define_my_steps() {
// folder only has one structure step
$this->add_step(new restore_folder_activity_structure_step('folder_structure', 'folder.xml'));
}
/**
* Define the contents in the activity that must be
* processed by the link decoder
*/
public static function define_decode_contents() {
$contents = array();
$contents[] = new restore_decode_content('folder', array('intro'), 'folder');
return $contents;
}
/**
* Define the decoding rules for links belonging
* to the activity to be executed by the link decoder
*/
public static function define_decode_rules() {
$rules = array();
$rules[] = new restore_decode_rule('FOLDERVIEWBYID', '/mod/folder/view.php?id=$1', 'course_module');
$rules[] = new restore_decode_rule('FOLDERINDEX', '/mod/folder/index.php?id=$1', 'course');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* folder logs. It must return one array
* of {@link restore_log_rule} objects
*/
public static function define_restore_log_rules() {
$rules = array();
$rules[] = new restore_log_rule('folder', 'add', 'view.php?id={course_module}', '{folder}');
$rules[] = new restore_log_rule('folder', 'edit', 'edit.php?id={course_module}', '{folder}');
$rules[] = new restore_log_rule('folder', 'view', 'view.php?id={course_module}', '{folder}');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* course logs. It must return one array
* of {@link restore_log_rule} objects
*
* Note this rules are applied when restoring course logs
* by the restore final task, but are defined here at
* activity level. All them are rules not linked to any module instance (cmid = 0)
*/
public static function define_restore_log_rules_for_course() {
$rules = array();
$rules[] = new restore_log_rule('folder', 'view all', 'index.php?id={course}', null);
return $rules;
}
}
@@ -0,0 +1,69 @@
<?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/>.
/**
* @package mod_folder
* @subpackage backup-moodle2
* @copyright 2010 onwards Eloy Lafuente (stronk7) {@link http://stronk7.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Define all the restore steps that will be used by the restore_folder_activity_task
*/
/**
* Structure step to restore one folder activity
*/
class restore_folder_activity_structure_step extends restore_activity_structure_step {
protected function define_structure() {
$paths = array();
$paths[] = new restore_path_element('folder', '/activity/folder');
// Return the paths wrapped into standard activity structure
return $this->prepare_activity_structure($paths);
}
protected function process_folder($data) {
global $DB;
$data = (object)$data;
$oldid = $data->id;
$data->course = $this->get_courseid();
// Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
// See MDL-9367.
// If showexpanded is not set, apply site default.
if (!isset($data->showexpanded)) {
$data->showexpanded = get_config('folder', 'showexpanded');
}
// insert the folder record
$newitemid = $DB->insert_record('folder', $data);
// immediately after inserting "activity" record, call this
$this->apply_activity_instance($newitemid);
}
protected function after_execute() {
// Add folder related files, no need to match by itemname (just internally handled context)
$this->add_related_files('mod_folder', 'intro', null);
$this->add_related_files('mod_folder', 'content', null);
}
}
@@ -0,0 +1,46 @@
<?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/>.
/**
* Activity base class.
*
* @package mod_folder
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Activity base class.
*
* @package mod_folder
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
abstract class activity_base extends \core_analytics\local\indicator\community_of_inquiry_activity {
/**
* No need to fetch grades for resources.
*
* @param \core_analytics\course $course
* @return void
*/
public function fetch_student_grades(\core_analytics\course $course) {
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* Cognitive depth indicator - folder.
*
* @package mod_folder
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Cognitive depth indicator - folder.
*
* @package mod_folder
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class cognitive_depth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:cognitivedepth', 'mod_folder');
}
public function get_indicator_type() {
return self::INDICATOR_COGNITIVE;
}
public function get_cognitive_depth_level(\cm_info $cm) {
return self::COGNITIVE_LEVEL_1;
}
}
@@ -0,0 +1,56 @@
<?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/>.
/**
* Social breadth indicator - folder.
*
* @package mod_folder
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Social breadth indicator - folder.
*
* @package mod_folder
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class social_breadth extends activity_base {
/**
* Returns the name.
*
* If there is a corresponding '_help' string this will be shown as well.
*
* @return \lang_string
*/
public static function get_name(): \lang_string {
return new \lang_string('indicator:socialbreadth', 'mod_folder');
}
public function get_indicator_type() {
return self::INDICATOR_SOCIAL;
}
public function get_social_breadth_level(\cm_info $cm) {
return self::SOCIAL_LEVEL_1;
}
}
@@ -0,0 +1,84 @@
<?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/>.
declare(strict_types=1);
namespace mod_folder\completion;
use core_completion\activity_custom_completion;
/**
* Activity custom completion subclass for the folder resource.
*
* Class for defining mod_folder's custom completion rules.
*
* @package mod_folder
* @copyright 2022 David Woloszyn <david.woloszyn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class custom_completion extends activity_custom_completion {
/**
* Fetches the completion state for a given completion rule.
*
* @param string $rule The completion rule.
* @return int The completion state.
*/
public function get_state(string $rule): int {
return COMPLETION_UNKNOWN;
}
/**
* Fetch the list of custom completion rules that this module defines.
*
* @return array
*/
public static function get_defined_custom_rules(): array {
// This activity/resource does not have any custom rules.
return [];
}
/**
* Returns an associative array of the descriptions of custom completion rules.
*
* @return array
*/
public function get_custom_rule_descriptions(): array {
// This activity/resource does not have any custom rule descriptions.
return [];
}
/**
* Show the manual completion button depending on the display option set.
*
* @return bool
*/
public function manual_completion_always_shown(): bool {
$display = $this->cm->customdata->display ?? null;
return ($display == FOLDER_DISPLAY_INLINE ?? false);
}
/**
* Returns an array of all completion rules, in the order they should be displayed to users.
*
* @return array
*/
public function get_sort_order(): array {
// This module only supports manual completion.
return [];
}
}
+61
View File
@@ -0,0 +1,61 @@
<?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/>.
/**
* Content export definition.
*
* @package mod_folder
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\content;
use core\content\export\exportable_items\exportable_filearea;
use core\content\export\exporters\abstract_mod_exporter;
/**
* A class which assists a component to export content.
*
* @copyright 2020 Andrew Nicols <andrew@nicols.co.uk>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class exporter extends abstract_mod_exporter {
/**
* Get the exportable items for mod_folder.
*
* @param bool $includeuserdata Whether to include user data, in addition to shared content.
* @return \core\content\export\exportable_item[]
*/
public function get_exportables(bool $includeuserdata = false): array {
$contentitems = [];
$contentitems[] = new exportable_filearea(
$this->get_context(),
$this->get_component(),
get_string('foldercontent', 'mod_folder'),
// The files held in mod_folder are stored in the 'content' filearea, under itemid 0.
'content',
0,
// The itemid is used in the URL when accessing.
0
);
return $contentitems;
}
}
@@ -0,0 +1,95 @@
<?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/>.
/**
* The mod_folder course module downloaded event.
*
* @package mod_folder
* @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_folder course module viewed event class.
*
* @package mod_folder
* @since Moodle 3.1
* @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class all_files_downloaded extends \core\event\base {
/**
* Init method.
*
* @return void
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'folder';
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' downloaded a zip archive containing all the files from the folder activity with " .
"course module id '$this->contextinstanceid'.";
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventallfilesdownloaded', 'folder');
}
/**
* Get URL related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url("/mod/folder/view.php", array('id' => $this->contextinstanceid));
}
/**
* Custom validation.
*
* @throws \coding_exception
* @return void
*/
protected function validate_data() {
parent::validate_data();
// Make sure this class is never used without proper object details.
if (empty($this->objectid) || empty($this->objecttable)) {
throw new \coding_exception('The course_module_viewed event must define objectid and object table.');
}
// Make sure the context level is set to module.
if ($this->contextlevel != CONTEXT_MODULE) {
throw new \coding_exception('Context level must be CONTEXT_MODULE.');
}
}
}
@@ -0,0 +1,39 @@
<?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/>.
/**
* The mod_folder instance list viewed event.
*
* @package mod_folder
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_folder instance list viewed event class.
*
* @package mod_folder
* @since Moodle 2.7
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_instance_list_viewed extends \core\event\course_module_instance_list_viewed {
// No code required here as the parent class handles it all.
}
@@ -0,0 +1,51 @@
<?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/>.
/**
* The mod_folder course module viewed event.
*
* @package mod_folder
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_folder course module viewed event class.
*
* @package mod_folder
* @since Moodle 2.7
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class course_module_viewed extends \core\event\course_module_viewed {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
$this->data['objecttable'] = 'folder';
}
public static function get_objectid_mapping() {
return array('db' => 'folder', 'restore' => 'folder');
}
}
@@ -0,0 +1,78 @@
<?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/>.
/**
* The mod_folder folder updated event.
*
* @package mod_folder
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_folder folder updated event class.
*
* @package mod_folder
* @since Moodle 2.7
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class folder_updated extends \core\event\base {
/**
* Init method.
*/
protected function init() {
$this->data['crud'] = 'u';
$this->data['edulevel'] = self::LEVEL_TEACHING;
$this->data['objecttable'] = 'folder';
}
/**
* Return localised event name.
*
* @return string
*/
public static function get_name() {
return get_string('eventfolderupdated', 'mod_folder');
}
/**
* Returns description of what happened.
*
* @return string
*/
public function get_description() {
return "The user with id '$this->userid' updated the folder activity with course module id '$this->contextinstanceid'.";
}
/**
* Get url related to the action.
*
* @return \moodle_url
*/
public function get_url() {
return new \moodle_url('/mod/folder/edit.php', array('id' => $this->contextinstanceid));
}
public static function get_objectid_mapping() {
return array('db' => 'folder', 'restore' => 'folder');
}
}
+189
View File
@@ -0,0 +1,189 @@
<?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/>.
use core_course\external\helper_for_get_mods_by_courses;
use core_external\external_api;
use core_external\external_function_parameters;
use core_external\external_multiple_structure;
use core_external\external_single_structure;
use core_external\external_value;
use core_external\external_warnings;
use core_external\util;
/**
* folder external functions
*
* @package mod_folder
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
class mod_folder_external extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function view_folder_parameters() {
return new external_function_parameters(
array(
'folderid' => new external_value(PARAM_INT, 'folder instance id')
)
);
}
/**
* Simulate the folder/view.php web interface page: trigger events, completion, etc...
*
* @param int $folderid the folder instance id
* @return array of warnings and status result
* @since Moodle 3.0
* @throws moodle_exception
*/
public static function view_folder($folderid) {
global $DB, $CFG;
require_once($CFG->dirroot . "/mod/folder/lib.php");
$params = self::validate_parameters(self::view_folder_parameters(),
array(
'folderid' => $folderid
));
$warnings = array();
// Request and permission validation.
$folder = $DB->get_record('folder', array('id' => $params['folderid']), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($folder, 'folder');
$context = context_module::instance($cm->id);
self::validate_context($context);
require_capability('mod/folder:view', $context);
// Call the page/lib API.
folder_view($folder, $course, $cm, $context);
$result = array();
$result['status'] = true;
$result['warnings'] = $warnings;
return $result;
}
/**
* Returns description of method result value
*
* @return \core_external\external_description
* @since Moodle 3.0
*/
public static function view_folder_returns() {
return new external_single_structure(
array(
'status' => new external_value(PARAM_BOOL, 'status: true if success'),
'warnings' => new external_warnings()
)
);
}
/**
* Describes the parameters for get_folders_by_courses.
*
* @return external_function_parameters
* @since Moodle 3.3
*/
public static function get_folders_by_courses_parameters() {
return new external_function_parameters (
array(
'courseids' => new external_multiple_structure(
new external_value(PARAM_INT, 'Course id'), 'Array of course ids', VALUE_DEFAULT, array()
),
)
);
}
/**
* Returns a list of folders in a provided list of courses.
* If no list is provided all folders that the user can view will be returned.
*
* @param array $courseids course ids
* @return array of warnings and folders
* @since Moodle 3.3
*/
public static function get_folders_by_courses($courseids = array()) {
$warnings = array();
$returnedfolders = array();
$params = array(
'courseids' => $courseids,
);
$params = self::validate_parameters(self::get_folders_by_courses_parameters(), $params);
$mycourses = array();
if (empty($params['courseids'])) {
$mycourses = enrol_get_my_courses();
$params['courseids'] = array_keys($mycourses);
}
// Ensure there are courseids to loop through.
if (!empty($params['courseids'])) {
list($courses, $warnings) = util::validate_courses($params['courseids'], $mycourses);
// Get the folders in this course, this function checks users visibility permissions.
// We can avoid then additional validate_context calls.
$folders = get_all_instances_in_courses("folder", $courses);
foreach ($folders as $folder) {
helper_for_get_mods_by_courses::format_name_and_intro($folder, 'mod_folder');
$returnedfolders[] = $folder;
}
}
$result = array(
'folders' => $returnedfolders,
'warnings' => $warnings
);
return $result;
}
/**
* Describes the get_folders_by_courses return value.
*
* @return external_single_structure
* @since Moodle 3.3
*/
public static function get_folders_by_courses_returns() {
return new external_single_structure(
array(
'folders' => new external_multiple_structure(
new external_single_structure(array_merge(
helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
[
'revision' => new external_value(PARAM_INT, 'Incremented when after each file changes, to avoid cache'),
'timemodified' => new external_value(PARAM_INT, 'Last time the folder was modified'),
'display' => new external_value(PARAM_INT, 'Display type of folder contents on a separate page or inline'),
'showexpanded' => new external_value(PARAM_INT, '1 = expanded, 0 = collapsed for sub-folders'),
'showdownloadfolder' => new external_value(PARAM_INT, 'Whether to show the download folder button'),
'forcedownload' => new external_value(PARAM_INT, 'Whether file download is forced'),
]
))
),
'warnings' => new external_warnings(),
)
);
}
}
+44
View File
@@ -0,0 +1,44 @@
<?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/>.
/**
* Privacy Subsystem implementation for mod_folder.
*
* @package mod_folder
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_folder module does not store any data.
*
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class provider implements \core_privacy\local\metadata\null_provider {
/**
* Get the language string identifier with the component's language
* file to explain why this plugin stores no data.
*
* @return string
*/
public static function get_reason(): string {
return 'privacy:metadata';
}
}
+58
View File
@@ -0,0 +1,58 @@
<?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/>.
/**
* Search area for mod_folder activities.
*
* @package mod_folder
* @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\search;
defined('MOODLE_INTERNAL') || die();
/**
* Search area for mod_folder activities.
*
* @package mod_folder
* @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class activity extends \core_search\base_activity {
/**
* Returns true if this area uses file indexing.
*
* @return bool
*/
public function uses_file_indexing() {
return true;
}
/**
* Return the context info required to index files for
* this search area.
*
* @return array
*/
public function get_search_fileareas() {
$fileareas = array('intro', 'content'); // Fileareas.
return $fileareas;
}
}
+70
View File
@@ -0,0 +1,70 @@
<?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/>.
/**
* Capability definitions for the folder module.
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$capabilities = array(
'mod/folder:addinstance' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/course:manageactivities'
),
'mod/folder:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'guest' => CAP_ALLOW,
'user' => CAP_ALLOW,
)
),
/* TODO: review public portfolio API first!
'mod/folder:portfolioexport' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'editingteacher' => CAP_ALLOW,
)
),*/
// Can manage files in the folder.
'mod/folder:managefiles' => array(
'riskbitmask' => RISK_SPAM | RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW
)
)
);
+36
View File
@@ -0,0 +1,36 @@
<?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/>.
/**
* Post installation and migration code.
*
* This file replaces:
* - STATEMENTS section in db/install.xml
* - lib.php/modulename_install() post installation hook
* - partially defaults.php
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
function xmldb_folder_install() {
global $CFG;
}
+29
View File
@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/folder/db" VERSION="20200213" COMMENT="XMLDB file for Folder module"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="folder" COMMENT="each record is one folder resource">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true"/>
<FIELD NAME="course" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="name" TYPE="char" LENGTH="255" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="intro" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="introformat" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="revision" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="incremented when after each file changes, solves browser caching issues"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="display" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="Display type of folder contents - on a separate page or inline"/>
<FIELD NAME="showexpanded" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="1 = expanded, 0 = collapsed for sub-folders"/>
<FIELD NAME="showdownloadfolder" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="1 = show download folder button"/>
<FIELD NAME="forcedownload" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="1" SEQUENCE="false" COMMENT="1 = force download of individual files"/>
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id"/>
</KEYS>
<INDEXES>
<INDEX NAME="course" UNIQUE="false" FIELDS="course"/>
</INDEXES>
</TABLE>
</TABLES>
</XMLDB>
+34
View File
@@ -0,0 +1,34 @@
<?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/>.
/**
* Definition of log events
*
* @package mod_folder
* @category log
* @copyright 2010 Petr Skoda (http://skodak.org)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$logs = array(
array('module'=>'folder', 'action'=>'view', 'mtable'=>'folder', 'field'=>'name'),
array('module'=>'folder', 'action'=>'view all', 'mtable'=>'folder', 'field'=>'name'),
array('module'=>'folder', 'action'=>'update', 'mtable'=>'folder', 'field'=>'name'),
array('module'=>'folder', 'action'=>'add', 'mtable'=>'folder', 'field'=>'name'),
);
+48
View File
@@ -0,0 +1,48 @@
<?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/>.
/**
* folder external functions and service definitions.
*
* @package mod_folder
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
defined('MOODLE_INTERNAL') || die;
$functions = array(
'mod_folder_view_folder' => array(
'classname' => 'mod_folder_external',
'methodname' => 'view_folder',
'description' => 'Simulate the view.php web interface folder: trigger events, completion, etc...',
'type' => 'write',
'capabilities' => 'mod/folder:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_folder_get_folders_by_courses' => array(
'classname' => 'mod_folder_external',
'methodname' => 'get_folders_by_courses',
'description' => 'Returns a list of folders in a provided list of courses, if no list is provided all folders that
the user can view will be returned. Please note that this WS is not returning the folder contents.',
'type' => 'read',
'capabilities' => 'mod/folder:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
);
+59
View File
@@ -0,0 +1,59 @@
<?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/>.
/**
* Folder module upgrade code
*
* This file keeps track of upgrades to
* the resource module
*
* Sometimes, changes between versions involve
* alterations to database structures and other
* major things that may break installations.
*
* The upgrade function in this file will attempt
* to perform all the necessary actions to upgrade
* your older installation to the current version.
*
* If there's something it cannot do itself, it
* will tell you what you need to do.
*
* The commands in here will all be database-neutral,
* using the methods of database_manager class
*
* Please do not forget to use upgrade_set_timeout()
* before any action that may take longer time to finish.
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_folder_upgrade($oldversion) {
// Automatically generated Moodle v4.1.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.2.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.3.0 release upgrade line.
// Put any upgrade step following this.
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+69
View File
@@ -0,0 +1,69 @@
<?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/>.
/**
* Folder download
*
* @package mod_folder
* @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require_once(__DIR__ . "/../../config.php");
$id = required_param('id', PARAM_INT); // Course module ID.
$cm = get_coursemodule_from_id('folder', $id, 0, true, MUST_EXIST);
$course = $DB->get_record('course', array('id' => $cm->course), '*', MUST_EXIST);
require_course_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/folder:view', $context);
$folder = $DB->get_record('folder', array('id' => $cm->instance), '*', MUST_EXIST);
$downloadable = folder_archive_available($folder, $cm);
if (!$downloadable) {
throw new \moodle_exception('cannotdownloaddir', 'repository');
}
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_folder', 'content');
if (empty($files)) {
throw new \moodle_exception('cannotdownloaddir', 'repository');
}
// Log zip as downloaded.
folder_downloaded($folder, $course, $cm, $context);
// Close the session.
\core\session\manager::write_close();
$foldername = format_string($folder->name, true, ["context" => $context]);
$filename = shorten_filename(clean_filename($foldername . "-" . date("Ymd")) . ".zip");
$zipwriter = \core_files\archive_writer::get_stream_writer($filename, \core_files\archive_writer::ZIP_WRITER);
foreach ($files as $file) {
if ($file->is_directory()) {
continue;
}
$pathinzip = $file->get_filepath() . $file->get_filename();
$zipwriter->add_file_from_stored_file($pathinzip, $file);
}
// Finish the archive.
$zipwriter->finish();
exit();
+90
View File
@@ -0,0 +1,90 @@
<?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/>.
/**
* Manage files in folder module instance
*
* @package mod_folder
* @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
require_once("$CFG->dirroot/mod/folder/locallib.php");
require_once("$CFG->dirroot/mod/folder/edit_form.php");
require_once("$CFG->dirroot/repository/lib.php");
$id = required_param('id', PARAM_INT); // Course module ID
$cm = get_coursemodule_from_id('folder', $id, 0, true, MUST_EXIST);
$context = context_module::instance($cm->id, MUST_EXIST);
$folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST);
$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
require_login($course, false, $cm);
require_capability('mod/folder:managefiles', $context);
$PAGE->set_url('/mod/folder/edit.php', array('id' => $cm->id));
$PAGE->set_title($course->shortname.': '.$folder->name);
$PAGE->set_heading($course->fullname);
$PAGE->set_activity_record($folder);
$PAGE->set_secondary_active_tab('modulepage');
$PAGE->activityheader->set_attrs([
'hidecompletion' => true,
'description' => ''
]);
$PAGE->add_body_class('limitedwidth');
$data = new stdClass();
$data->id = $cm->id;
$maxbytes = get_user_max_upload_file_size($context, $CFG->maxbytes);
$options = array('subdirs' => 1, 'maxbytes' => $maxbytes, 'maxfiles' => -1, 'accepted_types' => '*');
file_prepare_standard_filemanager($data, 'files', $options, $context, 'mod_folder', 'content', 0);
$mform = new mod_folder_edit_form(null, array('data'=>$data, 'options'=>$options));
if ($folder->display == FOLDER_DISPLAY_INLINE) {
$redirecturl = course_get_url($cm->course, $cm->sectionnum);
} else {
$redirecturl = new moodle_url('/mod/folder/view.php', array('id' => $cm->id));
}
if ($mform->is_cancelled()) {
redirect($redirecturl);
} else if ($formdata = $mform->get_data()) {
$formdata = file_postupdate_standard_filemanager($formdata, 'files', $options, $context, 'mod_folder', 'content', 0);
$folder->timemodified = time();
$folder->revision = $folder->revision + 1;
$DB->update_record('folder', $folder);
$params = array(
'context' => $context,
'objectid' => $folder->id
);
$event = \mod_folder\event\folder_updated::create($params);
$event->add_record_snapshot('folder', $folder);
$event->trigger();
redirect($redirecturl);
}
echo $OUTPUT->header();
echo $OUTPUT->box_start('generalbox foldertree');
$mform->display();
echo $OUTPUT->box_end();
echo $OUTPUT->footer();
+45
View File
@@ -0,0 +1,45 @@
<?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/>.
/**
* A moodle form to manage folder files
*
* @package mod_folder
* @copyright 2010 Dongsheng Cai <dongsheng@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once("$CFG->libdir/formslib.php");
class mod_folder_edit_form extends moodleform {
function definition() {
$mform = $this->_form;
$data = $this->_customdata['data'];
$options = $this->_customdata['options'];
$mform->addElement('hidden', 'id', $data->id);
$mform->setType('id', PARAM_INT);
$mform->addElement('filemanager', 'files_filemanager', get_string('files'), null, $options);
$submit_string = get_string('savechanges');
$this->add_action_buttons(true, $submit_string);
$this->set_data($data);
}
}
+105
View File
@@ -0,0 +1,105 @@
<?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/>.
/**
* List of file folders in course
*
* @package mod_folder
* @copyright 2009 onwards Martin Dougiamas (http://dougiamas.com)
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
$id = required_param('id', PARAM_INT); // course id
$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
require_course_login($course, true);
$PAGE->set_pagelayout('incourse');
$params = array(
'context' => context_course::instance($course->id)
);
$event = \mod_folder\event\course_module_instance_list_viewed::create($params);
$event->add_record_snapshot('course', $course);
$event->trigger();
$strfolder = get_string('modulename', 'folder');
$strfolders = get_string('modulenameplural', 'folder');
$strname = get_string('name');
$strintro = get_string('moduleintro');
$strlastmodified = get_string('lastmodified');
$PAGE->set_url('/mod/folder/index.php', array('id' => $course->id));
$PAGE->set_title($course->shortname.': '.$strfolders);
$PAGE->set_heading($course->fullname);
$PAGE->set_secondary_active_tab('coursehome');
$PAGE->navbar->add($strfolders);
echo $OUTPUT->header();
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading($strfolders);
}
if (!$folders = get_all_instances_in_course('folder', $course)) {
notice(get_string('thereareno', 'moodle', $strfolders), "$CFG->wwwroot/course/view.php?id=$course->id");
exit;
}
$usesections = course_format_uses_sections($course->format);
$table = new html_table();
$table->attributes['class'] = 'generaltable mod_index';
if ($usesections) {
$strsectionname = get_string('sectionname', 'format_'.$course->format);
$table->head = array ($strsectionname, $strname, $strintro);
$table->align = array ('center', 'left', 'left');
} else {
$table->head = array ($strlastmodified, $strname, $strintro);
$table->align = array ('left', 'left', 'left');
}
$modinfo = get_fast_modinfo($course);
$currentsection = '';
foreach ($folders as $folder) {
$cm = $modinfo->cms[$folder->coursemodule];
if ($usesections) {
$printsection = '';
if ($folder->section !== $currentsection) {
if ($folder->section) {
$printsection = get_section_name($course, $folder->section);
}
if ($currentsection !== '') {
$table->data[] = 'hr';
}
$currentsection = $folder->section;
}
} else {
$printsection = '<span class="smallinfo">'.userdate($folder->timemodified)."</span>";
}
$class = $folder->visible ? '' : 'class="dimmed"'; // hidden modules are dimmed
$table->data[] = array (
$printsection,
"<a $class href=\"view.php?id=$cm->id\">".format_string($folder->name)."</a>",
format_module_intro('folder', $folder, $cm->id));
}
echo html_writer::table($table);
echo $OUTPUT->footer();
+73
View File
@@ -0,0 +1,73 @@
<?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/>.
/**
* Strings for component 'folder', language 'en', branch 'MOODLE_20_STABLE'
*
* @package mod_folder
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['bynameondate'] = 'by {$a->name} - {$a->date}';
$string['contentheader'] = 'Content';
$string['dnduploadmakefolder'] = 'Unzip files and create folder';
$string['downloadfolder'] = 'Download folder';
$string['eventallfilesdownloaded'] = 'Zip archive of folder downloaded';
$string['eventfolderupdated'] = 'Folder updated';
$string['folder:addinstance'] = 'Add a new folder';
$string['folder:managefiles'] = 'Manage files in folder module';
$string['folder:view'] = 'View folder content';
$string['foldercontent'] = 'Files and subfolders';
$string['forcedownload'] = 'Force download of files';
$string['forcedownload_help'] = 'Whether certain files, such as images or HTML files, should be displayed in the browser rather than being downloaded. Note that for security reasons, the setting should only be unticked if all users with the capability to manage files in the folder are trusted users.';
$string['indicator:cognitivedepth'] = 'Folder cognitive';
$string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in a Folder resource.';
$string['indicator:cognitivedepthdef'] = 'Folder cognitive';
$string['indicator:cognitivedepthdef_help'] = 'The participant has reached this percentage of the cognitive engagement offered by the Folder resources during this analysis interval (Levels = No view, View)';
$string['indicator:cognitivedepthdef_link'] = 'Learning_analytics_indicators#Cognitive_depth';
$string['indicator:socialbreadth'] = 'Folder social';
$string['indicator:socialbreadth_help'] = 'This indicator is based on the social breadth reached by the student in a Folder resource.';
$string['indicator:socialbreadthdef'] = 'Folder social';
$string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the Folder resources during this analysis interval (Levels = No participation, Participant alone)';
$string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth';
$string['modulename'] = 'Folder';
$string['modulename_help'] = 'The folder module enables a teacher to display a number of related files inside a single folder, reducing scrolling on the course page. A zipped folder may be uploaded and unzipped for display, or an empty folder created and files uploaded into it.
A folder may be used
* For a series of files on one topic, for example a set of past examination papers in pdf format or a collection of image files for use in student projects
* To provide a shared uploading space for teachers on the course page (keeping the folder hidden so that only teachers can see it)';
$string['modulename_link'] = 'mod/folder/view';
$string['modulenameplural'] = 'Folders';
$string['newfoldercontent'] = 'New folder content';
$string['page-mod-folder-x'] = 'Any folder module page';
$string['page-mod-folder-view'] = 'Folder module main page';
$string['privacy:metadata'] = 'The Folder resource plugin does not store any personal data.';
$string['pluginadministration'] = 'Folder administration';
$string['pluginname'] = 'Folder';
$string['display'] = 'Display folder contents';
$string['display_help'] = 'If you choose to display the folder contents on a course page, there will be no link to a separate page. The description will be displayed only if \'Display description on course page\' is ticked. Note that participants view actions cannot be logged in this case.';
$string['displaypage'] = 'On a separate page';
$string['displayinline'] = 'Inline on a course page';
$string['noautocompletioninline'] = 'Automatic completion on viewing of activity can not be selected together with "Display inline" option';
$string['search:activity'] = 'Folder';
$string['showdownloadfolder'] = 'Show download folder button';
$string['showdownloadfolder_help'] = 'If set to \'yes\', a button will be displayed allowing the contents of the folder to be downloaded as a zip file.';
$string['showexpanded'] = 'Show subfolders expanded';
$string['showexpanded_help'] = 'If set to \'yes\', subfolders are shown expanded by default; otherwise they are shown collapsed.';
$string['maxsizetodownload'] = 'Maximum folder download size (MB)';
$string['maxsizetodownload_help'] = 'The maximum size of folder that can be downloaded as a zip file. If set to zero, the folder size is unlimited.';
+866
View File
@@ -0,0 +1,866 @@
<?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/>.
/**
* Mandatory public API of folder module
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/** Display folder contents on a separate page */
define('FOLDER_DISPLAY_PAGE', 0);
/** Display folder contents inline in a course */
define('FOLDER_DISPLAY_INLINE', 1);
/**
* List of features supported in Folder module
* @param string $feature FEATURE_xx constant for requested feature
* @return mixed True if module supports feature, false if not, null if doesn't know or string for the module purpose.
*/
function folder_supports($feature) {
switch($feature) {
case FEATURE_MOD_ARCHETYPE: return MOD_ARCHETYPE_RESOURCE;
case FEATURE_GROUPS: return false;
case FEATURE_GROUPINGS: return false;
case FEATURE_MOD_INTRO: return true;
case FEATURE_COMPLETION_TRACKS_VIEWS: return true;
case FEATURE_GRADE_HAS_GRADE: return false;
case FEATURE_GRADE_OUTCOMES: return false;
case FEATURE_BACKUP_MOODLE2: return true;
case FEATURE_SHOW_DESCRIPTION: return true;
case FEATURE_MOD_PURPOSE: return MOD_PURPOSE_CONTENT;
default: return null;
}
}
/**
* This function is used by the reset_course_userdata function in moodlelib.
* @param $data the data submitted from the reset course.
* @return array status array
*/
function folder_reset_userdata($data) {
// Any changes to the list of dates that needs to be rolled should be same during course restore and course reset.
// See MDL-9367.
return array();
}
/**
* List the actions that correspond to a view of this module.
* This is used by the participation report.
*
* Note: This is not used by new logging system. Event with
* crud = 'r' and edulevel = LEVEL_PARTICIPATING will
* be considered as view action.
*
* @return array
*/
function folder_get_view_actions() {
return array('view', 'view all');
}
/**
* List the actions that correspond to a post of this module.
* This is used by the participation report.
*
* Note: This is not used by new logging system. Event with
* crud = ('c' || 'u' || 'd') and edulevel = LEVEL_PARTICIPATING
* will be considered as post action.
*
* @return array
*/
function folder_get_post_actions() {
return array('update', 'add');
}
/**
* Add folder instance.
* @param object $data
* @param object $mform
* @return int new folder instance id
*/
function folder_add_instance($data, $mform) {
global $DB;
$cmid = $data->coursemodule;
$draftitemid = $data->files;
$data->timemodified = time();
// If 'showexpanded' is not set, apply the site config.
if (!isset($data->showexpanded)) {
$data->showexpanded = get_config('folder', 'showexpanded');
}
$data->id = $DB->insert_record('folder', $data);
// we need to use context now, so we need to make sure all needed info is already in db
$DB->set_field('course_modules', 'instance', $data->id, array('id'=>$cmid));
$context = context_module::instance($cmid);
if ($draftitemid) {
file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true));
}
$completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null;
\core_completion\api::update_completion_date_event($data->coursemodule, 'folder', $data->id, $completiontimeexpected);
return $data->id;
}
/**
* Update folder instance.
* @param object $data
* @param object $mform
* @return bool true
*/
function folder_update_instance($data, $mform) {
global $CFG, $DB;
$cmid = $data->coursemodule;
$draftitemid = $data->files;
$data->timemodified = time();
$data->id = $data->instance;
$data->revision++;
$DB->update_record('folder', $data);
$context = context_module::instance($cmid);
if ($draftitemid = file_get_submitted_draft_itemid('files')) {
file_save_draft_area_files($draftitemid, $context->id, 'mod_folder', 'content', 0, array('subdirs'=>true));
}
$completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null;
\core_completion\api::update_completion_date_event($data->coursemodule, 'folder', $data->id, $completiontimeexpected);
return true;
}
/**
* Delete folder instance.
* @param int $id
* @return bool true
*/
function folder_delete_instance($id) {
global $DB;
if (!$folder = $DB->get_record('folder', array('id'=>$id))) {
return false;
}
$cm = get_coursemodule_from_instance('folder', $id);
\core_completion\api::update_completion_date_event($cm->id, 'folder', $folder->id, null);
// note: all context files are deleted automatically
$DB->delete_records('folder', array('id'=>$folder->id));
return true;
}
/**
* Lists all browsable file areas
*
* @package mod_folder
* @category files
* @param stdClass $course course object
* @param stdClass $cm course module object
* @param stdClass $context context object
* @return array
*/
function folder_get_file_areas($course, $cm, $context) {
$areas = array();
$areas['content'] = get_string('foldercontent', 'folder');
return $areas;
}
/**
* File browsing support for folder module content area.
*
* @package mod_folder
* @category files
* @param file_browser $browser file browser instance
* @param array $areas file areas
* @param stdClass $course course object
* @param stdClass $cm course module object
* @param stdClass $context context object
* @param string $filearea file area
* @param int $itemid item ID
* @param string $filepath file path
* @param string $filename file name
* @return file_info instance or null if not found
*/
function folder_get_file_info($browser, $areas, $course, $cm, $context, $filearea, $itemid, $filepath, $filename) {
global $CFG;
if ($filearea === 'content') {
if (!has_capability('mod/folder:view', $context)) {
return NULL;
}
$fs = get_file_storage();
$filepath = is_null($filepath) ? '/' : $filepath;
$filename = is_null($filename) ? '.' : $filename;
if (!$storedfile = $fs->get_file($context->id, 'mod_folder', 'content', 0, $filepath, $filename)) {
if ($filepath === '/' and $filename === '.') {
$storedfile = new virtual_root_file($context->id, 'mod_folder', 'content', 0);
} else {
// not found
return null;
}
}
require_once("$CFG->dirroot/mod/folder/locallib.php");
$urlbase = $CFG->wwwroot.'/pluginfile.php';
// students may read files here
$canwrite = has_capability('mod/folder:managefiles', $context);
return new folder_content_file_info($browser, $context, $storedfile, $urlbase, $areas[$filearea], true, true, $canwrite, false);
}
// note: folder_intro handled in file_browser automatically
return null;
}
/**
* Serves the folder files.
*
* @package mod_folder
* @category files
* @param stdClass $course course object
* @param stdClass $cm course module
* @param stdClass $context context object
* @param string $filearea file area
* @param array $args extra arguments
* @param bool $forcedownload whether or not force download
* @param array $options additional options affecting the file serving
* @return bool false if file not found, does not return if found - just send the file
*/
function folder_pluginfile($course, $cm, $context, $filearea, $args, $forcedownload, array $options=array()) {
global $CFG, $DB;
if ($context->contextlevel != CONTEXT_MODULE) {
return false;
}
require_course_login($course, true, $cm);
if (!has_capability('mod/folder:view', $context)) {
return false;
}
if ($filearea !== 'content') {
// intro is handled automatically in pluginfile.php
return false;
}
array_shift($args); // ignore revision - designed to prevent caching problems only
$fs = get_file_storage();
$relativepath = implode('/', $args);
$fullpath = "/$context->id/mod_folder/content/0/$relativepath";
if (!$file = $fs->get_file_by_hash(sha1($fullpath)) or $file->is_directory()) {
return false;
}
// Set security posture for in-browser display.
if (!$forcedownload) {
header("Content-Security-Policy: default-src 'none'; img-src 'self'; media-src 'self'");
}
// Finally send the file.
send_stored_file($file, 0, 0, $forcedownload, $options);
}
/**
* Return a list of page types
* @param string $pagetype current page type
* @param stdClass $parentcontext Block's parent context
* @param stdClass $currentcontext Current context of block
*/
function folder_page_type_list($pagetype, $parentcontext, $currentcontext) {
$module_pagetype = array('mod-folder-*'=>get_string('page-mod-folder-x', 'folder'));
return $module_pagetype;
}
/**
* Export folder resource contents
*
* @return array of file content
*/
function folder_export_contents($cm, $baseurl) {
global $CFG, $DB;
$contents = array();
$context = context_module::instance($cm->id);
$folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST);
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_folder', 'content', 0, 'sortorder DESC, id ASC', false);
foreach ($files as $fileinfo) {
$file = array();
$file['type'] = 'file';
$file['filename'] = $fileinfo->get_filename();
$file['filepath'] = $fileinfo->get_filepath();
$file['filesize'] = $fileinfo->get_filesize();
$file['fileurl'] = file_encode_url("$CFG->wwwroot/" . $baseurl, '/'.$context->id.'/mod_folder/content/'.$folder->revision.$fileinfo->get_filepath().$fileinfo->get_filename(), true);
$file['timecreated'] = $fileinfo->get_timecreated();
$file['timemodified'] = $fileinfo->get_timemodified();
$file['sortorder'] = $fileinfo->get_sortorder();
$file['userid'] = $fileinfo->get_userid();
$file['author'] = $fileinfo->get_author();
$file['license'] = $fileinfo->get_license();
$file['mimetype'] = $fileinfo->get_mimetype();
$file['isexternalfile'] = $fileinfo->is_external_file();
if ($file['isexternalfile']) {
$file['repositorytype'] = $fileinfo->get_repository_type();
}
$contents[] = $file;
}
return $contents;
}
/**
* Register the ability to handle drag and drop file uploads
* @return array containing details of the files / types the mod can handle
*/
function folder_dndupload_register() {
return array('files' => array(
array('extension' => 'zip', 'message' => get_string('dnduploadmakefolder', 'mod_folder'))
));
}
/**
* Handle a file that has been uploaded
* @param object $uploadinfo details of the file / content that has been uploaded
* @return int instance id of the newly created mod
*/
function folder_dndupload_handle($uploadinfo) {
global $DB, $USER;
// Gather the required info.
$data = new stdClass();
$data->course = $uploadinfo->course->id;
$data->name = $uploadinfo->displayname;
$data->intro = '<p>'.$uploadinfo->displayname.'</p>';
$data->introformat = FORMAT_HTML;
$data->coursemodule = $uploadinfo->coursemodule;
$data->files = null; // We will unzip the file and sort out the contents below.
$data->id = folder_add_instance($data, null);
// Retrieve the file from the draft file area.
$context = context_module::instance($uploadinfo->coursemodule);
file_save_draft_area_files($uploadinfo->draftitemid, $context->id, 'mod_folder', 'temp', 0, array('subdirs'=>true));
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_folder', 'temp', 0, 'sortorder', false);
// Only ever one file - extract the contents.
$file = reset($files);
$success = $file->extract_to_storage(new zip_packer(), $context->id, 'mod_folder', 'content', 0, '/', $USER->id);
$fs->delete_area_files($context->id, 'mod_folder', 'temp', 0);
if ($success) {
return $data->id;
}
$DB->delete_records('folder', array('id' => $data->id));
return false;
}
/**
* Given a coursemodule object, this function returns the extra
* information needed to print this activity in various places.
*
* If folder needs to be displayed inline we store additional information
* in customdata, so functions {@link folder_cm_info_dynamic()} and
* {@link folder_cm_info_view()} do not need to do DB queries
*
* @param cm_info $cm
* @return cached_cm_info info
*/
function folder_get_coursemodule_info($cm) {
global $DB;
if (!($folder = $DB->get_record('folder', array('id' => $cm->instance),
'id, name, display, showexpanded, showdownloadfolder, forcedownload, intro, introformat'))) {
return NULL;
}
$cminfo = new cached_cm_info();
$cminfo->name = $folder->name;
if ($folder->display == FOLDER_DISPLAY_INLINE) {
// prepare folder object to store in customdata
$fdata = new stdClass();
$fdata->showexpanded = $folder->showexpanded;
$fdata->showdownloadfolder = $folder->showdownloadfolder;
$fdata->forcedownload = $folder->forcedownload;
if ($cm->showdescription && strlen(trim($folder->intro))) {
$fdata->intro = $folder->intro;
if ($folder->introformat != FORMAT_MOODLE) {
$fdata->introformat = $folder->introformat;
}
}
$cminfo->customdata = $fdata;
} else {
if ($cm->showdescription) {
// Convert intro to html. Do not filter cached version, filters run at display time.
$cminfo->content = format_module_intro('folder', $folder, $cm->id, false);
}
}
return $cminfo;
}
/**
* Sets dynamic information about a course module
*
* This function is called from cm_info when displaying the module
* mod_folder can be displayed inline on course page and therefore have no course link
*
* @param cm_info $cm
*/
function folder_cm_info_dynamic(cm_info $cm) {
if ($cm->get_custom_data()) {
// the field 'customdata' is not empty IF AND ONLY IF we display contens inline
$cm->set_no_view_link();
}
}
/**
* Overwrites the content in the course-module object with the folder files list
* if folder.display == FOLDER_DISPLAY_INLINE
*
* @param cm_info $cm
*/
function folder_cm_info_view(cm_info $cm) {
global $PAGE;
if ($cm->uservisible && $cm->customdata &&
has_capability('mod/folder:view', $cm->context)) {
// Restore folder object from customdata.
// Note the field 'customdata' is not empty IF AND ONLY IF we display contens inline.
// Otherwise the content is default.
$folder = $cm->customdata;
$folder->id = (int)$cm->instance;
$folder->course = (int)$cm->course;
$folder->display = FOLDER_DISPLAY_INLINE;
$folder->name = $cm->name;
if (empty($folder->intro)) {
$folder->intro = '';
}
if (empty($folder->introformat)) {
$folder->introformat = FORMAT_MOODLE;
}
// display folder
$renderer = $PAGE->get_renderer('mod_folder');
$cm->set_content($renderer->display_folder($folder), true);
}
}
/**
* Mark the activity completed (if required) and trigger the course_module_viewed event.
*
* @param stdClass $folder folder object
* @param stdClass $course course object
* @param stdClass $cm course module object
* @param stdClass $context context object
* @since Moodle 3.0
*/
function folder_view($folder, $course, $cm, $context) {
// Trigger course_module_viewed event.
$params = array(
'context' => $context,
'objectid' => $folder->id
);
$event = \mod_folder\event\course_module_viewed::create($params);
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('folder', $folder);
$event->trigger();
// Completion.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
}
/**
* Check if the folder can be zipped and downloaded.
* @param stdClass $folder
* @param context_module $cm
* @return bool True if the folder can be zipped and downloaded.
* @throws \dml_exception
*/
function folder_archive_available($folder, $cm) {
if (!$folder->showdownloadfolder) {
return false;
}
$context = context_module::instance($cm->id);
$fs = get_file_storage();
$dir = $fs->get_area_tree($context->id, 'mod_folder', 'content', 0);
$size = folder_get_directory_size($dir);
$maxsize = get_config('folder', 'maxsizetodownload') * 1024 * 1024;
if ($size == 0) {
return false;
}
if (!empty($maxsize) && $size > $maxsize) {
return false;
}
return true;
}
/**
* Recursively measure the size of the files in a directory.
* @param array $directory
* @return int size of directory contents in bytes
*/
function folder_get_directory_size($directory) {
$size = 0;
foreach ($directory['files'] as $file) {
$size += $file->get_filesize();
}
foreach ($directory['subdirs'] as $subdirectory) {
$size += folder_get_directory_size($subdirectory);
}
return $size;
}
/**
* Mark the activity completed (if required) and trigger the all_files_downloaded event.
*
* @param stdClass $folder folder object
* @param stdClass $course course object
* @param stdClass $cm course module object
* @param stdClass $context context object
* @since Moodle 3.1
*/
function folder_downloaded($folder, $course, $cm, $context) {
$params = array(
'context' => $context,
'objectid' => $folder->id
);
$event = \mod_folder\event\all_files_downloaded::create($params);
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('folder', $folder);
$event->trigger();
// Completion.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
}
/**
* Returns all uploads since a given time in specified folder.
*
* @param array $activities
* @param int $index
* @param int $timestart
* @param int $courseid
* @param int $cmid
* @param int $userid
* @param int $groupid not used, but required for compatibilty with other modules
*/
function folder_get_recent_mod_activity(&$activities, &$index, $timestart, $courseid, $cmid, $userid=0, $groupid=0) {
global $DB, $OUTPUT;
$modinfo = get_fast_modinfo($courseid);
$cm = $modinfo->cms[$cmid];
$context = context_module::instance($cm->id);
if (!has_capability('mod/folder:view', $context)) {
return;
}
$instance = $DB->get_record('folder', ['id' => $cm->instance], '*', MUST_EXIST);
$files = folder_get_recent_activity($context, $timestart, $userid);
foreach ($files as $file) {
$tmpactivity = (object) [
'type' => 'folder',
'cmid' => $cm->id,
'sectionnum' => $cm->sectionnum,
'timestamp' => $file->get_timemodified(),
'user' => core_user::get_user($file->get_userid()),
];
$url = moodle_url::make_pluginfile_url(
$file->get_contextid(),
'mod_folder',
'content',
$file->get_itemid(),
$file->get_filepath(),
$file->get_filename(),
!empty($instance->forcedownload)
);
if (file_extension_in_typegroup($file->get_filename(), 'web_image')) {
$image = $url->out(false, array('preview' => 'tinyicon', 'oid' => $file->get_timemodified()));
$image = html_writer::empty_tag('img', array('src' => $image));
} else {
$image = $OUTPUT->pix_icon(file_file_icon($file), $file->get_filename(), 'moodle');
}
$tmpactivity->content = (object) [
'image' => $image,
'filename' => $file->get_filename(),
'url' => $url,
];
$activities[$index++] = $tmpactivity;
}
}
/**
* Outputs the folder uploads indicated by $activity.
*
* @param object $activity the activity object the folder resides in
* @param int $courseid the id of the course the folder resides in
* @param bool $detail not used, but required for compatibilty with other modules
* @param int $modnames not used, but required for compatibilty with other modules
* @param bool $viewfullnames not used, but required for compatibilty with other modules
*/
function folder_print_recent_mod_activity($activity, $courseid, $detail, $modnames, $viewfullnames) {
global $OUTPUT;
$content = $activity->content;
$tableoptions = [
'border' => '0',
'cellpadding' => '3',
'cellspacing' => '0'
];
$output = html_writer::start_tag('table', $tableoptions);
$output .= html_writer::start_tag('tr');
$output .= html_writer::tag('td', $content->image, ['class' => 'fp-icon', 'valign' => 'top']);
$output .= html_writer::start_tag('td');
$output .= html_writer::start_div('fp-filename');
$output .= html_writer::link($content->url, $content->filename);
$output .= html_writer::end_div();
// Show the uploader.
$fullname = fullname($activity->user, $viewfullnames);
$userurl = new moodle_url('/user/view.php');
$userurl->params(['id' => $activity->user->id, 'course' => $courseid]);
$by = new stdClass();
$by->name = html_writer::link($userurl, $fullname);
$by->date = userdate($activity->timestamp);
$authornamedate = get_string('bynameondate', 'folder', $by);
$output .= html_writer::div($authornamedate, 'user');
// Finish up the table.
$output .= html_writer::end_tag('tr');
$output .= html_writer::end_tag('table');
echo $output;
}
/**
* Gets recent file uploads in a given folder. Does not perform security checks.
*
* @param object $context
* @param int $timestart
* @param int $userid
*
* @return array
*/
function folder_get_recent_activity($context, $timestart, $userid=0) {
$newfiles = array();
$fs = get_file_storage();
$files = $fs->get_area_files($context->id, 'mod_folder', 'content');
foreach ($files as $file) {
if ($file->get_timemodified() <= $timestart) {
continue;
}
if ($file->get_filename() === '.') {
continue;
}
if (!empty($userid) && $userid !== $file->get_userid()) {
continue;
}
$newfiles[] = $file;
}
return $newfiles;
}
/**
* Given a course and a date, prints a summary of all the new
* files posted in folder resources since that date
*
* @uses CONTEXT_MODULE
* @param object $course
* @param bool $viewfullnames capability
* @param int $timestart
* @return bool success
*/
function folder_print_recent_activity($course, $viewfullnames, $timestart) {
global $OUTPUT;
$folders = get_all_instances_in_course('folder', $course);
if (empty($folders)) {
return false;
}
// The list of all new files.
$newfiles = [];
// Save the force download setting of all instances with files indexed by context.
$forcedownloads = [];
$modinfo = get_fast_modinfo($course);
foreach ($folders as $folder) {
// Skip resources if the user can't view them.
$cm = $modinfo->cms[$folder->coursemodule];
$context = context_module::instance($cm->id);
if (!has_capability('mod/folder:view', $context)) {
continue;
}
// Get the files uploaded in the current time frame.
$newfiles = array_merge($newfiles, folder_get_recent_activity($context, $timestart));
if (!isset($forcedownloads[$context->id])) {
$forcedownloads[$context->id] = !empty($folder->forcedownload);
}
}
if (empty($newfiles)) {
return false;
}
// Build list of files.
echo $OUTPUT->heading(get_string('newfoldercontent', 'folder') . ':', 6);
$list = html_writer::start_tag('ul', ['class' => 'unlist']);
foreach ($newfiles as $file) {
$filename = $file->get_filename();
$contextid = $file->get_contextid();
$url = moodle_url::make_pluginfile_url(
$contextid,
'mod_folder',
'content',
$file->get_itemid(),
$file->get_filepath(), $filename,
$forcedownloads[$contextid] ?? false
);
$list .= html_writer::start_tag('li');
$list .= html_writer::start_div('head');
$list .= html_writer::div(userdate($file->get_timemodified(), get_string('strftimerecent')), 'date');
$list .= html_writer::div($file->get_author(), 'name');
$list .= html_writer::end_div(); // Head.
$list .= html_writer::start_div('info');
$list .= html_writer::link($url, $filename);
$list .= html_writer::end_div(); // Info.
$list .= html_writer::end_tag('li');
}
$list .= html_writer::end_tag('ul');
echo $list;
return true;
}
/**
* Check if the module has any update that affects the current user since a given time.
*
* @param cm_info $cm course module data
* @param int $from the time to check updates from
* @param array $filter if we need to check only specific updates
* @return stdClass an object with the different type of areas indicating if they were updated or not
* @since Moodle 3.2
*/
function folder_check_updates_since(cm_info $cm, $from, $filter = array()) {
$updates = course_check_module_updates_since($cm, $from, array('content'), $filter);
return $updates;
}
/**
* This function receives a calendar event and returns the action associated with it, or null if there is none.
*
* This is used by block_myoverview in order to display the event appropriately. If null is returned then the event
* is not displayed on the block.
*
* @param calendar_event $event
* @param \core_calendar\action_factory $factory
* @param int $userid User id to use for all capability checks, etc. Set to 0 for current user (default).
* @return \core_calendar\local\event\entities\action_interface|null
*/
function mod_folder_core_calendar_provide_event_action(calendar_event $event,
\core_calendar\action_factory $factory,
int $userid = 0) {
global $USER;
if (!$userid) {
$userid = $USER->id;
}
$cm = get_fast_modinfo($event->courseid, $userid)->instances['folder'][$event->instance];
if (!$cm->uservisible) {
// The module is not visible to the user for any reason.
return null;
}
$completion = new \completion_info($cm->get_course());
$completiondata = $completion->get_data($cm, false, $userid);
if ($completiondata->completionstate != COMPLETION_INCOMPLETE) {
return null;
}
return $factory->create_instance(
get_string('view'),
new \moodle_url('/mod/folder/view.php', ['id' => $cm->id]),
1,
true
);
}
/**
* Given an array with a file path, it returns the itemid and the filepath for the defined filearea.
*
* @param string $filearea The filearea.
* @param array $args The path (the part after the filearea and before the filename).
* @return array The itemid and the filepath inside the $args path, for the defined filearea.
*/
function mod_folder_get_path_from_pluginfile(string $filearea, array $args): array {
// Folder never has an itemid (the number represents the revision but it's not stored in database).
array_shift($args);
// Get the filepath.
if (empty($args)) {
$filepath = '/';
} else {
$filepath = '/' . implode('/', $args) . '/';
}
return [
'itemid' => 0,
'filepath' => $filepath,
];
}
+47
View File
@@ -0,0 +1,47 @@
<?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/>.
/**
* Private folder module utility functions
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once("$CFG->dirroot/mod/folder/lib.php");
require_once("$CFG->libdir/filelib.php");
/**
* File browsing support class
*/
class folder_content_file_info extends file_info_stored {
public function get_parent() {
if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
return $this->browser->get_file_info($this->context);
}
return parent::get_parent();
}
public function get_visible_name() {
if ($this->lf->get_filepath() === '/' and $this->lf->get_filename() === '.') {
return $this->topvisiblename;
}
return parent::get_visible_name();
}
}
+113
View File
@@ -0,0 +1,113 @@
<?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/>.
/**
* Folder configuration form
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
require_once ($CFG->dirroot.'/course/moodleform_mod.php');
class mod_folder_mod_form extends moodleform_mod {
function definition() {
global $CFG;
$mform = $this->_form;
$config = get_config('folder');
//-------------------------------------------------------
$mform->addElement('header', 'general', get_string('general', 'form'));
$mform->addElement('text', 'name', get_string('name'), array('size'=>'48'));
if (!empty($CFG->formatstringstriptags)) {
$mform->setType('name', PARAM_TEXT);
} else {
$mform->setType('name', PARAM_CLEANHTML);
}
$mform->addRule('name', null, 'required', null, 'client');
$mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'client');
$this->standard_intro_elements();
//-------------------------------------------------------
$mform->addElement('header', 'content', get_string('contentheader', 'folder'));
$mform->addElement('filemanager', 'files', get_string('files'), null, array('subdirs'=>1, 'accepted_types'=>'*'));
$mform->addElement('select', 'display', get_string('display', 'mod_folder'),
array(FOLDER_DISPLAY_PAGE => get_string('displaypage', 'mod_folder'),
FOLDER_DISPLAY_INLINE => get_string('displayinline', 'mod_folder')));
$mform->addHelpButton('display', 'display', 'mod_folder');
if (!$this->courseformat->has_view_page()) {
$mform->setConstant('display', FOLDER_DISPLAY_PAGE);
$mform->hardFreeze('display');
}
$mform->setExpanded('content');
// Adding option to show sub-folders expanded or collapsed by default.
$mform->addElement('advcheckbox', 'showexpanded', get_string('showexpanded', 'folder'));
$mform->addHelpButton('showexpanded', 'showexpanded', 'mod_folder');
$mform->setDefault('showexpanded', $config->showexpanded);
// Adding option to enable downloading archive of folder.
$mform->addElement('advcheckbox', 'showdownloadfolder', get_string('showdownloadfolder', 'folder'));
$mform->addHelpButton('showdownloadfolder', 'showdownloadfolder', 'mod_folder');
$mform->setDefault('showdownloadfolder', true);
// Adding option to enable viewing of individual files.
$mform->addElement('advcheckbox', 'forcedownload', get_string('forcedownload', 'folder'));
$mform->addHelpButton('forcedownload', 'forcedownload', 'mod_folder');
$mform->setDefault('forcedownload', true);
//-------------------------------------------------------
$this->standard_coursemodule_elements();
//-------------------------------------------------------
$this->add_action_buttons();
//-------------------------------------------------------
$mform->addElement('hidden', 'revision');
$mform->setType('revision', PARAM_INT);
$mform->setDefault('revision', 1);
}
function data_preprocessing(&$default_values) {
if ($this->current->instance) {
// editing existing instance - copy existing files into draft area
$draftitemid = file_get_submitted_draft_itemid('files');
file_prepare_draft_area($draftitemid, $this->context->id, 'mod_folder', 'content', 0, array('subdirs'=>true));
$default_values['files'] = $draftitemid;
}
}
function validation($data, $files) {
$errors = parent::validation($data, $files);
// Completion: Automatic on-view completion can not work together with
// "display inline" option
if (empty($errors['completion']) &&
array_key_exists('completion', $data) &&
$data['completion'] == COMPLETION_TRACKING_AUTOMATIC &&
!empty($data['completionview']) &&
$data['display'] == FOLDER_DISPLAY_INLINE) {
$errors['completion'] = get_string('noautocompletioninline', 'mod_folder');
}
return $errors;
}
}
+3
View File
@@ -0,0 +1,3 @@
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMid meet">
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.79541 4.91064C4.9631 4.91064 4.28992 5.5883 4.29544 6.4206L4.36838 17.4131C4.37385 18.2376 5.0438 18.9031 5.86834 18.9031L18.8452 18.9031C19.6736 18.9031 20.3452 18.2315 20.3452 17.4031L20.3451 10.3949C20.3451 9.56648 19.6735 8.89491 18.8451 8.89491H14.2757C13.4905 8.89491 12.7509 8.52597 12.2785 7.89865L10.4789 5.5084C10.1955 5.13202 9.7517 4.91065 9.28055 4.91065L5.79541 4.91064ZM3.29547 6.42723C3.28626 5.04007 4.40822 3.91064 5.79541 3.91064L9.28055 3.91065C10.0657 3.91065 10.8053 4.27953 11.2776 4.90674H18.849C20.2297 4.90674 21.349 6.02603 21.349 7.40674V10.4067C21.349 10.428 21.3477 10.449 21.3451 10.4695L21.3452 17.4031C21.3452 18.7838 20.2259 19.9031 18.8452 19.9031L5.86834 19.9031C4.4941 19.9031 3.37752 18.7939 3.3684 17.4197L3.29547 6.42723ZM13.0774 7.29716L12.0305 5.90674H18.849C19.6774 5.90674 20.349 6.57831 20.349 7.40674V8.39767C19.9305 8.08205 19.4097 7.89491 18.8451 7.89491H14.2757C13.8046 7.89491 13.3608 7.67354 13.0774 7.29716ZM13.8545 15.91C13.5784 15.91 13.3545 16.1339 13.3545 16.41C13.3545 16.6862 13.5784 16.91 13.8545 16.91H17.8533C18.1294 16.91 18.3533 16.6862 18.3533 16.41C18.3533 16.1339 18.1294 15.91 17.8533 15.91H13.8545Z" fill="#212529"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+30
View File
@@ -0,0 +1,30 @@
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/>.
copyright 2009 Petr Skoda (http://skodak.org)
license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
Folder module
=============
Folder module is a successor to original 'directory' type plugin of Resource module.
This module is intended for distribution of large number of documents.
TODO:
* reimplement portfolio support (MDL-20070)
* new backup/restore and old restore transformation (MDL-20072)
+211
View File
@@ -0,0 +1,211 @@
<?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/>.
/**
* Folder module renderer
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
class mod_folder_renderer extends plugin_renderer_base {
/**
* Returns html to display the content of mod_folder
* (Description, folder files and optionally Edit button)
*
* @param stdClass $folder record from 'folder' table (please note
* it may not contain fields 'revision' and 'timemodified')
* @return string
*/
public function display_folder(stdClass $folder) {
static $treecounter = 0;
$folderinstances = get_fast_modinfo($folder->course)->get_instances_of('folder');
if (!isset($folderinstances[$folder->id]) ||
!($cm = $folderinstances[$folder->id]) ||
!($context = context_module::instance($cm->id))) {
// Some error in parameters.
// Don't throw any errors in renderer, just return empty string.
// Capability to view module must be checked before calling renderer.
return '';
}
$data = [];
if (trim($folder->intro)) {
if ($folder->display == FOLDER_DISPLAY_INLINE && $cm->showdescription) {
// for "display inline" do not filter, filters run at display time.
$data['intro'] = format_module_intro('folder', $folder, $cm->id, false);
}
}
$buttons = [];
// Display the "Edit" button if current user can edit folder contents.
// Do not display it on the course page for the teachers because there
// is an "Edit settings" option in the action menu with the same functionality.
$canmanagefolderfiles = has_capability('mod/folder:managefiles', $context);
$canmanagecourseactivities = has_capability('moodle/course:manageactivities', $context);
if ($canmanagefolderfiles && ($folder->display != FOLDER_DISPLAY_INLINE || !$canmanagecourseactivities)) {
$editbutton = new single_button(new moodle_url('/mod/folder/edit.php', ['id' => $cm->id]),
get_string('edit'), 'post', single_button::BUTTON_PRIMARY);
$editbutton->class = 'navitem';
$data['edit_button'] = $editbutton->export_for_template($this->output);
$data['hasbuttons'] = true;
}
$downloadable = folder_archive_available($folder, $cm);
if ($downloadable) {
$downloadbutton = new single_button(new moodle_url('/mod/folder/download_folder.php', ['id' => $cm->id]),
get_string('downloadfolder', 'folder'), 'get');
$downloadbutton->class = 'navitem ml-auto';
$data['download_button'] = $downloadbutton->export_for_template($this->output);
$data['hasbuttons'] = true;
}
$foldertree = new folder_tree($folder, $cm);
if ($folder->display == FOLDER_DISPLAY_INLINE) {
// Display module name as the name of the root directory.
$foldertree->dir['dirname'] = $cm->get_formatted_name(array('escape' => false));
}
$data['id'] = 'folder_tree'. ($treecounter++);
$data['showexpanded'] = !empty($foldertree->folder->showexpanded);
$data['dir'] = $this->renderable_tree_elements($foldertree, ['files' => [], 'subdirs' => [$foldertree->dir]]);
return $this->render_from_template('mod_folder/folder', $data);
}
/**
* Internal function - creates htmls structure suitable for YUI tree.
*
* @deprecated since Moodle 4.3
*/
protected function htmllize_tree($tree, $dir) {
global $CFG;
debugging(
'Method htmllize_tree() is deprecated. Please use renderable_tree_elements instead',
DEBUG_DEVELOPER
);
if (empty($dir['subdirs']) and empty($dir['files'])) {
return '';
}
$result = '<ul>';
foreach ($dir['subdirs'] as $subdir) {
$image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle');
$filename = html_writer::tag('span', $image, array('class' => 'fp-icon')).
html_writer::tag('span', s($subdir['dirname']), array('class' => 'fp-filename'));
$filename = html_writer::tag('div', $filename, array('class' => 'fp-filename-icon'));
$result .= html_writer::tag('li', $filename. $this->htmllize_tree($tree, $subdir));
}
foreach ($dir['files'] as $file) {
$filename = $file->get_filename();
$url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
$file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $filename, false);
$filenamedisplay = clean_filename($filename);
if (file_extension_in_typegroup($filename, 'web_image')) {
$image = $url->out(false, array('preview' => 'tinyicon', 'oid' => $file->get_timemodified()));
$image = html_writer::empty_tag('img', array('src' => $image));
} else {
$image = $this->output->pix_icon(file_file_icon($file), $filenamedisplay, 'moodle');
}
$filename = html_writer::tag('span', $image, array('class' => 'fp-icon')).
html_writer::tag('span', $filenamedisplay, array('class' => 'fp-filename'));
$urlparams = null;
if ($tree->folder->forcedownload) {
$urlparams = ['forcedownload' => 1];
}
$filename = html_writer::tag('span',
html_writer::link($url->out(false, $urlparams), $filename),
['class' => 'fp-filename-icon']
);
$result .= html_writer::tag('li', $filename);
}
$result .= '</ul>';
return $result;
}
/**
* Internal function - Creates elements structure suitable for mod_folder/folder template.
*
* @param folder_tree $tree The folder tree to work with.
* @param array $dir The subdir and files structure to convert into a tree.
* @return array The structure to be rendered by mod_folder/folder template.
*/
protected function renderable_tree_elements(folder_tree $tree, array $dir): array {
if (empty($dir['subdirs']) && empty($dir['files'])) {
return [];
}
$elements = [];
foreach ($dir['subdirs'] as $subdir) {
$htmllize = $this->renderable_tree_elements($tree, $subdir);
$image = $this->output->pix_icon(file_folder_icon(), $subdir['dirname'], 'moodle');
$elements[] = [
'name' => $subdir['dirname'],
'icon' => $image,
'subdirs' => $htmllize,
'hassubdirs' => !empty($htmllize),
];
}
foreach ($dir['files'] as $file) {
$filename = $file->get_filename();
$filenamedisplay = clean_filename($filename);
$url = moodle_url::make_pluginfile_url($file->get_contextid(), $file->get_component(),
$file->get_filearea(), $file->get_itemid(), $file->get_filepath(), $filename, false);
if (file_extension_in_typegroup($filename, 'web_image')) {
$image = $url->out(false, ['preview' => 'tinyicon', 'oid' => $file->get_timemodified()]);
$image = html_writer::empty_tag('img', ['src' => $image]);
} else {
$image = $this->output->pix_icon(file_file_icon($file), $filenamedisplay, 'moodle');
}
if ($tree->folder->forcedownload) {
$url->param('forcedownload', 1);
}
$elements[] = [
'name' => $filenamedisplay,
'icon' => $image,
'url' => $url,
'subdirs' => null,
'hassubdirs' => false,
];
}
return $elements;
}
}
class folder_tree implements renderable {
public $context;
public $folder;
public $cm;
public $dir;
public function __construct($folder, $cm) {
$this->folder = $folder;
$this->cm = $cm;
$this->context = context_module::instance($cm->id);
$fs = get_file_storage();
$this->dir = $fs->get_area_tree($this->context->id, 'mod_folder', 'content', 0);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?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/>.
/**
* Folder module admin settings and defaults
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
if ($ADMIN->fulltree) {
//--- general settings -----------------------------------------------------------------------------------
$settings->add(new admin_setting_configcheckbox('folder/showexpanded',
get_string('showexpanded', 'folder'),
get_string('showexpanded_help', 'folder'), 1));
$settings->add(new admin_setting_configtext('folder/maxsizetodownload',
get_string('maxsizetodownload', 'folder'),
get_string('maxsizetodownload_help', 'folder'), '', PARAM_INT));
}
+3
View File
@@ -0,0 +1,3 @@
div.course-content div.generalbox.folderbuttons {
padding-left: 35px;
}
+102
View File
@@ -0,0 +1,102 @@
{{!
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/>.
}}
{{!
@template mod_folder/folder
Template for displaying folder resource.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
"id": 42,
"showexpanded": true,
"buttons": {
"edit_button": {
"id": "edit_button",
"label": "Edit",
"url": "/mod/folder/edit.php",
"classes": "navitem"
},
"download_button": {
"id": "download_button",
"label": "Download",
"url": "/mod/folder/download.php",
"classes": "navitem"
}
},
"dir": [
{
"name": "Folder",
"icon": "<img src='icon' alt='alt'>",
"hassubdirs": true,
"subdirs": [
{
"name": "File1",
"icon": "<img src='icon' alt='alt'>",
"hassubdirs": false,
"subdirs": null
}
]
},
{
"name": "File2",
"icon": "<img src='icon' alt='alt'>",
"hassubdirs": false,
"subdirs": null
}
]
}
}}
<div class="flex-fill description-inner text-break">
{{{intro}}}
{{#hasbuttons}}
<div class="container-fluid">
<div class="row">
{{#edit_button}}
{{>core/single_button}}
{{/edit_button}}
{{#download_button}}
{{>core/single_button}}
{{/download_button}}
</div>
</div>
{{/hasbuttons}}
<div class="box generalbox pt-0 pb-3 foldertree">
<div id="{{{id}}}" class="filemanager">
{{#dir}}
<ul>
<li>
{{>mod_folder/tree}}
</li>
</ul>
{{/dir}}
</div>
</div>
</div>
{{#js}}
// Init tree JS.
require(['mod_folder/folder'], function(Folder) {
Folder.initTree('{{{id}}}', '{{{showexpanded}}}');
});
{{/js}}
+65
View File
@@ -0,0 +1,65 @@
{{!
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/>.
}}
{{!
@template mod_folder/tree
Template for displaying a folder content subdirs and files tree.
Classes required for JS:
* none
Data attributes required for JS:
* none
Example context (json):
{
"name": "Folder",
"icon": "<img src='icon' alt='alt'>",
"hassubdirs": true,
"subdirs": [
{
"name": "File1",
"icon": "<img src='icon' alt='alt'>",
"hassubdirs": false,
"subdirs": null
}
]
}
}}
<div class="fp-filename-icon">
<span class="fp-icon">
{{{icon}}}
</span>
<span class="fp-filename">
{{#url}}
<a href="{{url}}">{{{name}}}</a>
{{/url}}
{{^url}}
{{{name}}}
{{/url}}
</span>
</div>
{{#hassubdirs}}
<ul>
{{#subdirs}}
<li>
{{>mod_folder/tree}}
</li>
{{/subdirs}}
</ul>
{{/hassubdirs}}
@@ -0,0 +1,43 @@
<?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 mod_folder\backup;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->libdir . "/phpunit/classes/restore_date_testcase.php");
/**
* Restore date tests.
*
* @package mod_folder
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class restore_date_test extends \restore_date_testcase {
public function test_restore_dates(): void {
global $DB;
list($course, $folder) = $this->create_course_and_module('folder');
// Do backup and restore.
$newcourseid = $this->backup_and_restore($course);
$newfolder = $DB->get_record('folder', ['course' => $newcourseid]);
$this->assertFieldsNotRolledForward($folder, $newfolder, ['timemodified']);
}
}
@@ -0,0 +1,72 @@
@mod @mod_folder @core_completion
Feature: View activity completion information in the folder activity
In order to have visibility of folder completion requirements
As a student
I need to be able to view my folder completion progress
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| student1 | Vinnie | Student1 | student1@example.com |
| teacher1 | Darrell | Teacher1 | teacher1@example.com |
And the following "courses" exist:
| fullname | shortname | enablecompletion | showcompletionconditions |
| Course 1 | C1 | 1 | 1 |
| Course 2 | C2 | 1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
| student1 | C2 | student |
Scenario: View automatic completion items
Given the following "activity" exists:
| activity | folder |
| course | C1 |
| idnumber | mh1 |
| name | Music history |
| section | 1 |
| completion | 2 |
| completionview | 1 |
# Teacher view.
And I am on the "Music history" "folder activity" page logged in as teacher1
And "Music history" should have the "View" completion condition
And I log out
# Student view.
When I am on the "Music history" "folder activity" page logged in as student1
Then the "View" completion condition of "Music history" is displayed as "done"
@javascript
Scenario: Use manual completion
Given the following "activity" exists:
| activity | folder |
| course | C1 |
| idnumber | mh1 |
| name | Music history |
| section | 1 |
| completion | 1 |
And I am on the "Music history" "folder activity" page logged in as teacher1
# Teacher view.
And the manual completion button for "Music history" should be disabled
And I log out
# Student view.
When I am on the "Music history" "folder activity" page logged in as student1
Then the manual completion button of "Music history" is displayed as "Mark as done"
And I toggle the manual completion state of "Music history"
And the manual completion button of "Music history" is displayed as "Done"
@javascript
Scenario: The manual completion button will be shown on the course page for Inline on a course page display mode
Given the following "activity" exists:
| activity | folder |
| course | C2 |
| idnumber | mh2 |
| name | Music history |
| section | 1 |
| completion | 1 |
| display | 1 |
When I am on the "Course 2" course page logged in as student1
Then the manual completion button for "Music history" should exist
And the manual completion button of "Music history" is displayed as "Mark as done"
And I toggle the manual completion state of "Music history"
And the manual completion button of "Music history" is displayed as "Done"
@@ -0,0 +1,48 @@
@mod @mod_resource @_file_upload
Feature: Details of uploaded file in the resource can be changed
In order to change details of an uploaded file in a folder resource
As a teacher
I should be able to upload a file
Background:
Given the following "users" exist:
| username | firstname | lastname | email |
| teacher1 | Teacher | 1 | t1@example.com |
And the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
And the following "course enrolments" exist:
| user | course | role |
| teacher1 | C1 | editingteacher |
And the following "activities" exist:
| activity | course | name |
| folder | C1 | Folder1 |
@javascript
Scenario: Uploaded file details can be changed
Given I am on the "Folder1" "folder activity" page logged in as teacher1
And I click on "Edit" "button"
# Upload a file in folder resource
And I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager
And I press "Save changes"
And I click on "Edit" "button"
And I click on "empty.txt" "link"
# Initially, file details are set to default values
And the following fields match these values:
| Name | empty.txt |
| Author | Teacher 1 |
| licence | Licence not specified |
# Update the file details for testing
When I set the following fields to these values:
| Name | empty_file.txt |
| Author | Teacher 1 |
| licence | All rights reserved |
And I press "Update"
And I press "Save changes"
# Confirm that file details have been updated correctly
And I click on "Edit" "button"
And I click on "empty_file.txt" "link"
Then the following fields match these values:
| Name | empty_file.txt |
| Author | Teacher 1 |
| licence | All rights reserved |
@@ -0,0 +1,43 @@
@mod @mod_folder @block @block_recent_activity
Feature: Files added in folder activity are visible in the recent activity block
In order to view and download folder activity from recent activity block
As a teacher
I should be able to create folder activity with contents
Background:
Given the following "courses" exist:
| fullname | shortname |
| Course 1 | C1 |
And the following "blocks" exist:
| blockname | contextlevel | reference | pagetypepattern | defaultregion |
| recent_activity | Course | C1 | course-view-* | side-pre |
And the following "activities" exist:
| activity | course | name |
| folder | C1 | Folder 1 |
@_file_upload @javascript
Scenario: Files added in folder activity are visible in recent activity block
Given I am on the "Folder 1" "folder activity" page logged in as admin
And I click on "Edit" "button"
# Upload different file types in folder resource
And I upload "lib/tests/fixtures/empty.txt" file to "Files" filemanager
And I upload "lib/tests/fixtures/gd-logo.png" file to "Files" filemanager
And I press "Save changes"
# Confirm folder activity and files within the folder are visible in Recent activity block
When I am on the "Course 1" course page
Then I should see "Folder 1" in the "Recent activity" "block"
And I should see "empty.txt" in the "Recent activity" "block"
And I should see "gd-logo.png" in the "Recent activity" "block"
And I click on "Full report of recent activity..." "link"
# Confirm files within folder activity are visible in the full report
And "Folder 1" "link" should exist
And "empty.txt" "link" should exist
And "gd-logo.png" "link" should exist
And "//img[@alt='empty.txt']" "xpath_element" should exist
And "//img[contains(@src, 'preview=tinyicon')]" "xpath_element" should exist
# Confirm files are downloadable
And following "empty.txt" should download a file that:
| Has mimetype | text/plain |
| Contains text | empty file for testing purposes |
And following "gd-logo.png" should download a file that:
| Has mimetype | image/png |
+95
View File
@@ -0,0 +1,95 @@
<?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/>.
/**
* Events tests.
*
* @package mod_folder
* @category test
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\event;
class events_test extends \advanced_testcase {
/**
* Tests set up.
*/
public function setUp(): void {
$this->resetAfterTest();
}
/**
* Test the folder updated event.
*
* There is no external API for updating a folder, so the unit test will simply create
* and trigger the event and ensure the legacy log data is returned as expected.
*/
public function test_folder_updated(): void {
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
$params = array(
'context' => \context_module::instance($folder->cmid),
'objectid' => $folder->id,
'courseid' => $course->id
);
$event = \mod_folder\event\folder_updated::create($params);
$event->add_record_snapshot('folder', $folder);
// Trigger and capturing the event.
$sink = $this->redirectEvents();
$event->trigger();
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\mod_folder\event\folder_updated', $event);
$this->assertEquals(\context_module::instance($folder->cmid), $event->get_context());
$this->assertEquals($folder->id, $event->objectid);
}
/**
* Test the folder updated event.
*
* There is no external API for updating a folder, so the unit test will simply create
* and trigger the event and ensure the legacy log data is returned as expected.
*/
public function test_all_files_downloaded(): void {
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
$context = \context_module::instance($folder->cmid);
$cm = get_coursemodule_from_id('folder', $folder->cmid, $course->id, true, MUST_EXIST);
$sink = $this->redirectEvents();
folder_downloaded($folder, $course, $cm, $context);
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = reset($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\mod_folder\event\all_files_downloaded', $event);
$this->assertEquals(\context_module::instance($folder->cmid), $event->get_context());
$this->assertEquals($folder->id, $event->objectid);
$expected = array($course->id, 'folder', 'edit', 'edit.php?id=' . $folder->cmid, $folder->id, $folder->cmid);
$this->assertEventContextNotUsed($event);
}
}
+233
View File
@@ -0,0 +1,233 @@
<?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 mod_folder;
use core_external\external_api;
use externallib_advanced_testcase;
use mod_folder_external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* External mod_folder functions unit tests
*
* @package mod_folder
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
class externallib_test extends externallib_advanced_testcase {
/**
* Test view_folder
*/
public function test_view_folder(): void {
global $DB;
$this->resetAfterTest(true);
$this->setAdminUser();
// Setup test data.
$course = $this->getDataGenerator()->create_course();
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
$context = \context_module::instance($folder->cmid);
$cm = get_coursemodule_from_instance('folder', $folder->id);
// Test invalid instance id.
try {
mod_folder_external::view_folder(0);
$this->fail('Exception expected due to invalid mod_folder instance id.');
} catch (\moodle_exception $e) {
$this->assertEquals('invalidrecord', $e->errorcode);
}
// Test not-enrolled user.
$user = self::getDataGenerator()->create_user();
$this->setUser($user);
try {
mod_folder_external::view_folder($folder->id);
$this->fail('Exception expected due to not enrolled user.');
} catch (\moodle_exception $e) {
$this->assertEquals('requireloginerror', $e->errorcode);
}
// Test user with full capabilities.
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->getDataGenerator()->enrol_user($user->id, $course->id, $studentrole->id);
// Trigger and capture the event.
$sink = $this->redirectEvents();
$result = mod_folder_external::view_folder($folder->id);
$result = external_api::clean_returnvalue(mod_folder_external::view_folder_returns(), $result);
$events = $sink->get_events();
$this->assertCount(1, $events);
$event = array_shift($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\mod_folder\event\course_module_viewed', $event);
$this->assertEquals($context, $event->get_context());
$moodlefolder = new \moodle_url('/mod/folder/view.php', array('id' => $cm->id));
$this->assertEquals($moodlefolder, $event->get_url());
$this->assertEventContextNotUsed($event);
$this->assertNotEmpty($event->get_name());
// Test user with no capabilities.
// We need a explicit prohibit since this capability is only defined in authenticated user and guest roles.
assign_capability('mod/folder:view', CAP_PROHIBIT, $studentrole->id, $context->id);
// Empty all the caches that may be affected by this change.
accesslib_clear_all_caches_for_unit_testing();
\course_modinfo::clear_instance_cache();
try {
mod_folder_external::view_folder($folder->id);
$this->fail('Exception expected due to missing capability.');
} catch (\moodle_exception $e) {
$this->assertEquals('requireloginerror', $e->errorcode);
}
}
/**
* Test test_mod_folder_get_folders_by_courses
*/
public function test_mod_folder_get_folders_by_courses(): void {
global $DB;
$this->resetAfterTest(true);
$course1 = self::getDataGenerator()->create_course();
$course2 = self::getDataGenerator()->create_course();
$student = self::getDataGenerator()->create_user();
$studentrole = $DB->get_record('role', array('shortname' => 'student'));
$this->getDataGenerator()->enrol_user($student->id, $course1->id, $studentrole->id);
self::setUser($student);
// First folder.
$record = new \stdClass();
$record->course = $course1->id;
$record->forcedownload = 1;
$folder1 = self::getDataGenerator()->create_module('folder', $record);
// Second folder.
$record = new \stdClass();
$record->course = $course2->id;
$record->forcedownload = 0;
$folder2 = self::getDataGenerator()->create_module('folder', $record);
// Execute real Moodle enrolment as we'll call unenrol() method on the instance later.
$enrol = enrol_get_plugin('manual');
$enrolinstances = enrol_get_instances($course2->id, true);
foreach ($enrolinstances as $courseenrolinstance) {
if ($courseenrolinstance->enrol == "manual") {
$instance2 = $courseenrolinstance;
break;
}
}
$enrol->enrol_user($instance2, $student->id, $studentrole->id);
$returndescription = mod_folder_external::get_folders_by_courses_returns();
// Create what we expect to be returned when querying the two courses.
$expectedfields = array('id', 'coursemodule', 'course', 'name', 'intro', 'introformat', 'introfiles', 'lang', 'revision',
'timemodified', 'display', 'showexpanded', 'showdownloadfolder', 'section', 'visible',
'forcedownload', 'groupmode', 'groupingid');
// Add expected coursemodule and data.
$folder1->coursemodule = $folder1->cmid;
$folder1->introformat = 1;
$folder1->section = 0;
$folder1->visible = true;
$folder1->groupmode = 0;
$folder1->groupingid = 0;
$folder1->introfiles = [];
$folder1->lang = '';
$folder2->coursemodule = $folder2->cmid;
$folder2->introformat = 1;
$folder2->section = 0;
$folder2->visible = true;
$folder2->groupmode = 0;
$folder2->groupingid = 0;
$folder2->introfiles = [];
$folder2->lang = '';
foreach ($expectedfields as $field) {
$expected1[$field] = $folder1->{$field};
$expected2[$field] = $folder2->{$field};
}
$expectedfolders = array($expected2, $expected1);
// Call the external function passing course ids.
$result = mod_folder_external::get_folders_by_courses(array($course2->id, $course1->id));
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedfolders, $result['folders']);
$this->assertCount(0, $result['warnings']);
// Call the external function without passing course id.
$result = mod_folder_external::get_folders_by_courses();
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedfolders, $result['folders']);
$this->assertCount(0, $result['warnings']);
// Add a file to the intro.
$fileintroname = "fileintro.txt";
$filerecordinline = array(
'contextid' => \context_module::instance($folder2->cmid)->id,
'component' => 'mod_folder',
'filearea' => 'intro',
'itemid' => 0,
'filepath' => '/',
'filename' => $fileintroname,
);
$fs = get_file_storage();
$timepost = time();
$fs->create_file_from_string($filerecordinline, 'image contents (not really)');
$result = mod_folder_external::get_folders_by_courses(array($course2->id, $course1->id));
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertCount(1, $result['folders'][0]['introfiles']);
$this->assertEquals($fileintroname, $result['folders'][0]['introfiles'][0]['filename']);
// Unenrol user from second course.
$enrol->unenrol_user($instance2, $student->id);
array_shift($expectedfolders);
// Call the external function without passing course id.
$result = mod_folder_external::get_folders_by_courses();
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedfolders, $result['folders']);
// Call for the second course we unenrolled the user from, expected warning.
$result = mod_folder_external::get_folders_by_courses(array($course2->id));
$this->assertCount(1, $result['warnings']);
$this->assertEquals('1', $result['warnings'][0]['warningcode']);
$this->assertEquals($course2->id, $result['warnings'][0]['itemid']);
}
}
+49
View File
@@ -0,0 +1,49 @@
<?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/>.
/**
* mod_folder data generator.
*
* @package mod_folder
* @category test
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* mod_folder data generator class.
*
* @package mod_folder
* @category test
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_folder_generator extends testing_module_generator {
public function create_instance($record = null, array $options = null) {
// Add default values for folder.
$record = (array)$record + array('display' => 0);
if (!isset($record['showexpanded'])) {
$record['showexpanded'] = get_config('folder', 'showexpanded');
}
if (!isset($record['files'])) {
$record['files'] = file_get_unused_draft_itemid();
}
return parent::create_instance($record, (array)$options);
}
}
+61
View File
@@ -0,0 +1,61 @@
<?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 mod_folder;
/**
* Generator tests class for mod_folder.
*
* @package mod_folder
* @category test
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class generator_test extends \advanced_testcase {
public function test_create_instance(): void {
global $DB, $USER;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$this->assertFalse($DB->record_exists('folder', array('course' => $course->id)));
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course));
$records = $DB->get_records('folder', array('course' => $course->id), 'id');
$this->assertEquals(1, count($records));
$this->assertTrue(array_key_exists($folder->id, $records));
$params = array('course' => $course->id, 'name' => 'Another folder');
$folder = $this->getDataGenerator()->create_module('folder', $params);
$records = $DB->get_records('folder', array('course' => $course->id), 'id');
$this->assertEquals(2, count($records));
$this->assertEquals('Another folder', $records[$folder->id]->name);
// Examples of adding a folder with files (do not validate anything, just check for exceptions).
$params = array(
'course' => $course->id,
'files' => file_get_unused_draft_itemid()
);
$usercontext = \context_user::instance($USER->id);
$filerecord = array('component' => 'user', 'filearea' => 'draft',
'contextid' => $usercontext->id, 'itemid' => $params['files'],
'filename' => 'file1.txt', 'filepath' => '/');
$fs = get_file_storage();
$fs->create_file_from_string($filerecord, 'Test file contents');
$folder = $this->getDataGenerator()->create_module('folder', $params);
}
}
+403
View File
@@ -0,0 +1,403 @@
<?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/>.
/**
* Unit tests for mod_folder lib
*
* @package mod_folder
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
namespace mod_folder;
use context_user;
use context_module;
defined('MOODLE_INTERNAL') || die();
/**
* Unit tests for mod_folder lib
*
* @package mod_folder
* @category external
* @copyright 2015 Juan Leyva <juan@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
* @since Moodle 3.0
*/
class lib_test extends \advanced_testcase {
/**
* Setup.
*/
public function setUp(): void {
$this->resetAfterTest();
$this->setAdminUser();
}
/**
* Prepares things before this test case is initialised
* @return void
*/
public static function setUpBeforeClass(): void {
global $CFG;
require_once($CFG->dirroot . '/mod/folder/lib.php');
}
/**
* Test folder_view
* @return void
*/
public function test_folder_view(): void {
global $CFG;
$CFG->enablecompletion = 1;
// Setup test data.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1));
$context = \context_module::instance($folder->cmid);
$cm = get_coursemodule_from_instance('folder', $folder->id);
// Trigger and capture the event.
$sink = $this->redirectEvents();
folder_view($folder, $course, $cm, $context);
$events = $sink->get_events();
// 2 additional events thanks to completion.
$this->assertCount(3, $events);
$event = array_shift($events);
// Checking that the event contains the expected values.
$this->assertInstanceOf('\mod_folder\event\course_module_viewed', $event);
$this->assertEquals($context, $event->get_context());
$moodleurl = new \moodle_url('/mod/folder/view.php', array('id' => $cm->id));
$this->assertEquals($moodleurl, $event->get_url());
$this->assertEventContextNotUsed($event);
$this->assertNotEmpty($event->get_name());
// Check completion status.
$completion = new \completion_info($course);
$completiondata = $completion->get_data($cm);
$this->assertEquals(1, $completiondata->completionstate);
}
public function test_folder_core_calendar_provide_event_action(): void {
// Create the activity.
$course = $this->getDataGenerator()->create_course();
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
// Confirm the event was decorated.
$this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
$this->assertEquals(get_string('view'), $actionevent->get_name());
$this->assertInstanceOf('moodle_url', $actionevent->get_url());
$this->assertEquals(1, $actionevent->get_item_count());
$this->assertTrue($actionevent->is_actionable());
}
public function test_folder_core_calendar_provide_event_action_for_non_user(): void {
global $CFG;
// Create a course.
$course = $this->getDataGenerator()->create_course();
// Create the activity.
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Now, log out.
$CFG->forcelogin = true; // We don't want to be logged in as guest, as guest users might still have some capabilities.
$this->setUser();
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
// Confirm the event is not shown at all.
$this->assertNull($actionevent);
}
public function test_folder_core_calendar_provide_event_action_in_hidden_section(): void {
// Create a course.
$course = $this->getDataGenerator()->create_course();
// Create a student.
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Create the activity.
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Set sections 0 as hidden.
set_section_visible($course->id, 0, 0);
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
// Confirm the event is not shown at all.
$this->assertNull($actionevent);
}
public function test_folder_core_calendar_provide_event_action_for_user(): void {
// Create a course.
$course = $this->getDataGenerator()->create_course();
// Create a student.
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Create the activity.
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id));
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Now, log out.
$this->setUser();
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event for the student.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
// Confirm the event was decorated.
$this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent);
$this->assertEquals(get_string('view'), $actionevent->get_name());
$this->assertInstanceOf('moodle_url', $actionevent->get_url());
$this->assertEquals(1, $actionevent->get_item_count());
$this->assertTrue($actionevent->is_actionable());
}
public function test_folder_core_calendar_provide_event_action_already_completed(): void {
global $CFG;
$CFG->enablecompletion = 1;
// Create the activity.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
// Get some additional data.
$cm = get_coursemodule_from_instance('folder', $folder->id);
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Mark the activity as completed.
$completion = new \completion_info($course);
$completion->set_module_viewed($cm);
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory);
// Ensure result was null.
$this->assertNull($actionevent);
}
public function test_folder_core_calendar_provide_event_action_already_completed_for_user(): void {
global $CFG;
$CFG->enablecompletion = 1;
// Create a course.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
// Create a student.
$student = $this->getDataGenerator()->create_and_enrol($course, 'student');
// Create the activity.
$folder = $this->getDataGenerator()->create_module('folder', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
// Get some additional data.
$cm = get_coursemodule_from_instance('folder', $folder->id);
// Create a calendar event.
$event = $this->create_action_event($course->id, $folder->id,
\core_completion\api::COMPLETION_EVENT_TYPE_DATE_COMPLETION_EXPECTED);
// Mark the activity as completed for the student.
$completion = new \completion_info($course);
$completion->set_module_viewed($cm, $student->id);
// Now, log out.
$this->setUser();
// Create an action factory.
$factory = new \core_calendar\action_factory();
// Decorate action event for the student.
$actionevent = mod_folder_core_calendar_provide_event_action($event, $factory, $student->id);
// Ensure result was null.
$this->assertNull($actionevent);
}
/**
* Creates an action event.
*
* @param int $courseid The course id.
* @param int $instanceid The instance id.
* @param string $eventtype The event type.
* @return bool|calendar_event
*/
private function create_action_event($courseid, $instanceid, $eventtype) {
$event = new \stdClass();
$event->name = 'Calendar event';
$event->modulename = 'folder';
$event->courseid = $courseid;
$event->instance = $instanceid;
$event->type = CALENDAR_EVENT_TYPE_ACTION;
$event->eventtype = $eventtype;
$event->timestart = time();
return \calendar_event::create($event);
}
/**
* Test Get recent mod activity method.
* @covers ::folder_get_recent_mod_activity
* @dataProvider folder_get_recent_mod_activity_provider
*
* @param int $forcedownload The forcedownload option.
* @param bool $hascapability if the user has the mod/folder:view capability
* @param int $count The expected recent activities entries.
*/
public function test_folder_get_recent_mod_activity(int $forcedownload, bool $hascapability, int $count): void {
global $USER, $DB;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
// Add files to draft area.
$filesitem = file_get_unused_draft_itemid();
$usercontext = context_user::instance($USER->id);
$filerecord = [
'component' => 'user',
'filearea' => 'draft',
'contextid' => $usercontext->id,
'itemid' => $filesitem,
'filename' => 'file1.txt', 'filepath' => '/',
];
$fs = get_file_storage();
$fs->create_file_from_string($filerecord, 'First test file contents');
// And a second file.
$filerecord['filename'] = 'file2.txt';
$fs->create_file_from_string($filerecord, 'Second test file contents');
// Create the activity.
$module = $this->getDataGenerator()->create_module(
'folder',
['course' => $course->id, 'forcedownload' => $forcedownload, 'files' => $filesitem]
);
// Get some additional data.
$cm = get_coursemodule_from_instance('folder', $module->id);
$context = context_module::instance($cm->id);
// Add user with the specific capability.
$user = $this->getDataGenerator()->create_user();
$this->getDataGenerator()->enrol_user($user->id, $course->id, 'editingteacher');
if (!$hascapability) {
// The recent activiy uses "folder:view" capability which is allowed by default.
$role = $DB->get_record('role', ['shortname' => 'editingteacher'], '*', MUST_EXIST);
assign_capability('mod/folder:view', CAP_PROHIBIT, $role->id, $context->id, true);
}
$this->setUser($user);
// Get the recent activity.
$index = 1;
$activities = [];
folder_get_recent_mod_activity($activities, $index, time() - HOURSECS, $course->id, $cm->id);
// Check recent activity.
$this->assertCount($count, $activities);
foreach ($activities as $index => $activity) {
$this->assertEquals('folder', $activity->type);
$content = $activity->content;
$this->assertEquals("file{$index}.txt", $content->filename);
$urlparams = $content->url->params();
if ($forcedownload) {
$this->assertEquals(1, $urlparams['forcedownload']);
} else {
$this->assertArrayNotHasKey('forcedownload', $urlparams);
}
}
}
/**
* Data provider for test_folder_get_recent_mod_activity().
*
* @return array
*/
public function folder_get_recent_mod_activity_provider(): array {
return [
'Teacher with force download' => [
'forcedownload' => 1,
'hascapability' => true,
'count' => 2,
],
'Teacher with no force download' => [
'forcedownload' => 0,
'hascapability' => true,
'count' => 2,
],
'Invalid user with force download' => [
'forcedownload' => 1,
'hascapability' => false,
'count' => 0,
],
'Invalid user with no force download' => [
'forcedownload' => 0,
'hascapability' => false,
'count' => 0,
],
];
}
}
+132
View File
@@ -0,0 +1,132 @@
<?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/>.
/**
* Folder search unit tests.
*
* @package mod_folder
* @category test
* @copyright 2016 Eric Merrill {@link http://www.merrilldigital.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_folder\search;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/search/tests/fixtures/testable_core_search.php');
/**
* Provides the unit tests for forum search.
*
* @package mod_folder
* @category test
* @copyright 2016 Eric Merrill {@link http://www.merrilldigital.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class search_test extends \advanced_testcase {
/**
* @var string Area id
*/
protected $folderareaid = null;
public function setUp(): void {
$this->resetAfterTest(true);
set_config('enableglobalsearch', true);
$this->folderareaid = \core_search\manager::generate_areaid('mod_folder', 'activity');
// Set \core_search::instance to the mock_search_engine as we don't require the search engine to be working to test this.
$search = \testable_core_search::instance();
}
/**
* Test for folder file attachments.
*
* @return void
*/
public function test_attach_files(): void {
global $USER;
$this->setAdminUser();
// Setup test data.
$course = $this->getDataGenerator()->create_course();
$fs = get_file_storage();
$usercontext = \context_user::instance($USER->id);
$record = new \stdClass();
$record->course = $course->id;
$record->files = file_get_unused_draft_itemid();
// Attach the main file. We put them in the draft area, create_module will move them.
$filerecord = array(
'contextid' => $usercontext->id,
'component' => 'user',
'filearea' => 'draft',
'itemid' => $record->files,
'filepath' => '/'
);
// Attach 4 files.
for ($i = 1; $i <= 4; $i++) {
$filerecord['filename'] = 'myfile'.$i;
$fs->create_file_from_string($filerecord, 'Test folder file '.$i);
}
// And a fifth in a sub-folder.
$filerecord['filename'] = 'myfile5';
$filerecord['filepath'] = '/subfolder/';
$fs->create_file_from_string($filerecord, 'Test folder file 5');
$this->getDataGenerator()->create_module('folder', $record);
// Returns the instance as long as the area is supported.
$searcharea = \core_search\manager::get_search_area($this->folderareaid);
$this->assertInstanceOf('\mod_folder\search\activity', $searcharea);
$recordset = $searcharea->get_recordset_by_timestamp(0);
$nrecords = 0;
foreach ($recordset as $record) {
$doc = $searcharea->get_document($record);
$searcharea->attach_files($doc);
$files = $doc->get_files();
// Folder should return all files attached.
$this->assertCount(5, $files);
// We don't know the order, so get all the names, then sort, then check.
$filenames = array();
foreach ($files as $file) {
$filenames[] = $file->get_filename();
}
sort($filenames);
for ($i = 1; $i <= 5; $i++) {
$this->assertEquals('myfile'.$i, $filenames[($i - 1)]);
}
$nrecords++;
}
// If there would be an error/failure in the foreach above the recordset would be closed on shutdown.
$recordset->close();
$this->assertEquals(1, $nrecords);
}
}
+5
View File
@@ -0,0 +1,5 @@
This files describes API changes in /mod/folder/*,
information provided here is intended especially for developers.
=== 4.3 ===
* htmllize_tree() method has been deprecated. Use renderable_tree_elements() instead.
+30
View File
@@ -0,0 +1,30 @@
<?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/>.
/**
* Folder module version information
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
$plugin->version = 2024042200; // The current module version (Date: YYYYMMDDXX).
$plugin->requires = 2024041600; // Requires this Moodle version.
$plugin->component = 'mod_folder'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;
+80
View File
@@ -0,0 +1,80 @@
<?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/>.
/**
* Folder module main user interface
*
* @package mod_folder
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
require('../../config.php');
require_once("$CFG->dirroot/mod/folder/locallib.php");
require_once("$CFG->dirroot/repository/lib.php");
require_once($CFG->libdir . '/completionlib.php');
$id = optional_param('id', 0, PARAM_INT); // Course module ID
$f = optional_param('f', 0, PARAM_INT); // Folder instance id
if ($f) { // Two ways to specify the module
$folder = $DB->get_record('folder', array('id'=>$f), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('folder', $folder->id, $folder->course, true, MUST_EXIST);
} else {
$cm = get_coursemodule_from_id('folder', $id, 0, true, MUST_EXIST);
$folder = $DB->get_record('folder', array('id'=>$cm->instance), '*', MUST_EXIST);
}
$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
require_course_login($course, true, $cm);
$context = context_module::instance($cm->id);
require_capability('mod/folder:view', $context);
if ($folder->display == FOLDER_DISPLAY_INLINE) {
redirect(course_get_url($folder->course, $cm->sectionnum));
}
$params = array(
'context' => $context,
'objectid' => $folder->id
);
$event = \mod_folder\event\course_module_viewed::create($params);
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('folder', $folder);
$event->trigger();
// Update 'viewed' state if required by completion system
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
$PAGE->set_url('/mod/folder/view.php', array('id' => $cm->id));
$PAGE->set_title($course->shortname.': '.$folder->name);
$PAGE->set_heading($course->fullname);
$PAGE->set_activity_record($folder);
$PAGE->add_body_class('limitedwidth');
$output = $PAGE->get_renderer('mod_folder');
echo $output->header();
echo $output->display_folder($folder);
echo $output->footer();