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
+115
View File
@@ -0,0 +1,115 @@
<?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_url
* @copyright 2011 Andrew Davis <andrew@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* URL conversion handler. This resource handler is called by moodle1_mod_resource_handler
*/
class moodle1_mod_url_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'];
$cminfo = $this->get_cminfo($instanceid, 'resource');
$moduleid = $cminfo['id'];
$contextid = $this->converter->get_contextid(CONTEXT_MODULE, $moduleid);
// prepare the new url instance record
$url = array();
$url['id'] = $data['id'];
$url['name'] = $data['name'];
$url['intro'] = $data['intro'];
$url['introformat'] = $data['introformat'];
$url['externalurl'] = $data['reference'];
$url['timemodified'] = $data['timemodified'];
// populate display and displayoptions fields
$options = array('printintro' => 1);
if ($data['options'] == 'frame') {
$url['display'] = RESOURCELIB_DISPLAY_FRAME;
} else if ($data['options'] == 'objectframe') {
$url['display'] = RESOURCELIB_DISPLAY_EMBED;
} else if ($data['popup']) {
$url['display'] = RESOURCELIB_DISPLAY_POPUP;
$rawoptions = explode(',', $data['popup']);
foreach ($rawoptions as $rawoption) {
list($name, $value) = explode('=', trim($rawoption), 2);
if ($value > 0 and ($name == 'width' or $name == 'height')) {
$options['popup'.$name] = $value;
continue;
}
}
} else {
$url['display'] = RESOURCELIB_DISPLAY_AUTO;
}
$url['displayoptions'] = serialize($options);
// populate the parameters field
$parameters = array();
if ($data['alltext']) {
$rawoptions = explode(',', $data['alltext']);
foreach ($rawoptions as $rawoption) {
list($variable, $parameter) = explode('=', trim($rawoption), 2);
$parameters[$parameter] = $variable;
}
}
$url['parameters'] = serialize($parameters);
// convert course files embedded into the intro
$this->fileman = $this->converter->get_file_manager($contextid, 'mod_url', 'intro');
$url['intro'] = moodle1_converter::migrate_referenced_files($url['intro'], $this->fileman);
// write url.xml
$this->open_xml_writer("activities/url_{$moduleid}/url.xml");
$this->xmlwriter->begin_tag('activity', array('id' => $instanceid, 'moduleid' => $moduleid,
'modulename' => 'url', 'contextid' => $contextid));
$this->write_xml('url', $url, array('/url/id'));
$this->xmlwriter->end_tag('activity');
$this->close_xml_writer();
// write inforef.xml
$this->open_xml_writer("activities/url_{$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,77 @@
<?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_url_activity_task class
*
* @package mod_url
* @category backup
* @copyright 2010 onwards Andrew Davis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
require_once($CFG->dirroot . '/mod/url/backup/moodle2/backup_url_stepslib.php');
/**
* Provides all the settings and steps to perform one complete backup of the activity
*/
class backup_url_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 url.xml file
*/
protected function define_my_steps() {
$this->add_step(new backup_url_activity_structure_step('url_structure', 'url.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.'/mod/url','#');
//Access a list of all links in a course
$pattern = '#('.$base.'/index\.php\?id=)([0-9]+)#';
$replacement = '$@URLINDEX*$2@$';
$content = preg_replace($pattern, $replacement, $content);
//Access the link supplying a course module id
$pattern = '#('.$base.'/view\.php\?id=)([0-9]+)#';
$replacement = '$@URLVIEWBYID*$2@$';
$content = preg_replace($pattern, $replacement, $content);
//Access the link supplying an instance id
$pattern = '#('.$base.'/view\.php\?u=)([0-9]+)#';
$replacement = '$@URLVIEWBYU*$2@$';
$content = preg_replace($pattern, $replacement, $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_url_activity_task
*
* @package mod_url
* @copyright 2010 onwards Andrew Davis
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die;
/**
* Define the complete url structure for backup, with file and id annotations
*/
class backup_url_activity_structure_step extends backup_activity_structure_step {
protected function define_structure() {
//the URL module stores no user info
// Define each element separated
$url = new backup_nested_element('url', array('id'), array(
'name', 'intro', 'introformat', 'externalurl',
'display', 'displayoptions', 'parameters', 'timemodified'));
// Build the tree
//nothing here for URLs
// Define sources
$url->set_source_table('url', array('id' => backup::VAR_ACTIVITYID));
// Define id annotations
//module has no id annotations
// Define file annotations
$url->annotate_files('mod_url', 'intro', null); // This file area hasn't itemid
// Return the root element (url), wrapped into standard activity structure
return $this->prepare_activity_structure($url);
}
}
@@ -0,0 +1,110 @@
<?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_url
* @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/url/backup/moodle2/restore_url_stepslib.php'); // Because it exists (must)
/**
* url restore task that provides all the settings and steps to perform one
* complete restore of the activity
*/
class restore_url_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() {
// url only has one structure step
$this->add_step(new restore_url_activity_structure_step('url_structure', 'url.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('url', array('intro', 'externalurl'), 'url');
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('URLINDEX', '/mod/url/index.php?id=$1', 'course');
$rules[] = new restore_decode_rule('URLVIEWBYID', '/mod/url/view.php?id=$1', 'course_module');
$rules[] = new restore_decode_rule('URLVIEWBYU', '/mod/url/view.php?u=$1', 'url');
return $rules;
}
/**
* Define the restore log rules that will be applied
* by the {@link restore_logs_processor} when restoring
* url 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('url', 'add', 'view.php?id={course_module}', '{url}');
$rules[] = new restore_log_rule('url', 'update', 'view.php?id={course_module}', '{url}');
$rules[] = new restore_log_rule('url', 'view', 'view.php?id={course_module}', '{url}');
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('url', 'view all', 'index.php?id={course}', null);
return $rules;
}
}
@@ -0,0 +1,63 @@
<?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_url
* @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_url_activity_task
*/
/**
* Structure step to restore one url activity
*/
class restore_url_activity_structure_step extends restore_activity_structure_step {
protected function define_structure() {
$paths = array();
$paths[] = new restore_path_element('url', '/activity/url');
// Return the paths wrapped into standard activity structure
return $this->prepare_activity_structure($paths);
}
protected function process_url($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.
// insert the url record
$newitemid = $DB->insert_record('url', $data);
// immediately after inserting "activity" record, call this
$this->apply_activity_instance($newitemid);
}
protected function after_execute() {
// Add url related files, no need to match by itemname (just internally handled context)
$this->add_related_files('mod_url', 'intro', 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_url
* @copyright 2017 onwards Ankit Agarwal <ankit.agrr@gmail.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Activity base class.
*
* @package mod_url
* @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 - url.
*
* @package mod_url
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Cognitive depth indicator - url.
*
* @package mod_url
* @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_url');
}
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 - url.
*
* @package mod_url
* @copyright 2017 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\analytics\indicator;
defined('MOODLE_INTERNAL') || die();
/**
* Social breadth indicator - url.
*
* @package mod_url
* @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_url');
}
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,94 @@
<?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_url\completion;
use core_completion\activity_custom_completion;
/**
* Activity custom completion subclass for the url resource.
*
* Class for defining mod_url's custom completion rules and fetching the completion statuses
* of the custom completion rules for a given url instance and a user.
*
* @package mod_url
* @copyright 2021 Huong Nguyen <huongn@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 do 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 do not have any custom rule descriptions.
return [];
}
/**
* Show the manual completion or not regardless of the course's showcompletionconditions setting.
*
* @return bool
*/
public function manual_completion_always_shown(): bool {
global $CFG;
require_once($CFG->libdir.'/resourcelib.php');
$display = $this->cm->customdata['display'] ?? null;
$displaytypes = [
RESOURCELIB_DISPLAY_NEW,
RESOURCELIB_DISPLAY_OPEN,
RESOURCELIB_DISPLAY_POPUP
];
return in_array($display, $displaytypes);
}
/**
* 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 [];
}
}
@@ -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_url instance list viewed event.
*
* @package mod_url
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_url instance list viewed event class.
*
* @package mod_url
* @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 {
}
@@ -0,0 +1,53 @@
<?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_url course module viewed event.
*
* @package mod_url
* @copyright 2013 Mark Nelson <markn@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\event;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_url course module viewed event class.
*
* @package mod_url
* @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.
*
* @return void
*/
protected function init() {
$this->data['objecttable'] = 'url';
$this->data['crud'] = 'r';
$this->data['edulevel'] = self::LEVEL_PARTICIPATING;
}
public static function get_objectid_mapping() {
return array('db' => 'url', 'restore' => 'url');
}
}
+188
View File
@@ -0,0 +1,188 @@
<?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;
/**
* URL external functions
*
* @package mod_url
* @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_url_external extends external_api {
/**
* Returns description of method parameters
*
* @return external_function_parameters
* @since Moodle 3.0
*/
public static function view_url_parameters() {
return new external_function_parameters(
array(
'urlid' => new external_value(PARAM_INT, 'url instance id')
)
);
}
/**
* Trigger the course module viewed event and update the module completion status.
*
* @param int $urlid the url instance id
* @return array of warnings and status result
* @since Moodle 3.0
* @throws moodle_exception
*/
public static function view_url($urlid) {
global $DB, $CFG;
require_once($CFG->dirroot . "/mod/url/lib.php");
$params = self::validate_parameters(self::view_url_parameters(),
array(
'urlid' => $urlid
));
$warnings = array();
// Request and permission validation.
$url = $DB->get_record('url', array('id' => $params['urlid']), '*', MUST_EXIST);
list($course, $cm) = get_course_and_cm_from_instance($url, 'url');
$context = context_module::instance($cm->id);
self::validate_context($context);
require_capability('mod/url:view', $context);
// Call the url/lib API.
url_view($url, $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_url_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_urls_by_courses.
*
* @return external_function_parameters
* @since Moodle 3.3
*/
public static function get_urls_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 urls in a provided list of courses.
* If no list is provided all urls that the user can view will be returned.
*
* @param array $courseids course ids
* @return array of warnings and urls
* @since Moodle 3.3
*/
public static function get_urls_by_courses($courseids = array()) {
$warnings = array();
$returnedurls = array();
$params = array(
'courseids' => $courseids,
);
$params = self::validate_parameters(self::get_urls_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 urls in this course, this function checks users visibility permissions.
// We can avoid then additional validate_context calls.
$urls = get_all_instances_in_courses("url", $courses);
foreach ($urls as $url) {
helper_for_get_mods_by_courses::format_name_and_intro($url, 'mod_url');
$returnedurls[] = $url;
}
}
$result = array(
'urls' => $returnedurls,
'warnings' => $warnings
);
return $result;
}
/**
* Describes the get_urls_by_courses return value.
*
* @return external_single_structure
* @since Moodle 3.3
*/
public static function get_urls_by_courses_returns() {
return new external_single_structure(
array(
'urls' => new external_multiple_structure(
new external_single_structure(array_merge(
helper_for_get_mods_by_courses::standard_coursemodule_elements_returns(),
[
'externalurl' => new external_value(PARAM_RAW_TRIMMED, 'External URL'),
'display' => new external_value(PARAM_INT, 'How to display the url'),
'displayoptions' => new external_value(PARAM_RAW, 'Display options (width, height)'),
'parameters' => new external_value(PARAM_RAW, 'Parameters to append to the URL'),
'timemodified' => new external_value(PARAM_INT, 'Last time the url was modified'),
]
))
),
'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_url.
*
* @package mod_url
* @copyright 2018 Zig Tan <zig@moodle.com>
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\privacy;
defined('MOODLE_INTERNAL') || die();
/**
* The mod_url 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';
}
}
+65
View File
@@ -0,0 +1,65 @@
<?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_url activities.
*
* @package mod_url
* @copyright 2015 David Monllao {@link http://www.davidmonllao.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url\search;
defined('MOODLE_INTERNAL') || die();
/**
* Search area for mod_url activities.
*
* @package mod_url
* @copyright 2016 Dan Poltawski
* @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;
}
/**
* Returns the document associated with this activity.
*
* Overwrites base_activity to add the provided URL as description.
*
* @param \stdClass $record
* @param array $options
* @return \core_search\document|false
*/
public function get_document($record, $options = array()) {
$doc = parent::get_document($record, $options);
if (!$doc) {
return false;
}
$doc->set('description1', $record->externalurl);
return $doc;
}
}
+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/>.
/**
* Capability definitions for the url module.
*
* @package mod_url
* @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/url:view' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'guest' => CAP_ALLOW,
'user' => CAP_ALLOW,
)
),
'mod/url:addinstance' => array(
'riskbitmask' => RISK_XSS,
'captype' => 'write',
'contextlevel' => CONTEXT_COURSE,
'archetypes' => array(
'editingteacher' => CAP_ALLOW,
'manager' => CAP_ALLOW
),
'clonepermissionsfrom' => 'moodle/course:manageactivities'
),
/* TODO: review public portfolio API first!
'mod/url:portfolioexport' => array(
'captype' => 'read',
'contextlevel' => CONTEXT_MODULE,
'archetypes' => array(
'teacher' => CAP_ALLOW,
'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_url
* @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_url_install() {
global $CFG;
}
+28
View File
@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8" ?>
<XMLDB PATH="mod/url/db" VERSION="20120122" COMMENT="XMLDB file for URL module"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../lib/xmldb/xmldb.xsd"
>
<TABLES>
<TABLE NAME="url" COMMENT="each record is one url 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="externalurl" TYPE="text" NOTNULL="true" SEQUENCE="false"/>
<FIELD NAME="display" TYPE="int" LENGTH="4" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
<FIELD NAME="displayoptions" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="parameters" TYPE="text" NOTNULL="false" SEQUENCE="false"/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" DEFAULT="0" SEQUENCE="false"/>
</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_url
* @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'=>'url', 'action'=>'view', 'mtable'=>'url', 'field'=>'name'),
array('module'=>'url', 'action'=>'view all', 'mtable'=>'url', 'field'=>'name'),
array('module'=>'url', 'action'=>'update', 'mtable'=>'url', 'field'=>'name'),
array('module'=>'url', 'action'=>'add', 'mtable'=>'url', '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/>.
/**
* URL external functions and service definitions.
*
* @package mod_url
* @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_url_view_url' => array(
'classname' => 'mod_url_external',
'methodname' => 'view_url',
'description' => 'Trigger the course module viewed event and update the module completion status.',
'type' => 'write',
'capabilities' => 'mod/url:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE)
),
'mod_url_get_urls_by_courses' => array(
'classname' => 'mod_url_external',
'methodname' => 'get_urls_by_courses',
'description' => 'Returns a list of urls in a provided list of courses, if no list is provided all urls that the user
can view will be returned.',
'type' => 'read',
'capabilities' => 'mod/url:view',
'services' => array(MOODLE_OFFICIAL_MOBILE_SERVICE),
),
);
+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/>.
/**
* URL 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_url
* @copyright 2009 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
function xmldb_url_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.
if ($oldversion < 2023100901) {
// Enable variables to be set for URL resource.
if (!get_config('url', 'allowvariables')) {
set_config('allowvariables', true, 'url');
}
// URL savepoint reached.
upgrade_mod_savepoint(true, 2023100901, 'url');
}
// Automatically generated Moodle v4.4.0 release upgrade line.
// Put any upgrade step following this.
return true;
}
+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/>.
/**
* List of deprecated mod_url functions.
*
* @package mod_url
* @copyright 2021 Peter D
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
/**
* Print url heading.
*
* @deprecated since 4.0
* @param object $url
* @param object $cm
* @param object $course
* @param bool $notused This variable is no longer used.
* @return void
*/
function url_print_heading($url, $cm, $course, $notused = false) {
global $OUTPUT;
debugging('url_print_heading is deprecated. Handled by activity_header now.', DEBUG_DEVELOPER);
echo $OUTPUT->heading(format_string($url->name), 2);
}
/**
* Print url introduction.
*
* @deprecated since 4.0
* @param object $url
* @param object $cm
* @param object $course
* @param bool $ignoresettings print even if not specified in modedit
* @return void
*/
function url_print_intro($url, $cm, $course, $ignoresettings=false) {
global $OUTPUT;
debugging('url_print_intro is deprecated. Handled by activity_header now.', DEBUG_DEVELOPER);
if ($intro = url_get_intro($url, $cm, $ignoresettings)) {
echo $OUTPUT->box_start('mod_introbox', 'urlintro');
echo $intro;
echo $OUTPUT->box_end();
}
}
+111
View File
@@ -0,0 +1,111 @@
<?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 urls in course
*
* @package mod_url
* @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_url\event\course_module_instance_list_viewed::create($params);
$event->add_record_snapshot('course', $course);
$event->trigger();
$strurl = get_string('modulename', 'url');
$strurls = get_string('modulenameplural', 'url');
$strname = get_string('name');
$strintro = get_string('moduleintro');
$strlastmodified = get_string('lastmodified');
$PAGE->set_url('/mod/url/index.php', array('id' => $course->id));
$PAGE->set_title($course->shortname.': '.$strurls);
$PAGE->set_heading($course->fullname);
$PAGE->navbar->add($strurls);
echo $OUTPUT->header();
if (!$PAGE->has_secondary_navigation()) {
echo $OUTPUT->heading($strurls);
}
if (!$urls = get_all_instances_in_course('url', $course)) {
notice(get_string('thereareno', 'moodle', $strurls), "$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 ($urls as $url) {
$cm = $modinfo->cms[$url->coursemodule];
if ($usesections) {
$printsection = '';
if ($url->section !== $currentsection) {
if ($url->section) {
$printsection = get_section_name($course, $url->section);
}
if ($currentsection !== '') {
$table->data[] = 'hr';
}
$currentsection = $url->section;
}
} else {
$printsection = '<span class="smallinfo">'.userdate($url->timemodified)."</span>";
}
$extra = empty($cm->extra) ? '' : $cm->extra;
$icon = '';
if (!empty($cm->icon)) {
// each url has an icon in 2.0
$icon = $OUTPUT->pix_icon($cm->icon, get_string('modulename', $cm->modname)) . ' ';
}
$class = $url->visible ? '' : 'class="dimmed"'; // hidden modules are dimmed
$table->data[] = array (
$printsection,
"<a $class $extra href=\"view.php?id=$cm->id\">".$icon.format_string($url->name)."</a>",
format_module_intro('url', $url, $cm->id));
}
echo html_writer::table($table);
echo $OUTPUT->footer();
+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/>.
/**
* Strings for component 'url', language 'en', branch 'MOODLE_20_STABLE'
*
* @package mod_url
* @copyright 1999 onwards Martin Dougiamas {@link http://moodle.com}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
$string['allowvariables'] = 'Allow URL variables';
$string['allowvariables_desc'] = 'Allow variables to be added to URLs. Variables enable you to pass internal information, such as the user\'s name, as part of the URL. Be aware of potential privacy risks when using this feature.';
$string['clicktoopen'] = 'Click on {$a} to open the resource.';
$string['configdisplayoptions'] = 'Select all options that should be available, existing settings are not modified. Hold CTRL key to select multiple fields.';
$string['configframesize'] = 'When a web page or an uploaded file is displayed within a frame, this value is the height (in pixels) of the top frame (which contains the navigation).';
$string['configrolesinparams'] = 'Should customised role names (from the course settings) be available as variables for URL parameters?';
$string['configsecretphrase'] = 'This secret phrase is used to produce encrypted code value that can be sent to some servers as a parameter. The encrypted code is produced by an md5 value of the current user IP address concatenated with your secret phrase. ie code = md5(IP.secretphrase). Please note that this is not reliable because IP address may change and is often shared by different computers.';
$string['contentheader'] = 'Content';
$string['createurl'] = 'Create a URL';
$string['displayoptions'] = 'Available display options';
$string['displayselect'] = 'Display';
$string['displayselect_help'] = 'This setting, together with the URL file type and whether the browser allows embedding, determines how the URL is displayed. Options may include:
* Automatic - The best display option for the URL is selected automatically
* Embed - The URL is displayed within the page below the navigation bar together with the URL description and any blocks
* Open - Only the URL is displayed in the browser window
* In pop-up - The URL is displayed in a new browser window without menus or an address bar
* In frame - The URL is displayed within a frame below the navigation bar and URL description
* New window - The URL is displayed in a new browser window with menus and an address bar';
$string['displayselectexplain'] = 'Choose display type, unfortunately not all types are suitable for all URLs.';
$string['externalurl'] = 'External URL';
$string['framesize'] = 'Frame height';
$string['invalidstoredurl'] = 'Cannot display this resource, URL is invalid.';
$string['chooseavariable'] = 'Choose a variable...';
$string['indicator:cognitivedepth'] = 'URL cognitive';
$string['indicator:cognitivedepth_help'] = 'This indicator is based on the cognitive depth reached by the student in a URL resource.';
$string['indicator:cognitivedepthdef'] = 'URL cognitive';
$string['indicator:cognitivedepthdef_help'] = 'The participant has reached this percentage of the cognitive engagement offered by the URL resources during this analysis interval (Levels = No view, View)';
$string['indicator:cognitivedepthdef_link'] = 'Learning_analytics_indicators#Cognitive_depth';
$string['indicator:socialbreadth'] = 'URL social';
$string['indicator:socialbreadth_help'] = 'This indicator is based on the social breadth reached by the student in a URL resource.';
$string['indicator:socialbreadthdef'] = 'URL social';
$string['indicator:socialbreadthdef_help'] = 'The participant has reached this percentage of the social engagement offered by the URL resources during this analysis interval (Levels = No participation, Participant alone)';
$string['indicator:socialbreadthdef_link'] = 'Learning_analytics_indicators#Social_breadth';
$string['invalidurl'] = 'Entered URL is invalid';
$string['modulename'] = 'URL';
$string['modulename_help'] = 'The URL module enables a teacher to provide a web link as a course resource. Anything that is freely available online, such as documents or images, can be linked to; the URL doesnt have to be the home page of a website. The URL of a particular web page may be copied and pasted or a teacher can use the file picker and choose a link from a repository such as Flickr, YouTube or Wikimedia (depending upon which repositories are enabled for the site).
There are a number of display options for the URL, such as embedded or opening in a new window and advanced options for passing information, such as a student\'s name, to the URL if required.
Note that URLs can also be added to any other resource or activity type through the text editor.';
$string['modulename_link'] = 'mod/url/view';
$string['modulenameplural'] = 'URLs';
$string['name'] = 'Name';
$string['name_help'] = 'This will serve as the link text for the URL.
Enter a meaningful text that concisely describes the URL\'s purpose.
Avoid using the word "link". This will help screen reader users as screen readers announce links (e.g. "Moodle.org, link") so there\'s no need to include the word "link" in the name field.';
$string['page-mod-url-x'] = 'Any URL module page';
$string['parameterinfo'] = '&amp;parameter=variable';
$string['parametersheader'] = 'URL variables';
$string['parametersheader_help'] = 'This section allows you to pass internal information as part of the URL. This is useful if the URL is an interactive web page that takes parameters, and you want to pass something like the name of the current user, for example. Enter the name of the URL\'s parameter in the text box then select the corresponding site variable.';
$string['pluginadministration'] = 'URL module administration';
$string['pluginname'] = 'URL';
$string['popupheight'] = 'Pop-up height (in pixels)';
$string['popupheightexplain'] = 'Specifies default height of popup windows.';
$string['popupwidth'] = 'Pop-up width (in pixels)';
$string['popupwidthexplain'] = 'Specifies default width of popup windows.';
$string['printintro'] = 'Display URL description';
$string['printintroexplain'] = 'Display URL description below content? Some display types may not display description even if enabled.';
$string['privacy:metadata'] = 'The URL resource plugin does not store any personal data.';
$string['rolesinparams'] = 'Role names as URL variables';
$string['search:activity'] = 'URL';
$string['serverurl'] = 'Server URL';
$string['url:addinstance'] = 'Add a new URL resource';
$string['url:view'] = 'View URL';
+415
View File
@@ -0,0 +1,415 @@
<?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 url module
*
* @package mod_url
* @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;
/**
* List of features supported in URL 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 url_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 url_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 url_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 url_get_post_actions() {
return array('update', 'add');
}
/**
* Add url instance.
* @param object $data
* @param object $mform
* @return int new url instance id
*/
function url_add_instance($data, $mform) {
global $CFG, $DB;
require_once($CFG->dirroot.'/mod/url/locallib.php');
$parameters = array();
for ($i=0; $i < 100; $i++) {
$parameter = "parameter_$i";
$variable = "variable_$i";
if (empty($data->$parameter) or empty($data->$variable)) {
continue;
}
$parameters[$data->$parameter] = $data->$variable;
}
$data->parameters = serialize($parameters);
$displayoptions = array();
if ($data->display == RESOURCELIB_DISPLAY_POPUP) {
$displayoptions['popupwidth'] = $data->popupwidth;
$displayoptions['popupheight'] = $data->popupheight;
}
if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) {
$displayoptions['printintro'] = (int)!empty($data->printintro);
}
$data->displayoptions = serialize($displayoptions);
$data->externalurl = url_fix_submitted_url($data->externalurl);
$data->timemodified = time();
$data->id = $DB->insert_record('url', $data);
$completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null;
\core_completion\api::update_completion_date_event($data->coursemodule, 'url', $data->id, $completiontimeexpected);
return $data->id;
}
/**
* Update url instance.
* @param object $data
* @param object $mform
* @return bool true
*/
function url_update_instance($data, $mform) {
global $CFG, $DB;
require_once($CFG->dirroot.'/mod/url/locallib.php');
$parameters = array();
for ($i=0; $i < 100; $i++) {
$parameter = "parameter_$i";
$variable = "variable_$i";
if (empty($data->$parameter) or empty($data->$variable)) {
continue;
}
$parameters[$data->$parameter] = $data->$variable;
}
$data->parameters = serialize($parameters);
$displayoptions = array();
if ($data->display == RESOURCELIB_DISPLAY_POPUP) {
$displayoptions['popupwidth'] = $data->popupwidth;
$displayoptions['popupheight'] = $data->popupheight;
}
if (in_array($data->display, array(RESOURCELIB_DISPLAY_AUTO, RESOURCELIB_DISPLAY_EMBED, RESOURCELIB_DISPLAY_FRAME))) {
$displayoptions['printintro'] = (int)!empty($data->printintro);
}
$data->displayoptions = serialize($displayoptions);
$data->externalurl = url_fix_submitted_url($data->externalurl);
$data->timemodified = time();
$data->id = $data->instance;
$DB->update_record('url', $data);
$completiontimeexpected = !empty($data->completionexpected) ? $data->completionexpected : null;
\core_completion\api::update_completion_date_event($data->coursemodule, 'url', $data->id, $completiontimeexpected);
return true;
}
/**
* Delete url instance.
* @param int $id
* @return bool true
*/
function url_delete_instance($id) {
global $DB;
if (!$url = $DB->get_record('url', array('id'=>$id))) {
return false;
}
$cm = get_coursemodule_from_instance('url', $id);
\core_completion\api::update_completion_date_event($cm->id, 'url', $id, null);
// note: all context files are deleted automatically
$DB->delete_records('url', array('id'=>$url->id));
return true;
}
/**
* Given a course_module object, this function returns any
* "extra" information that may be needed when printing
* this activity in a course listing.
*
* See {@link course_modinfo::get_array_of_activities()}
*
* @param object $coursemodule
* @return cached_cm_info info
*/
function url_get_coursemodule_info($coursemodule) {
global $CFG, $DB;
require_once("$CFG->dirroot/mod/url/locallib.php");
if (!$url = $DB->get_record('url', array('id'=>$coursemodule->instance),
'id, name, display, displayoptions, externalurl, parameters, intro, introformat')) {
return NULL;
}
$info = new cached_cm_info();
$info->name = $url->name;
// Note: there should be a way to differentiate links from normal resources.
$info->icon = url_guess_icon($url->externalurl);
$display = url_get_final_display_type($url);
if ($display == RESOURCELIB_DISPLAY_POPUP) {
$fullurl = "$CFG->wwwroot/mod/url/view.php?id=$coursemodule->id&amp;redirect=1";
$options = empty($url->displayoptions) ? [] : (array) unserialize_array($url->displayoptions);
$width = empty($options['popupwidth']) ? 620 : $options['popupwidth'];
$height = empty($options['popupheight']) ? 450 : $options['popupheight'];
$wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes";
$info->onclick = "window.open('$fullurl', '', '$wh'); return false;";
} else if ($display == RESOURCELIB_DISPLAY_NEW) {
$fullurl = "$CFG->wwwroot/mod/url/view.php?id=$coursemodule->id&amp;redirect=1";
$info->onclick = "window.open('$fullurl'); return false;";
}
if ($coursemodule->showdescription) {
// Convert intro to html. Do not filter cached version, filters run at display time.
$info->content = format_module_intro('url', $url, $coursemodule->id, false);
}
$info->customdata['display'] = $display;
// The icon will be filtered from now on because the custom icons have been updated.
$info->customdata['filtericon'] = true;
return $info;
}
/**
* 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 url_page_type_list($pagetype, $parentcontext, $currentcontext) {
$module_pagetype = array('mod-url-*'=>get_string('page-mod-url-x', 'url'));
return $module_pagetype;
}
/**
* Export URL resource contents
*
* @return array of file content
*/
function url_export_contents($cm, $baseurl) {
global $CFG, $DB;
require_once("$CFG->dirroot/mod/url/locallib.php");
$contents = array();
$context = context_module::instance($cm->id);
$course = $DB->get_record('course', array('id'=>$cm->course), '*', MUST_EXIST);
$urlrecord = $DB->get_record('url', array('id'=>$cm->instance), '*', MUST_EXIST);
$fullurl = str_replace('&amp;', '&', url_get_full_url($urlrecord, $cm, $course));
$isurl = clean_param($fullurl, PARAM_URL);
if (empty($isurl)) {
return [];
}
$url = array();
$url['type'] = 'url';
$url['filename'] = clean_param(format_string($urlrecord->name), PARAM_FILE);
$url['filepath'] = null;
$url['filesize'] = 0;
$url['fileurl'] = $fullurl;
$url['timecreated'] = null;
$url['timemodified'] = $urlrecord->timemodified;
$url['sortorder'] = null;
$url['userid'] = null;
$url['author'] = null;
$url['license'] = null;
$contents[] = $url;
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 url_dndupload_register() {
return array('types' => array(
array('identifier' => 'url', 'message' => get_string('createurl', 'url'))
));
}
/**
* 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 url_dndupload_handle($uploadinfo) {
// Gather all the required data.
$data = new stdClass();
$data->course = $uploadinfo->course->id;
$data->name = $uploadinfo->displayname;
$data->intro = '<p>'.$uploadinfo->displayname.'</p>';
$data->introformat = FORMAT_HTML;
$data->externalurl = clean_param($uploadinfo->content, PARAM_URL);
$data->timemodified = time();
$data->coursemodule = $uploadinfo->coursemodule;
// Set the display options to the site defaults.
$config = get_config('url');
$data->display = $config->display;
$data->popupwidth = $config->popupwidth;
$data->popupheight = $config->popupheight;
$data->printintro = $config->printintro;
return url_add_instance($data, null);
}
/**
* Mark the activity completed (if required) and trigger the course_module_viewed event.
*
* @param stdClass $url url object
* @param stdClass $course course object
* @param stdClass $cm course module object
* @param stdClass $context context object
* @since Moodle 3.0
*/
function url_view($url, $course, $cm, $context) {
// Trigger course_module_viewed event.
$params = array(
'context' => $context,
'objectid' => $url->id
);
$event = \mod_url\event\course_module_viewed::create($params);
$event->add_record_snapshot('course_modules', $cm);
$event->add_record_snapshot('course', $course);
$event->add_record_snapshot('url', $url);
$event->trigger();
// Completion.
$completion = new completion_info($course);
$completion->set_module_viewed($cm);
}
/**
* 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 url_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 ID override for calendar events
* @return \core_calendar\local\event\entities\action_interface|null
*/
function mod_url_core_calendar_provide_event_action(calendar_event $event,
\core_calendar\action_factory $factory, $userid = 0) {
global $USER;
if (empty($userid)) {
$userid = $USER->id;
}
$cm = get_fast_modinfo($event->courseid, $userid)->instances['url'][$event->instance];
$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/url/view.php', ['id' => $cm->id]),
1,
true
);
}
+569
View File
@@ -0,0 +1,569 @@
<?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 url module utility functions
*
* @package mod_url
* @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->libdir/filelib.php");
require_once("$CFG->libdir/resourcelib.php");
require_once("$CFG->dirroot/mod/url/lib.php");
/**
* This methods does weak url validation, we are looking for major problems only,
* no strict RFE validation.
*
* @param $url
* @return bool true is seems valid, false if definitely not valid URL
*/
function url_appears_valid_url($url) {
if (preg_match('/^(\/|https?:|ftp:)/i', $url)) {
// note: this is not exact validation, we look for severely malformed URLs only
return (bool) preg_match('/^[a-z]+:\/\/([^:@\s]+:[^@\s]+@)?[^ @]+(:[0-9]+)?(\/[^#]*)?(#.*)?$/i', $url);
} else {
return (bool)preg_match('/^[a-z]+:\/\/...*$/i', $url);
}
}
/**
* Fix common URL problems that we want teachers to see fixed
* the next time they edit the resource.
*
* This function does not include any XSS protection.
*
* @param string $url
* @return string
*/
function url_fix_submitted_url($url) {
// note: empty urls are prevented in form validation
$url = trim($url);
// remove encoded entities - we want the raw URI here
$url = html_entity_decode($url, ENT_QUOTES, 'UTF-8');
if (!preg_match('|^[a-z]+:|i', $url) and !preg_match('|^/|', $url)) {
// invalid URI, try to fix it by making it normal URL,
// please note relative urls are not allowed, /xx/yy links are ok
$url = 'http://'.$url;
}
return $url;
}
/**
* Return full url with all extra parameters
*
* This function does not include any XSS protection.
*
* @param stdClass $url
* @param object $cm
* @param object $course
* @param object $config
* @return string url with & encoded as &amp;
*/
function url_get_full_url($url, $cm, $course, $config=null) {
$parameters = empty($url->parameters) ? [] : (array) unserialize_array($url->parameters);
// make sure there are no encoded entities, it is ok to do this twice
$fullurl = html_entity_decode($url->externalurl, ENT_QUOTES, 'UTF-8');
$letters = '\pL';
$latin = 'a-zA-Z';
$digits = '0-9';
$symbols = '\x{20E3}\x{00AE}\x{00A9}\x{203C}\x{2047}\x{2048}\x{2049}\x{3030}\x{303D}\x{2139}\x{2122}\x{3297}\x{3299}' .
'\x{2300}-\x{23FF}\x{2600}-\x{27BF}\x{2B00}-\x{2BF0}';
$arabic = '\x{FE00}-\x{FEFF}';
$math = '\x{2190}-\x{21FF}\x{2900}-\x{297F}';
$othernumbers = '\x{2460}-\x{24FF}';
$geometric = '\x{25A0}-\x{25FF}';
$emojis = '\x{1F000}-\x{1F6FF}';
if (preg_match('/^(\/|https?:|ftp:)/i', $fullurl) or preg_match('|^/|', $fullurl)) {
// encode extra chars in URLs - this does not make it always valid, but it helps with some UTF-8 problems
// Thanks to 💩.la emojis count as valid, too.
$allowed = "[" . $letters . $latin . $digits . $symbols . $arabic . $math . $othernumbers . $geometric .
$emojis . "]" . preg_quote(';/?:@=&$_.+!*(),-#%', '/');
$fullurl = preg_replace_callback("/[^$allowed]/u", 'url_filter_callback', $fullurl);
} else {
// encode special chars only
$fullurl = str_replace('"', '%22', $fullurl);
$fullurl = str_replace('\'', '%27', $fullurl);
$fullurl = str_replace(' ', '%20', $fullurl);
$fullurl = str_replace('<', '%3C', $fullurl);
$fullurl = str_replace('>', '%3E', $fullurl);
}
if (!$config) {
$config = get_config('url');
}
// add variable url parameters
if ($config->allowvariables && !empty($parameters)) {
$paramvalues = url_get_variable_values($url, $cm, $course, $config);
foreach ($parameters as $parse=>$parameter) {
if (isset($paramvalues[$parameter])) {
$parameters[$parse] = rawurlencode($parse).'='.rawurlencode($paramvalues[$parameter]);
} else {
unset($parameters[$parse]);
}
}
if (!empty($parameters)) {
if (stripos($fullurl, 'teamspeak://') === 0) {
$fullurl = $fullurl.'?'.implode('?', $parameters);
} else {
$join = (strpos($fullurl, '?') === false) ? '?' : '&';
$fullurl = $fullurl.$join.implode('&', $parameters);
}
}
}
// encode all & to &amp; entity
$fullurl = str_replace('&', '&amp;', $fullurl);
return $fullurl;
}
/**
* Unicode encoding helper callback
* @internal
* @param array $matches
* @return string
*/
function url_filter_callback($matches) {
return rawurlencode($matches[0]);
}
/**
* Print url header.
* @param object $url
* @param object $cm
* @param object $course
* @return void
*/
function url_print_header($url, $cm, $course) {
global $PAGE, $OUTPUT;
$PAGE->set_title($course->shortname.': '.$url->name);
$PAGE->set_heading($course->fullname);
$PAGE->set_activity_record($url);
echo $OUTPUT->header();
}
/**
* Get url introduction.
*
* @param object $url
* @param object $cm
* @param bool $ignoresettings print even if not specified in modedit
* @return string
*/
function url_get_intro(object $url, object $cm, bool $ignoresettings = false): string {
$options = empty($url->displayoptions) ? [] : (array) unserialize_array($url->displayoptions);
if ($ignoresettings or !empty($options['printintro'])) {
if (trim(strip_tags($url->intro))) {
return format_module_intro('url', $url, $cm->id);
}
}
return '';
}
/**
* Display url frames.
* @param object $url
* @param object $cm
* @param object $course
* @return does not return
*/
function url_display_frame($url, $cm, $course) {
global $PAGE, $OUTPUT, $CFG;
$frame = optional_param('frameset', 'main', PARAM_ALPHA);
if ($frame === 'top') {
$PAGE->set_pagelayout('frametop');
$PAGE->activityheader->set_attrs([
'description' => url_get_intro($url, $cm),
'title' => format_string($url->name)
]);
url_print_header($url, $cm, $course);
echo $OUTPUT->footer();
die;
} else {
$config = get_config('url');
$context = context_module::instance($cm->id);
$exteurl = url_get_full_url($url, $cm, $course, $config);
$navurl = "$CFG->wwwroot/mod/url/view.php?id=$cm->id&amp;frameset=top";
$coursecontext = context_course::instance($course->id);
$courseshortname = format_string($course->shortname, true, array('context' => $coursecontext));
$title = strip_tags($courseshortname.': '.format_string($url->name));
$framesize = $config->framesize;
$modulename = s(get_string('modulename','url'));
$contentframetitle = s(format_string($url->name));
$dir = get_string('thisdirection', 'langconfig');
$extframe = <<<EOF
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">
<html dir="$dir">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>$title</title>
</head>
<frameset rows="$framesize,*">
<frame src="$navurl" title="$modulename"/>
<frame src="$exteurl" title="$contentframetitle"/>
</frameset>
</html>
EOF;
@header('Content-Type: text/html; charset=utf-8');
echo $extframe;
die;
}
}
/**
* Print url info and link.
* @param object $url
* @param object $cm
* @param object $course
*/
function url_print_workaround($url, $cm, $course) {
global $OUTPUT, $PAGE, $USER;
$PAGE->activityheader->set_description(url_get_intro($url, $cm, true));
url_print_header($url, $cm, $course);
$fullurl = new moodle_url(url_get_full_url($url, $cm, $course));
$display = url_get_final_display_type($url);
if ($display == RESOURCELIB_DISPLAY_POPUP) {
$jsfullurl = addslashes_js($fullurl->out(false));
$options = empty($url->displayoptions) ? [] : (array) unserialize_array($url->displayoptions);
$width = empty($options['popupwidth']) ? 620 : $options['popupwidth'];
$height = empty($options['popupheight']) ? 450 : $options['popupheight'];
$wh = "width=$width,height=$height,toolbar=no,location=no,menubar=no,copyhistory=no,status=no,directories=no,scrollbars=yes,resizable=yes";
$attributes = ['onclick' => "window.open('$jsfullurl', '', '$wh'); return false;"];
} else if ($display == RESOURCELIB_DISPLAY_NEW) {
$attributes = ['onclick' => "this.target='_blank';"];
} else {
$attributes = [];
}
echo '<div class="urlworkaround">';
print_string('clicktoopen', 'url', html_writer::link($fullurl, format_string($cm->name), $attributes));
echo '</div>';
echo $OUTPUT->footer();
die;
}
/**
* Display embedded url file.
* @param object $url
* @param object $cm
* @param object $course
*/
function url_display_embed($url, $cm, $course) {
global $PAGE, $OUTPUT;
$mimetype = resourcelib_guess_url_mimetype($url->externalurl);
$fullurl = url_get_full_url($url, $cm, $course);
$title = $url->name;
$moodleurl = new moodle_url($fullurl);
$link = html_writer::link($moodleurl, format_string($cm->name));
$clicktoopen = get_string('clicktoopen', 'url', $link);
$extension = resourcelib_get_extension($url->externalurl);
$mediamanager = core_media_manager::instance($PAGE);
$embedoptions = array(
core_media_manager::OPTION_TRUSTED => true,
core_media_manager::OPTION_BLOCK => true
);
if (in_array($mimetype, array('image/gif','image/jpeg','image/png'))) { // It's an image
$code = resourcelib_embed_image($fullurl, $title);
} else if ($mediamanager->can_embed_url($moodleurl, $embedoptions)) {
// Media (audio/video) file.
$code = $mediamanager->embed_url($moodleurl, $title, 0, 0, $embedoptions);
} else {
// anything else - just try object tag enlarged as much as possible
$code = resourcelib_embed_general($fullurl, $title, $clicktoopen, $mimetype);
}
$PAGE->activityheader->set_description(url_get_intro($url, $cm));
url_print_header($url, $cm, $course);
echo $code;
echo $OUTPUT->footer();
die;
}
/**
* Decide the best display format.
* @param object $url
* @return int display type constant
*/
function url_get_final_display_type($url) {
global $CFG;
if ($url->display != RESOURCELIB_DISPLAY_AUTO) {
return $url->display;
}
// detect links to local moodle pages
if (strpos($url->externalurl, $CFG->wwwroot) === 0) {
if (strpos($url->externalurl, 'file.php') === false and strpos($url->externalurl, '.php') !== false ) {
// most probably our moodle page with navigation
return RESOURCELIB_DISPLAY_OPEN;
}
}
// Binaries and other formats that are known to cause trouble for external links.
static $download = ['application/zip', 'application/x-tar', 'application/g-zip',
'application/pdf', 'text/html', 'document/unknown'];
static $embed = array('image/gif', 'image/jpeg', 'image/png', 'image/svg+xml', // images
'application/x-shockwave-flash', 'video/x-flv', 'video/x-ms-wm', // video formats
'video/quicktime', 'video/mpeg', 'video/mp4',
'audio/mp3', 'audio/x-realaudio-plugin', 'x-realaudio-plugin', // audio formats,
);
$mimetype = resourcelib_guess_url_mimetype($url->externalurl);
if (in_array($mimetype, $download)) {
return RESOURCELIB_DISPLAY_DOWNLOAD;
}
if (in_array($mimetype, $embed)) {
return RESOURCELIB_DISPLAY_EMBED;
}
// let the browser deal with it somehow
return RESOURCELIB_DISPLAY_OPEN;
}
/**
* Get the parameters that may be appended to URL
* @param object $config url module config options
* @return array array describing opt groups
*/
function url_get_variable_options($config) {
global $CFG;
$options = array();
$options[''] = array('' => get_string('chooseavariable', 'url'));
$options[get_string('course')] = array(
'courseid' => 'id',
'coursefullname' => get_string('fullnamecourse'),
'courseshortname' => get_string('shortnamecourse'),
'courseidnumber' => get_string('idnumbercourse'),
'coursesummary' => get_string('summary'),
'courseformat' => get_string('format'),
);
$options[get_string('modulename', 'url')] = array(
'urlinstance' => 'id',
'urlcmid' => 'cmid',
'urlname' => get_string('name'),
'urlidnumber' => get_string('idnumbermod'),
);
$options[get_string('miscellaneous')] = array(
'sitename' => get_string('fullsitename'),
'serverurl' => get_string('serverurl', 'url'),
'currenttime' => get_string('time'),
'lang' => get_string('language'),
);
if (!empty($config->secretphrase)) {
$options[get_string('miscellaneous')]['encryptedcode'] = get_string('encryptedcode');
}
$options[get_string('user')] = array(
'userid' => 'id',
'userusername' => get_string('username'),
'useridnumber' => get_string('idnumber'),
'userfirstname' => get_string('firstname'),
'userlastname' => get_string('lastname'),
'userfullname' => get_string('fullnameuser'),
'useremail' => get_string('email'),
'userphone1' => get_string('phone1'),
'userphone2' => get_string('phone2'),
'userinstitution' => get_string('institution'),
'userdepartment' => get_string('department'),
'useraddress' => get_string('address'),
'usercity' => get_string('city'),
'usertimezone' => get_string('timezone'),
);
if ($config->rolesinparams) {
$roles = role_fix_names(get_all_roles());
$roleoptions = array();
foreach ($roles as $role) {
$roleoptions['course'.$role->shortname] = get_string('yourwordforx', '', $role->localname);
}
$options[get_string('roles')] = $roleoptions;
}
return $options;
}
/**
* Get the parameter values that may be appended to URL
* @param object $url module instance
* @param object $cm
* @param object $course
* @param object $config module config options
* @return array of parameter values
*/
function url_get_variable_values($url, $cm, $course, $config) {
global $USER, $CFG;
$site = get_site();
$coursecontext = context_course::instance($course->id);
$values = array (
'courseid' => $course->id,
'coursefullname' => format_string($course->fullname, true, array('context' => $coursecontext)),
'courseshortname' => format_string($course->shortname, true, array('context' => $coursecontext)),
'courseidnumber' => $course->idnumber,
'coursesummary' => $course->summary,
'courseformat' => $course->format,
'lang' => current_language(),
'sitename' => format_string($site->fullname, true, array('context' => $coursecontext)),
'serverurl' => $CFG->wwwroot,
'currenttime' => time(),
'urlinstance' => $url->id,
'urlcmid' => $cm->id,
'urlname' => format_string($url->name, true, array('context' => $coursecontext)),
'urlidnumber' => $cm->idnumber,
);
if (isloggedin()) {
$values['userid'] = $USER->id;
$values['userusername'] = $USER->username;
$values['useridnumber'] = $USER->idnumber;
$values['userfirstname'] = $USER->firstname;
$values['userlastname'] = $USER->lastname;
$values['userfullname'] = fullname($USER);
$values['useremail'] = $USER->email;
$values['userphone1'] = $USER->phone1;
$values['userphone2'] = $USER->phone2;
$values['userinstitution'] = $USER->institution;
$values['userdepartment'] = $USER->department;
$values['useraddress'] = $USER->address;
$values['usercity'] = $USER->city;
$now = new DateTime('now', core_date::get_user_timezone_object());
$values['usertimezone'] = $now->getOffset() / 3600.0; // Value in hours for BC.
}
// weak imitation of Single-Sign-On, for backwards compatibility only
// NOTE: login hack is not included in 2.0 any more, new contrib auth plugin
// needs to be createed if somebody needs the old functionality!
if (!empty($config->secretphrase)) {
$values['encryptedcode'] = url_get_encrypted_parameter($url, $config);
}
//hmm, this is pretty fragile and slow, why do we need it here??
if ($config->rolesinparams) {
$coursecontext = context_course::instance($course->id);
$roles = role_fix_names(get_all_roles($coursecontext), $coursecontext, ROLENAME_ALIAS);
foreach ($roles as $role) {
$values['course'.$role->shortname] = $role->localname;
}
}
return $values;
}
/**
* BC internal function
* @param object $url
* @param object $config
* @return string
*/
function url_get_encrypted_parameter($url, $config) {
global $CFG;
if (file_exists("$CFG->dirroot/local/externserverfile.php")) {
require_once("$CFG->dirroot/local/externserverfile.php");
if (function_exists('extern_server_file')) {
return extern_server_file($url, $config);
}
}
return md5(getremoteaddr().$config->secretphrase);
}
/**
* Optimised mimetype detection from general URL
* @param $fullurl
* @param null $unused This parameter has been deprecated since 4.3 and should not be used anymore.
* @return string|null mimetype or null when the filetype is not relevant.
*/
function url_guess_icon($fullurl, $unused = null) {
global $CFG;
require_once("$CFG->libdir/filelib.php");
if ($unused !== null) {
debugging('Deprecated argument passed to ' . __FUNCTION__, DEBUG_DEVELOPER);
}
if (substr_count($fullurl, '/') < 3 or substr($fullurl, -1) === '/') {
// Most probably default directory - index.php, index.html, etc. Return null because
// we want to use the default module icon instead of the HTML file icon.
return null;
}
try {
// There can be some cases where the url is invalid making parse_url() to return false.
// That will make moodle_url class to throw an exception, so we need to catch the exception to prevent errors.
$moodleurl = new moodle_url($fullurl);
$fullurl = $moodleurl->out_omit_querystring();
} catch (\moodle_exception $e) {
// If an exception is thrown, means the url is invalid. No need to log exception.
return null;
}
$icon = file_extension_icon($fullurl);
$htmlicon = file_extension_icon('.htm');
$unknownicon = file_extension_icon('');
$phpicon = file_extension_icon('.php'); // Exception for php files.
// We do not want to return those icon types, the module icon is more appropriate.
if ($icon === $unknownicon || $icon === $htmlicon || $icon === $phpicon) {
return null;
}
return $icon;
}
+195
View File
@@ -0,0 +1,195 @@
<?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/>.
/**
* URL configuration form
*
* @package mod_url
* @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');
require_once($CFG->dirroot.'/mod/url/locallib.php');
class mod_url_mod_form extends moodleform_mod {
function definition() {
global $CFG, $DB;
$mform = $this->_form;
$config = get_config('url');
//-------------------------------------------------------
$mform->addElement('header', 'general', get_string('general', 'form'));
$mform->addElement('text', 'name', get_string('name'), array('size'=>'48'));
$mform->addHelpButton('name', 'name', 'url');
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');
$mform->addElement('url', 'externalurl', get_string('externalurl', 'url'), array('size'=>'60'), array('usefilepicker'=>true));
$mform->setType('externalurl', PARAM_RAW_TRIMMED);
$mform->addRule('externalurl', null, 'required', null, 'client');
$this->standard_intro_elements();
$element = $mform->getElement('introeditor');
$attributes = $element->getAttributes();
$attributes['rows'] = 5;
$element->setAttributes($attributes);
//-------------------------------------------------------
$mform->addElement('header', 'optionssection', get_string('appearance'));
if ($this->current->instance) {
$options = resourcelib_get_displayoptions(explode(',', $config->displayoptions), $this->current->display);
} else {
$options = resourcelib_get_displayoptions(explode(',', $config->displayoptions));
}
if (count($options) == 1) {
$mform->addElement('hidden', 'display');
$mform->setType('display', PARAM_INT);
reset($options);
$mform->setDefault('display', key($options));
} else {
$mform->addElement('select', 'display', get_string('displayselect', 'url'), $options);
$mform->setDefault('display', $config->display);
$mform->addHelpButton('display', 'displayselect', 'url');
}
if (array_key_exists(RESOURCELIB_DISPLAY_POPUP, $options)) {
$mform->addElement('text', 'popupwidth', get_string('popupwidth', 'url'), array('size'=>3));
if (count($options) > 1) {
$mform->hideIf('popupwidth', 'display', 'noteq', RESOURCELIB_DISPLAY_POPUP);
}
$mform->setType('popupwidth', PARAM_INT);
$mform->setDefault('popupwidth', $config->popupwidth);
$mform->addElement('text', 'popupheight', get_string('popupheight', 'url'), array('size'=>3));
if (count($options) > 1) {
$mform->hideIf('popupheight', 'display', 'noteq', RESOURCELIB_DISPLAY_POPUP);
}
$mform->setType('popupheight', PARAM_INT);
$mform->setDefault('popupheight', $config->popupheight);
}
if (array_key_exists(RESOURCELIB_DISPLAY_AUTO, $options) or
array_key_exists(RESOURCELIB_DISPLAY_EMBED, $options) or
array_key_exists(RESOURCELIB_DISPLAY_FRAME, $options)) {
$mform->addElement('checkbox', 'printintro', get_string('printintro', 'url'));
$mform->hideIf('printintro', 'display', 'eq', RESOURCELIB_DISPLAY_POPUP);
$mform->hideIf('printintro', 'display', 'eq', RESOURCELIB_DISPLAY_OPEN);
$mform->hideIf('printintro', 'display', 'eq', RESOURCELIB_DISPLAY_NEW);
$mform->setDefault('printintro', $config->printintro);
}
//-------------------------------------------------------
if ($config->allowvariables) {
$mform->addElement('header', 'parameterssection', get_string('parametersheader', 'url'));
$mform->addElement('static', 'parametersinfo', '', get_string('parametersheader_help', 'url'));
if (empty($this->current->parameters)) {
$parcount = 5;
} else {
$parcount = 5 + count((array)unserialize_array($this->current->parameters));
$parcount = ($parcount > 100) ? 100 : $parcount;
}
$options = url_get_variable_options($config);
for ($i = 0; $i < $parcount; $i++) {
$parameter = "parameter_$i";
$variable = "variable_$i";
$pargroup = "pargoup_$i";
$group = [
$mform->createElement('text', $parameter, '', ['size' => '12']),
$mform->createElement('selectgroups', $variable, '', $options),
];
$mform->addGroup($group, $pargroup, get_string('parameterinfo', 'url'), ' ', false);
$mform->setType($parameter, PARAM_RAW);
}
}
//-------------------------------------------------------
$this->standard_coursemodule_elements();
//-------------------------------------------------------
$this->add_action_buttons();
}
function data_preprocessing(&$default_values) {
if (!empty($default_values['displayoptions'])) {
$displayoptions = (array) unserialize_array($default_values['displayoptions']);
if (isset($displayoptions['printintro'])) {
$default_values['printintro'] = $displayoptions['printintro'];
}
if (!empty($displayoptions['popupwidth'])) {
$default_values['popupwidth'] = $displayoptions['popupwidth'];
}
if (!empty($displayoptions['popupheight'])) {
$default_values['popupheight'] = $displayoptions['popupheight'];
}
}
if (!empty($default_values['parameters'])) {
$parameters = (array) unserialize_array($default_values['parameters']);
$i = 0;
foreach ($parameters as $parameter=>$variable) {
$default_values['parameter_'.$i] = $parameter;
$default_values['variable_'.$i] = $variable;
$i++;
}
}
}
function validation($data, $files) {
$errors = parent::validation($data, $files);
// Validating Entered url, we are looking for obvious problems only,
// teachers are responsible for testing if it actually works.
// This is not a security validation!! Teachers are allowed to enter "javascript:alert(666)" for example.
// NOTE: do not try to explain the difference between URL and URI, people would be only confused...
if (!empty($data['externalurl'])) {
$url = $data['externalurl'];
if (preg_match('|^/|', $url)) {
// links relative to server root are ok - no validation necessary
} else if (preg_match('|^[a-z]+://|i', $url) or preg_match('|^https?:|i', $url) or preg_match('|^ftp:|i', $url)) {
// normal URL
if (!url_appears_valid_url($url)) {
$errors['externalurl'] = get_string('invalidurl', 'url');
}
} else if (preg_match('|^[a-z]+:|i', $url)) {
// general URI such as teamspeak, mailto, etc. - it may or may not work in all browsers,
// we do not validate these at all, sorry
} else {
// invalid URI, we try to fix it by adding 'http://' prefix,
// relative links are NOT allowed because we display the link on different pages!
if (!url_appears_valid_url('http://'.$url)) {
$errors['externalurl'] = get_string('invalidurl', 'url');
}
}
}
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="M18.7785 5.21877C17.1473 3.58756 14.5026 3.58756 12.8714 5.21877L11.5714 6.51877C11.3761 6.71403 11.3761 7.03062 11.5714 7.22588C11.7666 7.42114 12.0832 7.42114 12.2785 7.22588L13.5785 5.92587C14.8191 4.68519 16.8307 4.68519 18.0714 5.92587C19.3121 7.16656 19.3121 9.1781 18.0714 10.4188L15.4714 13.0188C14.2307 14.2595 12.2191 14.2595 10.9785 13.0188C10.7832 12.8235 10.4666 12.8235 10.2713 13.0188C10.0761 13.2141 10.0761 13.5306 10.2713 13.7259C11.9026 15.3571 14.5473 15.3571 16.1785 13.7259L18.7785 11.1259C20.4097 9.49469 20.4097 6.84998 18.7785 5.21877ZM5.22145 18.781C6.85266 20.4122 9.49737 20.4122 11.1286 18.781L12.4286 17.481C12.6238 17.2857 12.6238 16.9692 12.4286 16.7739C12.2333 16.5786 11.9167 16.5786 11.7215 16.7739L10.4215 18.0739C9.18079 19.3146 7.16924 19.3146 5.92856 18.0739C4.68788 16.8332 4.68788 14.8217 5.92856 13.581L8.52857 10.981C9.76925 9.74029 11.7808 9.74029 13.0215 10.981C13.2167 11.1762 13.5333 11.1762 13.7286 10.981C13.9238 10.7857 13.9238 10.4691 13.7286 10.2739C12.0974 8.64266 9.45267 8.64266 7.82146 10.2739L5.22145 12.8739C3.59025 14.5051 3.59024 17.1498 5.22145 18.781Z" fill="#212529"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

+28
View File
@@ -0,0 +1,28 @@
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
URL module
=============
URL module is one of the successors to original 'file' type plugin of Resource module.
TODO:
* implement portfolio support (MDL-20084)
* new backup/restore and old restore transformation (MDL-20085)
+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/>.
/**
* Url module admin settings and defaults
*
* @package mod_url
* @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) {
require_once("$CFG->libdir/resourcelib.php");
$displayoptions = resourcelib_get_displayoptions(array(RESOURCELIB_DISPLAY_AUTO,
RESOURCELIB_DISPLAY_EMBED,
RESOURCELIB_DISPLAY_FRAME,
RESOURCELIB_DISPLAY_OPEN,
RESOURCELIB_DISPLAY_NEW,
RESOURCELIB_DISPLAY_POPUP,
));
$defaultdisplayoptions = array(RESOURCELIB_DISPLAY_AUTO,
RESOURCELIB_DISPLAY_EMBED,
RESOURCELIB_DISPLAY_OPEN,
RESOURCELIB_DISPLAY_POPUP,
);
//--- general settings -----------------------------------------------------------------------------------
$settings->add(new admin_setting_configtext('url/framesize',
get_string('framesize', 'url'), get_string('configframesize', 'url'), 130, PARAM_INT));
$settings->add(new admin_setting_configpasswordunmask('url/secretphrase', get_string('password'),
get_string('configsecretphrase', 'url'), ''));
$settings->add(new admin_setting_configcheckbox('url/allowvariables',
get_string('allowvariables', 'url'), get_string('allowvariables_desc', 'url'), false));
$settings->add(new admin_setting_configcheckbox('url/rolesinparams',
get_string('rolesinparams', 'url'), get_string('configrolesinparams', 'url'), false));
$settings->hide_if('url/rolesinparams', 'url/allowvariables');
$settings->add(new admin_setting_configmultiselect('url/displayoptions',
get_string('displayoptions', 'url'), get_string('configdisplayoptions', 'url'),
$defaultdisplayoptions, $displayoptions));
//--- modedit defaults -----------------------------------------------------------------------------------
$settings->add(new admin_setting_heading('urlmodeditdefaults', get_string('modeditdefaults', 'admin'), get_string('condifmodeditdefaults', 'admin')));
$settings->add(new admin_setting_configcheckbox('url/printintro',
get_string('printintro', 'url'), get_string('printintroexplain', 'url'), 1));
$settings->add(new admin_setting_configselect('url/display',
get_string('displayselect', 'url'), get_string('displayselectexplain', 'url'), RESOURCELIB_DISPLAY_AUTO, $displayoptions));
$settings->add(new admin_setting_configtext('url/popupwidth',
get_string('popupwidth', 'url'), get_string('popupwidthexplain', 'url'), 620, PARAM_INT, 7));
$settings->add(new admin_setting_configtext('url/popupheight',
get_string('popupheight', 'url'), get_string('popupheightexplain', 'url'), 450, PARAM_INT, 7));
}
+3
View File
@@ -0,0 +1,3 @@
.path-mod-url .resourcecontent {
text-align: center;
}
@@ -0,0 +1,223 @@
@mod @mod_url @core_completion
Feature: View activity completion information in the URL resource
In order to have visibility of URL completion requirements
As a student
I need to be able to view my URL 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 | category | enablecompletion | showcompletionconditions |
| Course 1 | C1 | 0 | 1 | 1 |
And the following "course enrolments" exist:
| user | course | role |
| student1 | C1 | student |
| teacher1 | C1 | editingteacher |
And the following config values are set as admin:
| displayoptions | 0,1,2,3,4,5,6 | url |
Scenario: View automatic completion items in automatic display mode as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 0 |
When I am on the "Music history" "url activity" page logged in as teacher1
Then "Music history" "link" should exist
And I should see "Click on Music history to open the resource."
And "Music history" should have the "View" completion condition
Scenario: View automatic completion items in automatic display mode as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 0 |
When I am on the "Music history" "url activity" page logged in as student1
Then the "View" completion condition of "Music history" is displayed as "done"
Scenario: View automatic completion items in embed display mode as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 1 |
When I am on the "Music history" "url activity" page logged in as teacher1
Then "Music history" should have the "View" completion condition
Scenario: View automatic completion items in embed display mode as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 1 |
When I am on the "Music history" "url activity" page logged in as student1
Then the "View" completion condition of "Music history" is displayed as "done"
@javascript
Scenario: View automatic completion items in open display mode as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 5 |
When I am on the "Music history" "url activity" page logged in as teacher1
And I am on the "Course 1" course page
Then "Music history" should have the "View" completion condition
@javascript
Scenario: View automatic completion items in open display mode as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 5 |
When I am on the "Music history" "url activity" page logged in as student1
And I am on the "Course 1" course page
Then the "View" completion condition of "Music history" is displayed as "done"
Scenario: View automatic completion items in pop-up display mode as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 6 |
| popupwidth | 620 |
| popupheight | 450 |
When I am on the "Music history" "url activity" page logged in as student1
Then "Music history" should have the "View" completion condition
Scenario: View automatic completion items in pop-up display mode as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 2 |
| completionview | 1 |
| display | 6 |
| popupwidth | 620 |
| popupheight | 450 |
When I am on the "Music history" "url activity" page logged in as student1
Then the "View" completion condition of "Music history" is displayed as "done"
@javascript
Scenario: Use manual completion with automatic URL as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 1 |
| completionview | 1 |
| display | 0 |
When I am on the "Music history" "url activity" page logged in as teacher1
Then the manual completion button for "Music history" should be disabled
@javascript
Scenario: Use manual completion with automatic URL as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 1 |
| completionview | 1 |
| display | 0 |
When I am on the "Course 1" course 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 Outline: The Mark as done completion condition will be shown on the course page for Open, In pop-up and New window display mode if the Show activity completion conditions is set to No as teacher
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 1 |
| completionview | 1 |
| display | <display> |
| popupwidth | 620 |
| popupheight | 450 |
When I am on the "Course 1" course page logged in as teacher1
Then "Music history" should have the "Mark as done" completion condition
Examples:
| display | description |
| 0 | Auto |
| 6 | Popup |
| 3 | New |
@javascript
Scenario Outline: The manual completion button will be shown on the course page for Open, In pop-up and New window display mode if the Show activity completion conditions is set to No as student
Given the following "activity" exists:
| activity | url |
| course | C1 |
| idnumber | Music history |
| name | Music history |
| intro | URL description |
| externalurl | https://moodle.org/ |
| completion | 1 |
| completionview | 1 |
| display | <display> |
| popupwidth | 620 |
| popupheight | 450 |
When I am on the "Course 1" 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"
Examples:
| display | description |
| 0 | Auto |
| 6 | Popup |
| 3 | New |
+52
View File
@@ -0,0 +1,52 @@
@mod @mod_url @javascript
Feature: Manage URL variables
In order to maintain privacy for URLs
As a teacher
I need to be able to manage URL variables safely
Background:
Given the following "courses" exist:
| fullname | shortname | category |
| Course 1 | C1 | 0 |
Scenario: Disabling URL variables hides Role names as URL variables check box
Given the following config values are set as admin:
| allowvariables | 1 | url |
And I log in as "admin"
And I navigate to "Plugins > Activity modules > URL" in site administration
When I click on "Allow URL variables" "checkbox"
Then I should not see "Role names as URL variables"
And I click on "Allow URL variables" "checkbox"
And I should see "Role names as URL variables"
Scenario: Disable the use of URL variables
Given the following config values are set as admin:
| allowvariables | 0 | url |
When I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "URL" to section "1" using the activity chooser
Then I should not see "URL variables"
Scenario: Enable the use of URL variables without role names
Given the following config values are set as admin:
| allowvariables | 1 | url |
| rolesinparams | 0 | url |
When I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "URL" to section "1" using the activity chooser
Then I should see "URL variables"
And I expand all fieldsets
And I should see "Full site name" in the "id_variable_0" "select"
But I should not see "Roles" in the "id_variable_0" "select"
Scenario: Enable the use of URL variables with role names
Given the following config values are set as admin:
| allowvariables | 1 | url |
| rolesinparams | 1 | url |
When I log in as "admin"
And I am on "Course 1" course homepage with editing mode on
And I add a "URL" to section "1" using the activity chooser
Then I should see "URL variables"
And I expand all fieldsets
And I should see "Full site name" in the "id_variable_0" "select"
And I should see "Your word for 'Student'" in the "id_variable_0" "select"
+229
View File
@@ -0,0 +1,229 @@
<?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_url;
use core_external\external_api;
use externallib_advanced_testcase;
use mod_url_external;
defined('MOODLE_INTERNAL') || die();
global $CFG;
require_once($CFG->dirroot . '/webservice/tests/helpers.php');
/**
* External mod_url functions unit tests
*
* @package mod_url
* @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_url
*/
public function test_view_url(): void {
global $DB;
$this->resetAfterTest(true);
// Setup test data.
$course = $this->getDataGenerator()->create_course();
$url = $this->getDataGenerator()->create_module('url', array('course' => $course->id));
$context = \context_module::instance($url->cmid);
$cm = get_coursemodule_from_instance('url', $url->id);
// Test invalid instance id.
try {
mod_url_external::view_url(0);
$this->fail('Exception expected due to invalid mod_url 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_url_external::view_url($url->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_url_external::view_url($url->id);
$result = external_api::clean_returnvalue(mod_url_external::view_url_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_url\event\course_module_viewed', $event);
$this->assertEquals($context, $event->get_context());
$moodleurl = new \moodle_url('/mod/url/view.php', array('id' => $cm->id));
$this->assertEquals($moodleurl, $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/url: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_url_external::view_url($url->id);
$this->fail('Exception expected due to missing capability.');
} catch (\moodle_exception $e) {
$this->assertEquals('requireloginerror', $e->errorcode);
}
}
/**
* Test test_mod_url_get_urls_by_courses
*/
public function test_mod_url_get_urls_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);
// First url.
$record = new \stdClass();
$record->course = $course1->id;
$url1 = self::getDataGenerator()->create_module('url', $record);
// Second url.
$record = new \stdClass();
$record->course = $course2->id;
$url2 = self::getDataGenerator()->create_module('url', $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);
self::setUser($student);
$returndescription = mod_url_external::get_urls_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',
'externalurl', 'display', 'displayoptions', 'parameters', 'timemodified', 'section', 'visible', 'groupmode',
'groupingid');
// Add expected coursemodule and data.
$url1->coursemodule = $url1->cmid;
$url1->introformat = 1;
$url1->section = 0;
$url1->visible = true;
$url1->groupmode = 0;
$url1->groupingid = 0;
$url1->introfiles = [];
$url1->lang = '';
$url2->coursemodule = $url2->cmid;
$url2->introformat = 1;
$url2->section = 0;
$url2->visible = true;
$url2->groupmode = 0;
$url2->groupingid = 0;
$url2->introfiles = [];
$url2->lang = '';
foreach ($expectedfields as $field) {
$expected1[$field] = $url1->{$field};
$expected2[$field] = $url2->{$field};
}
$expectedurls = array($expected2, $expected1);
// Call the external function passing course ids.
$result = mod_url_external::get_urls_by_courses(array($course2->id, $course1->id));
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedurls, $result['urls']);
$this->assertCount(0, $result['warnings']);
// Call the external function without passing course id.
$result = mod_url_external::get_urls_by_courses();
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedurls, $result['urls']);
$this->assertCount(0, $result['warnings']);
// Add a file to the intro.
$filename = "file.txt";
$filerecordinline = array(
'contextid' => \context_module::instance($url2->cmid)->id,
'component' => 'mod_url',
'filearea' => 'intro',
'itemid' => 0,
'filepath' => '/',
'filename' => $filename,
);
$fs = get_file_storage();
$timepost = time();
$fs->create_file_from_string($filerecordinline, 'image contents (not really)');
$result = mod_url_external::get_urls_by_courses(array($course2->id, $course1->id));
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertCount(1, $result['urls'][0]['introfiles']);
$this->assertEquals($filename, $result['urls'][0]['introfiles'][0]['filename']);
// Unenrol user from second course and alter expected urls.
$enrol->unenrol_user($instance2, $student->id);
array_shift($expectedurls);
// Call the external function without passing course id.
$result = mod_url_external::get_urls_by_courses();
$result = external_api::clean_returnvalue($returndescription, $result);
$this->assertEquals($expectedurls, $result['urls']);
// Call for the second course we unenrolled the user from, expected warning.
$result = mod_url_external::get_urls_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']);
}
}
+50
View File
@@ -0,0 +1,50 @@
<?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_url data generator.
*
* @package mod_url
* @category test
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
defined('MOODLE_INTERNAL') || die();
/**
* mod_url data generator class.
*
* @package mod_url
* @category test
* @copyright 2013 Marina Glancy
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class mod_url_generator extends testing_module_generator {
public function create_instance($record = null, array $options = null) {
global $CFG;
require_once($CFG->libdir.'/resourcelib.php');
// Add default values for url.
$record = (array)$record + array(
'display' => RESOURCELIB_DISPLAY_AUTO,
'externalurl' => 'http://moodle.org/',
);
return parent::create_instance($record, (array)$options);
}
}
+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/>.
namespace mod_url;
/**
* Genarator tests class for mod_url.
*
* @package mod_url
* @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;
$this->resetAfterTest();
$this->setAdminUser();
$course = $this->getDataGenerator()->create_course();
$this->assertFalse($DB->record_exists('url', array('course' => $course->id)));
$url = $this->getDataGenerator()->create_module('url', array('course' => $course));
$records = $DB->get_records('url', array('course' => $course->id), 'id');
$this->assertEquals(1, count($records));
$this->assertTrue(array_key_exists($url->id, $records));
$params = array('course' => $course->id, 'name' => 'Another url');
$url = $this->getDataGenerator()->create_module('url', $params);
$records = $DB->get_records('url', array('course' => $course->id), 'id');
$this->assertEquals(2, count($records));
$this->assertEquals('Another url', $records[$url->id]->name);
}
}
+268
View File
@@ -0,0 +1,268 @@
<?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 some mod URL lib stuff.
*
* @package mod_url
* @category phpunit
* @copyright 2012 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
namespace mod_url;
defined('MOODLE_INTERNAL') || die();
/**
* mod_url tests
*
* @package mod_url
* @category phpunit
* @copyright 2011 Petr Skoda {@link http://skodak.org}
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class lib_test extends \advanced_testcase {
/**
* Prepares things before this test case is initialised
* @return void
*/
public static function setUpBeforeClass(): void {
global $CFG;
require_once($CFG->dirroot . '/mod/url/lib.php');
require_once($CFG->dirroot . '/mod/url/locallib.php');
}
/**
* Tests the url_appears_valid_url function
* @return void
*/
public function test_url_appears_valid_url(): void {
$this->assertTrue(url_appears_valid_url('http://example'));
$this->assertTrue(url_appears_valid_url('http://www.example.com'));
$this->assertTrue(url_appears_valid_url('http://www.examplé.com'));
$this->assertTrue(url_appears_valid_url('http://💩.la'));
$this->assertTrue(url_appears_valid_url('http://香港大學.香港'));
$this->assertTrue(url_appears_valid_url('http://وزارة-الأتصالات.مصر'));
$this->assertTrue(url_appears_valid_url('http://www.теннис-алт.рф'));
$this->assertTrue(url_appears_valid_url('http://имена.бг'));
$this->assertTrue(url_appears_valid_url('http://straße.de'));
$this->assertTrue(url_appears_valid_url('http://キース.コム'));
$this->assertTrue(url_appears_valid_url('http://太亞.中国'));
$this->assertTrue(url_appears_valid_url('http://www.რეგისტრაცია.გე'));
$this->assertTrue(url_appears_valid_url('http://уміц.укр'));
$this->assertTrue(url_appears_valid_url('http://현대.한국'));
$this->assertTrue(url_appears_valid_url('http://мон.мон'));
$this->assertTrue(url_appears_valid_url('http://тест.қаз'));
$this->assertTrue(url_appears_valid_url('http://рнидс.срб'));
$this->assertTrue(url_appears_valid_url('http://اسماء.شبكة'));
$this->assertTrue(url_appears_valid_url('http://www.informationssäkerhet.se'));
$this->assertTrue(url_appears_valid_url('http://москва.рф/services'));
$this->assertTrue(url_appears_valid_url('http://detdumærker.dk'));
$this->assertTrue(url_appears_valid_url('http://www.exa-mple2.com'));
$this->assertTrue(url_appears_valid_url('http://www.example.com/~nobody/index.html'));
$this->assertTrue(url_appears_valid_url('http://www.example.com#hmm'));
$this->assertTrue(url_appears_valid_url('http://www.example.com/#hmm'));
$this->assertTrue(url_appears_valid_url('http://www.example.com/žlutý koníček/lala.txt'));
$this->assertTrue(url_appears_valid_url('http://www.example.com/žlutý koníček/lala.txt#hmmmm'));
$this->assertTrue(url_appears_valid_url('http://www.example.com/index.php?xx=yy&zz=aa'));
$this->assertTrue(url_appears_valid_url('http://www.example.com:80/index.php?xx=yy&zz=aa'));
$this->assertTrue(url_appears_valid_url('https://user:password@www.example.com/žlutý koníček/lala.txt'));
$this->assertTrue(url_appears_valid_url('ftp://user:password@www.example.com/žlutý koníček/lala.txt'));
$this->assertFalse(url_appears_valid_url('http:example.com'));
$this->assertFalse(url_appears_valid_url('http:/example.com'));
$this->assertFalse(url_appears_valid_url('http://'));
$this->assertFalse(url_appears_valid_url('http://www.exa mple.com'));
$this->assertFalse(url_appears_valid_url('http://@www.example.com'));
$this->assertFalse(url_appears_valid_url('http://user:@www.example.com'));
$this->assertTrue(url_appears_valid_url('lalala://@:@/'));
}
/**
* Test url_view
* @return void
*/
public function test_url_view(): void {
global $CFG;
$CFG->enablecompletion = 1;
$this->resetAfterTest();
// Setup test data.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1));
$context = \context_module::instance($url->cmid);
$cm = get_coursemodule_from_instance('url', $url->id);
// Trigger and capture the event.
$sink = $this->redirectEvents();
$this->setAdminUser();
url_view($url, $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_url\event\course_module_viewed', $event);
$this->assertEquals($context, $event->get_context());
$url = new \moodle_url('/mod/url/view.php', array('id' => $cm->id));
$this->assertEquals($url, $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);
}
/**
* Test mod_url_core_calendar_provide_event_action with user override
*/
public function test_url_core_calendar_provide_event_action_user_override(): void {
global $CFG, $USER;
$this->resetAfterTest();
$this->setAdminUser();
$user = $this->getDataGenerator()->create_user();
$CFG->enablecompletion = 1;
// Create the activity.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
// Get some additional data.
$cm = get_coursemodule_from_instance('url', $url->id);
// Create a calendar event.
$event = $this->create_action_event($course->id, $url->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_url_core_calendar_provide_event_action($event, $factory, $USER->id);
// Decorate action with a userid override.
$actionevent2 = mod_url_core_calendar_provide_event_action($event, $factory, $user->id);
// Ensure result was null because it has been marked as completed for the associated user.
// Logic was brought across from the "_already_completed" function.
$this->assertNull($actionevent);
// Confirm the event was decorated.
$this->assertNotNull($actionevent2);
$this->assertInstanceOf('\core_calendar\local\event\value_objects\action', $actionevent2);
$this->assertEquals(get_string('view'), $actionevent2->get_name());
$this->assertInstanceOf('moodle_url', $actionevent2->get_url());
$this->assertEquals(1, $actionevent2->get_item_count());
$this->assertTrue($actionevent2->is_actionable());
}
public function test_url_core_calendar_provide_event_action(): void {
$this->resetAfterTest();
$this->setAdminUser();
// Create the activity.
$course = $this->getDataGenerator()->create_course();
$url = $this->getDataGenerator()->create_module('url', array('course' => $course->id));
// Create a calendar event.
$event = $this->create_action_event($course->id, $url->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_url_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_url_core_calendar_provide_event_action_already_completed(): void {
global $CFG;
$this->resetAfterTest();
$this->setAdminUser();
$CFG->enablecompletion = 1;
// Create the activity.
$course = $this->getDataGenerator()->create_course(array('enablecompletion' => 1));
$url = $this->getDataGenerator()->create_module('url', array('course' => $course->id),
array('completion' => 2, 'completionview' => 1, 'completionexpected' => time() + DAYSECS));
// Get some additional data.
$cm = get_coursemodule_from_instance('url', $url->id);
// Create a calendar event.
$event = $this->create_action_event($course->id, $url->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_url_core_calendar_provide_event_action($event, $factory);
// 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 = 'url';
$event->courseid = $courseid;
$event->instance = $instanceid;
$event->type = CALENDAR_EVENT_TYPE_ACTION;
$event->eventtype = $eventtype;
$event->timestart = time();
return \calendar_event::create($event);
}
}
+9
View File
@@ -0,0 +1,9 @@
This files describes API changes in the URL code.
=== 4.4 ===
* A new admin setting "Allow URL variables" has been added, which allows/disallows the use of variables for URL resources. Variables enable you to pass internal information, such as the user's name, as part of the URL.
=== 4.0 ===
* Functions url_print_heading and url_print_intro have been deprecated in favour for the activity header.
+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_url
* @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_url'; // Full name of the plugin (used for diagnostics)
$plugin->cron = 0;
+106
View File
@@ -0,0 +1,106 @@
<?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/>.
/**
* URL module main user interface
*
* @package mod_url
* @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/url/lib.php");
require_once("$CFG->dirroot/mod/url/locallib.php");
require_once($CFG->libdir . '/completionlib.php');
$id = optional_param('id', 0, PARAM_INT); // Course module ID
$u = optional_param('u', 0, PARAM_INT); // URL instance id
$redirect = optional_param('redirect', 0, PARAM_BOOL);
$forceview = optional_param('forceview', 0, PARAM_BOOL);
if ($u) { // Two ways to specify the module
$url = $DB->get_record('url', array('id'=>$u), '*', MUST_EXIST);
$cm = get_coursemodule_from_instance('url', $url->id, $url->course, false, MUST_EXIST);
} else {
$cm = get_coursemodule_from_id('url', $id, 0, false, MUST_EXIST);
$url = $DB->get_record('url', 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/url:view', $context);
// Completion and trigger events.
url_view($url, $course, $cm, $context);
$PAGE->set_url('/mod/url/view.php', array('id' => $cm->id));
// Make sure URL exists before generating output - some older sites may contain empty urls
// Do not use PARAM_URL here, it is too strict and does not support general URIs!
$exturl = trim($url->externalurl);
if (empty($exturl) or $exturl === 'http://') {
$PAGE->activityheader->set_description(url_get_intro($url, $cm));
url_print_header($url, $cm, $course);
notice(get_string('invalidstoredurl', 'url'), new moodle_url('/course/view.php', array('id'=>$cm->course)));
die;
}
unset($exturl);
$displaytype = url_get_final_display_type($url);
if ($displaytype == RESOURCELIB_DISPLAY_OPEN) {
$redirect = true;
}
if ($redirect && !$forceview) {
// coming from course page or url index page,
// the redirection is needed for completion tracking and logging
$fullurl = str_replace('&amp;', '&', url_get_full_url($url, $cm, $course));
if (!course_get_format($course)->has_view_page()) {
// If course format does not have a view page, add redirection delay with a link to the edit page.
// Otherwise teacher is redirected to the external URL without any possibility to edit activity or course settings.
$editurl = null;
if (has_capability('moodle/course:manageactivities', $context)) {
$editurl = new moodle_url('/course/modedit.php', array('update' => $cm->id));
$edittext = get_string('editthisactivity');
} else if (has_capability('moodle/course:update', $context->get_course_context())) {
$editurl = new moodle_url('/course/edit.php', array('id' => $course->id));
$edittext = get_string('editcoursesettings');
}
if ($editurl) {
redirect($fullurl, html_writer::link($editurl, $edittext)."<br/>".
get_string('pageshouldredirect'), 10);
}
}
redirect($fullurl);
}
switch ($displaytype) {
case RESOURCELIB_DISPLAY_EMBED:
url_display_embed($url, $cm, $course);
break;
case RESOURCELIB_DISPLAY_FRAME:
url_display_frame($url, $cm, $course);
break;
default:
url_print_workaround($url, $cm, $course);
break;
}