ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ.. /** * Class with front-end (editing form) functionality. * * This is a base class of a class implemented by each component, and also has * static methods. * * @package core_availability * @copyright 2014 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace core_availability; defined('MOODLE_INTERNAL') || die(); /** * Class with front-end (editing form) functionality. * * This is a base class of a class implemented by each component, and also has * static methods. * * @package core_availability * @copyright 2014 The Open University * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ abstract class frontend { /** * Decides whether this plugin should be available in a given course. The * plugin can do this depending on course or system settings. * * Default returns true. * * @param \stdClass $course Course object * @param \cm_info $cm Course-module currently being edited (null if none) * @param \section_info $section Section currently being edited (null if none) */ protected function allow_add($course, \cm_info $cm = null, \section_info $section = null) { return true; } /** * Gets a list of string identifiers (in the plugin's language file) that * are required in JavaScript for this plugin. The default returns nothing. * * You do not need to include the 'title' string (which is used by core) as * this is automatically added. * * @return array Array of required string identifiers */ protected function get_javascript_strings() { return array(); } /** * Gets additional parameters for the plugin's initInner function. * * Default returns no parameters. * * @param \stdClass $course Course object * @param \cm_info $cm Course-module currently being edited (null if none) * @param \section_info $section Section currently being edited (null if none) * @return array Array of parameters for the JavaScript function */ protected function get_javascript_init_params($course, \cm_info $cm = null, \section_info $section = null) { return array(); } /** * Gets the Frankenstyle component name for this plugin. * * @return string The component name for this plugin */ protected function get_component() { return preg_replace('~^(availability_.*?)\\\\frontend$~', '$1', get_class($this)); } /** * Includes JavaScript for the main system and all plugins. * * @param \stdClass $course Course object * @param \cm_info $cm Course-module currently being edited (null if none) * @param \section_info $section Section currently being edited (null if none) */ public static function include_all_javascript($course, \cm_info $cm = null, \section_info $section = null) { global $PAGE; // Prepare array of required YUI modules. It is bad for performance to // make multiple yui_module calls, so we group all the plugin modules // into a single call (the main init function will call init for each // plugin). $modules = array('moodle-core_availability-form', 'base', 'node', 'panel', 'moodle-core-notification-dialogue', 'json'); // Work out JS to include for all components. $pluginmanager = \core_plugin_manager::instance(); $enabled = $pluginmanager->get_enabled_plugins('availability'); $componentparams = new \stdClass(); foreach ($enabled as $plugin => $info) { // Create plugin front-end object. $class = '\availability_' . $plugin . '\frontend'; $frontend = new $class(); // Add to array of required YUI modules. $component = $frontend->get_component(); $modules[] = 'moodle-' . $component . '-form'; // Get parameters for this plugin. $componentparams->{$plugin} = array($component, $frontend->allow_add($course, $cm, $section), $frontend->get_javascript_init_params($course, $cm, $section)); // Include strings for this plugin. $identifiers = $frontend->get_javascript_strings(); $identifiers[] = 'title'; $identifiers[] = 'description'; $PAGE->requires->strings_for_js($identifiers, $component); } // Include all JS (in one call). The init function runs on DOM ready. $PAGE->requires->yui_module($modules, 'M.core_availability.form.init', array($componentparams), null, true); // Include main strings. $PAGE->requires->strings_for_js(array('none', 'cancel', 'delete', 'choosedots'), 'moodle'); $PAGE->requires->strings_for_js(array('addrestriction', 'invalid', 'listheader_sign_before', 'listheader_sign_pos', 'listheader_sign_neg', 'listheader_single', 'listheader_multi_after', 'listheader_multi_before', 'listheader_multi_or', 'listheader_multi_and', 'unknowncondition', 'hide_verb', 'hidden_individual', 'show_verb', 'shown_individual', 'hidden_all', 'shown_all', 'condition_group', 'condition_group_info', 'and', 'or', 'label_multi', 'label_sign', 'setheading', 'itemheading', 'missingplugin', 'disabled_verb'), 'availability'); } /** * For use within forms, reports any validation errors from the availability * field. * * @param array $data Form data fields * @param array $errors Error array */ public static function report_validation_errors(array $data, array &$errors) { // Empty value is allowed! if ($data['availabilityconditionsjson'] === '') { return; } // Decode value. $decoded = json_decode($data['availabilityconditionsjson']); if (!$decoded) { // This shouldn't be possible. throw new \coding_exception('Invalid JSON from availabilityconditionsjson field'); } if (!empty($decoded->errors)) { $error = ''; foreach ($decoded->errors as $stringinfo) { list ($component, $stringname) = explode(':', $stringinfo); if ($error !== '') { $error .= ' '; } $error .= get_string($stringname, $component); } $errors['availabilityconditionsjson'] = $error; } } /** * Converts an associative array into an array of objects with two fields. * * This is necessary because JavaScript associative arrays/objects are not * ordered (at least officially according to the language specification). * * @param array $inarray Associative array key => value * @param string $keyname Name to use for key in resulting array objects * @param string $valuename Name to use for value in resulting array objects * @return array Non-associative (numeric) array */ protected static function convert_associative_array_for_js(array $inarray, $keyname, $valuename) { $result = array(); foreach ($inarray as $key => $value) { $result[] = (object)array($keyname => $key, $valuename => $value); } return $result; } }