Merge branch 'MDL-81073' of https://github.com/paulholden/moodle
[moodle.git] / availability / classes / frontend.php
blob4852da2e82f93dcd4f0993b319fa51e9d07329ef
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle. If not, see <http://www.gnu.org/licenses/>.
17 /**
18 * Class with front-end (editing form) functionality.
20 * This is a base class of a class implemented by each component, and also has
21 * static methods.
23 * @package core_availability
24 * @copyright 2014 The Open University
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
28 namespace core_availability;
30 defined('MOODLE_INTERNAL') || die();
32 /**
33 * Class with front-end (editing form) functionality.
35 * This is a base class of a class implemented by each component, and also has
36 * static methods.
38 * @package core_availability
39 * @copyright 2014 The Open University
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 abstract class frontend {
43 /**
44 * Decides whether this plugin should be available in a given course. The
45 * plugin can do this depending on course or system settings.
47 * Default returns true.
49 * @param \stdClass $course Course object
50 * @param \cm_info $cm Course-module currently being edited (null if none)
51 * @param \section_info $section Section currently being edited (null if none)
53 protected function allow_add($course, \cm_info $cm = null,
54 \section_info $section = null) {
55 return true;
58 /**
59 * Gets a list of string identifiers (in the plugin's language file) that
60 * are required in JavaScript for this plugin. The default returns nothing.
62 * You do not need to include the 'title' string (which is used by core) as
63 * this is automatically added.
65 * @return array Array of required string identifiers
67 protected function get_javascript_strings() {
68 return array();
71 /**
72 * Gets additional parameters for the plugin's initInner function.
74 * Default returns no parameters.
76 * @param \stdClass $course Course object
77 * @param \cm_info $cm Course-module currently being edited (null if none)
78 * @param \section_info $section Section currently being edited (null if none)
79 * @return array Array of parameters for the JavaScript function
81 protected function get_javascript_init_params($course, \cm_info $cm = null,
82 \section_info $section = null) {
83 return array();
86 /**
87 * Gets the Frankenstyle component name for this plugin.
89 * @return string The component name for this plugin
91 protected function get_component() {
92 return preg_replace('~^(availability_.*?)\\\\frontend$~', '$1', get_class($this));
95 /**
96 * Includes JavaScript for the main system and all plugins.
98 * @param \stdClass $course Course object
99 * @param \cm_info $cm Course-module currently being edited (null if none)
100 * @param \section_info $section Section currently being edited (null if none)
102 public static function include_all_javascript($course, \cm_info $cm = null,
103 \section_info $section = null) {
104 global $PAGE;
106 // Prepare array of required YUI modules. It is bad for performance to
107 // make multiple yui_module calls, so we group all the plugin modules
108 // into a single call (the main init function will call init for each
109 // plugin).
110 $modules = array('moodle-core_availability-form', 'base', 'node',
111 'panel', 'moodle-core-notification-dialogue', 'json');
113 // Work out JS to include for all components.
114 $pluginmanager = \core_plugin_manager::instance();
115 $enabled = $pluginmanager->get_enabled_plugins('availability');
116 $componentparams = new \stdClass();
117 foreach ($enabled as $plugin => $info) {
118 // Create plugin front-end object.
119 $class = '\availability_' . $plugin . '\frontend';
120 $frontend = new $class();
122 // Add to array of required YUI modules.
123 $component = $frontend->get_component();
124 $modules[] = 'moodle-' . $component . '-form';
126 // Get parameters for this plugin.
127 $componentparams->{$plugin} = array($component,
128 $frontend->allow_add($course, $cm, $section),
129 $frontend->get_javascript_init_params($course, $cm, $section));
131 // Include strings for this plugin.
132 $identifiers = $frontend->get_javascript_strings();
133 $identifiers[] = 'title';
134 $identifiers[] = 'description';
135 $PAGE->requires->strings_for_js($identifiers, $component);
138 // Include all JS (in one call). The init function runs on DOM ready.
139 $PAGE->requires->yui_module($modules,
140 'M.core_availability.form.init', array($componentparams), null, true);
142 // Include main strings.
143 $PAGE->requires->strings_for_js(array('none', 'cancel', 'delete', 'choosedots'),
144 'moodle');
145 $PAGE->requires->strings_for_js(array('addrestriction', 'invalid',
146 'listheader_sign_before', 'listheader_sign_pos',
147 'listheader_sign_neg', 'listheader_single',
148 'listheader_multi_after', 'listheader_multi_before',
149 'listheader_multi_or', 'listheader_multi_and',
150 'unknowncondition', 'hide_verb', 'hidden_individual',
151 'show_verb', 'shown_individual', 'hidden_all', 'shown_all',
152 'condition_group', 'condition_group_info', 'and', 'or',
153 'label_multi', 'label_sign', 'setheading', 'itemheading',
154 'missingplugin', 'disabled_verb'),
155 'availability');
159 * For use within forms, reports any validation errors from the availability
160 * field.
162 * @param array $data Form data fields
163 * @param array $errors Error array
165 public static function report_validation_errors(array $data, array &$errors) {
166 // Empty value is allowed!
167 if ($data['availabilityconditionsjson'] === '') {
168 return;
171 // Decode value.
172 $decoded = json_decode($data['availabilityconditionsjson']);
173 if (!$decoded) {
174 // This shouldn't be possible.
175 throw new \coding_exception('Invalid JSON from availabilityconditionsjson field');
177 if (!empty($decoded->errors)) {
178 $error = '';
179 foreach ($decoded->errors as $stringinfo) {
180 list ($component, $stringname) = explode(':', $stringinfo);
181 if ($error !== '') {
182 $error .= ' ';
184 $error .= get_string($stringname, $component);
186 $errors['availabilityconditionsjson'] = $error;
191 * Converts an associative array into an array of objects with two fields.
193 * This is necessary because JavaScript associative arrays/objects are not
194 * ordered (at least officially according to the language specification).
196 * @param array $inarray Associative array key => value
197 * @param string $keyname Name to use for key in resulting array objects
198 * @param string $valuename Name to use for value in resulting array objects
199 * @return array Non-associative (numeric) array
201 protected static function convert_associative_array_for_js(array $inarray,
202 $keyname, $valuename) {
203 $result = array();
204 foreach ($inarray as $key => $value) {
205 $result[] = (object)array($keyname => $key, $valuename => $value);
207 return $result;