--- /dev/null
+CONTRIBUTING TO MOODLE
+======================
+
+Moodle is made by people like you. We are members of a big worldwide community
+of developers, designers, teachers, testers, translators and other users. We
+work in universities, schools, companies and other places. You are very welcome
+to join us and contribute to the project.
+
+See <https://docs.moodle.org/dev/Contributing_to_Moodle> for the many ways you
+can help, not only with coding.
+
+Moodle is open to community contributions to core, though all code must go
+through peer-review, automated behaviour testing, continuous integration and
+human post-integration checks.
+
+Pull requests
+-------------
+
+Please do not open pull requests via Github. The repository there is just a
+mirror of the official repository at <https://git.moodle.org>. Issues are
+reported and patches provided via <https://tracker.moodle.org>. See below for
+more information.
+
+Moodle core bug fixes and new features
+--------------------------------------
+
+During the years of intensive development, a mature process of including
+submitted patches has evolved.
+
+* Every bug fix or new feature must have a tracker issue.
+* You publish the branch implementing the fix or new feature in your public
+ clone of the moodle.git repository (typically on Github).
+* Your patch is peer-reviewed, discussed, integrated, tested and then released
+ as a part of moodle.git.
+* New features are developed on the master branch. Bug fixes are also
+ backported to currently supported maintenance (stable) branches.
+
+For further details, see <https://docs.moodle.org/dev/Process>.
+
+Moodle plugins
+--------------
+
+Moodle has a framework for additional plugins to extend its functionality. We
+have a Moodle plugins directory <https://moodle.org/plugins/> where you can
+register and maintain your plugin. Plugins hosted in the plugins directory can
+be easily installed and updated via the Moodle administration interface.
+
+* You are expected to have a public source code repository with your plugin
+ code.
+* After registering your plugin in the plugins directory it is reviewed before
+ being published.
+* You are expected to continuously release updated versions of the plugin via
+ the plugins directory. We do not pull from your code repository; you must do
+ it explicitly.
+
+For further details, see <https://docs.moodle.org/dev/Plugin_contribution>.
--- /dev/null
+MOODLE INSTALLATION
+===================
+
+Here is a short summary of the installation process (which can take just a few
+minutes):
+
+1. Move the Moodle files into your web directory.
+
+2. Create a single database for Moodle to store all its tables in (or choose an
+ existing database).
+
+3. Visit your Moodle site with a browser. You should be taken to the
+ install.php script, which will lead you through creating a config.php file
+ and then setting up Moodle, creating an admin account etc.
+
+4. Set up a cron task to call the file admin/cron.php every minute.
+
+For more information, see <https://docs.moodle.org/en/Installing_Moodle>.
+
+Good luck and have fun!
--- /dev/null
+*** PLEASE DO NOT OPEN PULL REQUESTS VIA GITHUB ***
+
+The moodle.git repository at Github is just a mirror of the official repository. We do not accept pull requests at Github.
+
+See CONTRIBUTING.txt guidelines for how to contribute patches for Moodle. Thank you.
+
+--
-QUICK INSTALL
-=============
+ .-..-.
+ _____ | || |
+ /____/-.---_ .---. .---. .-.| || | .---.
+ | | _ _ |/ _ \/ _ \/ _ || |/ __ \
+ * | | | | | || |_| || |_| || |_| || || |___/
+ |_| |_| |_|\_____/\_____/\_____||_|\_____)
-For the impatient, here is a basic outline of the
-installation process, which normally takes me only
-a few minutes:
+Moodle - the world's open source learning platform
-1) Move the Moodle files into your web directory.
+Moodle <https://moodle.org> is a learning platform designed to provide
+educators, administrators and learners with a single robust, secure and
+integrated system to create personalised learning environments.
-2) Create a single database for Moodle to store all
- its tables in (or choose an existing database).
+You can download Moodle <https://download.moodle.org> and run it on your own
+web server, ask one of our Moodle Partners <https://moodle.com/partners/> to
+assist you, or have a MoodleCloud site <https://moodle.com/cloud/> set up for
+you.
-3) Visit your Moodle site with a browser, you should
- be taken to the install.php script, which will lead
- you through creating a config.php file and then
- setting up Moodle, creating an admin account etc.
+Moodle is widely used around the world by universities, schools, companies and
+all manner of organisations and individuals.
-4) Set up a cron task to call the file admin/cron.php
- every five minutes or so.
+Moodle is provided freely as open source software, under the GNU General Public
+License <https://docs.moodle.org/dev/License>.
+Moodle is written in PHP and JavaScript and uses an SQL database for storing
+the data.
-For more information, see the INSTALL DOCUMENTATION:
-
- http://docs.moodle.org/en/Installing_Moodle
-
-
-Good luck and have fun!
-Martin Dougiamas, Lead Developer
-
+See <https://docs.moodle.org> for details of Moodle's many features.
-------------------------
-Moodle Trademark License
-------------------------
-
-The name Moodle™ is a registered trademark of the Moodle Trust.
-
-A key part of the business model that allows us to produce and
-distribute Moodle as completely Free open source software is that
-we restrict the commercial use of the Moodle trademark to those
-who have contracted to support Moodle development (Moodle Partners).
-
-If you are intending to use the name (and/or logo) to advertise
-generic Moodle™ services (eg Moodle Hosting, Moodle Support,
-Moodle Certification, Moodle Training, Moodle Consulting,
-Moodle Customisation, Moodle Courseware Development, Moodle
-Theme design, Moodle Integrations, Moodle Installations, etc)
-or as the name of a software package, then you must seek
-direct permission in writing from the Moodle Trust via the
-moodle.com helpdesk, in accordance with normal trademark
-restrictions.
-
-There are no restrictions on how you use the name in other
-contexts (for example, if you use Moodle just to provide
-courses then you can use the name freely to refer to it.)
-
-If you aren't sure of a particular case, please ask us via
-http://moodle.com/helpdesk: we'll be happy to either provide
-you with official permission in writing or help you fix
-your wording.
-
-Martin Dougiamas
-Executive Director
-Moodle Trust
-http://moodle.com
+MOODLE TRADEMARKS POLICY
+========================
+
+The word "Moodle" is trademarked in many countries around the world. The word
+was originally an acronym: Modular Object-Oriented Dynamic Learning
+Environment. The trademark is owned by Martin Dougiamas, Founder and Director
+of Moodle.
+
+The law obligates trademark owners to police their marks and prevent the use of
+confusingly similar names by third parties. Through this policy we’d like to
+make it clear how Moodle-related projects, organisations, and people can use
+the Moodle trademark. We’d also like to be clear about how use of the word is
+restricted when used to promote commercial Moodle services. We do this to
+protect the very business model that allows us to continue developing Moodle
+for you.
+
+Allowed uses
+------------
+
+The following uses don’t require any permission at all:
+
+* Referring to the software or the Moodle project.
+* Describing your own Moodle implementation (including within corporate
+ settings).
+* Describing a Moodle-based community hub.
+* Describing some software you’ve made that integrates with Moodle
+ (eg a Moodle integration feature on another system).
+
+Restricted uses
+---------------
+
+The following uses are generally prohibited without explicit and direct
+permission being granted to you by Moodle Pty Ltd. We do this to protect the
+Moodle project from software and sites which could confuse people. Please
+contact us to ask for permission in writing.
+
+* You can’t use "Moodle" in the name of your software (including Mobile apps)
+* You can’t use "Moodle" in your company name
+* You can’t use "Moodle" in your domain name
+* You can’t use "Moodle" in advertising-related keywords (such as Adsense)
+* You can’t use "Moodle" to describe services around Moodle (such as hosting,
+ training, support, consulting, course creation services, theme development,
+ customisation, installation, integration and certification). This applies
+ even if you do not charge for the services. Note that usually only Moodle
+ Partners have this permission.
+
+For information about the Moodle Partner Certification Mark as well as for how
+to contact us, please see <https://moodle.com/trademarks/>.
$output .= $this->header();
$output .= $this->maturity_info($maturity);
+ $output .= $this->legacy_log_store_writing_error();
$output .= empty($CFG->disableupdatenotifications) ? $this->available_updates($availableupdates, $availableupdatesfetch) : '';
$output .= $this->insecure_dataroot_warning($insecuredataroot);
$output .= $this->display_errors_warning($errorsdisplayed);
return $output;
}
+
+ /**
+ * Check to see if writing to the deprecated legacy log store is enabled.
+ *
+ * @return string An error message if writing to the legacy log store is enabled.
+ */
+ protected function legacy_log_store_writing_error() {
+ $enabled = get_config('logstore_legacy', 'loglegacy');
+ $plugins = explode(',', get_config('tool_log', 'enabled_stores'));
+ $enabled = $enabled && in_array('logstore_legacy', $plugins);
+
+ if ($enabled) {
+ return $this->warning(get_string('legacylogginginuse'));
+ }
+ }
}
protected $allpermissions; // We don't need perms ourselves, but all our subclasses do.
protected $strperms; // Language string cache.
protected $risksurl; // URL in moodledocs about risks.
- protected $riskicons = array(); // Cache to avoid regenerating the HTML for each risk icon.
/** @var array The capabilities to highlight as default/inherited. */
protected $parentpermissions;
protected $displaypermissions;
*/
public function get_risk_icon($type) {
global $OUTPUT;
- if (!isset($this->riskicons[$type])) {
- $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
- $text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
- $action = new popup_action('click', $this->risksurl, 'docspopup');
- $this->riskicons[$type] = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
- }
- return $this->riskicons[$type];
+
+ $iconurl = $OUTPUT->pix_url('i/' . str_replace('risk', 'risk_', $type));
+ $text = '<img src="' . $iconurl . '" alt="' . get_string($type . 'short', 'admin') . '" />';
+ $action = new popup_action('click', $this->risksurl, 'docspopup');
+ $riskicon = $OUTPUT->action_link($this->risksurl, $text, $action, array('title'=>get_string($type, 'admin')));
+
+ return $riskicon;
}
}
$ADMIN->add('reportplugins', $page);
}
+if ($hassiteconfig) {
+ // Global Search engine plugins.
+ $ADMIN->add('modules', new admin_category('searchplugins', new lang_string('search', 'admin')));
+ $temp = new admin_settingpage('manageglobalsearch', new lang_string('globalsearchmanage', 'admin'));
+
+ $pages = array();
+ $engines = array();
+ foreach (core_component::get_plugin_list('search') as $engine => $plugindir) {
+ $engines[$engine] = new lang_string('pluginname', 'search_' . $engine);
+ $settingspath = "$plugindir/settings.php";
+ if (file_exists($settingspath)) {
+ $settings = new admin_settingpage('search' . $engine,
+ new lang_string('pluginname', 'search_' . $engine), 'moodle/site:config');
+ include($settingspath);
+ if ($settings) {
+ $pages[] = $settings;
+ }
+ }
+ }
+
+ // Setup status.
+ $temp->add(new admin_setting_searchsetupinfo());
+
+ // Search engine selection.
+ $temp->add(new admin_setting_heading('searchengineheading', new lang_string('searchengine', 'admin'), ''));
+ $temp->add(new admin_setting_configselect('searchengine',
+ new lang_string('selectsearchengine', 'admin'), '', 'solr', $engines));
+
+ // Enable search areas.
+ $temp->add(new admin_setting_heading('searchareasheading', new lang_string('availablesearchareas', 'admin'), ''));
+ $searchareas = \core_search\manager::get_search_areas_list();
+ foreach ($searchareas as $areaid => $searcharea) {
+ list($componentname, $varname) = $searcharea->get_config_var_name();
+ $temp->add(new admin_setting_configcheckbox($componentname . '/' . $varname . '_enabled', $searcharea->get_visible_name(true),
+ '', 1, 1, 0));
+ }
+ $ADMIN->add('searchplugins', $temp);
+
+ foreach ($pages as $page) {
+ $ADMIN->add('searchplugins', $page);
+ }
+}
+
/// Add all admin tools
if ($hassiteconfig) {
$ADMIN->add('modules', new admin_category('tools', new lang_string('tools', 'admin')));
$optionalsubsystems->add(new admin_setting_configcheckbox('enableplagiarism', new lang_string('enableplagiarism','plagiarism'), new lang_string('configenableplagiarism','plagiarism'), 0));
$optionalsubsystems->add(new admin_setting_configcheckbox('enablebadges', new lang_string('enablebadges', 'badges'), new lang_string('configenablebadges', 'badges'), 1));
+
+ $optionalsubsystems->add(new admin_setting_configcheckbox('enableglobalsearch', new lang_string('enableglobalsearch', 'admin'),
+ new lang_string('enableglobalsearch_desc', 'admin'), 0, 1, 0));
}
/**
* Legacy add_to_log() code.
+ * @deprecated since Moodle 3.1 MDL-45104 - Please use supported log stores such as "standard" or "external" instead.
+ * @todo MDL-52805 This will be removed in Moodle 3.3
*
* @param int $courseid The course id
* @param string $module The module name e.g. forum, journal, resource, course, user etc
try {
\core\task\manager::configure_scheduled_task($task);
- $url = $PAGE->url;
- $url->params(array('success'=>get_string('changessaved')));
- redirect($url);
+ redirect($PAGE->url, get_string('changessaved'), null, \core\output\notification::NOTIFY_SUCCESS);
} catch (Exception $e) {
- $url = $PAGE->url;
- $url->params(array('error'=>$e->getMessage()));
- redirect($url);
+ redirect($PAGE->url, $e->getMessage(), null, \core\output\notification::NOTIFY_ERROR);
}
} else {
echo $OUTPUT->header();
} else {
echo $OUTPUT->header();
- $error = optional_param('error', '', PARAM_NOTAGS);
- if ($error) {
- echo $OUTPUT->notification($error, 'notifyerror');
- }
- $success = optional_param('success', '', PARAM_NOTAGS);
- if ($success) {
- echo $OUTPUT->notification($success, 'notifysuccess');
- }
$tasks = core\task\manager::get_all_scheduled_tasks();
echo $renderer->scheduled_tasks_table($tasks);
echo $OUTPUT->footer();
}
-
-
-
-
// Change the theme to 'base' because it overrides these templates.
$CFG->theme = 'base';
- $template = external::load_canonical_template('core', 'notification_problem');
+ $template = external::load_canonical_template('core', 'notification_error');
// Only the base template should contain the docs.
- $this->assertContains('@template core/notification_problem', $template);
+ $this->assertContains('@template core/notification_error', $template);
// Restore the original theme.
$CFG->theme = $originaltheme;
unset($allcohorts);
if (count($cohorts) < 2) {
- echo $OUTPUT->header();
- echo $OUTPUT->heading(get_string('bulkadd', 'core_cohort'));
- echo $OUTPUT->notification(get_string('bulknocohort', 'core_cohort'));
- echo $OUTPUT->continue_button(new moodle_url('/admin/user/user_bulk.php'));
- echo $OUTPUT->footer();
- die;
+ redirect(new moodle_url('/admin/user/user_bulk.php'), get_string('bulknocohort', 'core_cohort'));
}
$countries = get_string_manager()->get_list_of_countries(true);
$url = new moodle_url('/badges/action.php', $params);
if (!$badge->has_criteria()) {
- echo $OUTPUT->notification(get_string('error:cannotact', 'badges') . get_string('nocriteria', 'badges'));
- echo $OUTPUT->continue_button($returnurl);
+ redirect($returnurl, get_string('error:cannotact', 'badges') . get_string('nocriteria', 'badges'), null, \core\output\notification::NOTIFY_ERROR);
} else {
$message = get_string('reviewconfirm', 'badges', $badge->name);
echo $OUTPUT->confirm($message, $url, $returnurl);
--- /dev/null
+<?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/>.
+
+/**
+ * Global search block.
+ *
+ * @package block_globalsearch
+ * @copyright Prateek Sachan {@link http://prateeksachan.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Global search block.
+ *
+ * @package block_globalsearch
+ * @copyright Prateek Sachan {@link http://prateeksachan.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class block_globalsearch extends block_base {
+
+ /**
+ * Initialises the block.
+ *
+ * @return void
+ */
+ public function init() {
+ $this->title = get_string('pluginname', 'block_globalsearch');
+ }
+
+ /**
+ * Gets the block contents.
+ *
+ * If we can avoid it better not check the server status here as connecting
+ * to the server will slow down the whole page load.
+ *
+ * @return string The block HTML.
+ */
+ public function get_content() {
+ global $OUTPUT;
+ if ($this->content !== null) {
+ return $this->content;
+ }
+
+ $this->content = new stdClass();
+ $this->content->footer = '';
+
+ if (\core_search\manager::is_global_search_enabled() === false) {
+ $this->content->text = get_string('globalsearchdisabled', 'search');
+ return $this->content;
+ }
+
+ $url = new moodle_url('/search/index.php');
+ $this->content->footer .= html_writer::link($url, get_string('advancedsearch', 'search'));
+
+ $this->content->text = html_writer::start_tag('div', array('class' => 'searchform'));
+ $this->content->text .= html_writer::start_tag('form', array('action' => $url->out()));
+ $this->content->text .= html_writer::start_tag('fieldset', array('action' => 'invisiblefieldset'));
+
+ // Input.
+ $this->content->text .= html_writer::tag('label', get_string('search', 'search'),
+ array('for' => 'searchform_search', 'class' => 'accesshide'));
+ $inputoptions = array('id' => 'searchform_search', 'name' => 'q', 'type' => 'text', 'size' => '15');
+ $this->content->text .= html_writer::empty_tag('input', $inputoptions);
+
+ // Search button.
+ $this->content->text .= html_writer::tag('button', get_string('search', 'search'),
+ array('id' => 'searchform_button', 'type' => 'submit', 'title' => 'globalsearch'));
+ $this->content->text .= html_writer::end_tag('fieldset');
+ $this->content->text .= html_writer::end_tag('form');
+ $this->content->text .= html_writer::end_tag('div');
+
+ return $this->content;
+ }
+}
--- /dev/null
+<?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/>.
+
+/**
+ * Global search Block caps.
+ *
+ * @package block_globalsearch
+ * @copyright Prateek Sachan {@link http://prateeksachan.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+$capabilities = array(
+
+ 'block/globalsearch:myaddinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_SYSTEM,
+ 'archetypes' => array(
+ 'user' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/my:manageblocks'
+ ),
+
+ 'block/globalsearch:addinstance' => array(
+ 'captype' => 'write',
+ 'contextlevel' => CONTEXT_BLOCK,
+ 'archetypes' => array(
+ 'manager' => CAP_ALLOW
+ ),
+
+ 'clonepermissionsfrom' => 'moodle/site:manageblocks'
+ ),
+);
--- /dev/null
+<?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 'block_globalsearch'.
+ *
+ * @package block_globalsearch
+ * @copyright Prateek Sachan {@link http://prateeksachan.com}
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+$string['globalsearch:addinstance'] = 'Add a new global search block';
+$string['globalsearch:myaddinstance'] = 'Add a new global search block to Dashboard';
+$string['pluginname'] = 'Global search';
--- /dev/null
+<?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/>.
+
+/**
+ * Global Search version details.
+ *
+ * @package block_globalsearch
+ * @copyright Prateek Sachan {@link http://prateeksachan.com}
+ * @copyright Daniel Neis
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die;
+
+$plugin->version = 2016012000;
+$plugin->requires = 2015111000;
+$plugin->component = 'block_globalsearch';
// Turn our navigation items into list items.
$lis = array();
- $number = 0;
+ // Set the number to be static for unique id's.
+ static $number = 0;
foreach ($items as $item) {
$number++;
if (!$item->display && !$item->contains_active_node()) {
'invalidationevents' => array( // Optional
'contextmarkeddirty'
),
+ 'canuselocalstore' => false // Optional
'sharingoptions' => null // Optional
'defaultsharing' => null // Optional
)
* invalidationevents - An array of events that should trigger this cache to invalidate.
* sharingoptions - The sum of the possible sharing options that are applicable to the definition. An advanced setting.
* defaultsharing - The default sharing option to use. It's highly recommended that you don't set this unless there is a very specific reason not to use the system default.
-
+* canuselocalstore - The default is to required a shared cache location for all nodes in a multi webserver environment. If the cache uses revisions and never updates key data, administrators can use a local storage cache for this cache.
It's important to note that internally the definition is also aware of the component. This is picked up when the definition is read, based upon the location of the caches.php file.
The staticacceleration option.
Please be aware that if you are using Memcache or Memcached it is recommended to use dedicated Memcached servers.
When caches get purged the memcached servers you have configured get purged, any data stored within them whether it belongs to Moodle or not will be removed.
-If you are using Memcached for sessions as well as caching/testing and caches get purged your sessions will be removed prematurely and users will be need to start again.
\ No newline at end of file
+If you are using Memcached for sessions as well as caching/testing and caches get purged your sessions will be removed prematurely and users will be need to start again.
* + defaultsharing
* [int] The default sharing option to use. It's highly recommended that you don't set this unless there is a very
* specific reason not to use the system default.
+ * + canuselocalstore
+ * [bool] The cache is able to safely run with multiple copies on different webservers without any need for administrator
+ * intervention to ensure that data stays in sync across nodes. This is usually managed by a revision
+ * system as seen in modinfo cache or language cache. Requiring purge on upgrade is not sufficient as
+ * it requires administrator intervention on each node to make it work.
*
* For examples take a look at lib/db/caches.php
*
*/
protected $sharingoptions;
+ /**
+ * Whether this cache supports local storages.
+ * @var bool
+ */
+ protected $canuselocalstore = false;
+
/**
* The selected sharing option.
* @var int One of self::SHARING_*
$sharingoptions = self::SHARING_DEFAULT;
$selectedsharingoption = self::SHARING_DEFAULT;
$userinputsharingkey = '';
+ $canuselocalstore = false;
if (array_key_exists('simplekeys', $definition)) {
$simplekeys = (bool)$definition['simplekeys'];
$selectedsharingoption = self::SHARING_ALL;
}
}
+ if (array_key_exists('canuselocalstore', $definition)) {
+ $canuselocalstore = (bool)$definition['canuselocalstore'];
+ }
if (array_key_exists('userinputsharingkey', $definition) && !empty($definition['userinputsharingkey'])) {
$userinputsharingkey = (string)$definition['userinputsharingkey'];
$cachedefinition->sharingoptions = $sharingoptions;
$cachedefinition->selectedsharingoption = $selectedsharingoption;
$cachedefinition->userinputsharingkey = $userinputsharingkey;
+ $cachedefinition->canuselocalstore = $canuselocalstore;
return $cachedefinition;
}
return $this->requirelockingwrite;
}
+ /**
+ * Returns true if this definition allows local storage to be used for caching.
+ * @since Moodle 3.1.0
+ * @return bool
+ */
+ public function can_use_localstore() {
+ return $this->canuselocalstore;
+ }
+
/**
* Returns true if this definition requires a searchable cache.
* @since Moodle 2.4.4
* Sets the identifiers for this definition, or updates them if they have already been set.
*
* @param array $identifiers
+ * @return bool false if no identifiers where changed, true otherwise.
* @throws coding_exception
*/
public function set_identifiers(array $identifiers = array()) {
// If we are setting the exact same identifiers then just return as nothing really changed.
// We don't care about order as cache::make will use the same definition order all the time.
if ($identifiers === $this->identifiers) {
- return;
+ return false;
}
foreach ($this->requireidentifiers as $identifier) {
// Reset the key prefix's they need updating now.
$this->keyprefixsingle = null;
$this->keyprefixmulti = null;
+
+ return true;
}
/**
foreach ($keyvaluearray as $pair) {
$this->store[$pair['key']] = $pair['value'];
}
- return count($keyvaluearray);
+
}
- return 0;
+ return count($keyvaluearray);
}
/**
* @param array $identifiers
*/
public function set_identifiers(array $identifiers) {
- $this->definition->set_identifiers($identifiers);
+ if ($this->definition->set_identifiers($identifiers)) {
+ // As static acceleration uses input keys and not parsed keys
+ // it much be cleared when the identifier set is changed.
+ $this->staticaccelerationarray = array();
+ if ($this->staticaccelerationsize !== false) {
+ $this->staticaccelerationkeys = array();
+ $this->staticaccelerationcount = 0;
+ }
+ }
}
/**
* @throws coding_exception
*/
public function get($key, $strictness = IGNORE_MISSING) {
- // 1. Parse the key.
- $parsedkey = $this->parse_key($key);
- // 2. Get it from the static acceleration array if we can (only when it is enabled and it has already been requested/set).
- $result = false;
- if ($this->use_static_acceleration()) {
- $result = $this->static_acceleration_get($parsedkey);
- }
- if ($result !== false) {
- if (!is_scalar($result)) {
- // If data is an object it will be a reference.
- // If data is an array if may contain references.
- // We want to break references so that the cache cannot be modified outside of itself.
- // Call the function to unreference it (in the best way possible).
- $result = $this->unref($result);
+ // 1. Get it from the static acceleration array if we can (only when it is enabled and it has already been requested/set).
+ $usesstaticacceleration = $this->use_static_acceleration();
+
+ if ($usesstaticacceleration) {
+ $result = $this->static_acceleration_get($key);
+ if ($result !== false) {
+ return $result;
}
- return $result;
}
+
+ // 2. Parse the key.
+ $parsedkey = $this->parse_key($key);
+
// 3. Get it from the store. Obviously wasn't in the static acceleration array.
$result = $this->store->get($parsedkey);
if ($result !== false) {
if ($result instanceof cache_cached_object) {
$result = $result->restore_object();
}
- if ($this->use_static_acceleration()) {
- $this->static_acceleration_set($parsedkey, $result);
+ if ($usesstaticacceleration) {
+ $this->static_acceleration_set($key, $result);
}
}
+
// 4. Load if from the loader/datasource if we don't already have it.
$setaftervalidation = false;
if ($result === false) {
}
// 7. Make sure we don't pass back anything that could be a reference.
// We don't want people modifying the data in the cache.
- if (!is_scalar($result)) {
+ if (!$this->store->supports_dereferencing_objects() && !is_scalar($result)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
$parsedkeys[$pkey] = $key;
$keystofind[$pkey] = $key;
if ($isusingpersist) {
- $value = $this->static_acceleration_get($pkey);
+ $value = $this->static_acceleration_get($key);
if ($value !== false) {
$resultpersist[$pkey] = $value;
unset($keystofind[$pkey]);
$value = $value->restore_object();
}
if ($value !== false && $this->use_static_acceleration()) {
- $this->static_acceleration_set($key, $value);
+ $this->static_acceleration_set($keystofind[$key], $value);
}
$resultstore[$key] = $value;
}
// Create an array with the original keys and the found values. This will be what we return.
$fullresult = array();
foreach ($result as $key => $value) {
+ if (!is_scalar($value)) {
+ // If data is an object it will be a reference.
+ // If data is an array if may contain references.
+ // We want to break references so that the cache cannot be modified outside of itself.
+ // Call the function to unreference it (in the best way possible).
+ $value = $this->unref($value);
+ }
$fullresult[$parsedkeys[$key]] = $value;
}
unset($result);
// We have to let the loader do its own parsing of data as it may be unique.
$this->loader->set($key, $data);
}
+ $usestaticacceleration = $this->use_static_acceleration();
+
if (is_object($data) && $data instanceof cacheable_object) {
$data = new cache_cached_object($data);
- } else if (!is_scalar($data)) {
+ } else if (!$this->store->supports_dereferencing_objects() && !is_scalar($data)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
// Call the function to unreference it (in the best way possible).
$data = $this->unref($data);
}
+
+ if ($usestaticacceleration) {
+ $this->static_acceleration_set($key, $data);
+ }
+
if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) {
$data = new cache_ttl_wrapper($data, $this->definition->get_ttl());
}
$parsedkey = $this->parse_key($key);
- if ($this->use_static_acceleration()) {
- $this->static_acceleration_set($parsedkey, $data);
- }
+
return $this->store->set($parsedkey, $data);
}
$data = array();
$simulatettl = $this->has_a_ttl() && !$this->store_supports_native_ttl();
$usestaticaccelerationarray = $this->use_static_acceleration();
+ $needsdereferencing = !$this->store->supports_dereferencing_objects();
foreach ($keyvaluearray as $key => $value) {
if (is_object($value) && $value instanceof cacheable_object) {
$value = new cache_cached_object($value);
- } else if (!is_scalar($value)) {
+ } else if ($needsdereferencing && !is_scalar($value)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
// Call the function to unreference it (in the best way possible).
$value = $this->unref($value);
}
+ if ($usestaticaccelerationarray) {
+ $this->static_acceleration_set($key, $value);
+ }
if ($simulatettl) {
$value = new cache_ttl_wrapper($value, $this->definition->get_ttl());
}
'key' => $this->parse_key($key),
'value' => $value
);
- if ($usestaticaccelerationarray) {
- $this->static_acceleration_set($data[$key]['key'], $value);
- }
}
$successfullyset = $this->store->set_many($data);
if ($this->perfdebug && $successfullyset) {
* @return bool True if the cache has the requested key, false otherwise.
*/
public function has($key, $tryloadifpossible = false) {
- $parsedkey = $this->parse_key($key);
- if ($this->static_acceleration_has($parsedkey)) {
+ if ($this->static_acceleration_has($key)) {
// Hoorah, that was easy. It exists in the static acceleration array so we definitely have it.
return true;
}
+ $parsedkey = $this->parse_key($key);
+
if ($this->has_a_ttl() && !$this->store_supports_native_ttl()) {
// The data has a TTL and the store doesn't support it natively.
// We must fetch the data and expect a ttl wrapper.
}
if ($this->use_static_acceleration()) {
- $parsedkeys = array();
foreach ($keys as $id => $key) {
- $parsedkey = $this->parse_key($key);
- if ($this->static_acceleration_has($parsedkey)) {
+ if ($this->static_acceleration_has($key)) {
return true;
}
- $parsedkeys[] = $parsedkey;
}
- } else {
- $parsedkeys = array_map(array($this, 'parse_key'), $keys);
}
+ $parsedkeys = array_map(array($this, 'parse_key'), $keys);
return $this->store->has_any($parsedkeys);
}
* @return bool True of success, false otherwise.
*/
public function delete($key, $recurse = true) {
- $parsedkey = $this->parse_key($key);
- $this->static_acceleration_delete($parsedkey);
+ $this->static_acceleration_delete($key);
if ($recurse && $this->loader !== false) {
// Delete from the bottom of the stack first.
$this->loader->delete($key, $recurse);
}
+ $parsedkey = $this->parse_key($key);
return $this->store->delete($parsedkey);
}
* @return int The number of items successfully deleted.
*/
public function delete_many(array $keys, $recurse = true) {
- $parsedkeys = array_map(array($this, 'parse_key'), $keys);
if ($this->use_static_acceleration()) {
- foreach ($parsedkeys as $parsedkey) {
- $this->static_acceleration_delete($parsedkey);
+ foreach ($keys as $key) {
+ $this->static_acceleration_delete($key);
}
}
if ($recurse && $this->loader !== false) {
// Delete from the bottom of the stack first.
$this->loader->delete_many($keys, $recurse);
}
+ $parsedkeys = array_map(array($this, 'parse_key'), $keys);
return $this->store->delete_many($parsedkeys);
}
* @return bool
*/
protected function static_acceleration_has($key) {
- // This method of checking if an array was supplied is faster than is_array.
- if ($key === (array)$key) {
- $key = $key['key'];
- }
// This could be written as a single line, however it has been split because the ttl check is faster than the instanceof
// and has_expired calls.
- if (!$this->staticacceleration || !array_key_exists($key, $this->staticaccelerationarray)) {
+ if (!$this->staticacceleration || !isset($this->staticaccelerationarray[$key])) {
return false;
}
- if ($this->has_a_ttl() && $this->store_supports_native_ttl()) {
- return !($this->staticaccelerationarray[$key] instanceof cache_ttl_wrapper &&
- $this->staticaccelerationarray[$key]->has_expired());
- }
return true;
}
* Returns the item from the static acceleration array if it exists there.
*
* @param string $key The parsed key
- * @return mixed|false The data from the static acceleration array or false if it wasn't there.
+ * @return mixed|false Dereferenced data from the static acceleration array or false if it wasn't there.
*/
protected function static_acceleration_get($key) {
- // This method of checking if an array was supplied is faster than is_array.
- if ($key === (array)$key) {
- $key = $key['key'];
- }
- // This isset check is faster than array_key_exists but will return false
- // for null values, meaning null values will come from backing store not
- // the static acceleration array. We think this okay because null usage should be
- // very rare (see comment in MDL-39472).
if (!$this->staticacceleration || !isset($this->staticaccelerationarray[$key])) {
$result = false;
} else {
- $data = $this->staticaccelerationarray[$key];
- if (!$this->has_a_ttl() || !$data instanceof cache_ttl_wrapper) {
- if ($data instanceof cache_cached_object) {
- $data = $data->restore_object();
- }
- $result = $data;
- } else if ($data->has_expired()) {
- $this->static_acceleration_delete($key);
- $result = false;
+ $data = $this->staticaccelerationarray[$key]['data'];
+
+ if ($data instanceof cache_cached_object) {
+ $result = $data->restore_object();
+ } else if ($this->staticaccelerationarray[$key]['serialized']) {
+ $result = unserialize($data);
} else {
- if ($data instanceof cache_cached_object) {
- $data = $data->restore_object();
- }
- $result = $data->data;
+ $result = $data;
}
}
if ($result) {
* @return bool
*/
protected function static_acceleration_set($key, $data) {
- // This method of checking if an array was supplied is faster than is_array.
- if ($key === (array)$key) {
- $key = $key['key'];
- }
if ($this->staticaccelerationsize !== false && isset($this->staticaccelerationkeys[$key])) {
$this->staticaccelerationcount--;
unset($this->staticaccelerationkeys[$key]);
}
- $this->staticaccelerationarray[$key] = $data;
+
+ // We serialize anything that's not;
+ // 1. A known scalar safe value.
+ // 2. A definition that says it's simpledata. We trust it that it doesn't contain dangerous references.
+ // 3. An object that handles dereferencing by itself.
+ if (is_scalar($data) || $this->definition->uses_simple_data()
+ || $data instanceof cache_cached_object) {
+ $this->staticaccelerationarray[$key]['data'] = $data;
+ $this->staticaccelerationarray[$key]['serialized'] = false;
+ } else {
+ $this->staticaccelerationarray[$key]['data'] = serialize($data);
+ $this->staticaccelerationarray[$key]['serialized'] = true;
+ }
if ($this->staticaccelerationsize !== false) {
$this->staticaccelerationcount++;
$this->staticaccelerationkeys[$key] = $key;
*/
protected function static_acceleration_delete($key) {
unset($this->staticaccelerationarray[$key]);
- if ($this->staticaccelerationsize !== false) {
- $dropkey = array_search($key, $this->staticaccelerationkeys);
- if ($dropkey) {
- unset($this->staticaccelerationkeys[$dropkey]);
- $this->staticaccelerationcount--;
- }
+ if ($this->staticaccelerationsize !== false && isset($this->staticaccelerationkeys[$key])) {
+ unset($this->staticaccelerationkeys[$key]);
+ $this->staticaccelerationcount--;
}
return true;
}
}
// 6. Make sure we don't pass back anything that could be a reference.
// We don't want people modifying the data in the cache.
- if (!is_scalar($result)) {
+ if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($result)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
}
if (is_object($data) && $data instanceof cacheable_object) {
$data = new cache_cached_object($data);
- } else if (!is_scalar($data)) {
+ } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($data)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
if ($value instanceof cache_cached_object) {
/* @var cache_cached_object $value */
$value = $value->restore_object();
+ } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) {
+ // If data is an object it will be a reference.
+ // If data is an array if may contain references.
+ // We want to break references so that the cache cannot be modified outside of itself.
+ // Call the function to unreference it (in the best way possible).
+ $value = $this->unref($value);
}
$return[$key] = $value;
if ($value === false) {
foreach ($keyvaluearray as $key => $value) {
if (is_object($value) && $value instanceof cacheable_object) {
$value = new cache_cached_object($value);
- } else if (!is_scalar($value)) {
+ } else if (!$this->get_store()->supports_dereferencing_objects() && !is_scalar($value)) {
// If data is an object it will be a reference.
// If data is an array if may contain references.
// We want to break references so that the cache cannot be modified outside of itself.
*/
const IS_SEARCHABLE = 8;
+ /**
+ * The cache store dereferences objects.
+ *
+ * When set, loaders will assume that all data coming from this store has already had all references
+ * resolved. So even for complex object structures it will not try to remove references again.
+ */
+ const DEREFERENCES_OBJECTS = 16;
+
// Constants for the modes of a cache store
/**
return in_array('cache_is_searchable', class_implements($this));
}
+ /**
+ * Returns true if the store automatically dereferences objects.
+ *
+ * @return bool
+ */
+ public function supports_dereferencing_objects() {
+ return $this::get_supported_features() & self::DEREFERENCES_OBJECTS;
+ }
+
/**
* Creates a clone of this store instance ready to be initialised.
*
* The definition of the form
*/
protected final function definition() {
+ global $OUTPUT;
+
$definition = $this->_customdata['definition'];
$form = $this->_form;
list($currentstores, $storeoptions, $defaults) =
cache_administration_helper::get_definition_store_options($component, $area);
+ $storedata = cache_administration_helper::get_definition_summaries();
+ if ($storedata[$definition]['mode'] != cache_store::MODE_REQUEST) {
+ if (isset($storedata[$definition]['canuselocalstore']) && $storedata[$definition]['canuselocalstore']) {
+ $form->addElement('html', $OUTPUT->notification(get_string('localstorenotification', 'cache'), 'notifymessage'));
+ } else {
+ $form->addElement('html', $OUTPUT->notification(get_string('sharedstorenotification', 'cache'), 'notifymessage'));
+ }
+ }
$form->addElement('hidden', 'definition', $definition);
$form->setType('definition', PARAM_SAFEPATH);
$form->addElement('hidden', 'action', 'editdefinitionmapping');
'component' => $definition->get_component(),
'area' => $definition->get_area(),
'mappings' => $mappings,
+ 'canuselocalstore' => $definition->can_use_localstore(),
'sharingoptions' => self::get_definition_sharing_options($definition->get_sharing_options(), false),
'selectedsharingoption' => self::get_definition_sharing_options($definition->get_selected_sharing_option(), true),
'userinputsharingkey' => $definition->get_user_input_sharing_key()
public static function get_supported_features(array $configuration = array()) {
$supported = self::SUPPORTS_DATA_GUARANTEE +
self::SUPPORTS_NATIVE_TTL +
- self::IS_SEARCHABLE;
+ self::IS_SEARCHABLE +
+ self::DEREFERENCES_OBJECTS;
return $supported;
}
* @return int
*/
public static function get_supported_features(array $configuration = array()) {
- return self::SUPPORTS_NATIVE_TTL;
+ return self::SUPPORTS_NATIVE_TTL + self::DEREFERENCES_OBJECTS;
}
/**
* @return int
*/
public static function get_supported_features(array $configuration = array()) {
- return self::SUPPORTS_NATIVE_TTL;
+ return self::SUPPORTS_NATIVE_TTL + self::DEREFERENCES_OBJECTS;
}
/**
* @return int
*/
public static function get_supported_features(array $configuration = array()) {
- $supports = self::SUPPORTS_DATA_GUARANTEE;
+ $supports = self::SUPPORTS_DATA_GUARANTEE + self::DEREFERENCES_OBJECTS;
if (array_key_exists('extendedmode', $configuration) && $configuration['extendedmode']) {
$supports += self::SUPPORTS_MULTIPLE_IDENTIFIERS;
}
$this->assertEquals('pork', $var->subobj->subobj->key);
$this->assertTrue($cache->delete('obj'));
- // Death reference test... basicaly we don't want this to die.
+ // Death reference test... basically we don't want this to die.
$obj = new stdClass;
$obj->key = 'value';
$obj->self =& $obj;
$this->assertTrue($cache->delete('obj'));
+ // Death reference test on get_many... basically we don't want this to die.
+ $obj = new stdClass;
+ $obj->key = 'value';
+ $obj->self =& $obj;
+ $this->assertEquals(1, $cache->set_many(array('obj' => $obj)));
+ $var = $cache->get_many(array('obj'));
+ $this->assertInstanceOf('stdClass', $var['obj']);
+ $this->assertEquals('value', $var['obj']->key);
+
+ // Reference test after retrieve.
+ $obj = new stdClass;
+ $obj->key = 'value';
+ $this->assertEquals(1, $cache->set_many(array('obj' => $obj)));
+
+ $var1 = $cache->get_many(array('obj'));
+ $this->assertInstanceOf('stdClass', $var1['obj']);
+ $this->assertEquals('value', $var1['obj']->key);
+ $var1['obj']->key = 'eulav';
+ $this->assertEquals('eulav', $var1['obj']->key);
+
+ $var2 = $cache->get_many(array('obj'));
+ $this->assertInstanceOf('stdClass', $var2['obj']);
+ $this->assertEquals('value', $var2['obj']->key);
+
+ $this->assertTrue($cache->delete('obj'));
+
// Test strictness exceptions.
try {
$cache->get('exception', MUST_EXIST);
* @return false|mixed
*/
public function phpunit_static_acceleration_get($key) {
- $key = $this->parse_key($key);
return $this->static_acceleration_get($key);
}
}
This files describes API changes in /cache/stores/* - cache store plugins.
Information provided here is intended especially for developers.
+=== 3.1 ===
+* Cache stores has a new feature DEREFERENCES_OBJECTS.
+ This allows the cache loader to decide if it needs to handle dereferencing or whether the data
+ coming directly to it has already had references resolved.
+ - see supports_dereferencing_objects in store.php.
+
=== 2.9 ===
* Cache data source aggregation functionality has been removed. This functionality was found to be broken and unused.
It was decided that rather than fixing it it should be removed.
echo $OUTPUT->header();
echo $OUTPUT->heading($strdeletingcourse);
+ // This might take a while. Raise the execution time limit.
+ core_php_time_limit::raise();
// We do this here because it spits out feedback as it goes.
delete_course($course);
echo $OUTPUT->heading( get_string("deletedcourse", "", $courseshortname) );
$mform->addGroup($elementgroup, 'name_group', get_string('sectionname'), ' ', false);
$mform->addGroupRule('name_group', array('name' => array(array(get_string('maximumchars', '', 255), 'maxlength', 255))));
- // Add rule for name_group to make sure that the section name is not blank if 'Use default section name'
- // checkbox is unchecked.
- $mform->addRule('name_group', get_string('required'), 'required', null, 'client');
-
$mform->setDefault('usedefaultname', true);
$mform->setType('name', PARAM_TEXT);
$mform->disabledIf('name','usedefaultname','checked');
$editoroptions = $this->_customdata['editoroptions'];
$default_values = file_prepare_standard_editor($default_values, 'summary', $editoroptions,
$editoroptions['context'], 'course', 'section', $default_values->id);
- $default_values->usedefaultname = (is_null($default_values->name));
+ $default_values->usedefaultname = (strval($default_values->name) === '');
parent::set_data($default_values);
}
$data = parent::get_data();
if ($data !== null) {
$editoroptions = $this->_customdata['editoroptions'];
+ // Set name as an empty string if use default section name is checked.
if (!empty($data->usedefaultname)) {
- $data->name = null;
+ $data->name = '';
}
$data = file_postupdate_standard_editor($data, 'summary', $editoroptions,
$editoroptions['context'], 'course', 'section', $data->id);
\core_availability\frontend::report_validation_errors($data, $errors);
}
- // Validate section name if 'Use default section name' is unchecked.
- if (empty($data['usedefaultname'])) {
- // Make sure the trimmed value of section name is not empty.
- $trimmedname = trim($data['name']);
- if (empty($trimmedname)) {
- $errors['name_group'] = get_string('required');
- }
- }
-
return $errors;
}
}
return array(
new Given('I add a "' . $this->escape($activity) . '" to section "' . $this->escape($section) . '"'),
+ new Given('I wait to be redirected'),
new Given('I set the following fields to these values:', $data),
new Given('I press "' . get_string('savechangesandreturntocourse') . '"')
);
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_cohort to specified course.
- *
- * @package enrol_cohort
- * @copyright 2010 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/enrol/cohort/edit_form.php");
-require_once("$CFG->dirroot/enrol/cohort/locallib.php");
-require_once("$CFG->dirroot/group/lib.php");
-
-$courseid = required_param('courseid', PARAM_INT);
-$instanceid = optional_param('id', 0, PARAM_INT);
-$message = optional_param('message', null, PARAM_TEXT);
-
-$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-require_login($course);
-require_capability('moodle/course:enrolconfig', $context);
-require_capability('enrol/cohort:config', $context);
-
-$PAGE->set_url('/enrol/cohort/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid));
-$PAGE->set_pagelayout('admin');
-
-$returnurl = new moodle_url('/enrol/instances.php', array('id'=>$course->id));
-if (!enrol_is_enabled('cohort')) {
- redirect($returnurl);
-}
-
-$enrol = enrol_get_plugin('cohort');
-
-if ($instanceid) {
- $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'cohort', 'id'=>$instanceid), '*', MUST_EXIST);
-
-} else {
- // No instance yet, we have to add new instance.
- if (!$enrol->get_newinstance_link($course->id)) {
- redirect($returnurl);
- }
- navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
- $instance = new stdClass();
- $instance->id = null;
- $instance->courseid = $course->id;
- $instance->enrol = 'cohort';
- $instance->customint1 = ''; // Cohort id.
- $instance->customint2 = 0; // Optional group id.
-}
-
-// Try and make the manage instances node on the navigation active.
-$courseadmin = $PAGE->settingsnav->get('courseadmin');
-if ($courseadmin && $courseadmin->get('users') && $courseadmin->get('users')->get('manageinstances')) {
- $courseadmin->get('users')->get('manageinstances')->make_active();
-}
-
-
-$mform = new enrol_cohort_edit_form(null, array($instance, $enrol, $course));
-
-if ($mform->is_cancelled()) {
- redirect($returnurl);
-
-} else if ($data = $mform->get_data()) {
- if ($data->id) {
- // NOTE: no cohort changes here!!!
- if ($data->roleid != $instance->roleid) {
- // The sync script can only add roles, for perf reasons it does not modify them.
- role_unassign_all(array('contextid'=>$context->id, 'roleid'=>$instance->roleid, 'component'=>'enrol_cohort', 'itemid'=>$instance->id));
- }
- $instance->name = $data->name;
- $instance->status = $data->status;
- $instance->roleid = $data->roleid;
- $instance->customint2 = $data->customint2;
- $instance->timemodified = time();
- // Create a new group for the cohort if requested.
- if ($data->customint2 == COHORT_CREATE_GROUP) {
- require_capability('moodle/course:managegroups', $context);
- $groupid = enrol_cohort_create_new_group($course->id, $data->customint1);
- $instance->customint2 = $groupid;
- }
- $DB->update_record('enrol', $instance);
- \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
- } else {
- // Create a new group for the cohort if requested.
- if ($data->customint2 == COHORT_CREATE_GROUP) {
- require_capability('moodle/course:managegroups', $context);
- $groupid = enrol_cohort_create_new_group($course->id, $data->customint1);
- $enrol->add_instance($course, array('name' => $data->name, 'status' => $data->status,
- 'customint1' => $data->customint1, 'roleid' => $data->roleid, 'customint2' => $groupid));
- } else {
- $enrol->add_instance($course, array('name' => $data->name, 'status' => $data->status,
- 'customint1' => $data->customint1, 'roleid' => $data->roleid, 'customint2' => $data->customint2));
- }
- if (!empty($data->submitbuttonnext)) {
- $returnurl = new moodle_url($PAGE->url);
- $returnurl->param('message', 'added');
- }
- }
- $trace = new null_progress_trace();
- enrol_cohort_sync($trace, $course->id);
- $trace->finished();
- redirect($returnurl);
-}
-
-$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_cohort'));
-
-echo $OUTPUT->header();
-if ($message === 'added') {
- echo $OUTPUT->notification(get_string('instanceadded', 'enrol'), 'notifysuccess');
-}
-$mform->display();
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Adds instance form
- *
- * @package enrol_cohort
- * @copyright 2010 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/formslib.php");
-
-class enrol_cohort_edit_form extends moodleform {
-
- function definition() {
- global $CFG, $DB;
-
- $mform = $this->_form;
-
- list($instance, $plugin, $course) = $this->_customdata;
- $coursecontext = context_course::instance($course->id);
-
- $enrol = enrol_get_plugin('cohort');
-
- $groups = array(0 => get_string('none'));
- if (has_capability('moodle/course:managegroups', $coursecontext)) {
- $groups[COHORT_CREATE_GROUP] = get_string('creategroup', 'enrol_cohort');
- }
-
- foreach (groups_get_all_groups($course->id) as $group) {
- $groups[$group->id] = format_string($group->name, true, array('context'=>$coursecontext));
- }
-
- $mform->addElement('header','general', get_string('pluginname', 'enrol_cohort'));
-
- $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
- $mform->setType('name', PARAM_TEXT);
-
- $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
- ENROL_INSTANCE_DISABLED => get_string('no'));
- $mform->addElement('select', 'status', get_string('status', 'enrol_cohort'), $options);
-
- if ($instance->id) {
- if ($cohort = $DB->get_record('cohort', array('id'=>$instance->customint1))) {
- $cohorts = array($instance->customint1=>format_string($cohort->name, true, array('context'=>context::instance_by_id($cohort->contextid))));
- } else {
- $cohorts = array($instance->customint1=>get_string('error'));
- }
- $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $cohorts);
- $mform->setConstant('customint1', $instance->customint1);
- $mform->hardFreeze('customint1', $instance->customint1);
-
- } else {
- $cohorts = array('' => get_string('choosedots'));
- $allcohorts = cohort_get_available_cohorts($coursecontext, 0, 0, 0);
- foreach ($allcohorts as $c) {
- $cohorts[$c->id] = format_string($c->name);
- }
- $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $cohorts);
- $mform->addRule('customint1', get_string('required'), 'required', null, 'client');
- }
-
- $roles = get_assignable_roles($coursecontext);
- $roles[0] = get_string('none');
- $roles = array_reverse($roles, true); // Descending default sortorder.
- $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_cohort'), $roles);
- $mform->setDefault('roleid', $enrol->get_config('roleid'));
- if ($instance->id and !isset($roles[$instance->roleid])) {
- if ($role = $DB->get_record('role', array('id'=>$instance->roleid))) {
- $roles = role_fix_names($roles, $coursecontext, ROLENAME_ALIAS, true);
- $roles[$instance->roleid] = role_get_name($role, $coursecontext);
- } else {
- $roles[$instance->roleid] = get_string('error');
- }
- }
- $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_cohort'), $groups);
-
- $mform->addElement('hidden', 'courseid', null);
- $mform->setType('courseid', PARAM_INT);
-
- $mform->addElement('hidden', 'id', null);
- $mform->setType('id', PARAM_INT);
-
- if ($instance->id) {
- $this->add_action_buttons(true);
- } else {
- $this->add_add_buttons();
- }
-
- $this->set_data($instance);
- }
-
- /**
- * Adds buttons on create new method form
- */
- protected function add_add_buttons() {
- $mform = $this->_form;
- $buttonarray = array();
- $buttonarray[0] = $mform->createElement('submit', 'submitbutton', get_string('addinstance', 'enrol'));
- $buttonarray[1] = $mform->createElement('submit', 'submitbuttonnext', get_string('addinstanceanother', 'enrol'));
- $buttonarray[2] = $mform->createElement('cancel');
- $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
- $mform->closeHeaderBefore('buttonar');
- }
-
- function validation($data, $files) {
- global $DB;
-
- $errors = parent::validation($data, $files);
-
- $params = array('roleid'=>$data['roleid'], 'customint1'=>$data['customint1'], 'courseid'=>$data['courseid'], 'id'=>$data['id']);
- if ($DB->record_exists_select('enrol', "roleid = :roleid AND customint1 = :customint1 AND courseid = :courseid AND enrol = 'cohort' AND id <> :id", $params)) {
- $errors['roleid'] = get_string('instanceexists', 'enrol_cohort');
- }
-
- return $errors;
- }
-}
}
}
- /**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
- * @param int $courseid
- * @return moodle_url page url
- */
- public function get_newinstance_link($courseid) {
- if (!$this->can_add_new_instances($courseid)) {
- return NULL;
- }
- // Multiple instances supported - multiple parent courses linked.
- return new moodle_url('/enrol/cohort/edit.php', array('courseid'=>$courseid));
- }
-
/**
* Given a courseid this function returns true if the user is able to enrol or configure cohorts.
* AND there are cohorts that the user can view.
* @param int $courseid
* @return bool
*/
- protected function can_add_new_instances($courseid) {
+ public function can_add_instance($courseid) {
global $CFG;
require_once($CFG->dirroot . '/cohort/lib.php');
$coursecontext = context_course::instance($courseid);
}
/**
- * Returns edit icons for the page with list of instances.
- * @param stdClass $instance
- * @return array
+ * Add new instance of enrol plugin.
+ * @param object $course
+ * @param array $fields instance fields
+ * @return int id of new instance, null if can not be created
*/
- public function get_action_icons(stdClass $instance) {
- global $OUTPUT;
-
- if ($instance->enrol !== 'cohort') {
- throw new coding_exception('invalid enrol instance!');
+ public function add_instance($course, array $fields = null) {
+
+ if (!empty($fields['customint2']) && $fields['customint2'] == COHORT_CREATE_GROUP) {
+ // Create a new group for the cohort if requested.
+ $context = context_course::instance($course->id);
+ require_capability('moodle/course:managegroups', $context);
+ $groupid = enrol_cohort_create_new_group($course->id, $fields['customint1']);
+ $fields['customint2'] = $groupid;
}
- $context = context_course::instance($instance->courseid);
- $icons = array();
+ return parent::add_instance($course, $fields);
+ }
- if (has_capability('enrol/cohort:config', $context)) {
- $editlink = new moodle_url("/enrol/cohort/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
+ /**
+ * Update instance of enrol plugin.
+ * @param stdClass $instance
+ * @param stdClass $data modified instance fields
+ * @return boolean
+ */
+ public function update_instance($instance, $data) {
+ // NOTE: no cohort changes here!!!
+ $context = context_course::instance($instance->courseid);
+ if ($data->roleid != $instance->roleid) {
+ // The sync script can only add roles, for perf reasons it does not modify them.
+ $params = array(
+ 'contextid' => $context->id,
+ 'roleid' => $instance->roleid,
+ 'component' => 'enrol_cohort',
+ 'itemid' => $instance->id
+ );
+ role_unassign_all($params);
+ }
+ // Create a new group for the cohort if requested.
+ if ($data->customint2 == COHORT_CREATE_GROUP) {
+ require_capability('moodle/course:managegroups', $context);
+ $groupid = enrol_cohort_create_new_group($instance->courseid, $data->customint1);
+ $data->customint2 = $groupid;
}
- return $icons;
+ return parent::update_instance($instance, $data);
}
/**
$context = context_course::instance($instance->courseid);
return has_capability('enrol/cohort:config', $context);
}
+
+ /**
+ * Return an array of valid options for the status.
+ *
+ * @return array
+ */
+ protected function get_status_options() {
+ $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
+ ENROL_INSTANCE_DISABLED => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the cohorts.
+ *
+ * @param stdClass $instance
+ * @param context $context
+ * @return array
+ */
+ protected function get_cohort_options($instance, $context) {
+ global $DB, $CFG;
+
+ require_once($CFG->dirroot . '/cohort/lib.php');
+
+ $cohorts = array();
+
+ if ($instance->id) {
+ if ($cohort = $DB->get_record('cohort', array('id' => $instance->customint1))) {
+ $name = format_string($cohort->name, true, array('context' => context::instance_by_id($cohort->contextid)));
+ $cohorts = array($instance->customint1 => $name);
+ } else {
+ $cohorts = array($instance->customint1 => get_string('error'));
+ }
+ } else {
+ $cohorts = array('' => get_string('choosedots'));
+ $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0);
+ foreach ($allcohorts as $c) {
+ $cohorts[$c->id] = format_string($c->name);
+ }
+ }
+ return $cohorts;
+ }
+
+ /**
+ * Return an array of valid options for the roles.
+ *
+ * @param stdClass $instance
+ * @param context $coursecontext
+ * @return array
+ */
+ protected function get_role_options($instance, $coursecontext) {
+ global $DB;
+
+ $roles = get_assignable_roles($coursecontext);
+ $roles[0] = get_string('none');
+ $roles = array_reverse($roles, true); // Descending default sortorder.
+ if ($instance->id and !isset($roles[$instance->roleid])) {
+ if ($role = $DB->get_record('role', array('id' => $instance->roleid))) {
+ $roles = role_fix_names($roles, $coursecontext, ROLENAME_ALIAS, true);
+ $roles[$instance->roleid] = role_get_name($role, $coursecontext);
+ } else {
+ $roles[$instance->roleid] = get_string('error');
+ }
+ }
+
+ return $roles;
+ }
+
+ /**
+ * Return an array of valid options for the groups.
+ *
+ * @param context $coursecontext
+ * @return array
+ */
+ protected function get_group_options($coursecontext) {
+ $groups = array(0 => get_string('none'));
+ if (has_capability('moodle/course:managegroups', $coursecontext)) {
+ $groups[COHORT_CREATE_GROUP] = get_string('creategroup', 'enrol_cohort');
+ }
+
+ foreach (groups_get_all_groups($coursecontext->instanceid) as $group) {
+ $groups[$group->id] = format_string($group->name, true, array('context' => $coursecontext));
+ }
+
+ return $groups;
+ }
+
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $coursecontext
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $coursecontext) {
+ global $DB;
+
+ $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
+ $mform->setType('name', PARAM_TEXT);
+
+ $options = $this->get_status_options();
+ $mform->addElement('select', 'status', get_string('status', 'enrol_cohort'), $options);
+
+ $options = $this->get_cohort_options($instance, $coursecontext);
+ $mform->addElement('select', 'customint1', get_string('cohort', 'cohort'), $options);
+ if ($instance->id) {
+ $mform->setConstant('customint1', $instance->customint1);
+ $mform->hardFreeze('customint1', $instance->customint1);
+ } else {
+ $mform->addRule('customint1', get_string('required'), 'required', null, 'client');
+ }
+
+ $roles = $this->get_role_options($instance, $coursecontext);
+ $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_cohort'), $roles);
+ $mform->setDefault('roleid', $this->get_config('roleid'));
+ $groups = $this->get_group_options($coursecontext);
+ $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_cohort'), $groups);
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname" => value) of submitted data
+ * @param array $files array of uploaded files "element_name" => tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name" => "error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ global $DB;
+ $errors = array();
+
+ $params = array(
+ 'roleid' => $data['roleid'],
+ 'customint1' => $data['customint1'],
+ 'courseid' => $data['courseid'],
+ 'id' => $data['id']
+ );
+ $sql = "roleid = :roleid AND customint1 = :customint1 AND courseid = :courseid AND enrol = 'cohort' AND id <> :id";
+ if ($DB->record_exists_select('enrol', $sql, $params)) {
+ $errors['roleid'] = get_string('instanceexists', 'enrol_cohort');
+ }
+ $validstatus = array_keys($this->get_status_options());
+ $validcohorts = array_keys($this->get_cohort_options($instance, $context));
+ $validroles = array_keys($this->get_role_options($instance, $context));
+ $validgroups = array_keys($this->get_group_options($context));
+ $tovalidate = array(
+ 'name' => PARAM_TEXT,
+ 'status' => $validstatus,
+ 'customint1' => $validcohorts,
+ 'roleid' => $validroles,
+ 'customint2' => $validgroups
+ );
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
}
/**
* @return int $groupid Group ID for this cohort.
*/
function enrol_cohort_create_new_group($courseid, $cohortid) {
- global $DB;
+ global $DB, $CFG;
+
+ require_once($CFG->dirroot . '/group/lib.php');
$groupname = $DB->get_field('cohort', 'name', array('id' => $cohortid), MUST_EXIST);
$a = new stdClass();
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
/**
- * Edit instance of enrol_guest.
+ * Adds new instance of an enrolment plugin to specified course or edits current instance.
*
- * Adds new instance of enrol_guest to specified course
- * or edits current instance.
- *
- * @package enrol_guest
- * @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
+ * @package core_enrol
+ * @copyright 2015 Damyon Wiese
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
-require('../../config.php');
+require('../config.php');
+require_once('editinstance_form.php');
$courseid = required_param('courseid', PARAM_INT);
+$type = required_param('type', PARAM_COMPONENT);
$instanceid = optional_param('id', 0, PARAM_INT);
$course = $DB->get_record('course', array('id' => $courseid), '*', MUST_EXIST);
$context = context_course::instance($course->id, MUST_EXIST);
+$plugin = enrol_get_plugin($type);
+if (!$plugin) {
+ throw new moodle_exception('invaliddata', 'error');
+}
+
require_login($course);
-require_capability('enrol/guest:config', $context);
+require_capability('enrol/' . $type . ':config', $context);
-$PAGE->set_url('/enrol/guest/edit.php', array('courseid' => $course->id, 'id' => $instanceid));
+$PAGE->set_url('/enrol/editinstance.php', array('courseid' => $course->id, 'id' => $instanceid, 'type' => $type));
$PAGE->set_pagelayout('admin');
$return = new moodle_url('/enrol/instances.php', array('id' => $course->id));
-if (!enrol_is_enabled('guest')) {
+if (!enrol_is_enabled($type)) {
redirect($return);
}
-$plugin = enrol_get_plugin('guest');
-
if ($instanceid) {
- $conditions = array('courseid' => $course->id, 'enrol' => 'guest', 'id' => $instanceid);
- $instance = $DB->get_record('enrol', $conditions, '*', MUST_EXIST);
+ $instance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => $type, 'id' => $instanceid), '*', MUST_EXIST);
+
} else {
require_capability('moodle/course:enrolconfig', $context);
// No instance yet, we have to add new instance.
$instance = (object)$plugin->get_instance_defaults();
$instance->id = null;
$instance->courseid = $course->id;
+ $instance->status = ENROL_INSTANCE_ENABLED; // Do not use default for automatically created instances here.
}
-$mform = new \enrol_guest\enrol_guest_edit_form(null, array($instance, $plugin));
-$mform->set_data($instance);
+$mform = new enrol_instance_edit_form(null, array($instance, $plugin, $context, $type));
if ($mform->is_cancelled()) {
redirect($return);
} else if ($data = $mform->get_data()) {
if ($instance->id) {
- $reset = ($instance->status != $data->status);
+ $reset = false;
+ if (isset($data->status)) {
+ $reset = ($instance->status != $data->status);
+ }
+
+ foreach ($data as $key => $value) {
+ $instance->$key = $value;
+ }
- $instance->status = $data->status;
- $instance->password = $data->password;
$instance->timemodified = time();
- $DB->update_record('enrol', $instance);
+
+ $plugin->update_instance($instance, $data);
if ($reset) {
$context->mark_dirty();
}
- \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
} else {
- $fields = array(
- 'status' => $data->status,
- 'password' => $data->password);
+ $fields = (array) $data;
$plugin->add_instance($course, $fields);
}
}
$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_guest'));
+$PAGE->set_title(get_string('pluginname', 'enrol_' . $type));
echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('pluginname', 'enrol_guest'));
+echo $OUTPUT->heading(get_string('pluginname', 'enrol_' . $type));
$mform->display();
echo $OUTPUT->footer();
--- /dev/null
+<?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/>.
+
+/**
+ * Adds new instance of enrol_plugin to specified course or edits current instance.
+ *
+ * @package core_enrol
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+require_once($CFG->libdir.'/formslib.php');
+
+/**
+ * Standard edit form shared by all enrol plugins.
+ *
+ * @package core_enrol
+ * @copyright 2015 Damyon Wiese
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+class enrol_instance_edit_form extends moodleform {
+
+ /**
+ * Called to define this moodle form
+ *
+ * @return void
+ */
+ public function definition() {
+ global $DB;
+
+ $mform = $this->_form;
+
+ list($instance, $plugin, $context, $type) = $this->_customdata;
+
+ $mform->addElement('header', 'header', get_string('pluginname', 'enrol_' . $type));
+
+ $plugin->edit_instance_form($instance, $mform, $context);
+
+ $mform->addElement('hidden', 'id');
+ $mform->setType('id', PARAM_INT);
+ $mform->addElement('hidden', 'courseid');
+ $mform->setType('courseid', PARAM_INT);
+
+ $mform->addElement('hidden', 'type');
+ $mform->setType('type', PARAM_COMPONENT);
+ $instance->type = $type;
+
+ $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
+
+ $this->set_data($instance);
+ }
+
+ /**
+ * Validate this form. Calls plugin validation method.
+ *
+ * @param array $data
+ * @param array $files
+ * @return array
+ */
+ public function validation($data, $files) {
+ $errors = parent::validation($data, $files);
+
+ list($instance, $plugin, $context, $type) = $this->_customdata;
+
+ $pluginerrors = $plugin->edit_instance_validation($data, $files, $instance, $context);
+
+ $errors = array_merge($errors, $pluginerrors);
+
+ return $errors;
+ }
+
+}
+++ /dev/null
-<?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/>.
-
-/**
- * Guest access plugin.
- *
- * Adds new instance of enrol_guest to specified course
- * or edits current instance.
- *
- * @package enrol_guest
- * @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-namespace enrol_guest;
-use moodleform;
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once($CFG->libdir.'/formslib.php');
-
-/**
- * Class enrol_guest_edit_form
- * @copyright 2015 Andrew Hancox <andrewdchancox@googlemail.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-class enrol_guest_edit_form extends moodleform {
- /**
- * Form definition
- */
- public function definition() {
-
- $mform = $this->_form;
-
- list($instance, $plugin) = $this->_customdata;
-
- $mform->addElement('header', 'header', get_string('pluginname', 'enrol_guest'));
-
- $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
- ENROL_INSTANCE_DISABLED => get_string('no'));
- $mform->addElement('select', 'status', get_string('status', 'enrol_guest'), $options);
- $mform->addHelpButton('status', 'status', 'enrol_guest');
- $mform->setDefault('status', $plugin->get_config('status'));
- $mform->setAdvanced('status', $plugin->get_config('status_adv'));
-
- $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_guest'));
- $mform->addHelpButton('password', 'password', 'enrol_guest');
-
- // If we have a new instance and the password is required - make sure it is set. For existing
- // instances we do not force the password to be required as it may have been set to empty before
- // the password was required. We check in the validation function whether this check is required
- // for existing instances.
- if (empty($instance->id) && $plugin->get_config('requirepassword')) {
- $mform->addRule('password', get_string('required'), 'required', null);
- }
-
- $mform->addElement('hidden', 'id');
- $mform->setType('id', PARAM_INT);
- $mform->addElement('hidden', 'courseid');
- $mform->setType('courseid', PARAM_INT);
-
- $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
- }
-
- /**
- * Form validation
- *
- * @param array $data
- * @param array $files
- * @return array
- */
- public function validation($data, $files) {
- $errors = parent::validation($data, $files);
-
- list($instance, $plugin) = $this->_customdata;
- $checkpassword = false;
-
- if ($data['id']) {
- // Check the password if we are enabling the plugin again.
- if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) {
- $checkpassword = true;
- }
-
- // Check the password if the instance is enabled and the password has changed.
- if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) {
- $checkpassword = true;
- }
- } else {
- $checkpassword = true;
- }
-
- if ($checkpassword) {
- $require = $plugin->get_config('requirepassword');
- $policy = $plugin->get_config('usepasswordpolicy');
- if ($require && trim($data['password']) === '') {
- $errors['password'] = get_string('required');
- } else if (!empty($data['password']) && $policy) {
- $errmsg = '';
- if (!check_password_policy($data['password'], $errmsg)) {
- $errors['password'] = $errmsg;
- }
- }
- }
-
- return $errors;
- }
-}
return;
}
- /**
- * Sets up navigation entries.
- *
- * @param stdClass $instancesnode
- * @param stdClass $instance
- * @return void
- * @throws coding_exception
- */
- public function add_course_navigation($instancesnode, stdClass $instance) {
- if ($instance->enrol !== 'guest') {
- throw new coding_exception('Invalid enrol instance type!');
- }
-
- $context = context_course::instance($instance->courseid);
- if (has_capability('enrol/guest:config', $context)) {
- $managelink = new moodle_url('/enrol/guest/edit.php', array('courseid' => $instance->courseid, 'id' => $instance->id));
- $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
- }
- }
-
- /**
- * Returns edit icons for the page with list of instances
- * @param stdClass $instance
- * @return array
- * @throws coding_exception
- */
- public function get_action_icons(stdClass $instance) {
- global $OUTPUT;
-
- if ($instance->enrol !== 'guest') {
- throw new coding_exception('invalid enrol instance!');
- }
- $context = context_course::instance($instance->courseid);
-
- $icons = array();
-
- if (has_capability('enrol/guest:config', $context)) {
- $editlink = new moodle_url("/enrol/guest/edit.php", array('courseid' => $instance->courseid, 'id' => $instance->id));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
- }
-
- return $icons;
- }
-
/**
* Attempt to automatically gain temporary guest access to course,
* calling code has to make sure the plugin and instance are active.
}
/**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
+ * Returns true if the current user can add a new instance of enrolment plugin in course.
* @param int $courseid
- * @return moodle_url page url
+ * @return boolean
*/
- public function get_newinstance_link($courseid) {
+ public function can_add_instance($courseid) {
global $DB;
$context = context_course::instance($courseid, MUST_EXIST);
if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/guest:config', $context)) {
- return NULL;
+ return false;
}
if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'guest'))) {
- return NULL;
+ return false;
}
- return new moodle_url('/enrol/guest/edit.php', array('courseid' => $courseid));
+ return true;
}
/**
}
return $instanceinfo;
}
+
+ /**
+ * Return an array of valid options for the status.
+ *
+ * @return array
+ */
+ protected function get_status_options() {
+ $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
+ ENROL_INSTANCE_DISABLED => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $context
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
+ global $CFG;
+
+ $options = $this->get_status_options();
+ $mform->addElement('select', 'status', get_string('status', 'enrol_guest'), $options);
+ $mform->addHelpButton('status', 'status', 'enrol_guest');
+ $mform->setDefault('status', $this->get_config('status'));
+ $mform->setAdvanced('status', $this->get_config('status_adv'));
+
+ $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_guest'));
+ $mform->addHelpButton('password', 'password', 'enrol_guest');
+
+ // If we have a new instance and the password is required - make sure it is set. For existing
+ // instances we do not force the password to be required as it may have been set to empty before
+ // the password was required. We check in the validation function whether this check is required
+ // for existing instances.
+ if (empty($instance->id) && $this->get_config('requirepassword')) {
+ $mform->addRule('password', get_string('required'), 'required', null);
+ }
+ }
+
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ $errors = array();
+
+ $checkpassword = false;
+
+ if ($data['id']) {
+ // Check the password if we are enabling the plugin again.
+ if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) {
+ $checkpassword = true;
+ }
+
+ // Check the password if the instance is enabled and the password has changed.
+ if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) {
+ $checkpassword = true;
+ }
+ } else {
+ $checkpassword = true;
+ }
+
+ if ($checkpassword) {
+ $require = $this->get_config('requirepassword');
+ $policy = $this->get_config('usepasswordpolicy');
+ if ($require && trim($data['password']) === '') {
+ $errors['password'] = get_string('required');
+ } else if (!empty($data['password']) && $policy) {
+ $errmsg = '';
+ if (!check_password_policy($data['password'], $errmsg)) {
+ $errors['password'] = $errmsg;
+ }
+ }
+ }
+
+ $validstatus = array_keys($this->get_status_options());
+ $tovalidate = array(
+ 'status' => $validstatus
+ );
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
+
+
}
return $errors;
}
-}
\ No newline at end of file
+}
// access security is in each plugin
$candidates = array();
foreach (enrol_get_plugins(true) as $name=>$plugin) {
- if (!$link = $plugin->get_newinstance_link($course->id)) {
- continue;
+ if ($plugin->use_standard_editing_ui()) {
+ if ($plugin->can_add_instance($course->id)) {
+ // Standard add/edit UI.
+ $params = array('type' => $name, 'courseid' => $course->id);
+ $url = new moodle_url('/enrol/editinstance.php', $params);
+ $link = $url->out(false);
+ $candidates[$link] = get_string('pluginname', 'enrol_'.$name);
+ }
+ } else if ($url = $plugin->get_newinstance_link($course->id)) {
+ // Old custom UI.
+ $link = $url->out(false);
+ $candidates[$link] = get_string('pluginname', 'enrol_'.$name);
}
- $candidates[$link->out(false)] = get_string('pluginname', 'enrol_'.$name);
}
if ($candidates) {
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_manual to specified course
- * or edits current instance.
- *
- * @package enrol_manual
- * @copyright 2010 Petr Skoda {@link http://skodak.org}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require('../../config.php');
-require_once('edit_form.php');
-
-$courseid = required_param('courseid', PARAM_INT);
-
-$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-require_login($course);
-require_capability('enrol/manual:config', $context);
-
-$PAGE->set_url('/enrol/manual/edit.php', array('courseid'=>$course->id));
-$PAGE->set_pagelayout('admin');
-
-$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id));
-if (!enrol_is_enabled('manual')) {
- redirect($return);
-}
-
-$plugin = enrol_get_plugin('manual');
-
-if ($instances = $DB->get_records('enrol', array('courseid'=>$course->id, 'enrol'=>'manual'), 'id ASC')) {
- $instance = array_shift($instances);
- if ($instances) {
- // Oh - we allow only one instance per course!!
- foreach ($instances as $del) {
- $plugin->delete_instance($del);
- }
- }
- // Merge these two settings to one value for the single selection element.
- if ($instance->notifyall and $instance->expirynotify) {
- $instance->expirynotify = 2;
- }
- unset($instance->notifyall);
-
-} else {
- require_capability('moodle/course:enrolconfig', $context);
- // No instance yet, we have to add new instance.
- navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
- $instance = new stdClass();
- $instance->id = null;
- $instance->courseid = $course->id;
- $instance->expirynotify = $plugin->get_config('expirynotify');
- $instance->expirythreshold = $plugin->get_config('expirythreshold');
-}
-
-$mform = new enrol_manual_edit_form(null, array($instance, $plugin, $context));
-
-if ($mform->is_cancelled()) {
- redirect($return);
-
-} else if ($data = $mform->get_data()) {
- if ($data->expirynotify == 2) {
- $data->expirynotify = 1;
- $data->notifyall = 1;
- } else {
- $data->notifyall = 0;
- }
- if (!$data->expirynotify) {
- // Keep previous/default value of disabled expirythreshold option.
- $data->expirythreshold = $instance->expirythreshold;
- }
- if ($instance->id) {
- $instance->roleid = $data->roleid;
- $instance->enrolperiod = $data->enrolperiod;
- $instance->expirynotify = $data->expirynotify;
- $instance->notifyall = $data->notifyall;
- $instance->expirythreshold = $data->expirythreshold;
- $instance->timemodified = time();
- $markdirty = ($instance->status != $data->status);
- $instance->status = $data->status;
-
- $DB->update_record('enrol', $instance);
- \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
-
- if ($markdirty) {
- $context->mark_dirty();
- }
-
- } else {
- $fields = array(
- 'status' => $data->status,
- 'roleid' => $data->roleid,
- 'enrolperiod' => $data->enrolperiod,
- 'expirynotify' => $data->expirynotify,
- 'notifyall' => $data->notifyall,
- 'expirythreshold' => $data->expirythreshold);
- $plugin->add_instance($course, $fields);
- }
-
- redirect($return);
-}
-
-$PAGE->set_title(get_string('pluginname', 'enrol_manual'));
-$PAGE->set_heading($course->fullname);
-
-echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('pluginname', 'enrol_manual'));
-$mform->display();
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_manual to specified course
- * or edits current instance.
- *
- * @package enrol_manual
- * @copyright 2010 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.'/formslib.php');
-
-class enrol_manual_edit_form extends moodleform {
-
- function definition() {
- $mform = $this->_form;
-
- list($instance, $plugin, $context) = $this->_customdata;
-
- $mform->addElement('header', 'header', get_string('pluginname', 'enrol_manual'));
-
- $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
- ENROL_INSTANCE_DISABLED => get_string('no'));
- $mform->addElement('select', 'status', get_string('status', 'enrol_manual'), $options);
- $mform->addHelpButton('status', 'status', 'enrol_manual');
- $mform->setDefault('status', $plugin->get_config('status'));
-
- if ($instance->id) {
- $roles = get_default_enrol_roles($context, $instance->roleid);
- } else {
- $roles = get_default_enrol_roles($context, $plugin->get_config('roleid'));
- }
- $mform->addElement('select', 'roleid', get_string('defaultrole', 'role'), $roles);
- $mform->setDefault('roleid', $plugin->get_config('roleid'));
-
- $mform->addElement('duration', 'enrolperiod', get_string('defaultperiod', 'enrol_manual'), array('optional' => true, 'defaultunit' => 86400));
- $mform->setDefault('enrolperiod', $plugin->get_config('enrolperiod'));
- $mform->addHelpButton('enrolperiod', 'defaultperiod', 'enrol_manual');
-
- $options = array(0 => get_string('no'), 1 => get_string('expirynotifyenroller', 'core_enrol'), 2 => get_string('expirynotifyall', 'core_enrol'));
- $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options);
- $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol');
-
- $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), array('optional' => false, 'defaultunit' => 86400));
- $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol');
- $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0);
-
- $mform->addElement('hidden', 'courseid');
- $mform->setType('courseid', PARAM_INT);
-
- if (enrol_accessing_via_instance($instance)) {
- $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol'));
- }
-
- $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
-
- $this->set_data($instance);
- }
-
- function validation($data, $files) {
- global $DB;
-
- $errors = parent::validation($data, $files);
-
- if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) {
- $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol');
- }
-
- return $errors;
- }
-}
}
/**
- * Returns enrolment instance manage link.
+ * Return true if we can add a new instance to this course.
*
- * By defaults looks for manage.php file and tests for manage capability.
- *
- * @param navigation_node $instancesnode
- * @param stdClass $instance
- * @return moodle_url;
+ * @param int $courseid
+ * @return boolean
*/
- public function add_course_navigation($instancesnode, stdClass $instance) {
- if ($instance->enrol !== 'manual') {
- throw new coding_exception('Invalid enrol instance type!');
- }
-
- $context = context_course::instance($instance->courseid);
- if (has_capability('enrol/manual:config', $context)) {
- $managelink = new moodle_url('/enrol/manual/edit.php', array('courseid'=>$instance->courseid));
- $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
+ public function can_add_instance($courseid) {
+ $context = context_course::instance($courseid, MUST_EXIST);
+ if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/manual:config', $context)) {
+ return false;
}
+ // Multiple instances supported - multiple parent courses linked.
+ return true;
}
/**
public function get_action_icons(stdClass $instance) {
global $OUTPUT;
- if ($instance->enrol !== 'manual') {
- throw new coding_exception('invalid enrol instance!');
- }
$context = context_course::instance($instance->courseid);
$icons = array();
-
if (has_capability('enrol/manual:enrol', $context) or has_capability('enrol/manual:unenrol', $context)) {
$managelink = new moodle_url("/enrol/manual/manage.php", array('enrolid'=>$instance->id));
$icons[] = $OUTPUT->action_icon($managelink, new pix_icon('t/enrolusers', get_string('enrolusers', 'enrol_manual'), 'core', array('class'=>'iconsmall')));
}
- if (has_capability('enrol/manual:config', $context)) {
- $editlink = new moodle_url("/enrol/manual/edit.php", array('courseid'=>$instance->courseid));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
- }
+ $icons = $icons + parent::get_action_icons($instance);
return $icons;
}
- /**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
- * @param int $courseid
- * @return moodle_url page url
- */
- public function get_newinstance_link($courseid) {
- global $DB;
-
- $context = context_course::instance($courseid, MUST_EXIST);
-
- if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/manual:config', $context)) {
- return NULL;
- }
-
- if ($DB->record_exists('enrol', array('courseid'=>$courseid, 'enrol'=>'manual'))) {
- return NULL;
- }
-
- return new moodle_url('/enrol/manual/edit.php', array('courseid'=>$courseid));
- }
-
/**
* Add new instance of enrol plugin with default settings.
* @param stdClass $course
return parent::add_instance($course, $fields);
}
+ /**
+ * Update instance of enrol plugin.
+ * @param stdClass $instance
+ * @param stdClass $data modified instance fields
+ * @return boolean
+ */
+ public function update_instance($instance, $data) {
+ global $DB;
+
+ // Delete all other instances, leaving only one.
+ if ($instances = $DB->get_records('enrol', array('courseid' => $instance->courseid, 'enrol' => 'manual'), 'id ASC')) {
+ foreach ($instances as $anotherinstance) {
+ if ($anotherinstance->id != $instance->id) {
+ $this->delete_instance($anotherinstance);
+ }
+ }
+ }
+ return parent::update_instance($instance, $data);
+ }
+
/**
* Returns a button to manually enrol users through the manual enrolment plugin.
*
$this->enrol_user($instance, $userid, $roleid, $timestart, $timeend, $status, $recovergrades);
}
}
+
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Return an array of valid options for the status.
+ *
+ * @return array
+ */
+ protected function get_status_options() {
+ $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
+ ENROL_INSTANCE_DISABLED => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the roleid.
+ *
+ * @param stdClass $instance
+ * @param context $context
+ * @return array
+ */
+ protected function get_roleid_options($instance, $context) {
+ if ($instance->id) {
+ $roles = get_default_enrol_roles($context, $instance->roleid);
+ } else {
+ $roles = get_default_enrol_roles($context, $this->get_config('roleid'));
+ }
+ return $roles;
+ }
+
+ /**
+ * Return an array of valid options for the expirynotify.
+ *
+ * @return array
+ */
+ protected function get_expirynotify_options() {
+ $options = array(
+ 0 => get_string('no'),
+ 1 => get_string('expirynotifyenroller', 'core_enrol'),
+ 2 => get_string('expirynotifyall', 'core_enrol')
+ );
+ return $options;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $context
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
+
+ $options = $this->get_status_options();
+ $mform->addElement('select', 'status', get_string('status', 'enrol_manual'), $options);
+ $mform->addHelpButton('status', 'status', 'enrol_manual');
+ $mform->setDefault('status', $this->get_config('status'));
+
+ $roles = $this->get_roleid_options($instance, $context);
+ $mform->addElement('select', 'roleid', get_string('defaultrole', 'role'), $roles);
+ $mform->setDefault('roleid', $this->get_config('roleid'));
+
+ $options = array('optional' => true, 'defaultunit' => 86400);
+ $mform->addElement('duration', 'enrolperiod', get_string('defaultperiod', 'enrol_manual'), $options);
+ $mform->setDefault('enrolperiod', $this->get_config('enrolperiod'));
+ $mform->addHelpButton('enrolperiod', 'defaultperiod', 'enrol_manual');
+
+ $options = $this->get_expirynotify_options();
+ $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options);
+ $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol');
+
+ $options = array('optional' => false, 'defaultunit' => 86400);
+ $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), $options);
+ $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol');
+ $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0);
+
+ if (enrol_accessing_via_instance($instance)) {
+ $warntext = get_string('instanceeditselfwarningtext', 'core_enrol');
+ $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warntext);
+ }
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ $errors = array();
+
+ if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) {
+ $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol');
+ }
+
+ $validstatus = array_keys($this->get_status_options());
+ $validroles = array_keys($this->get_roleid_options($instance, $context));
+ $validexpirynotify = array_keys($this->get_expirynotify_options());
+
+ $tovalidate = array(
+ 'status' => $validstatus,
+ 'roleid' => $validroles,
+ 'enrolperiod' => PARAM_INT,
+ 'expirynotify' => $validexpirynotify,
+ 'expirythreshold' => PARAM_INT
+ );
+
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
+
}
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_meta to specified course.
- *
- * @package enrol_meta
- * @copyright 2010 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/enrol/meta/addinstance_form.php");
-require_once("$CFG->dirroot/enrol/meta/locallib.php");
-
-$id = required_param('id', PARAM_INT); // course id
-$message = optional_param('message', null, PARAM_TEXT);
-$instanceid = optional_param('enrolid', 0, PARAM_INT);
-
-$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-$PAGE->set_url('/enrol/meta/addinstance.php', array('id'=>$course->id));
-$PAGE->set_pagelayout('admin');
-
-navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-
-require_login($course);
-require_capability('moodle/course:enrolconfig', $context);
-
-$enrol = enrol_get_plugin('meta');
-if ($instanceid) {
- require_capability('enrol/meta:config', $context);
- $instance = $DB->get_record('enrol', array('courseid' => $course->id, 'enrol' => 'meta',
- 'id' => $instanceid), '*', MUST_EXIST);
-
-} else {
- if (!$enrol->get_newinstance_link($course->id)) {
- redirect(new moodle_url('/enrol/instances.php', array('id' => $course->id)));
- }
- $instance = null;
-}
-
-$mform = new enrol_meta_addinstance_form(null, array('course' => $course, 'instance' => $instance));
-
-if ($mform->is_cancelled()) {
- redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-
-} else if ($data = $mform->get_data()) {
- if (!empty($data->customint2) && $data->customint2 == ENROL_META_CREATE_GROUP) {
- $data->customint2 = enrol_meta_create_new_group($course->id, $data->link);
- }
- if ($instance) {
- if ($data->customint2 != $instance->customint2) {
- $DB->update_record('enrol', array('id' => $instance->id, 'customint2' => $data->customint2));
- enrol_meta_sync($course->id);
- }
- } else {
- $eid = $enrol->add_instance($course, array('customint1' => $data->link,
- 'customint2' => $data->customint2));
- enrol_meta_sync($course->id);
- if (!empty($data->submitbuttonnext)) {
- redirect(new moodle_url('/enrol/meta/addinstance.php',
- array('id' => $course->id, 'message' => 'added')));
- }
- }
- redirect(new moodle_url('/enrol/instances.php', array('id' => $course->id)));
-}
-
-$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_meta'));
-
-echo $OUTPUT->header();
-
-if ($message === 'added') {
- echo $OUTPUT->notification(get_string('instanceadded', 'enrol'), 'notifysuccess');
-}
-
-$mform->display();
-
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Adds instance form
- *
- * @package enrol_meta
- * @copyright 2010 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/formslib.php");
-
-class enrol_meta_addinstance_form extends moodleform {
- protected $course;
-
- function definition() {
- global $CFG, $DB;
-
- $mform = $this->_form;
- $course = $this->_customdata['course'];
- $instance = $this->_customdata['instance'];
- $this->course = $course;
-
- if ($instance) {
- $where = 'WHERE c.id = :courseid';
- $params = array('courseid' => $instance->customint1);
- $existing = array();
- } else {
- $where = '';
- $params = array();
- $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $course->id), '', 'customint1, id');
- }
-
- // TODO: this has to be done via ajax or else it will fail very badly on large sites!
- $courses = array('' => get_string('choosedots'));
- $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
- $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
-
- $plugin = enrol_get_plugin('meta');
- $sortorder = 'c.' . $plugin->get_config('coursesort', 'sortorder') . ' ASC';
-
- $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join $where ORDER BY $sortorder";
- $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE) + $params);
- foreach ($rs as $c) {
- if ($c->id == SITEID or $c->id == $course->id or isset($existing[$c->id])) {
- continue;
- }
- context_helper::preload_from_record($c);
- $coursecontext = context_course::instance($c->id);
- if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
- continue;
- }
- if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
- continue;
- }
- $courses[$c->id] = $coursecontext->get_context_name(false);
- }
- $rs->close();
-
- $groups = array(0 => get_string('none'));
- if (has_capability('moodle/course:managegroups', context_course::instance($course->id))) {
- $groups[ENROL_META_CREATE_GROUP] = get_string('creategroup', 'enrol_meta');
- }
- foreach (groups_get_all_groups($course->id) as $group) {
- $groups[$group->id] = format_string($group->name, true, array('context' => context_course::instance($course->id)));
- }
-
- $mform->addElement('header','general', get_string('pluginname', 'enrol_meta'));
-
- $mform->addElement('select', 'link', get_string('linkedcourse', 'enrol_meta'), $courses);
- $mform->addRule('link', get_string('required'), 'required', null, 'client');
-
- $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups);
-
- $mform->addElement('hidden', 'id', null);
- $mform->setType('id', PARAM_INT);
-
- $mform->addElement('hidden', 'enrolid');
- $mform->setType('enrolid', PARAM_INT);
-
- $data = array('id' => $course->id);
- if ($instance) {
- $data['link'] = $instance->customint1;
- $data['enrolid'] = $instance->id;
- $data['customint2'] = $instance->customint2;
- $mform->freeze('link');
- $this->add_action_buttons();
- } else {
- $this->add_add_buttons();
- }
- $this->set_data($data);
- }
-
- /**
- * Adds buttons on create new method form
- */
- protected function add_add_buttons() {
- $mform = $this->_form;
- $buttonarray = array();
- $buttonarray[0] = $mform->createElement('submit', 'submitbutton', get_string('addinstance', 'enrol'));
- $buttonarray[1] = $mform->createElement('submit', 'submitbuttonnext', get_string('addinstanceanother', 'enrol'));
- $buttonarray[2] = $mform->createElement('cancel');
- $mform->addGroup($buttonarray, 'buttonar', '', array(' '), false);
- $mform->closeHeaderBefore('buttonar');
- }
-
- function validation($data, $files) {
- global $DB, $CFG;
-
- $errors = parent::validation($data, $files);
-
- if ($this->_customdata['instance']) {
- // Nothing to validate in case of editing.
- return $errors;
- }
-
- // TODO: this is duplicated here because it may be necessary once we implement ajax course selection element
-
- if (!$c = $DB->get_record('course', array('id'=>$data['link']))) {
- $errors['link'] = get_string('required');
- } else {
- $coursecontext = context_course::instance($c->id);
- $existing = $DB->get_records('enrol', array('enrol'=>'meta', 'courseid'=>$this->course->id), '', 'customint1, id');
- if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
- $errors['link'] = get_string('error');
- } else if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
- $errors['link'] = get_string('error');
- } else if ($c->id == SITEID or $c->id == $this->course->id or isset($existing[$c->id])) {
- $errors['link'] = get_string('error');
- }
- }
-
- return $errors;
- }
-}
-
}
/**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
+ * Returns true if we can add a new instance to this course.
+ *
* @param int $courseid
- * @return moodle_url page url
+ * @return boolean
*/
- public function get_newinstance_link($courseid) {
+ public function can_add_instance($courseid) {
$context = context_course::instance($courseid, MUST_EXIST);
if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/meta:config', $context)) {
- return NULL;
+ return false;
}
- // multiple instances supported - multiple parent courses linked
- return new moodle_url('/enrol/meta/addinstance.php', array('id'=>$courseid));
+ // Multiple instances supported - multiple parent courses linked.
+ return true;
}
/**
// We should probably add some sync button to the course enrol methods overview page.
}
+ /**
+ * Add new instance of enrol plugin.
+ * @param object $course
+ * @param array $fields instance fields
+ * @return int id of new instance, null if can not be created
+ */
+ public function add_instance($course, array $fields = null) {
+ global $CFG;
+
+ require_once("$CFG->dirroot/enrol/meta/locallib.php");
+
+ if (!empty($fields['customint2']) && $fields['customint2'] == ENROL_META_CREATE_GROUP) {
+ $context = context_course::instance($course->id);
+ require_capability('moodle/course:managegroups', $context);
+ $groupid = enrol_meta_create_new_group($course->id, $fields['customint1']);
+ $fields['customint2'] = $groupid;
+ }
+
+ $result = parent::add_instance($course, $fields);
+
+ enrol_meta_sync($course->id);
+
+ return $result;
+ }
+
+ /**
+ * Update instance of enrol plugin.
+ * @param stdClass $instance
+ * @param stdClass $data modified instance fields
+ * @return boolean
+ */
+ public function update_instance($instance, $data) {
+ global $CFG;
+
+ require_once("$CFG->dirroot/enrol/meta/locallib.php");
+
+ if (!empty($data->customint2) && $data->customint2 == ENROL_META_CREATE_GROUP) {
+ $context = context_course::instance($instance->courseid);
+ require_capability('moodle/course:managegroups', $context);
+ $groupid = enrol_meta_create_new_group($instance->courseid, $data->customint1);
+ $data->customint2 = $groupid;
+ }
+
+ $result = parent::update_instance($instance, $data);
+
+ enrol_meta_sync($instance->courseid);
+
+ return $result;
+ }
+
/**
* Update instance status
*
return has_capability('enrol/meta:config', $context);
}
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Return an array of valid options for the courses.
+ *
+ * @param stdClass $instance
+ * @param context $coursecontext
+ * @return array
+ */
+ protected function get_course_options($instance, $coursecontext) {
+ global $DB;
+
+ if ($instance->id) {
+ $where = 'WHERE c.id = :courseid';
+ $params = array('courseid' => $instance->customint1);
+ $existing = array();
+ } else {
+ $where = '';
+ $params = array();
+ $instanceparams = array('enrol' => 'meta', 'courseid' => $instance->courseid);
+ $existing = $DB->get_records('enrol', $instanceparams, '', 'customint1, id');
+ }
+
+ // TODO: this has to be done via ajax or else it will fail very badly on large sites!
+ $courses = array('' => get_string('choosedots'));
+ $select = ', ' . context_helper::get_preload_record_columns_sql('ctx');
+ $join = "LEFT JOIN {context} ctx ON (ctx.instanceid = c.id AND ctx.contextlevel = :contextlevel)";
+
+ $sortorder = 'c.' . $this->get_config('coursesort', 'sortorder') . ' ASC';
+
+ $sql = "SELECT c.id, c.fullname, c.shortname, c.visible $select FROM {course} c $join $where ORDER BY $sortorder";
+ $rs = $DB->get_recordset_sql($sql, array('contextlevel' => CONTEXT_COURSE) + $params);
+ foreach ($rs as $c) {
+ if ($c->id == SITEID or $c->id == $instance->courseid or isset($existing[$c->id])) {
+ continue;
+ }
+ context_helper::preload_from_record($c);
+ $coursecontext = context_course::instance($c->id);
+ if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
+ continue;
+ }
+ if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
+ continue;
+ }
+ $courses[$c->id] = $coursecontext->get_context_name(false);
+ }
+ $rs->close();
+ return $courses;
+ }
+
+ /**
+ * Return an array of valid options for the groups.
+ *
+ * @param context $coursecontext
+ * @return array
+ */
+ protected function get_group_options($coursecontext) {
+ $groups = array(0 => get_string('none'));
+ $courseid = $coursecontext->instanceid;
+ if (has_capability('moodle/course:managegroups', $coursecontext)) {
+ $groups[ENROL_META_CREATE_GROUP] = get_string('creategroup', 'enrol_meta');
+ }
+ foreach (groups_get_all_groups($courseid) as $group) {
+ $groups[$group->id] = format_string($group->name, true, array('context' => $coursecontext));
+ }
+ return $groups;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $coursecontext
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $coursecontext) {
+ global $DB;
+
+ $courses = $this->get_course_options($instance, $coursecontext);
+ $groups = $this->get_group_options($coursecontext);
+
+ $mform->addElement('select', 'customint1', get_string('linkedcourse', 'enrol_meta'), $courses);
+ $mform->addRule('customint1', get_string('required'), 'required', null, 'client');
+ if (!empty($instance->id)) {
+ $mform->freeze('customint1');
+ }
+
+ $mform->addElement('select', 'customint2', get_string('addgroup', 'enrol_meta'), $groups);
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ global $DB;
+ $errors = array();
+ $thiscourseid = $context->instanceid;
+ $c = false;
+
+ if (!empty($data['customint1'])) {
+ $c = $DB->get_record('course', array('id' => $data['customint1']));
+ }
+
+ if (!$c) {
+ $errors['customint1'] = get_string('required');
+ } else {
+ $coursecontext = context_course::instance($c->id);
+ $existing = $DB->get_records('enrol', array('enrol' => 'meta', 'courseid' => $thiscourseid), '', 'customint1, id');
+ if (!$c->visible and !has_capability('moodle/course:viewhiddencourses', $coursecontext)) {
+ $errors['customint1'] = get_string('error');
+ } else if (!has_capability('enrol/meta:selectaslinked', $coursecontext)) {
+ $errors['customint1'] = get_string('error');
+ } else if ($c->id == SITEID or $c->id == $thiscourseid or isset($existing[$c->id])) {
+ $errors['customint1'] = get_string('error');
+ }
+ }
+
+ $validcourses = array_keys($this->get_course_options($instance, $context));
+ $validgroups = array_keys($this->get_group_options($context));
+
+ $tovalidate = array(
+ 'customint1' => $validcourses,
+ 'customint2' => $validgroups
+ );
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
+
+
/**
* Restore instance and map settings.
*
return;
}
- /**
- * Returns edit icons for the page with list of instances.
- * @param stdClass $instance
- * @return array
- */
- public function get_action_icons(stdClass $instance) {
- global $OUTPUT;
-
- if ($instance->enrol !== 'meta') {
- throw new coding_exception('invalid enrol instance!');
- }
- $context = context_course::instance($instance->courseid);
-
- $icons = array();
-
- if (has_capability('enrol/meta:config', $context)) {
- $editlink = new moodle_url("/enrol/meta/addinstance.php",
- array('id' => $instance->courseid, 'enrolid' => $instance->id));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
- }
-
- return $icons;
- }
}
Scenario: Add meta enrolment instance with groups
When I follow "Course 3"
And I navigate to "Enrolment methods" node in "Course administration > Users"
- And I set the field "Add method" to "Course meta link"
- And I press "Go"
+ And I select "Course meta link" from the "Add method" singleselect
And I set the following fields to these values:
| Link course | Course 1 |
| Add to group | Groupcourse 1 |
- And I press "Add method and create another"
+ And I press "Add method"
+ And I set the field "Add method" to "Course meta link"
+ And I press "Go"
And I set the following fields to these values:
| Link course | Course 2 |
| Add to group | Groupcourse 2 |
And I set the following fields to these values:
| Link course | Course 1 |
| Add to group | Groupcourse 1 |
- And I press "Add method and create another"
+ And I press "Add method"
+ And I select "Course meta link" from the "Add method" singleselect
And I set the following fields to these values:
| Link course | Course 2 |
And I press "Add method"
$this->assertEquals(7, $DB->count_records('user_enrolments'));
$this->assertEquals(6, $DB->count_records('role_assignments'));
+ // Disable the plugin to prevent add_instance from calling enrol_meta_sync.
+ $this->disable_plugin();
$e1 = $metalplugin->add_instance($course3, array('customint1'=>$course1->id));
$e2 = $metalplugin->add_instance($course3, array('customint1'=>$course2->id));
$e3 = $metalplugin->add_instance($course4, array('customint1'=>$course2->id));
$enrol1 = $DB->get_record('enrol', array('id'=>$e1));
$enrol2 = $DB->get_record('enrol', array('id'=>$e2));
$enrol3 = $DB->get_record('enrol', array('id'=>$e3));
+ $this->enable_plugin();
enrol_meta_sync($course4->id, false);
$this->assertEquals(9, $DB->count_records('user_enrolments'));
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_mnet into the specified course
- *
- * @package enrol_mnet
- * @copyright 2010 David Mudrak <david@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require(dirname(dirname(dirname(__FILE__))).'/config.php');
-require_once($CFG->dirroot.'/enrol/mnet/addinstance_form.php');
-require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php');
-
-$id = required_param('id', PARAM_INT); // course id
-
-$course = $DB->get_record('course', array('id'=>$id), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-require_login($course);
-require_capability('moodle/course:enrolconfig', $context);
-
-$PAGE->set_url('/enrol/mnet/addinstance.php', array('id'=>$course->id));
-$PAGE->set_pagelayout('standard');
-
-// Try and make the manage instances node on the navigation active
-$courseadmin = $PAGE->settingsnav->get('courseadmin');
-if ($courseadmin && $courseadmin->get('users') && $courseadmin->get('users')->get('manageinstances')) {
- $courseadmin->get('users')->get('manageinstances')->make_active();
-}
-
-$enrol = enrol_get_plugin('mnet');
-// make sure we were allowed to get here form the Enrolment methods page
-if (!$enrol->get_newinstance_link($course->id)) {
- redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-}
-$service = mnetservice_enrol::get_instance();
-$mform = new enrol_mnet_addinstance_form(null, array('course'=>$course, 'enrol'=>$enrol, 'service'=>$service));
-
-if ($mform->is_cancelled()) {
- redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-
-} else if ($data = $mform->get_data()) {
- $enrol->add_instance($course, array('customint1'=>$data->hostid, 'roleid'=>$data->roleid, 'name'=>$data->name));
- redirect(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-}
-
-$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_mnet'));
-
-echo $OUTPUT->header();
-$mform->display();
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Form to add an instance of enrol_mnet plugin
- *
- * @package enrol_mnet
- * @copyright 2010 David Mudrak <david@moodle.com>
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-defined('MOODLE_INTERNAL') || die();
-
-require_once("$CFG->libdir/formslib.php");
-
-class enrol_mnet_addinstance_form extends moodleform {
- function definition() {
- global $CFG, $DB;
-
- $mform = $this->_form;
- $course = $this->_customdata['course'];
- $enrol = $this->_customdata['enrol'];
- $service = $this->_customdata['service'];
- $coursecontext = context_course::instance($course->id);
-
- $subscribers = $service->get_remote_subscribers();
- $hosts = array(0 => get_string('remotesubscribersall', 'enrol_mnet'));
- foreach ($subscribers as $hostid => $subscriber) {
- $hosts[$hostid] = $subscriber->appname.': '.$subscriber->hostname.' ('.$subscriber->hosturl.')';
- }
- $roles = get_assignable_roles($coursecontext);
-
- $mform->addElement('header','general', get_string('pluginname', 'enrol_mnet'));
-
- $mform->addElement('select', 'hostid', get_string('remotesubscriber', 'enrol_mnet'), $hosts);
- $mform->addHelpButton('hostid', 'remotesubscriber', 'enrol_mnet');
- $mform->addRule('hostid', get_string('required'), 'required', null, 'client');
-
- $mform->addElement('select', 'roleid', get_string('roleforremoteusers', 'enrol_mnet'), $roles);
- $mform->addHelpButton('roleid', 'roleforremoteusers', 'enrol_mnet');
- $mform->addRule('roleid', get_string('required'), 'required', null, 'client');
- $mform->setDefault('roleid', $enrol->get_config('roleid'));
-
- $mform->addElement('text', 'name', get_string('instancename', 'enrol_mnet'));
- $mform->addHelpButton('name', 'instancename', 'enrol_mnet');
- $mform->setType('name', PARAM_TEXT);
-
- $mform->addElement('hidden', 'id', null);
- $mform->setType('id', PARAM_INT);
-
- $this->add_action_buttons();
-
- $this->set_data(array('id'=>$course->id));
- }
-
- /**
- * Do not allow multiple instances for single remote host
- *
- * @param array $data raw form data
- * @param array $files
- * @return array of errors
- */
- function validation($data, $files) {
- global $DB;
-
- $errors = array();
-
- if ($DB->record_exists('enrol', array('enrol' => 'mnet', 'courseid' => $data['id'], 'customint1' => $data['hostid']))) {
- $errors['hostid'] = get_string('error_multiplehost', 'enrol_mnet');
- }
-
- return $errors;
- }
-}
}
/**
- * Returns link to page which may be used to add new instance of enrolment plugin into the course
+ * Returns true if a new instance can be added to this course.
*
* The link is returned only if there are some MNet peers that we publish enrolment service to.
*
* @param int $courseid id of the course to add the instance to
- * @return moodle_url|null page url or null if instance can not be created
+ * @return boolean
*/
- public function get_newinstance_link($courseid) {
+ public function can_add_instance($courseid) {
global $CFG, $DB;
require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php');
$service = mnetservice_enrol::get_instance();
if (!$service->is_available()) {
- return null;
+ return false;
}
$coursecontext = context_course::instance($courseid);
if (!has_capability('moodle/course:enrolconfig', $coursecontext)) {
- return null;
+ return false;
}
$subscribers = $service->get_remote_subscribers();
if (empty($subscribers)) {
- return null;
+ return false;
}
- return new moodle_url('/enrol/mnet/addinstance.php', array('id'=>$courseid));
+ return true;
}
/**
$context = context_course::instance($instance->courseid);
return has_capability('enrol/mnet:config', $context);
}
+
+ /**
+ * Return an array of valid options for the hosts property.
+ *
+ * @return array
+ */
+ protected function get_valid_hosts_options() {
+ global $CFG;
+ require_once($CFG->dirroot.'/mnet/service/enrol/locallib.php');
+
+ $service = mnetservice_enrol::get_instance();
+
+ $subscribers = $service->get_remote_subscribers();
+ $hosts = array(0 => get_string('remotesubscribersall', 'enrol_mnet'));
+ foreach ($subscribers as $hostid => $subscriber) {
+ $hosts[$hostid] = $subscriber->appname.': '.$subscriber->hostname.' ('.$subscriber->hosturl.')';
+ }
+ return $hosts;
+ }
+
+ /**
+ * Return an array of valid options for the roles property.
+ *
+ * @param context $context
+ * @return array
+ */
+ protected function get_valid_roles_options($context) {
+ $roles = get_assignable_roles($context);
+ return $roles;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $context
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
+ global $CFG;
+
+ $hosts = $this->get_valid_hosts_options();
+ $mform->addElement('select', 'customint1', get_string('remotesubscriber', 'enrol_mnet'), $hosts);
+ $mform->addHelpButton('customint1', 'remotesubscriber', 'enrol_mnet');
+ $mform->addRule('customint1', get_string('required'), 'required', null, 'client');
+
+ $roles = $this->get_valid_roles_options($context);
+ $mform->addElement('select', 'roleid', get_string('roleforremoteusers', 'enrol_mnet'), $roles);
+ $mform->addHelpButton('roleid', 'roleforremoteusers', 'enrol_mnet');
+ $mform->addRule('roleid', get_string('required'), 'required', null, 'client');
+ $mform->setDefault('roleid', $this->get_config('roleid'));
+
+ $mform->addElement('text', 'name', get_string('instancename', 'enrol_mnet'));
+ $mform->addHelpButton('name', 'instancename', 'enrol_mnet');
+ $mform->setType('name', PARAM_TEXT);
+ }
+
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ global $DB;
+ $errors = array();
+
+ $validroles = array_keys($this->get_valid_roles_options($context));
+ $validhosts = array_keys($this->get_valid_hosts_options());
+
+ $params = array('enrol' => 'mnet', 'courseid' => $instance->courseid, 'customint1' => $data['customint1']);
+ if ($DB->record_exists('enrol', $params)) {
+ $errors['customint1'] = get_string('error_multiplehost', 'enrol_mnet');
+ }
+
+ $tovalidate = array(
+ 'customint1' => $validhosts,
+ 'roleid' => $validroles,
+ 'name' => PARAM_TEXT
+ );
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
}
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_paypal to specified course
- * or edits current instance.
- *
- * @package enrol_paypal
- * @copyright 2010 Petr Skoda {@link http://skodak.org}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require('../../config.php');
-require_once('edit_form.php');
-
-$courseid = required_param('courseid', PARAM_INT);
-$instanceid = optional_param('id', 0, PARAM_INT); // instanceid
-
-$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-require_login($course);
-require_capability('enrol/paypal:config', $context);
-
-$PAGE->set_url('/enrol/paypal/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid));
-$PAGE->set_pagelayout('admin');
-
-$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id));
-if (!enrol_is_enabled('paypal')) {
- redirect($return);
-}
-
-$plugin = enrol_get_plugin('paypal');
-
-if ($instanceid) {
- $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'paypal', 'id'=>$instanceid), '*', MUST_EXIST);
- $instance->cost = format_float($instance->cost, 2, true);
-} else {
- require_capability('moodle/course:enrolconfig', $context);
- // no instance yet, we have to add new instance
- navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
- $instance = new stdClass();
- $instance->id = null;
- $instance->courseid = $course->id;
-}
-
-$mform = new enrol_paypal_edit_form(NULL, array($instance, $plugin, $context));
-
-if ($mform->is_cancelled()) {
- redirect($return);
-
-} else if ($data = $mform->get_data()) {
- if ($instance->id) {
- $reset = ($instance->status != $data->status);
-
- $instance->status = $data->status;
- $instance->name = $data->name;
- $instance->cost = unformat_float($data->cost);
- $instance->currency = $data->currency;
- $instance->roleid = $data->roleid;
- $instance->enrolperiod = $data->enrolperiod;
- $instance->enrolstartdate = $data->enrolstartdate;
- $instance->enrolenddate = $data->enrolenddate;
- $instance->timemodified = time();
- $DB->update_record('enrol', $instance);
- \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
-
- if ($reset) {
- $context->mark_dirty();
- }
-
- } else {
- $fields = array('status'=>$data->status, 'name'=>$data->name, 'cost'=>unformat_float($data->cost), 'currency'=>$data->currency, 'roleid'=>$data->roleid,
- 'enrolperiod'=>$data->enrolperiod, 'enrolstartdate'=>$data->enrolstartdate, 'enrolenddate'=>$data->enrolenddate);
- $plugin->add_instance($course, $fields);
- }
-
- redirect($return);
-}
-
-$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_paypal'));
-
-echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('pluginname', 'enrol_paypal'));
-$mform->display();
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_paypal to specified course
- * or edits current instance.
- *
- * @package enrol_paypal
- * @copyright 2010 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.'/formslib.php');
-
-class enrol_paypal_edit_form extends moodleform {
-
- function definition() {
- $mform = $this->_form;
-
- list($instance, $plugin, $context) = $this->_customdata;
-
- $mform->addElement('header', 'header', get_string('pluginname', 'enrol_paypal'));
-
- $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
- $mform->setType('name', PARAM_TEXT);
-
- $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
- ENROL_INSTANCE_DISABLED => get_string('no'));
- $mform->addElement('select', 'status', get_string('status', 'enrol_paypal'), $options);
- $mform->setDefault('status', $plugin->get_config('status'));
-
- $mform->addElement('text', 'cost', get_string('cost', 'enrol_paypal'), array('size'=>4));
- $mform->setType('cost', PARAM_RAW); // Use unformat_float to get real value.
- $mform->setDefault('cost', format_float($plugin->get_config('cost'), 2, true));
-
- $paypalcurrencies = $plugin->get_currencies();
- $mform->addElement('select', 'currency', get_string('currency', 'enrol_paypal'), $paypalcurrencies);
- $mform->setDefault('currency', $plugin->get_config('currency'));
-
- if ($instance->id) {
- $roles = get_default_enrol_roles($context, $instance->roleid);
- } else {
- $roles = get_default_enrol_roles($context, $plugin->get_config('roleid'));
- }
- $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_paypal'), $roles);
- $mform->setDefault('roleid', $plugin->get_config('roleid'));
-
-
- $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_paypal'), array('optional' => true, 'defaultunit' => 86400));
- $mform->setDefault('enrolperiod', $plugin->get_config('enrolperiod'));
- $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_paypal');
-
- $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_paypal'), array('optional' => true));
- $mform->setDefault('enrolstartdate', 0);
- $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_paypal');
-
- $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_paypal'), array('optional' => true));
- $mform->setDefault('enrolenddate', 0);
- $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_paypal');
-
- $mform->addElement('hidden', 'id');
- $mform->setType('id', PARAM_INT);
-
- $mform->addElement('hidden', 'courseid');
- $mform->setType('courseid', PARAM_INT);
-
- if (enrol_accessing_via_instance($instance)) {
- $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol'));
- }
-
- $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
-
- $this->set_data($instance);
- }
-
- function validation($data, $files) {
- global $DB, $CFG;
- $errors = parent::validation($data, $files);
-
- list($instance, $plugin, $context) = $this->_customdata;
-
- if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
- $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_paypal');
- }
-
- $cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']);
- if (!is_numeric($cost)) {
- $errors['cost'] = get_string('costerror', 'enrol_paypal');
- }
-
- return $errors;
- }
-}
}
/**
- * Sets up navigation entries.
- *
- * @param object $instance
- * @return void
+ * Returns true if the user can add a new instance in this course.
+ * @param int $courseid
+ * @return boolean
*/
- public function add_course_navigation($instancesnode, stdClass $instance) {
- if ($instance->enrol !== 'paypal') {
- throw new coding_exception('Invalid enrol instance type!');
- }
+ public function can_add_instance($courseid) {
+ $context = context_course::instance($courseid, MUST_EXIST);
- $context = context_course::instance($instance->courseid);
- if (has_capability('enrol/paypal:config', $context)) {
- $managelink = new moodle_url('/enrol/paypal/edit.php', array('courseid'=>$instance->courseid, 'id'=>$instance->id));
- $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
+ if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) {
+ return false;
}
+
+ // multiple instances supported - different cost for different roles
+ return true;
}
/**
- * Returns edit icons for the page with list of instances
- * @param stdClass $instance
- * @return array
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
*/
- public function get_action_icons(stdClass $instance) {
- global $OUTPUT;
-
- if ($instance->enrol !== 'paypal') {
- throw new coding_exception('invalid enrol instance!');
- }
- $context = context_course::instance($instance->courseid);
-
- $icons = array();
+ public function use_standard_editing_ui() {
+ return true;
+ }
- if (has_capability('enrol/paypal:config', $context)) {
- $editlink = new moodle_url("/enrol/paypal/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
+ /**
+ * Add new instance of enrol plugin.
+ * @param object $course
+ * @param array $fields instance fields
+ * @return int id of new instance, null if can not be created
+ */
+ public function add_instance($course, array $fields = null) {
+ if ($fields && !empty($fields['cost'])) {
+ $fields['cost'] = unformat_float($fields['cost']);
}
-
- return $icons;
+ return parent::add_instance($course, $fields);
}
/**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
- * @param int $courseid
- * @return moodle_url page url
+ * Update instance of enrol plugin.
+ * @param stdClass $instance
+ * @param stdClass $data modified instance fields
+ * @return boolean
*/
- public function get_newinstance_link($courseid) {
- $context = context_course::instance($courseid, MUST_EXIST);
-
- if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/paypal:config', $context)) {
- return NULL;
+ public function update_instance($instance, $data) {
+ if ($data) {
+ $data->cost = unformat_float($data->cost);
}
-
- // multiple instances supported - different cost for different roles
- return new moodle_url('/enrol/paypal/edit.php', array('courseid'=>$courseid));
+ return parent::update_instance($instance, $data);
}
/**
$this->process_expirations($trace);
}
+ /**
+ * Return an array of valid options for the status.
+ *
+ * @return array
+ */
+ protected function get_status_options() {
+ $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
+ ENROL_INSTANCE_DISABLED => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the roleid.
+ *
+ * @param stdClass $instance
+ * @param context $context
+ * @return array
+ */
+ protected function get_roleid_options($instance, $context) {
+ if ($instance->id) {
+ $roles = get_default_enrol_roles($context, $instance->roleid);
+ } else {
+ $roles = get_default_enrol_roles($context, $this->get_config('roleid'));
+ }
+ return $roles;
+ }
+
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $context
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
+
+ $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'));
+ $mform->setType('name', PARAM_TEXT);
+
+ $options = $this->get_status_options();
+ $mform->addElement('select', 'status', get_string('status', 'enrol_paypal'), $options);
+ $mform->setDefault('status', $this->get_config('status'));
+
+ $mform->addElement('text', 'cost', get_string('cost', 'enrol_paypal'), array('size' => 4));
+ $mform->setType('cost', PARAM_RAW);
+ $mform->setDefault('cost', format_float($this->get_config('cost'), 2, true));
+
+ $paypalcurrencies = $this->get_currencies();
+ $mform->addElement('select', 'currency', get_string('currency', 'enrol_paypal'), $paypalcurrencies);
+ $mform->setDefault('currency', $this->get_config('currency'));
+
+ $roles = $this->get_roleid_options($instance, $context);
+ $mform->addElement('select', 'roleid', get_string('assignrole', 'enrol_paypal'), $roles);
+ $mform->setDefault('roleid', $this->get_config('roleid'));
+
+ $options = array('optional' => true, 'defaultunit' => 86400);
+ $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_paypal'), $options);
+ $mform->setDefault('enrolperiod', $this->get_config('enrolperiod'));
+ $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_paypal');
+
+ $options = array('optional' => true);
+ $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_paypal'), $options);
+ $mform->setDefault('enrolstartdate', 0);
+ $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_paypal');
+
+ $options = array('optional' => true);
+ $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_paypal'), $options);
+ $mform->setDefault('enrolenddate', 0);
+ $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_paypal');
+
+ if (enrol_accessing_via_instance($instance)) {
+ $warningtext = get_string('instanceeditselfwarningtext', 'core_enrol');
+ $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warningtext);
+ }
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ $errors = array();
+
+ if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
+ $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_paypal');
+ }
+
+ $cost = str_replace(get_string('decsep', 'langconfig'), '.', $data['cost']);
+ if (!is_numeric($cost)) {
+ $errors['cost'] = get_string('costerror', 'enrol_paypal');
+ }
+
+ $validstatus = array_keys($this->get_status_options());
+ $validcurrency = array_keys($this->get_currencies());
+ $validroles = array_keys($this->get_roleid_options($instance, $context));
+ $tovalidate = array(
+ 'name' => PARAM_TEXT,
+ 'status' => $validstatus,
+ 'currency' => $validcurrency,
+ 'roleid' => $validroles,
+ 'enrolperiod' => PARAM_INT,
+ 'enrolstartdate' => PARAM_INT,
+ 'enrolenddate' => PARAM_INT
+ );
+
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
+
/**
* Execute synchronisation.
* @param progress_trace $trace
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_self to specified course
- * or edits current instance.
- *
- * @package enrol_self
- * @copyright 2010 Petr Skoda {@link http://skodak.org}
- * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
- */
-
-require('../../config.php');
-require_once('edit_form.php');
-
-$courseid = required_param('courseid', PARAM_INT);
-$instanceid = optional_param('id', 0, PARAM_INT);
-
-$course = $DB->get_record('course', array('id'=>$courseid), '*', MUST_EXIST);
-$context = context_course::instance($course->id, MUST_EXIST);
-
-require_login($course);
-require_capability('enrol/self:config', $context);
-
-$PAGE->set_url('/enrol/self/edit.php', array('courseid'=>$course->id, 'id'=>$instanceid));
-$PAGE->set_pagelayout('admin');
-
-$return = new moodle_url('/enrol/instances.php', array('id'=>$course->id));
-if (!enrol_is_enabled('self')) {
- redirect($return);
-}
-
-/** @var enrol_self_plugin $plugin */
-$plugin = enrol_get_plugin('self');
-
-if ($instanceid) {
- $instance = $DB->get_record('enrol', array('courseid'=>$course->id, 'enrol'=>'self', 'id'=>$instanceid), '*', MUST_EXIST);
-
-} else {
- require_capability('moodle/course:enrolconfig', $context);
- // No instance yet, we have to add new instance.
- navigation_node::override_active_url(new moodle_url('/enrol/instances.php', array('id'=>$course->id)));
-
- $instance = (object)$plugin->get_instance_defaults();
- $instance->id = null;
- $instance->courseid = $course->id;
- $instance->status = ENROL_INSTANCE_ENABLED; // Do not use default for automatically created instances here.
-}
-
-// Merge these two settings to one value for the single selection element.
-if ($instance->notifyall and $instance->expirynotify) {
- $instance->expirynotify = 2;
-}
-unset($instance->notifyall);
-
-$mform = new enrol_self_edit_form(NULL, array($instance, $plugin, $context));
-
-if ($mform->is_cancelled()) {
- redirect($return);
-
-} else if ($data = $mform->get_data()) {
- if ($data->expirynotify == 2) {
- $data->expirynotify = 1;
- $data->notifyall = 1;
- } else {
- $data->notifyall = 0;
- }
- if (!$data->expirynotify) {
- // Keep previous/default value of disabled expirythreshold option.
- $data->expirythreshold = $instance->expirythreshold;
- }
- if (!isset($data->customint6)) {
- // Add previous value of newenrols if disabled.
- $data->customint6 = $instance->customint6;
- }
-
- if ($instance->id) {
- $reset = ($instance->status != $data->status);
-
- $instance->status = $data->status;
- $instance->name = $data->name;
- $instance->password = $data->password;
- $instance->customint1 = $data->customint1;
- $instance->customint2 = $data->customint2;
- $instance->customint3 = $data->customint3;
- $instance->customint4 = $data->customint4;
- $instance->customint5 = $data->customint5;
- $instance->customint6 = $data->customint6;
- $instance->customtext1 = $data->customtext1;
- $instance->roleid = $data->roleid;
- $instance->enrolperiod = $data->enrolperiod;
- $instance->expirynotify = $data->expirynotify;
- $instance->notifyall = $data->notifyall;
- $instance->expirythreshold = $data->expirythreshold;
- $instance->enrolstartdate = $data->enrolstartdate;
- $instance->enrolenddate = $data->enrolenddate;
- $instance->timemodified = time();
- $DB->update_record('enrol', $instance);
- \core\event\enrol_instance_updated::create_from_record($instance)->trigger();
-
- if ($reset) {
- $context->mark_dirty();
- }
-
- } else {
- $fields = array(
- 'status' => $data->status,
- 'name' => $data->name,
- 'password' => $data->password,
- 'customint1' => $data->customint1,
- 'customint2' => $data->customint2,
- 'customint3' => $data->customint3,
- 'customint4' => $data->customint4,
- 'customint5' => $data->customint5,
- 'customint6' => $data->customint6,
- 'customtext1' => $data->customtext1,
- 'roleid' => $data->roleid,
- 'enrolperiod' => $data->enrolperiod,
- 'expirynotify' => $data->expirynotify,
- 'notifyall' => $data->notifyall,
- 'expirythreshold' => $data->expirythreshold,
- 'enrolstartdate' => $data->enrolstartdate,
- 'enrolenddate' => $data->enrolenddate);
- $plugin->add_instance($course, $fields);
- }
-
- redirect($return);
-}
-
-$PAGE->set_heading($course->fullname);
-$PAGE->set_title(get_string('pluginname', 'enrol_self'));
-
-echo $OUTPUT->header();
-echo $OUTPUT->heading(get_string('pluginname', 'enrol_self'));
-$mform->display();
-echo $OUTPUT->footer();
+++ /dev/null
-<?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/>.
-
-/**
- * Adds new instance of enrol_self to specified course
- * or edits current instance.
- *
- * @package enrol_self
- * @copyright 2010 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.'/formslib.php');
-require_once($CFG->dirroot.'/cohort/lib.php');
-
-class enrol_self_edit_form extends moodleform {
-
- function definition() {
- global $DB;
-
- $mform = $this->_form;
-
- list($instance, $plugin, $context) = $this->_customdata;
-
- $mform->addElement('header', 'header', get_string('pluginname', 'enrol_self'));
-
- $nameattribs = array('size' => '20', 'maxlength' => '255');
- $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'), $nameattribs);
- $mform->setType('name', PARAM_TEXT);
- $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server');
-
- $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
- ENROL_INSTANCE_DISABLED => get_string('no'));
- $mform->addElement('select', 'status', get_string('status', 'enrol_self'), $options);
- $mform->addHelpButton('status', 'status', 'enrol_self');
-
- $options = array(1 => get_string('yes'), 0 => get_string('no'));
- $mform->addElement('select', 'customint6', get_string('newenrols', 'enrol_self'), $options);
- $mform->addHelpButton('customint6', 'newenrols', 'enrol_self');
- $mform->disabledIf('customint6', 'status', 'eq', ENROL_INSTANCE_DISABLED);
-
- $passattribs = array('size' => '20', 'maxlength' => '50');
- $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'), $passattribs);
- $mform->addHelpButton('password', 'password', 'enrol_self');
- if (empty($instance->id) and $plugin->get_config('requirepassword')) {
- $mform->addRule('password', get_string('required'), 'required', null, 'client');
- }
- $mform->addRule('password', get_string('maximumchars', '', 50), 'maxlength', 50, 'server');
-
- $options = array(1 => get_string('yes'),
- 0 => get_string('no'));
- $mform->addElement('select', 'customint1', get_string('groupkey', 'enrol_self'), $options);
- $mform->addHelpButton('customint1', 'groupkey', 'enrol_self');
-
- $roles = $this->extend_assignable_roles($context, $instance->roleid);
- $mform->addElement('select', 'roleid', get_string('role', 'enrol_self'), $roles);
-
- $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_self'), array('optional' => true, 'defaultunit' => 86400));
- $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_self');
-
- $options = array(0 => get_string('no'), 1 => get_string('expirynotifyenroller', 'core_enrol'), 2 => get_string('expirynotifyall', 'core_enrol'));
- $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options);
- $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol');
-
- $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), array('optional' => false, 'defaultunit' => 86400));
- $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol');
- $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0);
-
- $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_self'), array('optional' => true));
- $mform->setDefault('enrolstartdate', 0);
- $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_self');
-
- $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_self'), array('optional' => true));
- $mform->setDefault('enrolenddate', 0);
- $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_self');
-
- $options = array(0 => get_string('never'),
- 1800 * 3600 * 24 => get_string('numdays', '', 1800),
- 1000 * 3600 * 24 => get_string('numdays', '', 1000),
- 365 * 3600 * 24 => get_string('numdays', '', 365),
- 180 * 3600 * 24 => get_string('numdays', '', 180),
- 150 * 3600 * 24 => get_string('numdays', '', 150),
- 120 * 3600 * 24 => get_string('numdays', '', 120),
- 90 * 3600 * 24 => get_string('numdays', '', 90),
- 60 * 3600 * 24 => get_string('numdays', '', 60),
- 30 * 3600 * 24 => get_string('numdays', '', 30),
- 21 * 3600 * 24 => get_string('numdays', '', 21),
- 14 * 3600 * 24 => get_string('numdays', '', 14),
- 7 * 3600 * 24 => get_string('numdays', '', 7));
- $mform->addElement('select', 'customint2', get_string('longtimenosee', 'enrol_self'), $options);
- $mform->addHelpButton('customint2', 'longtimenosee', 'enrol_self');
-
- $mform->addElement('text', 'customint3', get_string('maxenrolled', 'enrol_self'));
- $mform->addHelpButton('customint3', 'maxenrolled', 'enrol_self');
- $mform->setType('customint3', PARAM_INT);
-
- $cohorts = array(0 => get_string('no'));
- $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0);
- if ($instance->customint5 && !isset($allcohorts[$instance->customint5]) &&
- ($c = $DB->get_record('cohort', array('id' => $instance->customint5), 'id, name, idnumber, contextid, visible', IGNORE_MISSING))) {
- // Current cohort was not found because current user can not see it. Still keep it.
- $allcohorts[$instance->customint5] = $c;
- }
- foreach ($allcohorts as $c) {
- $cohorts[$c->id] = format_string($c->name, true, array('context' => context::instance_by_id($c->contextid)));
- if ($c->idnumber) {
- $cohorts[$c->id] .= ' ['.s($c->idnumber).']';
- }
- }
- if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) {
- // Somebody deleted a cohort, better keep the wrong value so that random ppl can not enrol.
- $cohorts[$instance->customint5] = get_string('unknowncohort', 'cohort', $instance->customint5);
- }
- if (count($cohorts) > 1) {
- $mform->addElement('select', 'customint5', get_string('cohortonly', 'enrol_self'), $cohorts);
- $mform->addHelpButton('customint5', 'cohortonly', 'enrol_self');
- } else {
- $mform->addElement('hidden', 'customint5');
- $mform->setType('customint5', PARAM_INT);
- $mform->setConstant('customint5', 0);
- }
-
- $mform->addElement('advcheckbox', 'customint4', get_string('sendcoursewelcomemessage', 'enrol_self'));
- $mform->addHelpButton('customint4', 'sendcoursewelcomemessage', 'enrol_self');
-
- $mform->addElement('textarea', 'customtext1', get_string('customwelcomemessage', 'enrol_self'), array('cols'=>'60', 'rows'=>'8'));
- $mform->addHelpButton('customtext1', 'customwelcomemessage', 'enrol_self');
-
- $mform->addElement('hidden', 'id');
- $mform->setType('id', PARAM_INT);
- $mform->addElement('hidden', 'courseid');
- $mform->setType('courseid', PARAM_INT);
-
- if (enrol_accessing_via_instance($instance)) {
- $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), get_string('instanceeditselfwarningtext', 'core_enrol'));
- }
-
- $this->add_action_buttons(true, ($instance->id ? null : get_string('addinstance', 'enrol')));
-
- $this->set_data($instance);
- }
-
- function validation($data, $files) {
- global $DB, $CFG;
- $errors = parent::validation($data, $files);
-
- list($instance, $plugin, $context) = $this->_customdata;
- $checkpassword = false;
-
- if ($instance->id) {
- // Check the password if we are enabling the plugin again.
- if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) {
- $checkpassword = true;
- }
-
- // Check the password if the instance is enabled and the password has changed.
- if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) {
- $checkpassword = true;
- }
- } else {
- $checkpassword = true;
- }
-
- if ($checkpassword) {
- $require = $plugin->get_config('requirepassword');
- $policy = $plugin->get_config('usepasswordpolicy');
- if ($require and trim($data['password']) === '') {
- $errors['password'] = get_string('required');
- } else if (!empty($data['password']) && $policy) {
- $errmsg = '';
- if (!check_password_policy($data['password'], $errmsg)) {
- $errors['password'] = $errmsg;
- }
- }
- }
-
- if ($data['status'] == ENROL_INSTANCE_ENABLED) {
- if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
- $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_self');
- }
- }
-
- if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) {
- $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol');
- }
-
- return $errors;
- }
-
- /**
- * Gets a list of roles that this user can assign for the course as the default for self-enrolment.
- *
- * @param context $context the context.
- * @param integer $defaultrole the id of the role that is set as the default for self-enrolment
- * @return array index is the role id, value is the role name
- */
- function extend_assignable_roles($context, $defaultrole) {
- global $DB;
-
- $roles = get_assignable_roles($context, ROLENAME_BOTH);
- if (!isset($roles[$defaultrole])) {
- if ($role = $DB->get_record('role', array('id'=>$defaultrole))) {
- $roles[$defaultrole] = role_get_name($role, $context, ROLENAME_BOTH);
- }
- }
- return $roles;
- }
-}
}
/**
- * Sets up navigation entries.
+ * Return true if we can add a new instance to this course.
*
- * @param stdClass $instancesnode
- * @param stdClass $instance
- * @return void
- */
- public function add_course_navigation($instancesnode, stdClass $instance) {
- if ($instance->enrol !== 'self') {
- throw new coding_exception('Invalid enrol instance type!');
- }
-
- $context = context_course::instance($instance->courseid);
- if (has_capability('enrol/self:config', $context)) {
- $managelink = new moodle_url('/enrol/self/edit.php', array('courseid'=>$instance->courseid, 'id'=>$instance->id));
- $instancesnode->add($this->get_instance_name($instance), $managelink, navigation_node::TYPE_SETTING);
- }
- }
-
- /**
- * Returns edit icons for the page with list of instances
- * @param stdClass $instance
- * @return array
- */
- public function get_action_icons(stdClass $instance) {
- global $OUTPUT;
-
- if ($instance->enrol !== 'self') {
- throw new coding_exception('invalid enrol instance!');
- }
- $context = context_course::instance($instance->courseid);
-
- $icons = array();
-
- if (has_capability('enrol/self:config', $context)) {
- $editlink = new moodle_url("/enrol/self/edit.php", array('courseid'=>$instance->courseid, 'id'=>$instance->id));
- $icons[] = $OUTPUT->action_icon($editlink, new pix_icon('t/edit', get_string('edit'), 'core',
- array('class' => 'iconsmall')));
- }
-
- return $icons;
- }
-
- /**
- * Returns link to page which may be used to add new instance of enrolment plugin in course.
* @param int $courseid
- * @return moodle_url page url
+ * @return boolean
*/
- public function get_newinstance_link($courseid) {
+ public function can_add_instance($courseid) {
$context = context_course::instance($courseid, MUST_EXIST);
if (!has_capability('moodle/course:enrolconfig', $context) or !has_capability('enrol/self:config', $context)) {
- return NULL;
+ return false;
}
- // Multiple instances supported - different roles with different password.
- return new moodle_url('/enrol/self/edit.php', array('courseid'=>$courseid));
+
+ return true;
}
/**
if (true === $enrolstatus) {
// This user can self enrol using this instance.
- $form = new enrol_self_enrol_form(NULL, $instance);
+ $form = new enrol_self_enrol_form(null, $instance);
$instanceid = optional_param('instance', 0, PARAM_INT);
if ($instance->id == $instanceid) {
if ($data = $form->get_data()) {
return true;
}
+
+ /**
+ * Return an array of valid options for the status.
+ *
+ * @return array
+ */
+ protected function get_status_options() {
+ $options = array(ENROL_INSTANCE_ENABLED => get_string('yes'),
+ ENROL_INSTANCE_DISABLED => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the newenrols property.
+ *
+ * @return array
+ */
+ protected function get_newenrols_options() {
+ $options = array(1 => get_string('yes'), 0 => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the groupkey property.
+ *
+ * @return array
+ */
+ protected function get_groupkey_options() {
+ $options = array(1 => get_string('yes'), 0 => get_string('no'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the expirynotify property.
+ *
+ * @return array
+ */
+ protected function get_expirynotify_options() {
+ $options = array(0 => get_string('no'),
+ 1 => get_string('expirynotifyenroller', 'core_enrol'),
+ 2 => get_string('expirynotifyall', 'core_enrol'));
+ return $options;
+ }
+
+ /**
+ * Return an array of valid options for the longtimenosee property.
+ *
+ * @return array
+ */
+ protected function get_longtimenosee_options() {
+ $options = array(0 => get_string('never'),
+ 1800 * 3600 * 24 => get_string('numdays', '', 1800),
+ 1000 * 3600 * 24 => get_string('numdays', '', 1000),
+ 365 * 3600 * 24 => get_string('numdays', '', 365),
+ 180 * 3600 * 24 => get_string('numdays', '', 180),
+ 150 * 3600 * 24 => get_string('numdays', '', 150),
+ 120 * 3600 * 24 => get_string('numdays', '', 120),
+ 90 * 3600 * 24 => get_string('numdays', '', 90),
+ 60 * 3600 * 24 => get_string('numdays', '', 60),
+ 30 * 3600 * 24 => get_string('numdays', '', 30),
+ 21 * 3600 * 24 => get_string('numdays', '', 21),
+ 14 * 3600 * 24 => get_string('numdays', '', 14),
+ 7 * 3600 * 24 => get_string('numdays', '', 7));
+ return $options;
+ }
+
+ /**
+ * Add elements to the edit instance form.
+ *
+ * @param stdClass $instance
+ * @param MoodleQuickForm $mform
+ * @param context $context
+ * @return bool
+ */
+ public function edit_instance_form($instance, MoodleQuickForm $mform, $context) {
+ global $CFG;
+
+ // Merge these two settings to one value for the single selection element.
+ if ($instance->notifyall and $instance->expirynotify) {
+ $instance->expirynotify = 2;
+ }
+ unset($instance->notifyall);
+
+ $nameattribs = array('size' => '20', 'maxlength' => '255');
+ $mform->addElement('text', 'name', get_string('custominstancename', 'enrol'), $nameattribs);
+ $mform->setType('name', PARAM_TEXT);
+ $mform->addRule('name', get_string('maximumchars', '', 255), 'maxlength', 255, 'server');
+
+ $options = $this->get_status_options();
+ $mform->addElement('select', 'status', get_string('status', 'enrol_self'), $options);
+ $mform->addHelpButton('status', 'status', 'enrol_self');
+
+ $options = $this->get_newenrols_options();
+ $mform->addElement('select', 'customint6', get_string('newenrols', 'enrol_self'), $options);
+ $mform->addHelpButton('customint6', 'newenrols', 'enrol_self');
+ $mform->disabledIf('customint6', 'status', 'eq', ENROL_INSTANCE_DISABLED);
+
+ $passattribs = array('size' => '20', 'maxlength' => '50');
+ $mform->addElement('passwordunmask', 'password', get_string('password', 'enrol_self'), $passattribs);
+ $mform->addHelpButton('password', 'password', 'enrol_self');
+ if (empty($instance->id) and $this->get_config('requirepassword')) {
+ $mform->addRule('password', get_string('required'), 'required', null, 'client');
+ }
+ $mform->addRule('password', get_string('maximumchars', '', 50), 'maxlength', 50, 'server');
+
+ $options = $this->get_groupkey_options();
+ $mform->addElement('select', 'customint1', get_string('groupkey', 'enrol_self'), $options);
+ $mform->addHelpButton('customint1', 'groupkey', 'enrol_self');
+
+ $roles = $this->extend_assignable_roles($context, $instance->roleid);
+ $mform->addElement('select', 'roleid', get_string('role', 'enrol_self'), $roles);
+
+ $options = array('optional' => true, 'defaultunit' => 86400);
+ $mform->addElement('duration', 'enrolperiod', get_string('enrolperiod', 'enrol_self'), $options);
+ $mform->addHelpButton('enrolperiod', 'enrolperiod', 'enrol_self');
+
+ $options = $this->get_expirynotify_options();
+ $mform->addElement('select', 'expirynotify', get_string('expirynotify', 'core_enrol'), $options);
+ $mform->addHelpButton('expirynotify', 'expirynotify', 'core_enrol');
+
+ $options = array('optional' => false, 'defaultunit' => 86400);
+ $mform->addElement('duration', 'expirythreshold', get_string('expirythreshold', 'core_enrol'), $options);
+ $mform->addHelpButton('expirythreshold', 'expirythreshold', 'core_enrol');
+ $mform->disabledIf('expirythreshold', 'expirynotify', 'eq', 0);
+
+ $options = array('optional' => true);
+ $mform->addElement('date_time_selector', 'enrolstartdate', get_string('enrolstartdate', 'enrol_self'), $options);
+ $mform->setDefault('enrolstartdate', 0);
+ $mform->addHelpButton('enrolstartdate', 'enrolstartdate', 'enrol_self');
+
+ $options = array('optional' => true);
+ $mform->addElement('date_time_selector', 'enrolenddate', get_string('enrolenddate', 'enrol_self'), $options);
+ $mform->setDefault('enrolenddate', 0);
+ $mform->addHelpButton('enrolenddate', 'enrolenddate', 'enrol_self');
+
+ $options = $this->get_longtimenosee_options();
+ $mform->addElement('select', 'customint2', get_string('longtimenosee', 'enrol_self'), $options);
+ $mform->addHelpButton('customint2', 'longtimenosee', 'enrol_self');
+
+ $mform->addElement('text', 'customint3', get_string('maxenrolled', 'enrol_self'));
+ $mform->addHelpButton('customint3', 'maxenrolled', 'enrol_self');
+ $mform->setType('customint3', PARAM_INT);
+
+ require_once($CFG->dirroot.'/cohort/lib.php');
+
+ $cohorts = array(0 => get_string('no'));
+ $allcohorts = cohort_get_available_cohorts($context, 0, 0, 0);
+ if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) {
+ $c = $DB->get_record('cohort',
+ array('id' => $instance->customint5),
+ 'id, name, idnumber, contextid, visible',
+ IGNORE_MISSING);
+ if ($c) {
+ // Current cohort was not found because current user can not see it. Still keep it.
+ $allcohorts[$instance->customint5] = $c;
+ }
+ }
+ foreach ($allcohorts as $c) {
+ $cohorts[$c->id] = format_string($c->name, true, array('context' => context::instance_by_id($c->contextid)));
+ if ($c->idnumber) {
+ $cohorts[$c->id] .= ' ['.s($c->idnumber).']';
+ }
+ }
+ if ($instance->customint5 && !isset($allcohorts[$instance->customint5])) {
+ // Somebody deleted a cohort, better keep the wrong value so that random ppl can not enrol.
+ $cohorts[$instance->customint5] = get_string('unknowncohort', 'cohort', $instance->customint5);
+ }
+ if (count($cohorts) > 1) {
+ $mform->addElement('select', 'customint5', get_string('cohortonly', 'enrol_self'), $cohorts);
+ $mform->addHelpButton('customint5', 'cohortonly', 'enrol_self');
+ } else {
+ $mform->addElement('hidden', 'customint5');
+ $mform->setType('customint5', PARAM_INT);
+ $mform->setConstant('customint5', 0);
+ }
+
+ $mform->addElement('advcheckbox', 'customint4', get_string('sendcoursewelcomemessage', 'enrol_self'));
+ $mform->addHelpButton('customint4', 'sendcoursewelcomemessage', 'enrol_self');
+
+ $options = array('cols' => '60', 'rows' => '8');
+ $mform->addElement('textarea', 'customtext1', get_string('customwelcomemessage', 'enrol_self'), $options);
+ $mform->addHelpButton('customtext1', 'customwelcomemessage', 'enrol_self');
+
+ if (enrol_accessing_via_instance($instance)) {
+ $warntext = get_string('instanceeditselfwarningtext', 'core_enrol');
+ $mform->addElement('static', 'selfwarn', get_string('instanceeditselfwarning', 'core_enrol'), $warntext);
+ }
+ }
+
+ /**
+ * We are a good plugin and don't invent our own UI/validation code path.
+ *
+ * @return boolean
+ */
+ public function use_standard_editing_ui() {
+ return true;
+ }
+
+ /**
+ * Perform custom validation of the data used to edit the instance.
+ *
+ * @param array $data array of ("fieldname"=>value) of submitted data
+ * @param array $files array of uploaded files "element_name"=>tmp_file_path
+ * @param object $instance The instance loaded from the DB
+ * @param context $context The context of the instance we are editing
+ * @return array of "element_name"=>"error_description" if there are errors,
+ * or an empty array if everything is OK.
+ * @return void
+ */
+ public function edit_instance_validation($data, $files, $instance, $context) {
+ $errors = array();
+
+ $checkpassword = false;
+
+ if ($instance->id) {
+ // Check the password if we are enabling the plugin again.
+ if (($instance->status == ENROL_INSTANCE_DISABLED) && ($data['status'] == ENROL_INSTANCE_ENABLED)) {
+ $checkpassword = true;
+ }
+
+ // Check the password if the instance is enabled and the password has changed.
+ if (($data['status'] == ENROL_INSTANCE_ENABLED) && ($instance->password !== $data['password'])) {
+ $checkpassword = true;
+ }
+ } else {
+ $checkpassword = true;
+ }
+
+ if ($checkpassword) {
+ $require = $this->get_config('requirepassword');
+ $policy = $this->get_config('usepasswordpolicy');
+ if ($require and trim($data['password']) === '') {
+ $errors['password'] = get_string('required');
+ } else if (!empty($data['password']) && $policy) {
+ $errmsg = '';
+ if (!check_password_policy($data['password'], $errmsg)) {
+ $errors['password'] = $errmsg;
+ }
+ }
+ }
+
+ if ($data['status'] == ENROL_INSTANCE_ENABLED) {
+ if (!empty($data['enrolenddate']) and $data['enrolenddate'] < $data['enrolstartdate']) {
+ $errors['enrolenddate'] = get_string('enrolenddaterror', 'enrol_self');
+ }
+ }
+
+ if ($data['expirynotify'] > 0 and $data['expirythreshold'] < 86400) {
+ $errors['expirythreshold'] = get_string('errorthresholdlow', 'core_enrol');
+ }
+
+ // Now these ones are checked by quickforms, but we may be called by the upload enrolments tool, or a webservive.
+ if (core_text::strlen($data['name']) > 255) {
+ $errors['name'] = get_string('err_maxlength', 'form', 255);
+ }
+ $validstatus = array_keys($this->get_status_options());
+ $validnewenrols = array_keys($this->get_newenrols_options());
+ if (core_text::strlen($data['password']) > 50) {
+ $errors['name'] = get_string('err_maxlength', 'form', 50);
+ }
+ $validgroupkey = array_keys($this->get_groupkey_options());
+ $context = context_course::instance($instance->courseid);
+ $validroles = array_keys($this->extend_assignable_roles($context, $instance->roleid));
+ $validexpirynotify = array_keys($this->get_expirynotify_options());
+ $validlongtimenosee = array_keys($this->get_longtimenosee_options());
+ $tovalidate = array(
+ 'enrolstartdate' => PARAM_INT,
+ 'enrolenddate' => PARAM_INT,
+ 'name' => PARAM_TEXT,
+ 'customint1' => $validgroupkey,
+ 'customint2' => $validlongtimenosee,
+ 'customint3' => PARAM_INT,
+ 'customint4' => PARAM_BOOL,
+ 'customint5' => PARAM_INT,
+ 'customint6' => $validnewenrols,
+ 'status' => $validstatus,
+ 'enrolperiod' => PARAM_INT,
+ 'expirynotify' => $validexpirynotify,
+ 'roleid' => $validroles
+ );
+ if ($data['expirynotify'] != 0) {
+ $tovalidate['expirythreshold'] = PARAM_INT;
+ }
+ $typeerrors = $this->validate_param_types($data, $tovalidate);
+ $errors = array_merge($errors, $typeerrors);
+
+ return $errors;
+ }
+
+ /**
+ * Add new instance of enrol plugin.
+ * @param object $course
+ * @param array $fields instance fields
+ * @return int id of new instance, null if can not be created
+ */
+ public function add_instance($course, array $fields = null) {
+ // In the form we are representing 2 db columns with one field.
+ if (!empty($fields) && !empty($fields['expirynotify'])) {
+ if ($fields['expirynotify'] == 2) {
+ $fields['expirynotify'] = 1;
+ $fields['notifyall'] = 1;
+ } else {
+ $fields['notifyall'] = 0;
+ }
+ }
+
+ return parent::add_instance($course, $fields);
+ }
+
+ /**
+ * Update instance of enrol plugin.
+ * @param stdClass $instance
+ * @param stdClass $data modified instance fields
+ * @return boolean
+ */
+ public function update_instance($instance, $data) {
+ // In the form we are representing 2 db columns with one field.
+ if ($data->expirynotify == 2) {
+ $data->expirynotify = 1;
+ $data->notifyall = 1;
+ } else {
+ $data->notifyall = 0;
+ }
+ // Keep previous/default value of disabled expirythreshold option.
+ if (!$data->expirynotify) {
+ $data->expirythreshold = $instance->expirythreshold;
+ }
+ // Add previous value of newenrols if disabled.
+ if (!isset($data->customint6)) {
+ $data->customint6 = $instance->customint6;
+ }
+
+ return parent::update_instance($instance, $data);
+ }
+
+ /**
+ * Gets a list of roles that this user can assign for the course as the default for self-enrolment.
+ *
+ * @param context $context the context.
+ * @param integer $defaultrole the id of the role that is set as the default for self-enrolment
+ * @return array index is the role id, value is the role name
+ */
+ public function extend_assignable_roles($context, $defaultrole) {
+ global $DB;
+
+ $roles = get_assignable_roles($context, ROLENAME_BOTH);
+ if (!isset($roles[$defaultrole])) {
+ if ($role = $DB->get_record('role', array('id' => $defaultrole))) {
+ $roles[$defaultrole] = role_get_name($role, $context, ROLENAME_BOTH);
+ }
+ }
+ return $roles;
+ }
}
This files describes API changes in /enrol/* - plugins,
information provided here is intended especially for developers.
+=== 3.0 ===
+Enrolment plugins UI have been consolidated. Plugins can implement use_standard_editing_ui() function
+and add edit_instance_form() and edit_instance_validation() methods instead of providing their own edit.php and form. They can
+then rely on the default implementation of get_action_icons and get_course_navigation. In future
+this will mean they can be called by webservices/user upload tools because they can validate their data.
=== 3.1 ===
* core_enrol_external::get_enrolled_users now supports two additional parameters for ordering: sortby and sortdirection.
$courseid = required_param('id', PARAM_INT);
$action = optional_param('action', 0, PARAM_ALPHA);
$eid = optional_param('eid', 0, PARAM_ALPHANUM);
-$category = optional_param('category', null, PARAM_INT);
-$aggregationtype = optional_param('aggregationtype', null, PARAM_INT);
+$weightsadjusted = optional_param('weightsadjusted', 0, PARAM_INT);
$url = new moodle_url('/grade/edit/tree/index.php', array('id' => $courseid));
$PAGE->set_url($url);
$gpr = new grade_plugin_return(array('type'=>'edit', 'plugin'=>'tree', 'courseid'=>$courseid));
$returnurl = $gpr->get_return_url(null);
-// Change category aggregation if requested
-if (!is_null($category) && !is_null($aggregationtype) && confirm_sesskey()) {
- if (!$grade_category = grade_category::fetch(array('id'=>$category, 'courseid'=>$courseid))) {
- print_error('invalidcategoryid');
- }
-
- $data = new stdClass();
- $data->aggregation = $aggregationtype;
- grade_category::set_properties($grade_category, $data);
- $grade_category->update();
-
- grade_regrade_final_grades($courseid);
-}
-
-//first make sure we have proper final grades - we need it for locking changes
-$normalisationmessage = null;
-
-$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
-
-grade_regrade_final_grades($courseid);
-
-$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
-
-if (array_diff($originalweights, $alteredweights)) {
- $normalisationmessage = get_string('weightsadjusted', 'grades');
-}
-
// get the grading tree object
// note: total must be first for moving to work correctly, if you want it last moving code must be rewritten!
$gtree = new grade_tree($courseid, false, false);
$recreatetree = true;
}
}
+}
- $originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
+$originalweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
- grade_regrade_final_grades($courseid);
+/**
+ * Callback function to adjust the URL if weights changed after the
+ * regrade.
+ *
+ * @param int $courseid The course ID
+ * @param array $originalweights The weights before the regrade
+ * @param int $weightsadjusted Whether weights have been adjusted
+ * @return moodle_url A URL to redirect to after regrading when a progress bar is displayed.
+ */
+$grade_edit_tree_index_checkweights = function() use ($courseid, $originalweights, &$weightsadjusted) {
+ global $PAGE;
$alteredweights = grade_helper::fetch_all_natural_weights_for_course($courseid);
if (array_diff($originalweights, $alteredweights)) {
- $normalisationmessage = get_string('weightsadjusted', 'grades');
+ $weightsadjusted = 1;
+ return new moodle_url($PAGE->url, array('weightsadjusted' => $weightsadjusted));
}
+ return $PAGE->url;
+};
+
+if (grade_regrade_final_grades_if_required($course, $grade_edit_tree_index_checkweights)) {
+ $recreatetree = true;
}
print_grade_page_head($courseid, 'settings', 'setup', get_string('gradebooksetup', 'grades'));
if ($recreatetree) {
$grade_edit_tree = new grade_edit_tree($gtree, $movingeid, $gpr);
}
+
// Check to see if we have a normalisation message to send.
-if (!empty($normalisationmessage)) {
- echo $OUTPUT->notification($normalisationmessage, 'notifymessage');
+if ($weightsadjusted) {
+ echo $OUTPUT->notification(get_string('weightsadjusted', 'grades'), 'notifymessage');
}
echo html_writer::table($grade_edit_tree->table);
* @param $courseid int The course being exported
*/
function export_verify_grades($courseid) {
- $regraderesult = grade_regrade_final_grades($courseid);
- if (is_array($regraderesult)) {
- throw new moodle_exception('gradecantregrade', 'error', '', implode(', ', array_unique($regraderesult)));
+ if (grade_needs_regrade_final_grades($courseid)) {
+ throw new moodle_exception('gradesneedregrading', 'grades');
}
}
if (!strlen(trim($criterion['maxscore']))) {
$errors['err_nomaxscore'] = 1;
$criterion['error_description'] = true;
- } else if (!is_numeric($criterion['maxscore']) || $criterion['maxscore'] < 0) {
+ } else if (!is_numeric($criterion['maxscore'])) {
$errors['err_maxscorenotnumeric'] = 1;
$criterion['error_description'] = true;
+ } else if ($criterion['maxscore'] < 0) {
+ $errors['err_maxscoreisnegative'] = 1;
+ $criterion['error_description'] = true;
}
}
if (array_key_exists('moveup', $criterion) || $lastaction == 'movedown') {
$string['description'] = 'Description';
$string['descriptionmarkers'] = 'Description for Markers';
$string['descriptionstudents'] = 'Description for Students';
+$string['err_maxscoreisnegative'] = 'The max score is not valid, negative values are not allowed';
$string['err_maxscorenotnumeric'] = 'Criterion max score must be numeric';
$string['err_nocomment'] = 'Comment can not be empty';
$string['err_nodescription'] = 'Student description can not be empty';
$string['err_nomaxscore'] = 'Criterion max score can not be empty';
$string['err_noshortname'] = 'Criterion name can not be empty';
$string['err_shortnametoolong'] = 'Criterion name must be less than 256 characters';
-$string['err_scoreinvalid'] = 'The score given to {$a->criterianame} is not valid, the max score is: {$a->maxscore}';
+$string['err_scoreinvalid'] = 'The score given to \'{$a->criterianame}\' is not valid, the max score is: {$a->maxscore}';
+$string['err_scoreisnegative'] = 'The score given to \'{$a->criterianame}\' is not valid, negative values are not allowed';
$string['gradingof'] = '{$a} grading';
$string['guide'] = 'Marking guide';
$string['guidemappingexplained'] = 'WARNING: Your marking guide has a maximum grade of <b>{$a->maxscore} points</b> but the maximum grade set in your activity is {$a->modulegrade} The maximum score set in your marking guide will be scaled to the maximum grade in the module.<br />
|| $criterion['maxscore'] < $elementvalue['criteria'][$id]['score']
|| !is_numeric($elementvalue['criteria'][$id]['score'])
|| $elementvalue['criteria'][$id]['score'] < 0) {
- $this->validationerrors[$id]['score'] = $elementvalue['criteria'][$id]['score'];
+ $this->validationerrors[$id]['score'] = $elementvalue['criteria'][$id]['score'];
}
}
if (!empty($this->validationerrors)) {
$a = new stdClass();
$a->criterianame = s($criteria[$id]['shortname']);
$a->maxscore = $criteria[$id]['maxscore'];
- $html .= html_writer::tag('div', get_string('err_scoreinvalid', 'gradingform_guide', $a),
+ if ($this->validationerrors[$id]['score'] < 0) {
+ $html .= html_writer::tag('div', get_string('err_scoreisnegative', 'gradingform_guide', $a),
array('class' => 'gradingform_guide-error'));
+ } else {
+ $html .= html_writer::tag('div', get_string('err_scoreinvalid', 'gradingform_guide', $a),
+ array('class' => 'gradingform_guide-error'));
+ }
}
}
}
break;
default:
if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN && $value) {
+ // Id should be different then the actual input added later.
+ $attrs['id'] .= '_hidden';
$html .= html_writer::empty_tag('input', $attrs + array('type' => 'hidden', 'value' => $value));
}
// Display option as checkbox
if ($mode == gradingform_rubric_controller::DISPLAY_EDIT_FROZEN || $mode == gradingform_rubric_controller::DISPLAY_PREVIEW) {
$attrs['disabled'] = 'disabled';
unset($attrs['name']);
+ // Id should be different then the actual input added later.
+ $attrs['id'] .= '_disabled';
}
$html .= html_writer::empty_tag('input', $attrs);
$html .= html_writer::tag('label', get_string($option, 'gradingform_rubric'), array('for' => $attrs['id']));
grade_extend_settings($plugin_info, $courseid);
}
+ // Set the current report as active in the breadcrumbs.
+ if ($active_plugin !== null && $reportnav = $PAGE->settingsnav->find($active_plugin, navigation_node::TYPE_SETTING)) {
+ $reportnav->make_active();
+ }
+
$returnval = $OUTPUT->header();
if (!$return) {
set_user_preferences(array('grade_report_show'.$toggle_type => $toggle));
}
-//first make sure we have proper final grades - this must be done before constructing of the grade tree
-grade_regrade_final_grades($courseid);
-
// Perform actions
if (!empty($target) && !empty($action) && confirm_sesskey()) {
grade_report_grader::do_process_action($target, $action, $courseid);
$reportname = get_string('pluginname', 'gradereport_grader');
+// Do this check just before printing the grade header (and only do it once).
+grade_regrade_final_grades_if_required($course);
+
// Print header
print_grade_page_head($COURSE->id, 'report', 'grader', $reportname, false, $buttons);
}
$name = shorten_text($element['object']->get_name());
- $courseheader = html_writer::tag('span', $name, array('id' => 'courseheader'));
- $courseheader .= html_writer::label($showing, 'courseheader', false, array('class' => 'accesshide'));
+ $courseheaderid = 'courseheader_' . clean_param($name, PARAM_ALPHANUMEXT);
+ $courseheader = html_writer::tag('span', $name, array('id' => $courseheaderid));
+ $courseheader .= html_writer::label($showing, $courseheaderid, false, array('class' => 'accesshide'));
$courseheader .= $icon;
return $courseheader;
var userCells = Y.all(SELECTORS.USERCELL);
this.userColumnHeader.one('.cell').setStyle('width', userWidth);
this.userColumn.all('.cell').each(function(cell, idx) {
+ var height = userCells.item(idx).getComputedStyle(HEIGHT);
+ // Nasty hack to account for Internet Explorer
+ if(Y.UA.ie !== 0) {
+ var node = userCells.item(idx);
+ var allHeight = node.getDOMNode ?
+ node.getDOMNode().getBoundingClientRect().height :
+ node.get('offsetHeight');
+ var marginHeight = parseInt(node.getComputedStyle('marginTop'),10) +
+ parseInt(node.getComputedStyle('marginBottom'),10);
+ var paddingHeight = parseInt(node.getComputedStyle('paddingTop'),10) +
+ parseInt(node.getComputedStyle('paddingBottom'),10);
+ var borderHeight = parseInt(node.getComputedStyle('borderTopWidth'),10) +
+ parseInt(node.getComputedStyle('borderBottomWidth'),10);
+ height = allHeight - marginHeight - paddingHeight - borderHeight;
+ }
cell.setStyles({
width: userWidth,
- height: userCells.item(idx).getComputedStyle(HEIGHT)
+ height: height
});
}, this);
require_capability('gradereport/outcomes:view', $context);
// First make sure we have proper final grades.
-grade_regrade_final_grades($courseid);
+grade_regrade_final_grades_if_required($course);
// Grab all outcomes used in course.
$report_info = array();
}
$USER->grade_last_report[$course->id] = 'overview';
-//first make sure we have proper final grades - this must be done before constructing of the grade tree
-grade_regrade_final_grades($courseid);
+// First make sure we have proper final grades.
+grade_regrade_final_grades_if_required($course);
if (has_capability('moodle/grade:viewall', $context) && $courseid != SITEID) {
// Please note this would be extremely slow if we wanted to implement this properly for all teachers.
}
$courseparams = array('id' => $courseid);
-$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $courseparams));
+$pageparams = array(
+ 'id' => $courseid,
+ 'group' => $groupid,
+ 'userid' => $userid,
+ 'itemid' => $itemid,
+ 'item' => $itemtype,
+ 'page' => $page,
+ 'perpage' => $perpage,
+ );
+$PAGE->set_url(new moodle_url('/grade/report/singleview/index.php', $pageparams));
$PAGE->set_pagelayout('incourse');
if (!$course = $DB->get_record('course', $courseparams)) {
}
$USER->grade_last_report[$course->id] = 'singleview';
-// First make sure we have proper final grades -
-// this must be done before constructing of the grade tree.
-grade_regrade_final_grades($courseid);
+// First make sure we have proper final grades.
+grade_regrade_final_grades_if_required($course);
$report = new gradereport_singleview($courseid, $gpr, $context, $itemtype, $itemid);
| assign | C1 | a3 | Test assignment three | Submit something! |
| assign | C1 | a4 | Test assignment four | Submit nothing! |
- @javascript
Scenario: I can bulk insert grades and check their override flags for grade view.
Given I log in as "teacher1"
And I follow "Course 1"
And I follow "Single view for Test assignment one"
Then the field "Grade for james (Student) 1" matches value "50.00"
And the field "Override for james (Student) 1" matches value "0"
- And I click on "Perform bulk insert" "checkbox"
+ And I set the field "Perform bulk insert" to "1"
And I set the field "Insert value" to "1.0"
And I press "Save"
And I press "Continue"