Ignore:
Timestamp:
May 2, 2016, 12:09:23 PM (3 years ago)
Author:
jrpelegrina
Message:

Updated to moodle 3.0.3

Location:
moodle/trunk/fuentes/availability
Files:
2 added
60 edited

Legend:

Unmodified
Added
Removed
  • moodle/trunk/fuentes/availability/classes/info.php

    r136 r1331  
    312312     * @param \base_logger $logger Logger for any warnings
    313313     * @param int $dateoffset Date offset to be added to any dates (0 = none)
    314      */
    315     public function update_after_restore($restoreid, $courseid, \base_logger $logger, $dateoffset) {
     314     * @param \base_task $task Restore task
     315     */
     316    public function update_after_restore($restoreid, $courseid, \base_logger $logger,
     317            $dateoffset, \base_task $task) {
    316318        $tree = $this->get_availability_tree();
    317319        // Set static data for use by get_restore_date_offset function.
    318         self::$restoreinfo = array('restoreid' => $restoreid, 'dateoffset' => $dateoffset);
     320        self::$restoreinfo = array('restoreid' => $restoreid, 'dateoffset' => $dateoffset,
     321                'task' => $task);
    319322        $changed = $tree->update_after_restore($restoreid, $courseid, $logger,
    320323                $this->get_thing_name());
    321324        if ($changed) {
    322325            // Save modified data.
    323             $structure = $tree->save();
    324             $this->set_in_database(json_encode($structure));
     326            if ($tree->is_empty()) {
     327                // If the tree is empty, but the tree has changed, remove this condition.
     328                $this->set_in_database(null);
     329            } else {
     330                $structure = $tree->save();
     331                $this->set_in_database(json_encode($structure));
     332            }
    325333        }
    326334    }
     
    342350        }
    343351        return self::$restoreinfo['dateoffset'];
     352    }
     353
     354    /**
     355     * Gets the restore task (specifically, the task that calls the
     356     * update_after_restore method) for the current restore.
     357     *
     358     * @param string $restoreid Restore identifier
     359     * @return \base_task Restore task
     360     * @throws coding_exception If not in a restore (or not in that restore)
     361     */
     362    public static function get_restore_task($restoreid) {
     363        if (!self::$restoreinfo) {
     364            throw new coding_exception('Only valid during restore');
     365        }
     366        if (self::$restoreinfo['restoreid'] !== $restoreid) {
     367            throw new coding_exception('Data not available for that restore id');
     368        }
     369        return self::$restoreinfo['task'];
    344370    }
    345371
     
    609635        $tree = $this->get_availability_tree();
    610636        $checker = new capability_checker($this->get_context());
     637
     638        // Filter using availability tree.
    611639        $this->modinfo = get_fast_modinfo($this->get_course());
    612         $result = $tree->filter_user_list($users, false, $this, $checker);
     640        $filtered = $tree->filter_user_list($users, false, $this, $checker);
    613641        $this->modinfo = null;
     642
     643        // Include users in the result if they're either in the filtered list,
     644        // or they have viewhidden. This logic preserves ordering of the
     645        // passed users array.
     646        $result = array();
     647        $canviewhidden = $checker->get_users_by_capability($this->get_view_hidden_capability());
     648        foreach ($users as $userid => $data) {
     649            if (array_key_exists($userid, $filtered) || array_key_exists($userid, $canviewhidden)) {
     650                $result[$userid] = $users[$userid];
     651            }
     652        }
     653
    614654        return $result;
    615655    }
     656
     657    /**
     658     * Gets the capability used to view hidden activities/sections (as
     659     * appropriate).
     660     *
     661     * @return string Name of capability used to view hidden items of this type
     662     */
     663    protected abstract function get_view_hidden_capability();
    616664
    617665    /**
     
    619667     * by the conditions applied in the availability API, similar to calling
    620668     * get_enrolled_users and then filter_user_list. As for filter_user_list,
    621      * this ONLY filteres out users with conditions that are marked as applying
     669     * this ONLY filters out users with conditions that are marked as applying
    622670     * to user lists. For example, group conditions are included but date
    623671     * conditions are not included.
     
    641689            return array('', array());
    642690        }
     691
     692        // Get SQL for the availability filter.
    643693        $tree = $this->get_availability_tree();
    644         return $tree->get_user_list_sql(false, $this, $onlyactive);
     694        list ($filtersql, $filterparams) = $tree->get_user_list_sql(false, $this, $onlyactive);
     695        if ($filtersql === '') {
     696            // No restrictions, so return empty query.
     697            return array('', array());
     698        }
     699
     700        // Get SQL for the view hidden list.
     701        list ($viewhiddensql, $viewhiddenparams) = get_enrolled_sql(
     702                $this->get_context(), $this->get_view_hidden_capability(), 0, $onlyactive);
     703
     704        // Result is a union of the two.
     705        return array('(' . $filtersql . ') UNION (' . $viewhiddensql . ')',
     706                array_merge($filterparams, $viewhiddenparams));
    645707    }
    646708
     
    652714     * object.
    653715     *
    654      * @param string $info Info string
     716     * @param \renderable|string $inforenderable Info string or renderable
    655717     * @param int|\stdClass $courseorid
    656718     * @return string Correctly formatted info string
    657719     */
    658     public static function format_info($info, $courseorid) {
     720    public static function format_info($inforenderable, $courseorid) {
     721        global $PAGE;
     722
     723        // Use renderer if required.
     724        if (is_string($inforenderable)) {
     725            $info = $inforenderable;
     726        } else {
     727            $renderer = $PAGE->get_renderer('core', 'availability');
     728            $info = $renderer->render($inforenderable);
     729        }
     730
    659731        // Don't waste time if there are no special tags.
    660732        if (strpos($info, '<AVAILABILITY_') === false) {
  • moodle/trunk/fuentes/availability/classes/info_module.php

    r136 r1331  
    110110    }
    111111
     112    protected function get_view_hidden_capability() {
     113        return 'moodle/course:viewhiddenactivities';
     114    }
     115
    112116    public function get_user_list_sql($onlyactive = true) {
    113117        global $CFG, $DB;
     
    181185                $cmorid = $cmorid->id;
    182186            }
    183             $cm = $DB->get_record('course_modules', array('id' => $cmorid), '*', MUST_EXIST);
     187            $cm = $DB->get_record('course_modules', array('id' => $cmorid));
     188            if (!$cm) {
     189                // In some error cases, the course module may not exist.
     190                debugging('info_module::is_user_visible called with invalid cmid ' . $cmorid, DEBUG_DEVELOPER);
     191                return false;
     192            }
    184193        }
    185194
  • moodle/trunk/fuentes/availability/classes/info_section.php

    r136 r1331  
    5757    }
    5858
     59    protected function get_view_hidden_capability() {
     60        return 'moodle/course:viewhiddensections';
     61    }
     62
    5963    protected function set_in_database($availability) {
    6064        global $DB;
  • moodle/trunk/fuentes/availability/classes/tree.php

    r136 r1331  
    329329        foreach ($this->children as $index => $child) {
    330330            if (!$child->is_applied_to_user_lists()) {
    331                 continue;
     331                if ($andoperator) {
     332                    continue;
     333                } else {
     334                    // OR condition with one option that doesn't restrict user
     335                    // lists = everyone is allowed.
     336                    $anyconditions = false;
     337                    break;
     338                }
    332339            }
    333340            $childresult = $child->filter_user_list($users, $innernot, $info, $checker);
     
    360367        foreach ($this->children as $index => $child) {
    361368            if (!$child->is_applied_to_user_lists()) {
    362                 continue;
     369                if ($andoperator) {
     370                    continue;
     371                } else {
     372                    // OR condition with one option that doesn't restrict user
     373                    // lists = everyone is allowed.
     374                    $childresults = array();
     375                    break;
     376                }
    363377            }
    364378            $childresult = $child->get_user_list_sql($innernot, $info, $onlyactive);
     
    472486     * @param bool $root True if this is the root item
    473487     * @param bool $hidden Staff display; true if this tree has show=false (from parent)
     488     * @return string|renderable Information to render
    474489     */
    475490    protected function get_full_information_recursive(
    476491            $not, info $info, result $result = null, $root, $hidden = false) {
    477         global $PAGE;
    478 
    479492        // Get list of children - either full list, or those which are shown.
    480493        $children = $this->children;
     
    551564
    552565        // Format output for display.
    553         $renderer = $PAGE->get_renderer('core', 'availability');
    554         return $renderer->multiple_messages($root, $andoperator, $treehidden, $items);
     566        return new \core_availability_multiple_messages($root, $andoperator, $treehidden, $items);
    555567    }
    556568
     
    664676            \base_logger $logger, $name) {
    665677        $changed = false;
    666         foreach ($this->children as $child) {
    667             $thischanged = $child->update_after_restore($restoreid, $courseid,
    668                     $logger, $name);
    669             $changed = $changed || $thischanged;
     678        foreach ($this->children as $index => $child) {
     679            if ($child->include_after_restore($restoreid, $courseid, $logger, $name,
     680                    info::get_restore_task($restoreid))) {
     681                $thischanged = $child->update_after_restore($restoreid, $courseid,
     682                        $logger, $name);
     683                $changed = $changed || $thischanged;
     684            } else {
     685                unset($this->children[$index]);
     686                unset($this->showchildren[$index]);
     687                $this->showchildren = array_values($this->showchildren);
     688                $changed = true;
     689            }
    670690        }
    671691        return $changed;
  • moodle/trunk/fuentes/availability/classes/tree_node.php

    r136 r1331  
    8484
    8585    /**
     86     * Checks whether this node should be included after restore or not. The
     87     * node may be removed depending on restore settings, which you can get from
     88     * the $task object.
     89     *
     90     * By default nodes are still included after restore.
     91     *
     92     * @param string $restoreid Restore ID
     93     * @param int $courseid ID of target course
     94     * @param \base_logger $logger Logger for any warnings
     95     * @param string $name Name of this item (for use in warning messages)
     96     * @param \base_task $task Current restore task
     97     * @return bool True if there was any change
     98     */
     99    public function include_after_restore($restoreid, $courseid, \base_logger $logger, $name,
     100            \base_task $task) {
     101        return true;
     102    }
     103
     104    /**
    86105     * Updates this node after restore, returning true if anything changed.
    87106     * The default behaviour is simply to return false. If there is a problem
     
    89108     *
    90109     * Note: If you need information about the date offset, call
    91      * \core_availability\info::get_restore_date_offset($restoreid).
     110     * \core_availability\info::get_restore_date_offset($restoreid). For
     111     * information on the restoring task and its settings, call
     112     * \core_availability\info::get_restore_task($restoreid).
    92113     *
    93114     * @param string $restoreid Restore ID
     
    140161    /**
    141162     * Tests this condition against a user list. Users who do not meet the
    142      * condition will be removed from the list.
     163     * condition will be removed from the list, unless they have the ability
     164     * to view hidden activities/sections.
    143165     *
    144166     * This function must be implemented if is_applied_to_user_lists returns
     
    150172     * Within this function, if you need to check capabilities, please use
    151173     * the provided checker which caches results where possible.
     174     *
     175     * Conditions do not need to check the viewhiddenactivities or
     176     * viewhiddensections capabilities. These are handled by
     177     * core_availability\info::filter_user_list.
    152178     *
    153179     * @param array $users Array of userid => object
     
    168194     * by the conditions applied in the availability API, similar to calling
    169195     * get_enrolled_users and then filter_user_list. As for filter_user_list,
    170      * this ONLY filteres out users with conditions that are marked as applying
     196     * this ONLY filters out users with conditions that are marked as applying
    171197     * to user lists. For example, group conditions are included but date
    172198     * conditions are not included.
     
    180206     *
    181207     * If there are no conditions, the returned result is array('', array()).
     208     *
     209     * Conditions do not need to check the viewhiddenactivities or
     210     * viewhiddensections capabilities. These are handled by
     211     * core_availability\info::get_user_list_sql.
    182212     *
    183213     * @param bool $not True if this condition is applying in negative mode
  • moodle/trunk/fuentes/availability/condition/completion/classes/condition.php

    r136 r1331  
    5454    public function __construct($structure) {
    5555        // Get cmid.
    56         if (isset($structure->cm) && is_int($structure->cm)) {
    57             $this->cmid = $structure->cm;
     56        if (isset($structure->cm) && is_number($structure->cm)) {
     57            $this->cmid = (int)$structure->cm;
    5858        } else {
    5959            throw new \coding_exception('Missing or invalid ->cm for completion condition');
  • moodle/trunk/fuentes/availability/condition/completion/tests/behat/availability_completion.feature

    r136 r1331  
    1717      | teacher1 | C1     | editingteacher |
    1818      | student1 | C1     | student        |
    19     And I log in as "admin"
    20     And I set the following administration settings values:
    21       | Enable conditional access  | 1 |
    22       | Enable completion tracking | 1 |
    23     And I log out
     19    And the following config values are set as admin:
     20      | enableavailability  | 1 |
     21      | enablecompletion | 1 |
    2422
    2523  @javascript
     
    2725    # Basic setup.
    2826    Given I log in as "teacher1"
     27    And I am on site homepage
    2928    And I follow "Course 1"
    3029    And I turn editing mode on
     
    5352    When I log out
    5453    And I log in as "student1"
     54    And I am on site homepage
    5555    And I follow "Course 1"
    5656
  • moodle/trunk/fuentes/availability/condition/completion/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_completion';
  • moodle/trunk/fuentes/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-debug.js

    r136 r1331  
    2626M.availability_completion.form.getNode = function(json) {
    2727    // Create HTML structure.
    28     var strings = M.str.availability_completion;
    29     var html = strings.title + ' <span class="availability-group"><label>' +
    30             '<span class="accesshide">' + strings.label_cm + ' </span>' +
    31             '<select name="cm" title="' + strings.label_cm + '">' +
    32             '<option value="0">' + M.str.moodle.choosedots + '</option>';
     28    var html = M.util.get_string('title', 'availability_completion') + ' <span class="availability-group"><label>' +
     29            '<span class="accesshide">' + M.util.get_string('label_cm', 'availability_completion') + ' </span>' +
     30            '<select name="cm" title="' + M.util.get_string('label_cm', 'availability_completion') + '">' +
     31            '<option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    3332    for (var i = 0; i < this.cms.length; i++) {
    3433        var cm = this.cms[i];
     
    3635        html += '<option value="' + cm.id + '">' + cm.name + '</option>';
    3736    }
    38     html += '</select></label> <label><span class="accesshide">' + strings.label_completion +
    39             ' </span><select name="e" title="' + strings.label_completion + '">' +
    40             '<option value="1">' + strings.option_complete + '</option>' +
    41             '<option value="0">' + strings.option_incomplete + '</option>' +
    42             '<option value="2">' + strings.option_pass + '</option>' +
    43             '<option value="3">' + strings.option_fail + '</option>' +
     37    html += '</select></label> <label><span class="accesshide">' +
     38                M.util.get_string('label_completion', 'availability_completion') +
     39            ' </span><select name="e" title="' + M.util.get_string('label_completion', 'availability_completion') + '">' +
     40            '<option value="1">' + M.util.get_string('option_complete', 'availability_completion') + '</option>' +
     41            '<option value="0">' + M.util.get_string('option_incomplete', 'availability_completion') + '</option>' +
     42            '<option value="2">' + M.util.get_string('option_pass', 'availability_completion') + '</option>' +
     43            '<option value="3">' + M.util.get_string('option_fail', 'availability_completion') + '</option>' +
    4444            '</select></label></span>';
    4545    var node = Y.Node.create('<span>' + html + '</span>');
  • moodle/trunk/fuentes/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_completion-form",function(e,t){M.availability_completion=M.availability_completion||{},M.availability_completion.form=e.Object(M.core_availability.plugin),M.availability_completion.form.initInner=function(e){this.cms=e},M.availability_completion.form.getNode=function(t){var n=M.str.availability_completion,r=n.title+' <span class="availability-group"><label>'+'<span class="accesshide">'+n.label_cm+" </span>"+'<select name="cm" title="'+n.label_cm+'">'+'<option value="0">'+M.str.moodle.choosedots+"</option>";for(var i=0;i<this.cms.length;i++){var s=this.cms[i];r+='<option value="'+s.id+'">'+s.name+"</option>"}r+='</select></label> <label><span class="accesshide">'+n.label_completion+' </span><select name="e" title="'+n.label_completion+'">'+'<option value="1">'+n.option_complete+"</option>"+'<option value="0">'+n.option_incomplete+"</option>"+'<option value="2">'+n.option_pass+"</option>"+'<option value="3">'+n.option_fail+"</option>"+"</select></label></span>";var o=e.Node.create("<span>"+r+"</span>");t.cm!==undefined&&o.one("select[name=cm] > option[value="+t.cm+"]")&&o.one("select[name=cm]").set("value",""+t.cm),t.e!==undefined&&o.one("select[name=e]").set("value",""+t.e);if(!M.availability_completion.form.addedEvents){M.availability_completion.form.addedEvents=!0;var u=e.one("#fitem_id_availabilityconditionsjson");u.delegate("change",function(){M.core_availability.form.update()},".availability_completion select")}return o},M.availability_completion.form.fillValue=function(e,t){e.cm=parseInt(t.one("select[name=cm]").get("value"),10),e.e=parseInt(t.one("select[name=e]").get("value"),10)},M.availability_completion.form.fillErrors=function(e,t){var n=parseInt(t.one("select[name=cm]").get("value"),10);n===0&&e.push("availability_completion:error_selectcmid")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_completion-form",function(e,t){M.availability_completion=M.availability_completion||{},M.availability_completion.form=e.Object(M.core_availability.plugin),M.availability_completion.form.initInner=function(e){this.cms=e},M.availability_completion.form.getNode=function(t){var n=M.util.get_string("title","availability_completion")+' <span class="availability-group"><label>'+'<span class="accesshide">'+M.util.get_string("label_cm","availability_completion")+" </span>"+'<select name="cm" title="'+M.util.get_string("label_cm","availability_completion")+'">'+'<option value="0">'+M.util.get_string("choosedots","moodle")+"</option>";for(var r=0;r<this.cms.length;r++){var i=this.cms[r];n+='<option value="'+i.id+'">'+i.name+"</option>"}n+='</select></label> <label><span class="accesshide">'+M.util.get_string("label_completion","availability_completion")+' </span><select name="e" title="'+M.util.get_string("label_completion","availability_completion")+'">'+'<option value="1">'+M.util.get_string("option_complete","availability_completion")+"</option>"+'<option value="0">'+M.util.get_string("option_incomplete","availability_completion")+"</option>"+'<option value="2">'+M.util.get_string("option_pass","availability_completion")+"</option>"+'<option value="3">'+M.util.get_string("option_fail","availability_completion")+"</option>"+"</select></label></span>";var s=e.Node.create("<span>"+n+"</span>");t.cm!==undefined&&s.one("select[name=cm] > option[value="+t.cm+"]")&&s.one("select[name=cm]").set("value",""+t.cm),t.e!==undefined&&s.one("select[name=e]").set("value",""+t.e);if(!M.availability_completion.form.addedEvents){M.availability_completion.form.addedEvents=!0;var o=e.one("#fitem_id_availabilityconditionsjson");o.delegate("change",function(){M.core_availability.form.update()},".availability_completion select")}return s},M.availability_completion.form.fillValue=function(e,t){e.cm=parseInt(t.one("select[name=cm]").get("value"),10),e.e=parseInt(t.one("select[name=e]").get("value"),10)},M.availability_completion.form.fillErrors=function(e,t){var n=parseInt(t.one("select[name=cm]").get("value"),10);n===0&&e.push("availability_completion:error_selectcmid")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/completion/yui/build/moodle-availability_completion-form/moodle-availability_completion-form.js

    r136 r1331  
    2626M.availability_completion.form.getNode = function(json) {
    2727    // Create HTML structure.
    28     var strings = M.str.availability_completion;
    29     var html = strings.title + ' <span class="availability-group"><label>' +
    30             '<span class="accesshide">' + strings.label_cm + ' </span>' +
    31             '<select name="cm" title="' + strings.label_cm + '">' +
    32             '<option value="0">' + M.str.moodle.choosedots + '</option>';
     28    var html = M.util.get_string('title', 'availability_completion') + ' <span class="availability-group"><label>' +
     29            '<span class="accesshide">' + M.util.get_string('label_cm', 'availability_completion') + ' </span>' +
     30            '<select name="cm" title="' + M.util.get_string('label_cm', 'availability_completion') + '">' +
     31            '<option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    3332    for (var i = 0; i < this.cms.length; i++) {
    3433        var cm = this.cms[i];
     
    3635        html += '<option value="' + cm.id + '">' + cm.name + '</option>';
    3736    }
    38     html += '</select></label> <label><span class="accesshide">' + strings.label_completion +
    39             ' </span><select name="e" title="' + strings.label_completion + '">' +
    40             '<option value="1">' + strings.option_complete + '</option>' +
    41             '<option value="0">' + strings.option_incomplete + '</option>' +
    42             '<option value="2">' + strings.option_pass + '</option>' +
    43             '<option value="3">' + strings.option_fail + '</option>' +
     37    html += '</select></label> <label><span class="accesshide">' +
     38                M.util.get_string('label_completion', 'availability_completion') +
     39            ' </span><select name="e" title="' + M.util.get_string('label_completion', 'availability_completion') + '">' +
     40            '<option value="1">' + M.util.get_string('option_complete', 'availability_completion') + '</option>' +
     41            '<option value="0">' + M.util.get_string('option_incomplete', 'availability_completion') + '</option>' +
     42            '<option value="2">' + M.util.get_string('option_pass', 'availability_completion') + '</option>' +
     43            '<option value="3">' + M.util.get_string('option_fail', 'availability_completion') + '</option>' +
    4444            '</select></label></span>';
    4545    var node = Y.Node.create('<span>' + html + '</span>');
  • moodle/trunk/fuentes/availability/condition/completion/yui/src/form/js/form.js

    r136 r1331  
    2424M.availability_completion.form.getNode = function(json) {
    2525    // Create HTML structure.
    26     var strings = M.str.availability_completion;
    27     var html = strings.title + ' <span class="availability-group"><label>' +
    28             '<span class="accesshide">' + strings.label_cm + ' </span>' +
    29             '<select name="cm" title="' + strings.label_cm + '">' +
    30             '<option value="0">' + M.str.moodle.choosedots + '</option>';
     26    var html = M.util.get_string('title', 'availability_completion') + ' <span class="availability-group"><label>' +
     27            '<span class="accesshide">' + M.util.get_string('label_cm', 'availability_completion') + ' </span>' +
     28            '<select name="cm" title="' + M.util.get_string('label_cm', 'availability_completion') + '">' +
     29            '<option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    3130    for (var i = 0; i < this.cms.length; i++) {
    3231        var cm = this.cms[i];
     
    3433        html += '<option value="' + cm.id + '">' + cm.name + '</option>';
    3534    }
    36     html += '</select></label> <label><span class="accesshide">' + strings.label_completion +
    37             ' </span><select name="e" title="' + strings.label_completion + '">' +
    38             '<option value="1">' + strings.option_complete + '</option>' +
    39             '<option value="0">' + strings.option_incomplete + '</option>' +
    40             '<option value="2">' + strings.option_pass + '</option>' +
    41             '<option value="3">' + strings.option_fail + '</option>' +
     35    html += '</select></label> <label><span class="accesshide">' +
     36                M.util.get_string('label_completion', 'availability_completion') +
     37            ' </span><select name="e" title="' + M.util.get_string('label_completion', 'availability_completion') + '">' +
     38            '<option value="1">' + M.util.get_string('option_complete', 'availability_completion') + '</option>' +
     39            '<option value="0">' + M.util.get_string('option_incomplete', 'availability_completion') + '</option>' +
     40            '<option value="2">' + M.util.get_string('option_pass', 'availability_completion') + '</option>' +
     41            '<option value="3">' + M.util.get_string('option_fail', 'availability_completion') + '</option>' +
    4242            '</select></label></span>';
    4343    var node = Y.Node.create('<span>' + html + '</span>');
  • moodle/trunk/fuentes/availability/condition/date/classes/condition.php

    r136 r1331  
    235235        return false;
    236236    }
     237
     238    /**
     239     * Changes all date restrictions on a course by the specified shift amount.
     240     * Used by the course reset feature.
     241     *
     242     * @param int $courseid Course id
     243     * @param int $timeshift Offset in seconds
     244     */
     245    public static function update_all_dates($courseid, $timeshift) {
     246        global $DB;
     247
     248        $modinfo = get_fast_modinfo($courseid);
     249        $anychanged = false;
     250
     251        // Adjust dates from all course modules.
     252        foreach ($modinfo->cms as $cm) {
     253            if (!$cm->availability) {
     254                continue;
     255            }
     256            $info = new \core_availability\info_module($cm);
     257            $tree = $info->get_availability_tree();
     258            $dates = $tree->get_all_children('availability_date\condition');
     259            $changed = false;
     260            foreach ($dates as $date) {
     261                $date->time += $timeshift;
     262                $changed = true;
     263            }
     264
     265            // Save the updated course module.
     266            if ($changed) {
     267                $DB->set_field('course_modules', 'availability', json_encode($tree->save()),
     268                        array('id' => $cm->id));
     269                $anychanged = true;
     270            }
     271        }
     272
     273        // Adjust dates from all course sections.
     274        foreach ($modinfo->get_section_info_all() as $section) {
     275            if (!$section->availability) {
     276                continue;
     277            }
     278
     279            $info = new \core_availability\info_section($section);
     280            $tree = $info->get_availability_tree();
     281            $dates = $tree->get_all_children('availability_date\condition');
     282            $changed = false;
     283            foreach ($dates as $date) {
     284                $date->time += $timeshift;
     285                $changed = true;
     286            }
     287
     288            // Save the updated course module.
     289            if ($changed) {
     290                $DB->set_field('course_sections', 'availability', json_encode($tree->save()),
     291                        array('id' => $section->id));
     292                $anychanged = true;
     293            }
     294        }
     295
     296        // Ensure course cache is cleared if required.
     297        if ($anychanged) {
     298            rebuild_course_cache($courseid, true);
     299        }
     300    }
    237301}
  • moodle/trunk/fuentes/availability/condition/date/tests/behat/availability_date.feature

    r136 r1331  
    1717      | teacher1 | C1     | editingteacher |
    1818      | student1 | C1     | student        |
    19     And I log in as "admin"
    20     And I set the following administration settings values:
    21       | Enable conditional access  | 1 |
    22     And I log out
     19    And the following config values are set as admin:
     20      | enableavailability  | 1 |
    2321
    2422  @javascript
     
    2624    # Basic setup.
    2725    Given I log in as "teacher1"
     26    And I am on site homepage
    2827    And I follow "Course 1"
    2928    And I turn editing mode on
     
    5958    When I log out
    6059    And I log in as "student1"
     60    And I am on site homepage
    6161    And I follow "Course 1"
    6262
  • moodle/trunk/fuentes/availability/condition/date/tests/condition_test.php

    r136 r1331  
    2626
    2727use availability_date\condition;
     28use core_availability\tree;
    2829
    2930/**
     
    4849     */
    4950    public function test_in_tree() {
    50         global $SITE, $USER;
     51        global $SITE, $USER, $CFG;
    5152        $this->resetAfterTest();
    5253        $this->setAdminUser();
     
    5455        // Set server timezone for test. (Important as otherwise the timezone
    5556        // could be anything - this is modified by other unit tests, too.)
    56         date_default_timezone_set('UTC');
     57        $this->setTimezone('UTC');
    5758
    5859        // SEt user to GMT+5.
     
    180181     */
    181182    public function test_get_description() {
    182         global $SITE;
     183        global $SITE, $CFG;
     184
     185        $this->resetAfterTest();
     186        $this->setTimezone('UTC');
    183187
    184188        $modinfo = get_fast_modinfo($SITE);
     
    234238        $this->assertRegExp('~from.*5 March 2014([^0-9]*)$~', $information);
    235239    }
     240
     241    /**
     242     * Tests the update_all_dates function.
     243     */
     244    public function test_update_all_dates() {
     245        global $DB;
     246        $this->resetAfterTest();
     247
     248        // Create a course with 3 pages.
     249        $generator = $this->getDataGenerator();
     250        $course = $generator->create_course();
     251        $rec = array('course' => $course);
     252        $page1 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
     253        $page2 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
     254        $page3 = $generator->get_plugin_generator('mod_page')->create_instance($rec);
     255
     256        // Set the availability page 2 to a simple date condition. You can access
     257        // it from 1337 onwards.
     258        $simplecondition = tree::get_root_json(array(
     259                condition::get_json(condition::DIRECTION_FROM, 1337)));
     260        $DB->set_field('course_modules', 'availability',
     261                json_encode($simplecondition), array('id' => $page2->cmid));
     262
     263        // Set page 3 to a complex set of conditions including a nested date condition.
     264        // You can access it until 1459, *or* after 2810 if you belong to a group.
     265        $complexcondition = tree::get_root_json(array(
     266                condition::get_json(condition::DIRECTION_UNTIL, 1459),
     267                tree::get_nested_json(array(
     268                    condition::get_json(condition::DIRECTION_FROM, 2810),
     269                    \availability_group\condition::get_json()))),
     270                tree::OP_OR);
     271        $DB->set_field('course_modules', 'availability',
     272                json_encode($complexcondition), array('id' => $page3->cmid));
     273
     274        // Now use the update_all_dates function to move date forward 100000.
     275        condition::update_all_dates($course->id, 100000);
     276
     277        // Get the expected conditions after adjusting time, and compare to database.
     278        $simplecondition->c[0]->t = 101337;
     279        $complexcondition->c[0]->t = 101459;
     280        $complexcondition->c[1]->c[0]->t = 102810;
     281        $this->assertEquals($simplecondition, json_decode(
     282                $DB->get_field('course_modules', 'availability', array('id' => $page2->cmid))));
     283        $this->assertEquals($complexcondition, json_decode(
     284                $DB->get_field('course_modules', 'availability', array('id' => $page3->cmid))));
     285
     286        // The one without availability conditions should still be null.
     287        $this->assertNull($DB->get_field('course_modules', 'availability', array('id' => $page1->cmid)));
     288    }
    236289}
  • moodle/trunk/fuentes/availability/condition/date/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_date';
  • moodle/trunk/fuentes/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-debug.js

    r136 r1331  
    3030
    3131M.availability_date.form.getNode = function(json) {
    32     var strings = M.str.availability_date;
    33     var html = strings.direction_before + ' <span class="availability-group">' +
    34             '<label><span class="accesshide">' + strings.direction_label + ' </span>' +
     32    var html = M.util.get_string('direction_before', 'availability_date') + ' <span class="availability-group">' +
     33            '<label><span class="accesshide">' + M.util.get_string('direction_label', 'availability_date') + ' </span>' +
    3534            '<select name="direction">' +
    36             '<option value="&gt;=">' + strings.direction_from + '</option>' +
    37             '<option value="&lt;">' + strings.direction_until + '</option>' +
     35            '<option value="&gt;=">' + M.util.get_string('direction_from', 'availability_date') + '</option>' +
     36            '<option value="&lt;">' + M.util.get_string('direction_until', 'availability_date') + '</option>' +
    3837            '</select></label></span> ' + this.html;
    3938    var node = Y.Node.create('<span>' + html + '</span>');
     
    5958            },
    6059            failure : function() {
    61                 window.alert(M.str.availability_date.ajaxerror);
     60                window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    6261            }
    6362        }});
     
    133132        },
    134133        failure : function() {
    135             window.alert(M.str.availability_date.ajaxerror);
     134            window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    136135        }
    137136    }});
  • moodle/trunk/fuentes/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_date-form",function(e,t){M.availability_date=M.availability_date||{},M.availability_date.form=e.Object(M.core_availability.plugin),M.availability_date.form.initInner=function(e,t){this.html=e,this.defaultTime=t},M.availability_date.form.getNode=function(t){var n=M.str.availability_date,r=n.direction_before+' <span class="availability-group">'+'<label><span class="accesshide">'+n.direction_label+" </span>"+'<select name="direction">'+'<option value="&gt;=">'+n.direction_from+"</option>"+'<option value="&lt;">'+n.direction_until+"</option>"+"</select></label></span> "+this.html,i=e.Node.create("<span>"+r+"</span>");if(t.t!==undefined){i.setData("time",t.t),i.all("select:not([name=direction])").each(function(e){e.set("disabled",!0)});var s=M.cfg.wwwroot+"/availability/condition/date/ajax.php?action=fromtime"+"&time="+t.t;e.io(s,{on:{success:function(t,n){var r=e.JSON.parse(n.responseText);for(var s in r){var o=i.one("select[name=x\\["+s+"\\]]");o.set("value",""+r[s]),o.set("disabled",!1)}},failure:function(){window.alert(M.str.availability_date.ajaxerror)}}})}else i.setData("time",this.defaultTime);t.d!==undefined&&i.one("select[name=direction]").set("value",t.d);if(!M.availability_date.form.addedEvents){M.availability_date.form.addedEvents=!0;var o=e.one("#fitem_id_availabilityconditionsjson");o.delegate("change",function(){M.core_availability.form.update()},".availability_date select[name=direction]"),o.delegate("change",function(){M.availability_date.form.updateTime(this.ancestor("span.availability_date"))},".availability_date select:not([name=direction])")}if(i.one("a[href=#]")){M.form.dateselector.init_single_date_selector(i);var u=i.one("select[name=x\\[year\\]]"),a=u.set;u.set=function(e,t){a.call(u,e,t),e==="selectedIndex"&&setTimeout(function(){M.availability_date.form.updateTime(i)},0)}}return i},M.availability_date.form.updateTime=function(t){var n=M.cfg.wwwroot+"/availability/condition/date/ajax.php?action=totime"+"&year="+t.one("select[name=x\\[year\\]]").get("value")+"&month="+t.one("select[name=x\\[month\\]]").get("value")+"&day="+t.one("select[name=x\\[day\\]]").get("value")+"&hour="+t.one("select[name=x\\[hour\\]]").get("value")+"&minute="+t.one("select[name=x\\[minute\\]]").get("value");e.io(n,{on:{success:function(e,n){t.setData("time",n.responseText),M.core_availability.form.update()},failure:function(){window.alert(M.str.availability_date.ajaxerror)}}})},M.availability_date.form.fillValue=function(e,t){e.d=t.one("select[name=direction]").get("value"),e.t=parseInt(t.getData("time"),10)}},"@VERSION@",{requires:["base","node","event","io","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_date-form",function(e,t){M.availability_date=M.availability_date||{},M.availability_date.form=e.Object(M.core_availability.plugin),M.availability_date.form.initInner=function(e,t){this.html=e,this.defaultTime=t},M.availability_date.form.getNode=function(t){var n=M.util.get_string("direction_before","availability_date")+' <span class="availability-group">'+'<label><span class="accesshide">'+M.util.get_string("direction_label","availability_date")+" </span>"+'<select name="direction">'+'<option value="&gt;=">'+M.util.get_string("direction_from","availability_date")+"</option>"+'<option value="&lt;">'+M.util.get_string("direction_until","availability_date")+"</option>"+"</select></label></span> "+this.html,r=e.Node.create("<span>"+n+"</span>");if(t.t!==undefined){r.setData("time",t.t),r.all("select:not([name=direction])").each(function(e){e.set("disabled",!0)});var i=M.cfg.wwwroot+"/availability/condition/date/ajax.php?action=fromtime"+"&time="+t.t;e.io(i,{on:{success:function(t,n){var i=e.JSON.parse(n.responseText);for(var s in i){var o=r.one("select[name=x\\["+s+"\\]]");o.set("value",""+i[s]),o.set("disabled",!1)}},failure:function(){window.alert(M.util.get_string("ajaxerror","availability_date"))}}})}else r.setData("time",this.defaultTime);t.d!==undefined&&r.one("select[name=direction]").set("value",t.d);if(!M.availability_date.form.addedEvents){M.availability_date.form.addedEvents=!0;var s=e.one("#fitem_id_availabilityconditionsjson");s.delegate("change",function(){M.core_availability.form.update()},".availability_date select[name=direction]"),s.delegate("change",function(){M.availability_date.form.updateTime(this.ancestor("span.availability_date"))},".availability_date select:not([name=direction])")}if(r.one("a[href=#]")){M.form.dateselector.init_single_date_selector(r);var o=r.one("select[name=x\\[year\\]]"),u=o.set;o.set=function(e,t){u.call(o,e,t),e==="selectedIndex"&&setTimeout(function(){M.availability_date.form.updateTime(r)},0)}}return r},M.availability_date.form.updateTime=function(t){var n=M.cfg.wwwroot+"/availability/condition/date/ajax.php?action=totime"+"&year="+t.one("select[name=x\\[year\\]]").get("value")+"&month="+t.one("select[name=x\\[month\\]]").get("value")+"&day="+t.one("select[name=x\\[day\\]]").get("value")+"&hour="+t.one("select[name=x\\[hour\\]]").get("value")+"&minute="+t.one("select[name=x\\[minute\\]]").get("value");e.io(n,{on:{success:function(e,n){t.setData("time",n.responseText),M.core_availability.form.update()},failure:function(){window.alert(M.util.get_string("ajaxerror","availability_date"))}}})},M.availability_date.form.fillValue=function(e,t){e.d=t.one("select[name=direction]").get("value"),e.t=parseInt(t.getData("time"),10)}},"@VERSION@",{requires:["base","node","event","io","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/date/yui/build/moodle-availability_date-form/moodle-availability_date-form.js

    r136 r1331  
    3030
    3131M.availability_date.form.getNode = function(json) {
    32     var strings = M.str.availability_date;
    33     var html = strings.direction_before + ' <span class="availability-group">' +
    34             '<label><span class="accesshide">' + strings.direction_label + ' </span>' +
     32    var html = M.util.get_string('direction_before', 'availability_date') + ' <span class="availability-group">' +
     33            '<label><span class="accesshide">' + M.util.get_string('direction_label', 'availability_date') + ' </span>' +
    3534            '<select name="direction">' +
    36             '<option value="&gt;=">' + strings.direction_from + '</option>' +
    37             '<option value="&lt;">' + strings.direction_until + '</option>' +
     35            '<option value="&gt;=">' + M.util.get_string('direction_from', 'availability_date') + '</option>' +
     36            '<option value="&lt;">' + M.util.get_string('direction_until', 'availability_date') + '</option>' +
    3837            '</select></label></span> ' + this.html;
    3938    var node = Y.Node.create('<span>' + html + '</span>');
     
    5958            },
    6059            failure : function() {
    61                 window.alert(M.str.availability_date.ajaxerror);
     60                window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    6261            }
    6362        }});
     
    133132        },
    134133        failure : function() {
    135             window.alert(M.str.availability_date.ajaxerror);
     134            window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    136135        }
    137136    }});
  • moodle/trunk/fuentes/availability/condition/date/yui/src/form/js/form.js

    r136 r1331  
    2828
    2929M.availability_date.form.getNode = function(json) {
    30     var strings = M.str.availability_date;
    31     var html = strings.direction_before + ' <span class="availability-group">' +
    32             '<label><span class="accesshide">' + strings.direction_label + ' </span>' +
     30    var html = M.util.get_string('direction_before', 'availability_date') + ' <span class="availability-group">' +
     31            '<label><span class="accesshide">' + M.util.get_string('direction_label', 'availability_date') + ' </span>' +
    3332            '<select name="direction">' +
    34             '<option value="&gt;=">' + strings.direction_from + '</option>' +
    35             '<option value="&lt;">' + strings.direction_until + '</option>' +
     33            '<option value="&gt;=">' + M.util.get_string('direction_from', 'availability_date') + '</option>' +
     34            '<option value="&lt;">' + M.util.get_string('direction_until', 'availability_date') + '</option>' +
    3635            '</select></label></span> ' + this.html;
    3736    var node = Y.Node.create('<span>' + html + '</span>');
     
    5756            },
    5857            failure : function() {
    59                 window.alert(M.str.availability_date.ajaxerror);
     58                window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    6059            }
    6160        }});
     
    131130        },
    132131        failure : function() {
    133             window.alert(M.str.availability_date.ajaxerror);
     132            window.alert(M.util.get_string('ajaxerror', 'availability_date'));
    134133        }
    135134    }});
  • moodle/trunk/fuentes/availability/condition/grade/classes/condition.php

    r136 r1331  
    229229                            gi.courseid = ?', array($userid, $courseid));
    230230                foreach ($rs as $record) {
    231                     if (is_null($record->finalgrade)) {
     231                    // This function produces division by zero error warnings when rawgrademax and rawgrademin
     232                    // are equal. Below change does not affect function behavior, just avoids the warning.
     233                    if (is_null($record->finalgrade) || $record->rawgrademax == $record->rawgrademin) {
    232234                        // No grade = false.
    233235                        $cachedgrades[$record->id] = false;
     
    250252                $record = $DB->get_record('grade_grades', array(
    251253                    'userid' => $userid, 'itemid' => $gradeitemid));
    252                 if ($record && !is_null($record->finalgrade)) {
     254                // This function produces division by zero error warnings when rawgrademax and rawgrademin
     255                // are equal. Below change does not affect function behavior, just avoids the warning.
     256                if ($record && !is_null($record->finalgrade) && $record->rawgrademax != $record->rawgrademin) {
    253257                    $score = (($record->finalgrade - $record->rawgrademin) * 100) /
    254258                        ($record->rawgrademax - $record->rawgrademin);
  • moodle/trunk/fuentes/availability/condition/grade/classes/frontend.php

    r136 r1331  
    5656                continue;
    5757            }
    58             $gradeoptions[$id] = $item->get_name();
     58            $gradeoptions[$id] = $item->get_name(true);
    5959        }
    6060        \core_collator::asort($gradeoptions);
  • moodle/trunk/fuentes/availability/condition/grade/tests/behat/availability_grade.feature

    r136 r1331  
    1111    And the following "users" exist:
    1212      | username | email         |
    13       | teacher1 | t@example.org |
    14       | student1 | s@example.org |
     13      | teacher1 | t@example.com |
     14      | student1 | s@example.com |
    1515    And the following "course enrolments" exist:
    1616      | user     | course | role           |
    1717      | teacher1 | C1     | editingteacher |
    1818      | student1 | C1     | student        |
    19     And I log in as "admin"
    20     And I set the following administration settings values:
    21       | Enable conditional access  | 1 |
    22     And I log out
     19    And the following config values are set as admin:
     20      | enableavailability  | 1 |
    2321
    2422  @javascript
     
    2624    # Basic setup.
    2725    Given I log in as "teacher1"
     26    And I am on site homepage
    2827    And I follow "Course 1"
    2928    And I turn editing mode on
     
    6160    And I click on "min" "checkbox" in the ".availability-item" "css_element"
    6261    And I set the field "Minimum grade percentage (inclusive)" to "50"
     62    And I click on "max" "checkbox" in the ".availability-item" "css_element"
     63    And I set the field "Maximum grade percentage (exclusive)" to "80"
    6364    And I press "Save and return to course"
     65
     66    # Check if disabling a part of the restriction is get saved.
     67    And I open "P3" actions menu
     68    And I click on "Edit settings" "link" in the "P3" activity
     69    And I expand all fieldsets
     70    And I click on "max" "checkbox" in the ".availability-item" "css_element"
     71    And I press "Save and return to course"
     72    And I open "P3" actions menu
     73    And I click on "Edit settings" "link" in the "P3" activity
     74    And I expand all fieldsets
     75    And the field "Maximum grade percentage (exclusive)" matches value ""
     76    And I follow "Course 1"
    6477
    6578    # Add a Page with a grade condition for 10%.
     
    8194    When I log out
    8295    And I log in as "student1"
     96    And I am on site homepage
    8397    And I follow "Course 1"
    8498
     
    99113    When I log out
    100114    And I log in as "teacher1"
     115    And I am on site homepage
    101116    And I follow "Course 1"
    102117
     
    104119    And I follow "A1"
    105120    And I follow "View/grade all submissions"
    106     # Pick the grade link in the row that has s@example.org in it.
    107     And I click on "//a[contains(@href, 'action=grade') and ancestor::tr/td[normalize-space(.) = 's@example.org']]/img" "xpath_element"
     121    # Pick the grade link in the row that has s@example.com in it.
     122    And I click on "//a[contains(@href, 'action=grade') and ancestor::tr/td[normalize-space(.) = 's@example.com']]/img" "xpath_element"
    108123    And I set the field "Grade out of 100" to "40"
    109124    And I click on "Save changes" "button"
     
    112127    And I log out
    113128    And I log in as "student1"
     129    And I am on site homepage
    114130    And I follow "Course 1"
    115131
  • moodle/trunk/fuentes/availability/condition/grade/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_grade';
  • moodle/trunk/fuentes/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-debug.js

    r136 r1331  
    3838
    3939    // Create HTML structure.
    40     var strings = M.str.availability_grade;
    41     var html = '<label>' + strings.title + ' <span class="availability-group">' +
    42             '<select name="id"><option value="0">' + M.str.moodle.choosedots + '</option>';
     40    var html = '<label>' + M.util.get_string('title', 'availability_grade') + ' <span class="availability-group">' +
     41            '<select name="id"><option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4342    for (var i = 0; i < this.grades.length; i++) {
    4443        var grade = this.grades[i];
     
    4746    }
    4847    html += '</select></span></label> <span class="availability-group">' +
    49             '<label><input type="checkbox" name="min"/>' + strings.option_min +
    50             '</label> <label><span class="accesshide">' + strings.label_min +
     48            '<label><input type="checkbox" name="min"/>' + M.util.get_string('option_min', 'availability_grade') +
     49            '</label> <label><span class="accesshide">' + M.util.get_string('label_min', 'availability_grade') +
    5150            '</span><input type="text" name="minval" title="' +
    52             strings.label_min + '"/></label>%</span>' +
     51            M.util.get_string('label_min', 'availability_grade') + '"/></label>%</span>' +
    5352            '<span class="availability-group">' +
    54             '<label><input type="checkbox" name="max"/>' + strings.option_max +
    55             '</label> <label><span class="accesshide">' + strings.label_max +
     53            '<label><input type="checkbox" name="max"/>' + M.util.get_string('option_max', 'availability_grade') +
     54            '</label> <label><span class="accesshide">' + M.util.get_string('label_max', 'availability_grade') +
    5655            '</span><input type="text" name="maxval" title="' +
    57             strings.label_max + '"/></label>%</span>';
     56            M.util.get_string('label_max', 'availability_grade') + '"/></label>%</span>';
    5857    var node = Y.Node.create('<span>' + html + '</span>');
    5958
     
    9695        root.delegate('click', function() {
    9796            updateCheckbox(this, true);
     97            M.core_availability.form.update();
    9898        }, '.availability_grade input[type=checkbox]');
    9999
  • moodle/trunk/fuentes/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_grade-form",function(e,t){M.availability_grade=M.availability_grade||{},M.availability_grade.form=e.Object(M.core_availability.plugin),M.availability_grade.form.grades=null,M.availability_grade.form.initInner=function(e){this.grades=e,this.nodesSoFar=0},M.availability_grade.form.getNode=function(t){this.nodesSoFar++;var n=M.str.availability_grade,r="<label>"+n.title+' <span class="availability-group">'+'<select name="id"><option value="0">'+M.str.moodle.choosedots+"</option>";for(var i=0;i<this.grades.length;i++){var s=this.grades[i];r+='<option value="'+s.id+'">'+s.name+"</option>"}r+='</select></span></label> <span class="availability-group"><label><input type="checkbox" name="min"/>'+n.option_min+'</label> <label><span class="accesshide">'+n.label_min+'</span><input type="text" name="minval" title="'+n.label_min+'"/></label>%</span>'+'<span class="availability-group">'+'<label><input type="checkbox" name="max"/>'+n.option_max+'</label> <label><span class="accesshide">'+n.label_max+'</span><input type="text" name="maxval" title="'+n.label_max+'"/></label>%</span>';var o=e.Node.create("<span>"+r+"</span>");t.id!==undefined&&o.one("select[name=id] > option[value="+t.id+"]")&&o.one("select[name=id]").set("value",""+t.id),t.min!==undefined&&(o.one("input[name=min]").set("checked",!0),o.one("input[name=minval]").set("value",t.min)),t.max!==undefined&&(o.one("input[name=max]").set("checked",!0),o.one("input[name=maxval]").set("value",t.max));var u=function(e,t){var n=e.ancestor("label").next("label").one("input"),r=e.get("checked");return n.set("disabled",!r),t&&r&&n.focus(),r};o.all("input[type=checkbox]").each(u);if(!M.availability_grade.form.addedEvents){M.availability_grade.form.addedEvents=!0;var a=e.one("#fitem_id_availabilityconditionsjson");a.delegate("change",function(){M.core_availability.form.update()},".availability_grade select[name=id]"),a.delegate("click",function(){u(this,!0)},".availability_grade input[type=checkbox]"),a.delegate("valuechange",function(){M.core_availability.form.update()},".availability_grade input[type=text]")}return o},M.availability_grade.form.fillValue=function(e,t){e.id=parseInt(t.one("select[name=id]").get("value"),10),t.one("input[name=min]").get("checked")&&(e.min=this.getValue("minval",t)),t.one("input[name=max]").get("checked")&&(e.max=this.getValue("maxval",t))},M.availability_grade.form.getValue=function(e,t){var n=t.one("input[name="+e+"]").get("value");if(!/^[0-9]+([.,][0-9]+)?$/.test(n))return n;var r=parseFloat(n.replace(",","."));return r<0||r>100?n:r},M.availability_grade.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id===0&&e.push("availability_grade:error_selectgradeid"),n.min!==undefined&&typeof n.min=="string"||n.max!==undefined&&typeof n.max=="string"?e.push("availability_grade:error_invalidnumber"):n.min!==undefined&&n.max!==undefined&&n.min>=n.max&&e.push("availability_grade:error_backwardrange")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_grade-form",function(e,t){M.availability_grade=M.availability_grade||{},M.availability_grade.form=e.Object(M.core_availability.plugin),M.availability_grade.form.grades=null,M.availability_grade.form.initInner=function(e){this.grades=e,this.nodesSoFar=0},M.availability_grade.form.getNode=function(t){this.nodesSoFar++;var n="<label>"+M.util.get_string("title","availability_grade")+' <span class="availability-group">'+'<select name="id"><option value="0">'+M.util.get_string("choosedots","moodle")+"</option>";for(var r=0;r<this.grades.length;r++){var i=this.grades[r];n+='<option value="'+i.id+'">'+i.name+"</option>"}n+='</select></span></label> <span class="availability-group"><label><input type="checkbox" name="min"/>'+M.util.get_string("option_min","availability_grade")+'</label> <label><span class="accesshide">'+M.util.get_string("label_min","availability_grade")+'</span><input type="text" name="minval" title="'+M.util.get_string("label_min","availability_grade")+'"/></label>%</span>'+'<span class="availability-group">'+'<label><input type="checkbox" name="max"/>'+M.util.get_string("option_max","availability_grade")+'</label> <label><span class="accesshide">'+M.util.get_string("label_max","availability_grade")+'</span><input type="text" name="maxval" title="'+M.util.get_string("label_max","availability_grade")+'"/></label>%</span>';var s=e.Node.create("<span>"+n+"</span>");t.id!==undefined&&s.one("select[name=id] > option[value="+t.id+"]")&&s.one("select[name=id]").set("value",""+t.id),t.min!==undefined&&(s.one("input[name=min]").set("checked",!0),s.one("input[name=minval]").set("value",t.min)),t.max!==undefined&&(s.one("input[name=max]").set("checked",!0),s.one("input[name=maxval]").set("value",t.max));var o=function(e,t){var n=e.ancestor("label").next("label").one("input"),r=e.get("checked");return n.set("disabled",!r),t&&r&&n.focus(),r};s.all("input[type=checkbox]").each(o);if(!M.availability_grade.form.addedEvents){M.availability_grade.form.addedEvents=!0;var u=e.one("#fitem_id_availabilityconditionsjson");u.delegate("change",function(){M.core_availability.form.update()},".availability_grade select[name=id]"),u.delegate("click",function(){o(this,!0),M.core_availability.form.update()},".availability_grade input[type=checkbox]"),u.delegate("valuechange",function(){M.core_availability.form.update()},".availability_grade input[type=text]")}return s},M.availability_grade.form.fillValue=function(e,t){e.id=parseInt(t.one("select[name=id]").get("value"),10),t.one("input[name=min]").get("checked")&&(e.min=this.getValue("minval",t)),t.one("input[name=max]").get("checked")&&(e.max=this.getValue("maxval",t))},M.availability_grade.form.getValue=function(e,t){var n=t.one("input[name="+e+"]").get("value");if(!/^[0-9]+([.,][0-9]+)?$/.test(n))return n;var r=parseFloat(n.replace(",","."));return r<0||r>100?n:r},M.availability_grade.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id===0&&e.push("availability_grade:error_selectgradeid"),n.min!==undefined&&typeof n.min=="string"||n.max!==undefined&&typeof n.max=="string"?e.push("availability_grade:error_invalidnumber"):n.min!==undefined&&n.max!==undefined&&n.min>=n.max&&e.push("availability_grade:error_backwardrange")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/grade/yui/build/moodle-availability_grade-form/moodle-availability_grade-form.js

    r136 r1331  
    3838
    3939    // Create HTML structure.
    40     var strings = M.str.availability_grade;
    41     var html = '<label>' + strings.title + ' <span class="availability-group">' +
    42             '<select name="id"><option value="0">' + M.str.moodle.choosedots + '</option>';
     40    var html = '<label>' + M.util.get_string('title', 'availability_grade') + ' <span class="availability-group">' +
     41            '<select name="id"><option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4342    for (var i = 0; i < this.grades.length; i++) {
    4443        var grade = this.grades[i];
     
    4746    }
    4847    html += '</select></span></label> <span class="availability-group">' +
    49             '<label><input type="checkbox" name="min"/>' + strings.option_min +
    50             '</label> <label><span class="accesshide">' + strings.label_min +
     48            '<label><input type="checkbox" name="min"/>' + M.util.get_string('option_min', 'availability_grade') +
     49            '</label> <label><span class="accesshide">' + M.util.get_string('label_min', 'availability_grade') +
    5150            '</span><input type="text" name="minval" title="' +
    52             strings.label_min + '"/></label>%</span>' +
     51            M.util.get_string('label_min', 'availability_grade') + '"/></label>%</span>' +
    5352            '<span class="availability-group">' +
    54             '<label><input type="checkbox" name="max"/>' + strings.option_max +
    55             '</label> <label><span class="accesshide">' + strings.label_max +
     53            '<label><input type="checkbox" name="max"/>' + M.util.get_string('option_max', 'availability_grade') +
     54            '</label> <label><span class="accesshide">' + M.util.get_string('label_max', 'availability_grade') +
    5655            '</span><input type="text" name="maxval" title="' +
    57             strings.label_max + '"/></label>%</span>';
     56            M.util.get_string('label_max', 'availability_grade') + '"/></label>%</span>';
    5857    var node = Y.Node.create('<span>' + html + '</span>');
    5958
     
    9695        root.delegate('click', function() {
    9796            updateCheckbox(this, true);
     97            M.core_availability.form.update();
    9898        }, '.availability_grade input[type=checkbox]');
    9999
  • moodle/trunk/fuentes/availability/condition/grade/yui/src/form/js/form.js

    r136 r1331  
    3636
    3737    // Create HTML structure.
    38     var strings = M.str.availability_grade;
    39     var html = '<label>' + strings.title + ' <span class="availability-group">' +
    40             '<select name="id"><option value="0">' + M.str.moodle.choosedots + '</option>';
     38    var html = '<label>' + M.util.get_string('title', 'availability_grade') + ' <span class="availability-group">' +
     39            '<select name="id"><option value="0">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4140    for (var i = 0; i < this.grades.length; i++) {
    4241        var grade = this.grades[i];
     
    4544    }
    4645    html += '</select></span></label> <span class="availability-group">' +
    47             '<label><input type="checkbox" name="min"/>' + strings.option_min +
    48             '</label> <label><span class="accesshide">' + strings.label_min +
     46            '<label><input type="checkbox" name="min"/>' + M.util.get_string('option_min', 'availability_grade') +
     47            '</label> <label><span class="accesshide">' + M.util.get_string('label_min', 'availability_grade') +
    4948            '</span><input type="text" name="minval" title="' +
    50             strings.label_min + '"/></label>%</span>' +
     49            M.util.get_string('label_min', 'availability_grade') + '"/></label>%</span>' +
    5150            '<span class="availability-group">' +
    52             '<label><input type="checkbox" name="max"/>' + strings.option_max +
    53             '</label> <label><span class="accesshide">' + strings.label_max +
     51            '<label><input type="checkbox" name="max"/>' + M.util.get_string('option_max', 'availability_grade') +
     52            '</label> <label><span class="accesshide">' + M.util.get_string('label_max', 'availability_grade') +
    5453            '</span><input type="text" name="maxval" title="' +
    55             strings.label_max + '"/></label>%</span>';
     54            M.util.get_string('label_max', 'availability_grade') + '"/></label>%</span>';
    5655    var node = Y.Node.create('<span>' + html + '</span>');
    5756
     
    9493        root.delegate('click', function() {
    9594            updateCheckbox(this, true);
     95            M.core_availability.form.update();
    9696        }, '.availability_grade input[type=checkbox]');
    9797
  • moodle/trunk/fuentes/availability/condition/group/classes/condition.php

    r136 r1331  
    128128    }
    129129
     130    /**
     131     * Include this condition only if we are including groups in restore, or
     132     * if it's a generic 'same activity' one.
     133     *
     134     * @param int $restoreid The restore Id.
     135     * @param int $courseid The ID of the course.
     136     * @param base_logger $logger The logger being used.
     137     * @param string $name Name of item being restored.
     138     * @param base_task $task The task being performed.
     139     *
     140     * @return Integer groupid
     141     */
     142    public function include_after_restore($restoreid, $courseid, \base_logger $logger,
     143            $name, \base_task $task) {
     144        return !$this->groupid || $task->get_setting_value('groups');
     145    }
     146
    130147    public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) {
    131148        global $DB;
     
    230247     */
    231248    public static function get_json($groupid = 0) {
    232         return (object)array('type' => 'group', 'id' => (int)$groupid);
     249        $result = (object)array('type' => 'group');
     250        // Id is only included if set.
     251        if ($groupid) {
     252            $result->id = (int)$groupid;
     253        }
     254        return $result;
    233255    }
    234256
  • moodle/trunk/fuentes/availability/condition/group/tests/behat/availability_group.feature

    r136 r1331  
    1717      | teacher1 | C1     | editingteacher |
    1818      | student1 | C1     | student        |
    19     And I log in as "admin"
    20     And I set the following administration settings values:
    21       | Enable conditional access  | 1 |
    22     And I log out
     19    And the following config values are set as admin:
     20      | enableavailability  | 1 |
    2321
    2422  @javascript
     
    2624    # Basic setup.
    2725    Given I log in as "teacher1"
     26    And I am on site homepage
    2827    And I follow "Course 1"
    2928    And I turn editing mode on
     
    4342    # This step used to be 'And I follow "C1"', but Chrome thinks the breadcrumb
    4443    # is not clickable, so we'll go via the home page instead.
    45     And I am on homepage
     44    And I am on site homepage
    4645    And I follow "Course 1"
    4746    And I add a "Page" to section "1"
     
    8988    When I log out
    9089    And I log in as "student1"
     90    And I am on site homepage
    9191    And I follow "Course 1"
    9292
     
    102102    And I log out
    103103    And I log in as "student1"
     104    And I am on site homepage
    104105    And I follow "Course 1"
    105106
  • moodle/trunk/fuentes/availability/condition/group/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_group';
  • moodle/trunk/fuentes/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-debug.js

    r136 r1331  
    3434M.availability_group.form.getNode = function(json) {
    3535    // Create HTML structure.
    36     var strings = M.str.availability_group;
    37     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     36    var html = '<label>' + M.util.get_string('title', 'availability_group') + ' <span class="availability-group">' +
    3837            '<select name="id">' +
    39             '<option value="choose">' + M.str.moodle.choosedots + '</option>' +
    40             '<option value="any">' + strings.anygroup + '</option>';
     38            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>' +
     39            '<option value="any">' + M.util.get_string('anygroup', 'availability_group') + '</option>';
    4140    for (var i = 0; i < this.groups.length; i++) {
    4241        var group = this.groups[i];
  • moodle/trunk/fuentes/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_group-form",function(e,t){M.availability_group=M.availability_group||{},M.availability_group.form=e.Object(M.core_availability.plugin),M.availability_group.form.groups=null,M.availability_group.form.initInner=function(e){this.groups=e},M.availability_group.form.getNode=function(t){var n=M.str.availability_group,r="<label>"+n.title+' <span class="availability-group">'+'<select name="id">'+'<option value="choose">'+M.str.moodle.choosedots+"</option>"+'<option value="any">'+n.anygroup+"</option>";for(var i=0;i<this.groups.length;i++){var s=this.groups[i];r+='<option value="'+s.id+'">'+s.name+"</option>"}r+="</select></span></label>";var o=e.Node.create("<span>"+r+"</span>");t.creating===undefined&&(t.id!==undefined&&o.one("select[name=id] > option[value="+t.id+"]")?o.one("select[name=id]").set("value",""+t.id):t.id===undefined&&o.one("select[name=id]").set("value","any"));if(!M.availability_group.form.addedEvents){M.availability_group.form.addedEvents=!0;var u=e.one("#fitem_id_availabilityconditionsjson");u.delegate("change",function(){M.core_availability.form.update()},".availability_group select")}return o},M.availability_group.form.fillValue=function(e,t){var n=t.one("select[name=id]").get("value");n==="choose"?e.id="choose":n!=="any"&&(e.id=parseInt(n,10))},M.availability_group.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id&&n.id==="choose"&&e.push("availability_group:error_selectgroup")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_group-form",function(e,t){M.availability_group=M.availability_group||{},M.availability_group.form=e.Object(M.core_availability.plugin),M.availability_group.form.groups=null,M.availability_group.form.initInner=function(e){this.groups=e},M.availability_group.form.getNode=function(t){var n="<label>"+M.util.get_string("title","availability_group")+' <span class="availability-group">'+'<select name="id">'+'<option value="choose">'+M.util.get_string("choosedots","moodle")+"</option>"+'<option value="any">'+M.util.get_string("anygroup","availability_group")+"</option>";for(var r=0;r<this.groups.length;r++){var i=this.groups[r];n+='<option value="'+i.id+'">'+i.name+"</option>"}n+="</select></span></label>";var s=e.Node.create("<span>"+n+"</span>");t.creating===undefined&&(t.id!==undefined&&s.one("select[name=id] > option[value="+t.id+"]")?s.one("select[name=id]").set("value",""+t.id):t.id===undefined&&s.one("select[name=id]").set("value","any"));if(!M.availability_group.form.addedEvents){M.availability_group.form.addedEvents=!0;var o=e.one("#fitem_id_availabilityconditionsjson");o.delegate("change",function(){M.core_availability.form.update()},".availability_group select")}return s},M.availability_group.form.fillValue=function(e,t){var n=t.one("select[name=id]").get("value");n==="choose"?e.id="choose":n!=="any"&&(e.id=parseInt(n,10))},M.availability_group.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id&&n.id==="choose"&&e.push("availability_group:error_selectgroup")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/group/yui/build/moodle-availability_group-form/moodle-availability_group-form.js

    r136 r1331  
    3434M.availability_group.form.getNode = function(json) {
    3535    // Create HTML structure.
    36     var strings = M.str.availability_group;
    37     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     36    var html = '<label>' + M.util.get_string('title', 'availability_group') + ' <span class="availability-group">' +
    3837            '<select name="id">' +
    39             '<option value="choose">' + M.str.moodle.choosedots + '</option>' +
    40             '<option value="any">' + strings.anygroup + '</option>';
     38            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>' +
     39            '<option value="any">' + M.util.get_string('anygroup', 'availability_group') + '</option>';
    4140    for (var i = 0; i < this.groups.length; i++) {
    4241        var group = this.groups[i];
  • moodle/trunk/fuentes/availability/condition/group/yui/src/form/js/form.js

    r136 r1331  
    3232M.availability_group.form.getNode = function(json) {
    3333    // Create HTML structure.
    34     var strings = M.str.availability_group;
    35     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     34    var html = '<label>' + M.util.get_string('title', 'availability_group') + ' <span class="availability-group">' +
    3635            '<select name="id">' +
    37             '<option value="choose">' + M.str.moodle.choosedots + '</option>' +
    38             '<option value="any">' + strings.anygroup + '</option>';
     36            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>' +
     37            '<option value="any">' + M.util.get_string('anygroup', 'availability_group') + '</option>';
    3938    for (var i = 0; i < this.groups.length; i++) {
    4039        var group = this.groups[i];
  • moodle/trunk/fuentes/availability/condition/grouping/classes/condition.php

    r136 r1331  
    159159    }
    160160
     161    /**
     162     * Include this condition only if we are including groups in restore, or
     163     * if it's a generic 'same activity' one.
     164     *
     165     * @param int $restoreid The restore Id.
     166     * @param int $courseid The ID of the course.
     167     * @param base_logger $logger The logger being used.
     168     * @param string $name Name of item being restored.
     169     * @param base_task $task The task being performed.
     170     *
     171     * @return Integer groupid
     172     */
     173    public function include_after_restore($restoreid, $courseid, \base_logger $logger,
     174            $name, \base_task $task) {
     175        return !$this->groupingid || $task->get_setting_value('groups');
     176    }
     177
    161178    public function update_after_restore($restoreid, $courseid, \base_logger $logger, $name) {
    162179        global $DB;
  • moodle/trunk/fuentes/availability/condition/grouping/tests/behat/availability_grouping.feature

    r136 r1331  
    2323      | user     | group |
    2424      | student1 | GI1   |
    25     And I log in as "admin"
    26     And I set the following administration settings values:
    27       | Enable conditional access  | 1 |
    28     And I log out
     25    And the following config values are set as admin:
     26      | enableavailability  | 1 |
    2927
    3028  @javascript
     
    3230    # Basic setup.
    3331    Given I log in as "teacher1"
     32    And I am on site homepage
    3433    And I follow "Course 1"
    3534    And I turn editing mode on
     
    4544    # This step used to be 'And I follow "C1"', but Chrome thinks the breadcrumb
    4645    # is not clickable, so we'll go via the home page instead.
    47     And I am on homepage
     46    And I am on site homepage
    4847    And I follow "Course 1"
    4948    And the following "groupings" exist:
     
    9493      | GXI1     | GI1    |
    9594    And I log in as "student1"
     95    And I am on site homepage
    9696    And I follow "Course 1"
    9797
  • moodle/trunk/fuentes/availability/condition/grouping/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_grouping';
  • moodle/trunk/fuentes/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-debug.js

    r136 r1331  
    3434M.availability_grouping.form.getNode = function(json) {
    3535    // Create HTML structure.
    36     var strings = M.str.availability_grouping;
    37     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     36    var html = '<label>' + M.util.get_string('title', 'availability_grouping') + ' <span class="availability-group">' +
    3837            '<select name="id">' +
    39             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     38            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4039    for (var i = 0; i < this.groupings.length; i++) {
    4140        var grouping = this.groupings[i];
  • moodle/trunk/fuentes/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_grouping-form",function(e,t){M.availability_grouping=M.availability_grouping||{},M.availability_grouping.form=e.Object(M.core_availability.plugin),M.availability_grouping.form.groupings=null,M.availability_grouping.form.initInner=function(e){this.groupings=e},M.availability_grouping.form.getNode=function(t){var n=M.str.availability_grouping,r="<label>"+n.title+' <span class="availability-group">'+'<select name="id">'+'<option value="choose">'+M.str.moodle.choosedots+"</option>";for(var i=0;i<this.groupings.length;i++){var s=this.groupings[i];r+='<option value="'+s.id+'">'+s.name+"</option>"}r+="</select></span></label>";var o=e.Node.create("<span>"+r+"</span>");t.id!==undefined&&o.one("select[name=id] > option[value="+t.id+"]")&&o.one("select[name=id]").set("value",""+t.id);if(!M.availability_grouping.form.addedEvents){M.availability_grouping.form.addedEvents=!0;var u=e.one("#fitem_id_availabilityconditionsjson");u.delegate("change",function(){M.core_availability.form.update()},".availability_grouping select")}return o},M.availability_grouping.form.fillValue=function(e,t){var n=t.one("select[name=id]").get("value");n==="choose"?e.id="choose":e.id=parseInt(n,10)},M.availability_grouping.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id==="choose"&&e.push("availability_grouping:error_selectgrouping")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_grouping-form",function(e,t){M.availability_grouping=M.availability_grouping||{},M.availability_grouping.form=e.Object(M.core_availability.plugin),M.availability_grouping.form.groupings=null,M.availability_grouping.form.initInner=function(e){this.groupings=e},M.availability_grouping.form.getNode=function(t){var n="<label>"+M.util.get_string("title","availability_grouping")+' <span class="availability-group">'+'<select name="id">'+'<option value="choose">'+M.util.get_string("choosedots","moodle")+"</option>";for(var r=0;r<this.groupings.length;r++){var i=this.groupings[r];n+='<option value="'+i.id+'">'+i.name+"</option>"}n+="</select></span></label>";var s=e.Node.create("<span>"+n+"</span>");t.id!==undefined&&s.one("select[name=id] > option[value="+t.id+"]")&&s.one("select[name=id]").set("value",""+t.id);if(!M.availability_grouping.form.addedEvents){M.availability_grouping.form.addedEvents=!0;var o=e.one("#fitem_id_availabilityconditionsjson");o.delegate("change",function(){M.core_availability.form.update()},".availability_grouping select")}return s},M.availability_grouping.form.fillValue=function(e,t){var n=t.one("select[name=id]").get("value");n==="choose"?e.id="choose":e.id=parseInt(n,10)},M.availability_grouping.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.id==="choose"&&e.push("availability_grouping:error_selectgrouping")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/grouping/yui/build/moodle-availability_grouping-form/moodle-availability_grouping-form.js

    r136 r1331  
    3434M.availability_grouping.form.getNode = function(json) {
    3535    // Create HTML structure.
    36     var strings = M.str.availability_grouping;
    37     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     36    var html = '<label>' + M.util.get_string('title', 'availability_grouping') + ' <span class="availability-group">' +
    3837            '<select name="id">' +
    39             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     38            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4039    for (var i = 0; i < this.groupings.length; i++) {
    4140        var grouping = this.groupings[i];
  • moodle/trunk/fuentes/availability/condition/grouping/yui/src/form/js/form.js

    r136 r1331  
    3232M.availability_grouping.form.getNode = function(json) {
    3333    // Create HTML structure.
    34     var strings = M.str.availability_grouping;
    35     var html = '<label>' + strings.title + ' <span class="availability-group">' +
     34    var html = '<label>' + M.util.get_string('title', 'availability_grouping') + ' <span class="availability-group">' +
    3635            '<select name="id">' +
    37             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     36            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    3837    for (var i = 0; i < this.groupings.length; i++) {
    3938        var grouping = this.groupings[i];
  • moodle/trunk/fuentes/availability/condition/profile/tests/behat/availability_profile.feature

    r136 r1331  
    1111    And the following "users" exist:
    1212      | username | email         |
    13       | teacher1 | t@example.org |
    14       | student1 | s@example.org |
     13      | teacher1 | t@example.com |
     14      | student1 | s@example.com |
    1515    And the following "course enrolments" exist:
    1616      | user     | course | role           |
    1717      | teacher1 | C1     | editingteacher |
    1818      | student1 | C1     | student        |
    19     And I log in as "admin"
    20     And I set the following administration settings values:
    21       | Enable conditional access  | 1 |
    22     And I log out
     19    And the following config values are set as admin:
     20      | enableavailability  | 1 |
    2321
    2422  @javascript
     
    2624    # Basic setup.
    2725    Given I log in as "teacher1"
     26    And I am on site homepage
    2827    And I follow "Course 1"
    2928    And I turn editing mode on
     
    3938    And I click on "User profile" "button"
    4039    And I set the field "User profile field" to "Email address"
    41     And I set the field "Value to compare against" to "s@example.org"
     40    And I set the field "Value to compare against" to "s@example.com"
    4241    And I click on ".availability-item .availability-eye img" "css_element"
    4342    And I click on "Save and return to course" "button"
     
    5352    And I click on "User profile" "button"
    5453    And I set the field "User profile field" to "Email address"
    55     And I set the field "Value to compare against" to "q@example.org"
     54    And I set the field "Value to compare against" to "q@example.com"
    5655    And I click on ".availability-item .availability-eye img" "css_element"
    5756    And I click on "Save and return to course" "button"
     
    6059    When I log out
    6160    And I log in as "student1"
     61    And I am on site homepage
    6262    And I follow "Course 1"
    6363
     
    7979    # Set field value for user.
    8080    And I navigate to "Browse list of users" node in "Site administration > Users > Accounts"
    81     And I click on "a[title=Edit]" "css_element" in the "s@example.org" "table_row"
     81    And I click on "a[title=Edit]" "css_element" in the "s@example.com" "table_row"
    8282    And I expand all fieldsets
    8383    And I set the field "Super field" to "Bananaman"
     
    8585
    8686    # Set Page activity which has requirement on this field.
    87     And I am on homepage
     87    And I am on site homepage
    8888    And I follow "Course 1"
    8989    And I turn editing mode on
     
    112112    And I log out
    113113    And I log in as "student1"
     114    And I am on site homepage
    114115    And I follow "Course 1"
    115116    Then I should see "P1" in the "region-main" "region"
  • moodle/trunk/fuentes/availability/condition/profile/version.php

    r136 r1331  
    2525defined('MOODLE_INTERNAL') || die();
    2626
    27 $plugin->version = 2014111000;
    28 $plugin->requires = 2014110400;
     27$plugin->version = 2015111600;
     28$plugin->requires = 2015111000;
    2929$plugin->component = 'availability_profile';
  • moodle/trunk/fuentes/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-debug.js

    r136 r1331  
    3636M.availability_profile.form.getNode = function(json) {
    3737    // Create HTML structure.
    38     var strings = M.str.availability_profile;
    39     var html = '<span class="availability-group"><label>' + strings.conditiontitle + ' ' +
     38    var html = '<span class="availability-group"><label>' + M.util.get_string('conditiontitle', 'availability_profile') + ' ' +
    4039            '<select name="field">' +
    41             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     40            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4241    var fieldInfo;
    4342    for (var i = 0; i < this.standardFields.length; i++) {
     
    5150        html += '<option value="cf_' + fieldInfo.field + '">' + fieldInfo.display + '</option>';
    5251    }
    53     html += '</select></label> <label><span class="accesshide">' + strings.label_operator +
    54             ' </span><select name="op" title="' + strings.label_operator + '">';
     52    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_operator', 'availability_profile') +
     53            ' </span><select name="op" title="' + M.util.get_string('label_operator', 'availability_profile') + '">';
    5554    var operators = ['isequalto', 'contains', 'doesnotcontain', 'startswith', 'endswith',
    5655            'isempty', 'isnotempty'];
    5756    for (i = 0; i < operators.length; i++) {
    5857        html += '<option value="' + operators[i] + '">' +
    59                 strings['op_' + operators[i]] + '</option>';
     58                M.util.get_string('op_' + operators[i], 'availability_profile') + '</option>';
    6059    }
    61     html += '</select></label> <label><span class="accesshide">' + strings.label_value +
     60    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_value', 'availability_profile') +
    6261            '</span><input name="value" type="text" style="width: 10em" title="' +
    63             strings.label_value + '"/></label></span>';
     62            M.util.get_string('label_value', 'availability_profile') + '"/></label></span>';
    6463    var node = Y.Node.create('<span>' + html + '</span>');
    6564
  • moodle/trunk/fuentes/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form-min.js

    r136 r1331  
    1 YUI.add("moodle-availability_profile-form",function(e,t){M.availability_profile=M.availability_profile||{},M.availability_profile.form=e.Object(M.core_availability.plugin),M.availability_profile.form.profiles=null,M.availability_profile.form.initInner=function(e,t){this.standardFields=e,this.customFields=t},M.availability_profile.form.getNode=function(t){var n=M.str.availability_profile,r='<span class="availability-group"><label>'+n.conditiontitle+" "+'<select name="field">'+'<option value="choose">'+M.str.moodle.choosedots+"</option>",i;for(var s=0;s<this.standardFields.length;s++)i=this.standardFields[s],r+='<option value="sf_'+i.field+'">'+i.display+"</option>";for(s=0;s<this.customFields.length;s++)i=this.customFields[s],r+='<option value="cf_'+i.field+'">'+i.display+"</option>";r+='</select></label> <label><span class="accesshide">'+n.label_operator+' </span><select name="op" title="'+n.label_operator+'">';var o=["isequalto","contains","doesnotcontain","startswith","endswith","isempty","isnotempty"];for(s=0;s<o.length;s++)r+='<option value="'+o[s]+'">'+n["op_"+o[s]]+"</option>";r+='</select></label> <label><span class="accesshide">'+n.label_value+'</span><input name="value" type="text" style="width: 10em" title="'+n.label_value+'"/></label></span>';var u=e.Node.create("<span>"+r+"</span>");t.sf!==undefined&&u.one("select[name=field] > option[value=sf_"+t.sf+"]")?u.one("select[name=field]").set("value","sf_"+t.sf):t.cf!==undefined&&u.one("select[name=field] > option[value=cf_"+t.cf+"]")&&u.one("select[name=field]").set("value","cf_"+t.cf),t.op!==undefined&&u.one("select[name=op] > option[value="+t.op+"]")&&(u.one("select[name=op]").set("value",t.op),(t.op==="isempty"||t.op==="isnotempty")&&u.one("input[name=value]").set("disabled",!0)),t.v!==undefined&&u.one("input").set("value",t.v);if(!M.availability_profile.form.addedEvents){M.availability_profile.form.addedEvents=!0;var a=function(e){var t=e.ancestor("span.availability_profile"),n=t.one("select[name=op]"),r=n.get("value")==="isempty"||n.get("value")==="isnotempty";t.one("input[name=value]").set("disabled",r),M.core_availability.form.update()},f=e.one("#fitem_id_availabilityconditionsjson");f.delegate("change",function(){a(this)},".availability_profile select"),f.delegate("change",function(){a(this)},".availability_profile input[name=value]")}return u},M.availability_profile.form.fillValue=function(e,t){var n=t.one("select[name=field]").get("value");n.substr(0,3)==="sf_"?e.sf=n.substr(3):n.substr(0,3)==="cf_"&&(e.cf=n.substr(3)),e.op=t.one("select[name=op]").get("value");var r=t.one("input[name=value]");r.get("disabled")||(e.v=r.get("value"))},M.availability_profile.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.sf===undefined&&n.cf===undefined&&e.push("availability_profile:error_selectfield"),n.v!==undefined&&/^\s*$/.test(n.v)&&e.push("availability_profile:error_setvalue")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
     1YUI.add("moodle-availability_profile-form",function(e,t){M.availability_profile=M.availability_profile||{},M.availability_profile.form=e.Object(M.core_availability.plugin),M.availability_profile.form.profiles=null,M.availability_profile.form.initInner=function(e,t){this.standardFields=e,this.customFields=t},M.availability_profile.form.getNode=function(t){var n='<span class="availability-group"><label>'+M.util.get_string("conditiontitle","availability_profile")+" "+'<select name="field">'+'<option value="choose">'+M.util.get_string("choosedots","moodle")+"</option>",r;for(var i=0;i<this.standardFields.length;i++)r=this.standardFields[i],n+='<option value="sf_'+r.field+'">'+r.display+"</option>";for(i=0;i<this.customFields.length;i++)r=this.customFields[i],n+='<option value="cf_'+r.field+'">'+r.display+"</option>";n+='</select></label> <label><span class="accesshide">'+M.util.get_string("label_operator","availability_profile")+' </span><select name="op" title="'+M.util.get_string("label_operator","availability_profile")+'">';var s=["isequalto","contains","doesnotcontain","startswith","endswith","isempty","isnotempty"];for(i=0;i<s.length;i++)n+='<option value="'+s[i]+'">'+M.util.get_string("op_"+s[i],"availability_profile")+"</option>";n+='</select></label> <label><span class="accesshide">'+M.util.get_string("label_value","availability_profile")+'</span><input name="value" type="text" style="width: 10em" title="'+M.util.get_string("label_value","availability_profile")+'"/></label></span>';var o=e.Node.create("<span>"+n+"</span>");t.sf!==undefined&&o.one("select[name=field] > option[value=sf_"+t.sf+"]")?o.one("select[name=field]").set("value","sf_"+t.sf):t.cf!==undefined&&o.one("select[name=field] > option[value=cf_"+t.cf+"]")&&o.one("select[name=field]").set("value","cf_"+t.cf),t.op!==undefined&&o.one("select[name=op] > option[value="+t.op+"]")&&(o.one("select[name=op]").set("value",t.op),(t.op==="isempty"||t.op==="isnotempty")&&o.one("input[name=value]").set("disabled",!0)),t.v!==undefined&&o.one("input").set("value",t.v);if(!M.availability_profile.form.addedEvents){M.availability_profile.form.addedEvents=!0;var u=function(e){var t=e.ancestor("span.availability_profile"),n=t.one("select[name=op]"),r=n.get("value")==="isempty"||n.get("value")==="isnotempty";t.one("input[name=value]").set("disabled",r),M.core_availability.form.update()},a=e.one("#fitem_id_availabilityconditionsjson");a.delegate("change",function(){u(this)},".availability_profile select"),a.delegate("change",function(){u(this)},".availability_profile input[name=value]")}return o},M.availability_profile.form.fillValue=function(e,t){var n=t.one("select[name=field]").get("value");n.substr(0,3)==="sf_"?e.sf=n.substr(3):n.substr(0,3)==="cf_"&&(e.cf=n.substr(3)),e.op=t.one("select[name=op]").get("value");var r=t.one("input[name=value]");r.get("disabled")||(e.v=r.get("value"))},M.availability_profile.form.fillErrors=function(e,t){var n={};this.fillValue(n,t),n.sf===undefined&&n.cf===undefined&&e.push("availability_profile:error_selectfield"),n.v!==undefined&&/^\s*$/.test(n.v)&&e.push("availability_profile:error_setvalue")}},"@VERSION@",{requires:["base","node","event","moodle-core_availability-form"]});
  • moodle/trunk/fuentes/availability/condition/profile/yui/build/moodle-availability_profile-form/moodle-availability_profile-form.js

    r136 r1331  
    3636M.availability_profile.form.getNode = function(json) {
    3737    // Create HTML structure.
    38     var strings = M.str.availability_profile;
    39     var html = '<span class="availability-group"><label>' + strings.conditiontitle + ' ' +
     38    var html = '<span class="availability-group"><label>' + M.util.get_string('conditiontitle', 'availability_profile') + ' ' +
    4039            '<select name="field">' +
    41             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     40            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4241    var fieldInfo;
    4342    for (var i = 0; i < this.standardFields.length; i++) {
     
    5150        html += '<option value="cf_' + fieldInfo.field + '">' + fieldInfo.display + '</option>';
    5251    }
    53     html += '</select></label> <label><span class="accesshide">' + strings.label_operator +
    54             ' </span><select name="op" title="' + strings.label_operator + '">';
     52    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_operator', 'availability_profile') +
     53            ' </span><select name="op" title="' + M.util.get_string('label_operator', 'availability_profile') + '">';
    5554    var operators = ['isequalto', 'contains', 'doesnotcontain', 'startswith', 'endswith',
    5655            'isempty', 'isnotempty'];
    5756    for (i = 0; i < operators.length; i++) {
    5857        html += '<option value="' + operators[i] + '">' +
    59                 strings['op_' + operators[i]] + '</option>';
     58                M.util.get_string('op_' + operators[i], 'availability_profile') + '</option>';
    6059    }
    61     html += '</select></label> <label><span class="accesshide">' + strings.label_value +
     60    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_value', 'availability_profile') +
    6261            '</span><input name="value" type="text" style="width: 10em" title="' +
    63             strings.label_value + '"/></label></span>';
     62            M.util.get_string('label_value', 'availability_profile') + '"/></label></span>';
    6463    var node = Y.Node.create('<span>' + html + '</span>');
    6564
  • moodle/trunk/fuentes/availability/condition/profile/yui/src/form/js/form.js

    r136 r1331  
    3434M.availability_profile.form.getNode = function(json) {
    3535    // Create HTML structure.
    36     var strings = M.str.availability_profile;
    37     var html = '<span class="availability-group"><label>' + strings.conditiontitle + ' ' +
     36    var html = '<span class="availability-group"><label>' + M.util.get_string('conditiontitle', 'availability_profile') + ' ' +
    3837            '<select name="field">' +
    39             '<option value="choose">' + M.str.moodle.choosedots + '</option>';
     38            '<option value="choose">' + M.util.get_string('choosedots', 'moodle') + '</option>';
    4039    var fieldInfo;
    4140    for (var i = 0; i < this.standardFields.length; i++) {
     
    4948        html += '<option value="cf_' + fieldInfo.field + '">' + fieldInfo.display + '</option>';
    5049    }
    51     html += '</select></label> <label><span class="accesshide">' + strings.label_operator +
    52             ' </span><select name="op" title="' + strings.label_operator + '">';
     50    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_operator', 'availability_profile') +
     51            ' </span><select name="op" title="' + M.util.get_string('label_operator', 'availability_profile') + '">';
    5352    var operators = ['isequalto', 'contains', 'doesnotcontain', 'startswith', 'endswith',
    5453            'isempty', 'isnotempty'];
    5554    for (i = 0; i < operators.length; i++) {
    5655        html += '<option value="' + operators[i] + '">' +
    57                 strings['op_' + operators[i]] + '</option>';
     56                M.util.get_string('op_' + operators[i], 'availability_profile') + '</option>';
    5857    }
    59     html += '</select></label> <label><span class="accesshide">' + strings.label_value +
     58    html += '</select></label> <label><span class="accesshide">' + M.util.get_string('label_value', 'availability_profile') +
    6059            '</span><input name="value" type="text" style="width: 10em" title="' +
    61             strings.label_value + '"/></label></span>';
     60            M.util.get_string('label_value', 'availability_profile') + '"/></label></span>';
    6261    var node = Y.Node.create('<span>' + html + '</span>');
    6362
  • moodle/trunk/fuentes/availability/renderer.php

    r136 r1331  
    4141     * This function will not be called unless there are at least two messages.
    4242     *
    43      * @param bool $root True if this is a root-level list for an activity
    44      * @param bool $andoperator True if the messages are being combined as AND
    45      * @param bool $roothidden True if the root level should use 'hidden' message
    46      * @param array $messages Messages to render
     43     * @param core_availability_multiple_messages $renderable Multiple messages
    4744     * @return string Combined HTML
    4845     */
    49     public function multiple_messages($root, $andoperator, $roothidden, array $messages) {
     46    public function render_core_availability_multiple_messages(
     47            core_availability_multiple_messages $renderable) {
    5048        // Get initial message.
    51         $out = get_string('list_' . ($root ? 'root_' : '') .
    52                 ($andoperator ? 'and' : 'or') . ($roothidden ? '_hidden' : ''),
     49        $out = get_string('list_' . ($renderable->root ? 'root_' : '') .
     50                ($renderable->andoperator ? 'and' : 'or') . ($renderable->treehidden ? '_hidden' : ''),
    5351                'availability');
    5452
    5553        // Make the list.
    5654        $out .= html_writer::start_tag('ul');
    57         foreach ($messages as $message) {
    58             $out .= html_writer::tag('li', $message);
     55        foreach ($renderable->items as $item) {
     56            if (is_string($item)) {
     57                $str = $item;
     58            } else {
     59                $str = $this->render($item);
     60            }
     61            $out .= html_writer::tag('li', $str);
    5962        }
    6063        $out .= html_writer::end_tag('ul');
  • moodle/trunk/fuentes/availability/tests/behat/display_availability.feature

    r136 r1331  
    3535      | teacher1 | C1     | editingteacher |
    3636      | student1 | C1     | student        |
    37     And I log in as "admin"
    38     And I set the following administration settings values:
    39       | Enable conditional access | 1 |
    40     And I log out
     37    And the following config values are set as admin:
     38      | enableavailability | 1 |
    4139
    4240  @javascript
     
    4442    # Set up.
    4543    Given I log in as "teacher1"
     44    And I am on site homepage
    4645    And I follow "Course 1"
    4746    And I turn editing mode on
     
    7776    And I click on "User profile" "button" in the "Add restriction..." "dialogue"
    7877    And I set the field "User profile field" to "Email address"
    79     And I set the field "Value to compare against" to "email@example.org"
     78    And I set the field "Value to compare against" to "email@example.com"
    8079    And I set the field "Method of comparison" to "is equal to"
    8180    And I press "Save and return to course"
     
    106105    Given I log out
    107106    And I log in as "student1"
     107    And I am on site homepage
    108108    And I follow "Course 1"
    109109
    110110    # Page 1 display still there but should be dimmed and not a link.
    111111    Then I should see "Page 1" in the "#section-1 .dimmed_text" "css_element"
    112     And ".activityinstance a" "css_element" should not exist in the "#section-1" "css_element"
     112    And ".activityinstance a" "css_element" should not exist in the "Topic 1" "section"
    113113
    114114    # Date display should be present.
    115     And I should see "Available until" in the "#section-1" "css_element"
     115    And I should see "Available until" in the "Topic 1" "section"
    116116
    117117    # Page 2 display not there at all
     
    120120    # Page 3 display and link
    121121    And I should see "Page 3" in the "region-main" "region"
    122     And ".activityinstance a" "css_element" should exist in the "#section-3" "css_element"
     122    And ".activityinstance a" "css_element" should exist in the "Topic 3" "section"
    123123
    124124  @javascript
     
    126126    # Set up.
    127127    Given I log in as "teacher1"
     128    And I am on site homepage
    128129    And I follow "Course 1"
    129130    And I turn editing mode on
     
    149150
    150151    # This is necessary because otherwise it fails in Chrome, see MDL-44959
    151     And I am on homepage
     152    And I am on site homepage
    152153    And I follow "Course 1"
    153154
     
    174175    Given I log out
    175176    And I log in as "student1"
     177    And I am on site homepage
    176178    And I follow "Course 1"
    177179
  • moodle/trunk/fuentes/availability/tests/behat/edit_availability.feature

    r136 r1331  
    3131  Scenario: Confirm the 'enable availability' option is working
    3232    When I log in as "teacher1"
     33    And I am on site homepage
    3334    And I follow "Course 1"
    3435    And I turn editing mode on
     
    4041    Then "Restrict access" "fieldset" should not exist
    4142
    42     When I log out
    43     And I log in as "admin"
    44     And I set the following administration settings values:
    45       | Enable conditional access | 1 |
    46 
    47     When I log out
    48     And I log in as "teacher1"
    49     And I follow "Course 1"
    50     And I turn editing mode on
     43    And the following config values are set as admin:
     44      | enableavailability | 1 |
     45
     46    And I am on site homepage
     47    And I follow "Course 1"
    5148    And I add a "Page" to section "1"
    5249    Then "Restrict access" "fieldset" should exist
     
    5956  Scenario: Edit availability using settings in activity form
    6057    # Set up.
    61     Given I log in as "admin"
    62     And I set the following administration settings values:
    63       | Enable conditional access | 1 |
    64     And I log out
     58    Given the following config values are set as admin:
     59      | enableavailability | 1 |
    6560    And I log in as "teacher1"
    6661    And I follow "Course 1"
     
    154149  Scenario: Edit availability using settings in section form
    155150    # Set up.
    156     Given I log in as "admin"
    157     And I set the following administration settings values:
    158       | Enable conditional access | 1 |
    159     And I log out
     151    Given the following config values are set as admin:
     152      | enableavailability | 1 |
    160153    And I log in as "teacher1"
     154    And I am on site homepage
    161155    And I follow "Course 1"
    162156    And I turn editing mode on
     
    173167    And "Restriction type" "select" should be visible
    174168    And I should see "Date" in the "Restrict access" "fieldset"
     169
     170  @javascript
     171  Scenario: 'Add group/grouping access restriction' button unavailable
     172    # Button does not exist when conditional access restrictions are turned off.
     173    Given I log in as "admin"
     174    And I am on site homepage
     175    And I follow "Course 1"
     176    And I turn editing mode on
     177    And I add a "Forum" to section "1"
     178    When I expand all fieldsets
     179    Then "Add group/grouping access restriction" "button" should not exist
     180
     181  @javascript
     182  Scenario: Use the 'Add group/grouping access restriction' button
     183    # Button should initially be disabled.
     184    Given the following config values are set as admin:
     185      | enableavailability | 1 |
     186    And the following "groupings" exist:
     187      | name | course | idnumber |
     188      | GX1  | C1     | GXI1     |
     189    And I log in as "admin"
     190    And I am on site homepage
     191    And I follow "Course 1"
     192    And I turn editing mode on
     193    And I add a "Forum" to section "1"
     194    And I set the following fields to these values:
     195      | Forum name  | MyForum |
     196      | Description | x       |
     197    When I expand all fieldsets
     198    Then the "Add group/grouping access restriction" "button" should be disabled
     199
     200    # Turn on separate groups.
     201    And I set the field "Group mode" to "Separate groups"
     202    And the "Add group/grouping access restriction" "button" should be enabled
     203
     204    # Press the button and check it adds a restriction and disables itself.
     205    And I should see "None" in the "Restrict access" "fieldset"
     206    And I press "Add group/grouping access restriction"
     207    And I should see "Group" in the "Restrict access" "fieldset"
     208    And the "Add group/grouping access restriction" "button" should be disabled
     209
     210    # Delete the restriction and check it is enabled again.
     211    And I click on "Delete" "link" in the "Restrict access" "fieldset"
     212    And the "Add group/grouping access restriction" "button" should be enabled
     213
     214    # Try a grouping instead.
     215    And I set the field "Grouping" to "GX1"
     216    And I press "Add group/grouping access restriction"
     217    And I should see "Grouping" in the "Restrict access" "fieldset"
     218
     219    # Check the button still works after saving and editing.
     220    And I press "Save and display"
     221    And I navigate to "Edit settings" node in "Forum administration"
     222    And I expand all fieldsets
     223    And the "Add group/grouping access restriction" "button" should be disabled
     224    And I should see "Grouping" in the "Restrict access" "fieldset"
     225
     226    # And check it's still active if I delete the condition.
     227    And I click on "Delete" "link" in the "Restrict access" "fieldset"
     228    And the "Add group/grouping access restriction" "button" should be enabled
  • moodle/trunk/fuentes/availability/tests/component_test.php

    r136 r1331  
    5050        $pluginmanager = core_plugin_manager::instance();
    5151        $list = $pluginmanager->get_enabled_plugins('availability');
    52         $this->assertEquals(array('completion', 'date', 'grade', 'group', 'grouping', 'profile'),
    53                 array_keys($list));
     52        $this->assertArrayHasKey('completion', $list);
     53        $this->assertArrayHasKey('date', $list);
     54        $this->assertArrayHasKey('grade', $list);
     55        $this->assertArrayHasKey('group', $list);
     56        $this->assertArrayHasKey('grouping', $list);
     57        $this->assertArrayHasKey('profile', $list);
    5458    }
    5559}
  • moodle/trunk/fuentes/availability/tests/fixtures/mock_info.php

    r136 r1331  
    6161    }
    6262
     63    protected function get_view_hidden_capability() {
     64        return 'moodle/course:viewhiddensections';
     65    }
     66
    6367    protected function set_in_database($availability) {
    6468    }
  • moodle/trunk/fuentes/availability/tests/info_test.php

    r136 r1331  
    3636 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
    3737 */
    38 class info_testcase extends \advanced_testcase {
     38class info_testcase extends advanced_testcase {
    3939    public function setUp() {
    4040        // Load the mock condition so that it can be used.
     
    8888        $info = new info_module($cm3);
    8989        $this->assertFalse($info->is_available($information));
    90         $debugging = phpunit_util::get_debugging_messages();
    91         phpunit_util::reset_debugging();
     90        $debugging = $this->getDebuggingMessages();
     91        $this->resetDebugging();
    9292        $this->assertEquals(1, count($debugging));
    9393        $this->assertContains('Invalid availability', $debugging[0]->message);
     
    142142        $info = new info_section($sections[3]);
    143143        $this->assertFalse($info->is_available($information));
    144         $debugging = phpunit_util::get_debugging_messages();
    145         phpunit_util::reset_debugging();
     144        $debugging = $this->getDebuggingMessages();
     145        $this->resetDebugging();
    146146        $this->assertEquals(1, count($debugging));
    147147        $this->assertContains('Invalid availability', $debugging[0]->message);
     
    408408        $u2 = $generator->create_user();
    409409        $u3 = $generator->create_user();
     410        $studentroleid = $DB->get_field('role', 'id', array('shortname' => 'student'), MUST_EXIST);
    410411        $allusers = array($u1->id => $u1, $u2->id => $u2, $u3->id => $u3);
    411         $generator->enrol_user($u1->id, $course->id);
    412         $generator->enrol_user($u2->id, $course->id);
    413         $generator->enrol_user($u3->id, $course->id);
    414 
     412        $generator->enrol_user($u1->id, $course->id, $studentroleid);
     413        $generator->enrol_user($u2->id, $course->id, $studentroleid);
     414        $generator->enrol_user($u3->id, $course->id, $studentroleid);
     415
     416        // Page 2 allows access to users 2 and 3, while section 2 allows access
     417        // to users 1 and 2.
    415418        $pagegen = $generator->get_plugin_generator('mod_page');
    416419        $page = $pagegen->create_instance(array('course' => $course));
     
    484487        sort($result);
    485488        $this->assertEquals($expected, $result);
     489
     490        // If the students have viewhiddenactivities, they get past the module
     491        // restriction.
     492        role_change_permission($studentroleid, context_module::instance($page2->cmid),
     493                'moodle/course:viewhiddenactivities', CAP_ALLOW);
     494        $expected = array($u1->id, $u2->id);
     495        $this->assertEquals($expected, array_keys($info->filter_user_list($allusers)));
     496        list ($sql, $params) = $info->get_user_list_sql(true);
     497        $result = $DB->get_fieldset_sql($sql, $params);
     498        sort($result);
     499        $this->assertEquals($expected, $result);
     500
     501        // If they have viewhiddensections, they also get past the section
     502        // restriction.
     503        role_change_permission($studentroleid, context_course::instance($course->id),
     504                'moodle/course:viewhiddensections', CAP_ALLOW);
     505        $expected = array($u1->id, $u2->id, $u3->id);
     506        $this->assertEquals($expected, array_keys($info->filter_user_list($allusers)));
     507        list ($sql, $params) = $info->get_user_list_sql(true);
     508        $result = $DB->get_fieldset_sql($sql, $params);
     509        sort($result);
     510        $this->assertEquals($expected, $result);
    486511    }
    487512}
  • moodle/trunk/fuentes/availability/tests/tree_test.php

    r136 r1331  
    342342     */
    343343    protected function get_available_results($structure, \core_availability\info $info, $userid) {
     344        global $PAGE;
    344345        $tree = new tree($structure);
    345346        $result = $tree->check_available(false, $info, true, $userid);
    346         return array($result->is_available(), $tree->get_result_information($info, $result));
     347        $information = $tree->get_result_information($info, $result);
     348        if (!is_string($information)) {
     349            $renderer = $PAGE->get_renderer('core', 'availability');
     350            $information = $renderer->render($information);
     351        }
     352        return array($result->is_available(), $information);
    347353    }
    348354
     
    390396     */
    391397    public function test_get_full_information() {
     398        global $PAGE;
     399        $renderer = $PAGE->get_renderer('core', 'availability');
    392400        // Setup.
    393401        $info = new \core_availability\mock_info();
     
    418426        $tree = new tree($structure);
    419427        $this->assertRegExp('~<ul.*<ul.*<li.*1.*<li.*2.*</ul>.*<li.*3~',
    420                 $tree->get_full_information($info));
     428                $renderer->render($tree->get_full_information($info)));
    421429
    422430        // Test intro messages before list. First, OR message.
     
    427435        $tree = new tree($structure);
    428436        $this->assertRegExp('~Not available unless any of:.*<ul>~',
    429                 $tree->get_full_information($info));
     437                $renderer->render($tree->get_full_information($info)));
    430438
    431439        // Now, OR message when not shown.
     
    433441        $tree = new tree($structure);
    434442        $this->assertRegExp('~hidden.*<ul>~',
    435                 $tree->get_full_information($info));
     443                $renderer->render($tree->get_full_information($info)));
    436444
    437445        // AND message.
     
    441449        $tree = new tree($structure);
    442450        $this->assertRegExp('~Not available unless:.*<ul>~',
    443                 $tree->get_full_information($info));
     451                $renderer->render($tree->get_full_information($info)));
    444452
    445453        // Hidden markers on items.
    446454        $this->assertRegExp('~1.*hidden.*2.*hidden~',
    447                 $tree->get_full_information($info));
     455                $renderer->render($tree->get_full_information($info)));
    448456
    449457        // Hidden markers on child tree and items.
     
    453461        $tree = new tree($structure);
    454462        $this->assertRegExp('~1.*hidden.*All of \(hidden.*2.*3~',
    455                 $tree->get_full_information($info));
     463                $renderer->render($tree->get_full_information($info)));
    456464        $structure->c[1]->op = '|';
    457465        $tree = new tree($structure);
    458466        $this->assertRegExp('~1.*hidden.*Any of \(hidden.*2.*3~',
    459                 $tree->get_full_information($info));
     467                $renderer->render($tree->get_full_information($info)));
    460468
    461469        // Hidden markers on single-item display, AND and OR.
     
    481489        $tree = new tree($structure);
    482490        $this->assertRegExp('~Not available \(hidden.*1.*2~',
    483                 $tree->get_full_information($info));
     491                $renderer->render($tree->get_full_information($info)));
    484492
    485493        // Single item tree containing single item.
     
    600608        ksort($result);
    601609        $this->assertEquals(array(1, 3), array_keys($result));
     610
     611        // Tree with OR condition one of which doesn't filter.
     612        $structure = tree::get_root_json(array(
     613                self::mock(array('filter' => array(3))),
     614                self::mock(array())), tree::OP_OR);
     615        $tree = new tree($structure);
     616        $result = $tree->filter_user_list($users, false, $info, $checker);
     617        ksort($result);
     618        $this->assertEquals(array(1, 2, 3), array_keys($result));
    602619
    603620        // Tree with two condition that both filter (&).
     
    719736        sort($result);
    720737        $this->assertEquals(array($userinneither->id), $result);
     738
     739        // Tree with 'OR' of group conditions and a non-filtering condition.
     740        // The non-filtering condition should mean that ALL users are included.
     741        $tree = new tree(tree::get_root_json(array(
     742            \availability_group\condition::get_json($group1->id),
     743            \availability_date\condition::get_json(\availability_date\condition::DIRECTION_UNTIL, 3)
     744        ), tree::OP_OR));
     745        list($sql, $params) = $tree->get_user_list_sql(false, $info, false);
     746        $this->assertEquals('', $sql);
     747        $this->assertEquals(array(), $params);
    721748    }
    722749
  • moodle/trunk/fuentes/availability/upgrade.txt

    r136 r1331  
    22
    33The information here is intended only for developers.
     4
     5=== 2.9 ===
     6
     7* Condition plugins can now implement a new include_after_restore function to
     8  indicate that they should be removed during the restore process. (This is
     9  implemented so that group and grouping conditions are removed if groups are
     10  not restored.)
    411
    512=== 2.8 ===
  • moodle/trunk/fuentes/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-debug.js

    r136 r1331  
    6666     */
    6767    idCounter : 0,
     68
     69    /**
     70     * The 'Restrict by group' button if present.
     71     *
     72     * @property restrictByGroup
     73     * @type Y.Node
     74     */
     75    restrictByGroup : null,
    6876
    6977    /**
     
    122130            this.mainDiv.all('input,textarea,select').set('disabled', true);
    123131        }, this);
     132
     133        // If the form has group mode and/or grouping options, there is a
     134        // 'add restriction' button there.
     135        this.restrictByGroup = Y.one('#restrictbygroup');
     136        if (this.restrictByGroup) {
     137            this.restrictByGroup.on('click', this.addRestrictByGroup, this);
     138            var groupmode = Y.one('#id_groupmode');
     139            var groupingid = Y.one('#id_groupingid');
     140            if (groupmode) {
     141                groupmode.on('change', this.updateRestrictByGroup, this);
     142            }
     143            if (groupingid) {
     144                groupingid.on('change', this.updateRestrictByGroup, this);
     145            }
     146            this.updateRestrictByGroup();
     147        }
    124148    },
    125149
     
    144168        // Set into hidden form field, JS-encoded.
    145169        this.field.set('value', Y.JSON.stringify(jsValue));
     170
     171        // Also update the restrict by group button if present.
     172        this.updateRestrictByGroup();
     173    },
     174
     175    /**
     176     * Updates the status of the 'restrict by group' button (enables or disables
     177     * it) based on current availability restrictions and group/grouping settings.
     178     */
     179    updateRestrictByGroup : function() {
     180        if (!this.restrictByGroup) {
     181            return;
     182        }
     183
     184        // If the root list is anything other than the default 'and' type, disable.
     185        if (this.rootList.getValue().op !== '&') {
     186            this.restrictByGroup.set('disabled', true);
     187            return;
     188        }
     189
     190        // If there's already a group restriction, disable it.
     191        var alreadyGot = this.rootList.hasItemOfType('group') ||
     192                this.rootList.hasItemOfType('grouping');
     193        if (alreadyGot) {
     194            this.restrictByGroup.set('disabled', true);
     195            return;
     196        }
     197
     198        // If the groupmode and grouping id aren't set, disable it.
     199        var groupmode = Y.one('#id_groupmode');
     200        var groupingid = Y.one('#id_groupingid');
     201        if ((!groupmode || Number(groupmode.get('value')) === 0) &&
     202                (!groupingid || Number(groupingid.get('value')) === 0)) {
     203            this.restrictByGroup.set('disabled', true);
     204            return;
     205        }
     206
     207        this.restrictByGroup.set('disabled', false);
     208    },
     209
     210    /**
     211     * Called when the user clicks on the 'restrict by group' button. This is
     212     * a special case that adds a group or grouping restriction.
     213     *
     214     * By default this restriction is not shown which makes it similar to the
     215     *
     216     * @param e Button click event
     217     */
     218    addRestrictByGroup : function(e) {
     219        // If you don't prevent default, it submits the form for some reason.
     220        e.preventDefault();
     221
     222        // Add the condition.
     223        var groupingid = Y.one('#id_groupingid');
     224        var newChild;
     225        if (groupingid && Number(groupingid.get('value')) !== 0) {
     226            // Add a grouping restriction if one is specified.
     227            newChild = new M.core_availability.Item(
     228                    {type : 'grouping', id : Number(groupingid.get('value'))}, true);
     229        } else {
     230            // Otherwise just add a group restriction.
     231            newChild = new M.core_availability.Item({type : 'group'}, true);
     232        }
     233
     234        // Refresh HTML.
     235        this.rootList.addChild(newChild);
     236        this.update();
     237        this.rootList.renumber();
     238        this.rootList.updateHtml();
    146239    }
    147240};
     
    261354        this.root = root;
    262355    }
    263     var strings = M.str.availability;
    264356    // Create DIV structure (without kids).
    265357    this.node = Y.Node.create('<div class="availability-list"><h3 class="accesshide"></h3>' +
    266358            '<div class="availability-inner">' +
    267             '<div class="availability-header">' + strings.listheader_sign_before +
    268             ' <label><span class="accesshide">' + strings.label_sign +
    269             ' </span><select class="availability-neg" title="' + strings.label_sign + '">' +
    270             '<option value="">' + strings.listheader_sign_pos + '</option>' +
    271             '<option value="!">' + strings.listheader_sign_neg + '</option></select></label> ' +
    272             '<span class="availability-single">' + strings.listheader_single + '</span>' +
    273             '<span class="availability-multi">' + strings.listheader_multi_before +
    274             ' <label><span class="accesshide">' + strings.label_multi + ' </span>' +
    275             '<select class="availability-op" title="' + strings.label_multi + '"><option value="&">' +
    276             strings.listheader_multi_and + '</option>' +
    277             '<option value="|">' + strings.listheader_multi_or + '</option></select></label> ' +
    278             strings.listheader_multi_after + '</span></div>' +
     359            '<div class="availability-header">' + M.util.get_string('listheader_sign_before', 'availability') +
     360            ' <label><span class="accesshide">' + M.util.get_string('label_sign', 'availability') +
     361            ' </span><select class="availability-neg" title="' + M.util.get_string('label_sign', 'availability') + '">' +
     362            '<option value="">' + M.util.get_string('listheader_sign_pos', 'availability') + '</option>' +
     363            '<option value="!">' + M.util.get_string('listheader_sign_neg', 'availability') + '</option></select></label> ' +
     364            '<span class="availability-single">' + M.util.get_string('listheader_single', 'availability') + '</span>' +
     365            '<span class="availability-multi">' + M.util.get_string('listheader_multi_before', 'availability') +
     366            ' <label><span class="accesshide">' + M.util.get_string('label_multi', 'availability') + ' </span>' +
     367            '<select class="availability-op" title="' + M.util.get_string('label_multi', 'availability') + '"><option value="&">' +
     368            M.util.get_string('listheader_multi_and', 'availability') + '</option>' +
     369            '<option value="|">' + M.util.get_string('listheader_multi_or', 'availability') + '</option></select></label> ' +
     370            M.util.get_string('listheader_multi_after', 'availability') + '</span></div>' +
    279371            '<div class="availability-children"></div>' +
    280             '<div class="availability-none">' + M.str.moodle.none + '</div>' +
     372            '<div class="availability-none">' + M.util.get_string('none', 'moodle') + '</div>' +
    281373            '<div class="availability-button"></div></div></div>');
    282374    if (!root) {
     
    314406        // Also if it's not the root, none is actually invalid, so add a label.
    315407        noneNode.appendChild(Y.Node.create('<span class="label label-warning">' +
    316                 M.str.availability.invalid + '</span>'));
     408                M.util.get_string('invalid', 'availability') + '</span>'));
    317409    }
    318410
    319411    // Create the button and add it.
    320412    var button = Y.Node.create('<button type="button" class="btn btn-default">' +
    321             M.str.availability.addrestriction + '</button>');
     413            M.util.get_string('addrestriction', 'availability') + '</button>');
    322414    button.on("click", function() { this.clickAdd(); }, this);
    323415    this.node.one('div.availability-button').appendChild(button);
     
    510602    var connectorText;
    511603    if (this.inner.one('.availability-op').get('value') === '&') {
    512         connectorText = M.str.availability.and;
     604        connectorText = M.util.get_string('and', 'availability');
    513605    } else {
    514         connectorText = M.str.availability.or;
     606        connectorText = M.util.get_string('or', 'availability');
    515607    }
    516608    this.inner.all('> .availability-children > .availability-connector span.label').each(function(span) {
     
    574666            '<ul class="list-unstyled"></ul>' +
    575667            '<div class="availability-buttons mdl-align">' +
    576             '<button type="button" class="btn btn-default">' + M.str.moodle.cancel +
     668            '<button type="button" class="btn btn-default">' + M.util.get_string('cancel', 'moodle') +
    577669            '</button></div></div>');
    578670    var cancel = content.one('button');
     
    590682        li = Y.Node.create('<li class="clearfix"></li>');
    591683        id = 'availability_addrestriction_' + type;
    592         var pluginStrings = M.str['availability_' + type];
    593684        button = Y.Node.create('<button type="button" class="btn btn-default"' +
    594                 'id="' + id + '">' + pluginStrings.title + '</button>');
     685                'id="' + id + '">' + M.util.get_string('title', 'availability_' + type) + '</button>');
    595686        button.on('click', this.getAddHandler(type, dialogRef), this);
    596687        li.appendChild(button);
    597688        label = Y.Node.create('<label for="' + id + '">' +
    598                 pluginStrings.description + '</label>');
     689                M.util.get_string('description', 'availability_' + type) + '</label>');
    599690        li.appendChild(label);
    600691        ul.appendChild(li);
     
    604695    id = 'availability_addrestriction_list_';
    605696    button = Y.Node.create('<button type="button" class="btn btn-default"' +
    606             'id="' + id + '">' + M.str.availability.condition_group + '</button>');
     697            'id="' + id + '">' + M.util.get_string('condition_group', 'availability') + '</button>');
    607698    button.on('click', this.getAddHandler(null, dialogRef), this);
    608699    li.appendChild(button);
    609700    label = Y.Node.create('<label for="' + id + '">' +
    610             M.str.availability.condition_group_info + '</label>');
     701            M.util.get_string('condition_group_info', 'availability') + '</label>');
    611702    li.appendChild(label);
    612703    ul.appendChild(li);
    613704
    614705    var config = {
    615         headerContent : M.str.availability.addrestriction,
     706        headerContent : M.util.get_string('addrestriction', 'availability'),
    616707        bodyContent : content,
    617708        additionalBaseClass : 'availability-dialogue',
     
    641732M.core_availability.List.prototype.getAddHandler = function(type, dialogRef) {
    642733    return function() {
     734        var newItem;
    643735        if (type) {
    644736            // Create an Item object to represent the child.
     
    713805
    714806/**
     807 * Checks whether the list contains any items of the given type name.
     808 *
     809 * @method hasItemOfType
     810 * @param {String} pluginType Required plugin type (name)
     811 * @return {Boolean} True if there is one
     812 */
     813M.core_availability.List.prototype.hasItemOfType = function(pluginType) {
     814    // Check each item.
     815    for (var i = 0; i < this.children.length; i++) {
     816        var child = this.children[i];
     817        if (child instanceof M.core_availability.List) {
     818            // Recursive call.
     819            if (child.hasItemOfType(pluginType)) {
     820                return true;
     821            }
     822        } else {
     823            if (child.pluginType === pluginType) {
     824                return true;
     825            }
     826        }
     827    }
     828    return false;
     829};
     830
     831/**
    715832 * Eye icon for this list (null if none).
    716833 *
     
    767884        this.plugin = null;
    768885        this.pluginNode = Y.Node.create('<div class="availability-warning">' +
    769                 M.str.availability.missingplugin + '</div>');
     886                M.util.get_string('missingplugin', 'availability') + '</div>');
    770887    } else {
    771888        // Plugin is known.
     
    811928 */
    812929M.core_availability.Item.prototype.getValue = function() {
    813     value = { 'type' : this.pluginType };
     930    var value = { 'type' : this.pluginType };
    814931    if (this.plugin) {
    815932        this.plugin.fillValue(value, this.pluginNode);
     
    838955    var errorLabel = this.node.one('> .label-warning');
    839956    if (errors.length !== before && !errorLabel.get('firstChild')) {
    840         errorLabel.appendChild(document.createTextNode(M.str.availability.invalid));
     957        errorLabel.appendChild(document.createTextNode(M.util.get_string('invalid', 'availability')));
    841958    } else if (errors.length === before && errorLabel.get('firstChild')) {
    842959        errorLabel.get('firstChild').remove();
     
    854971    var headingParams = { number: number };
    855972    if (this.plugin) {
    856         headingParams.type = M.str['availability_' + this.pluginType].title;
     973        headingParams.type = M.util.get_string('title', 'availability_' + this.pluginType);
    857974    } else {
    858975        headingParams.type = '[' + this.pluginType + ']';
     
    9331050
    9341051    // Set up button text and icon.
    935     var suffix = individual ? '_individual' : '_all';
    936     var setHidden = function() {
    937         icon.set('src', M.util.image_url('i/show', 'core'));
    938         icon.set('alt', M.str.availability['hidden' + suffix]);
    939         this.span.set('title', M.str.availability['hidden' + suffix] + ' \u2022 ' +
    940                 M.str.availability.show_verb);
    941     };
    942     var setShown = function() {
    943         icon.set('src', M.util.image_url('i/hide', 'core'));
    944         icon.set('alt', M.str.availability['shown' + suffix]);
    945         this.span.set('title', M.str.availability['shown' + suffix] + ' \u2022 ' +
    946                 M.str.availability.hide_verb);
    947     };
     1052    var suffix = individual ? '_individual' : '_all',
     1053        setHidden = function() {
     1054            var hiddenStr = M.util.get_string('hidden' + suffix, 'availability');
     1055            icon.set('src', M.util.image_url('i/show', 'core'));
     1056            icon.set('alt', hiddenStr);
     1057            this.span.set('title', hiddenStr + ' \u2022 ' +
     1058                    M.util.get_string('show_verb', 'availability'));
     1059        },
     1060        setShown = function() {
     1061            var shownStr = M.util.get_string('shown' + suffix, 'availability');
     1062            icon.set('src', M.util.image_url('i/hide', 'core'));
     1063            icon.set('alt', shownStr);
     1064            this.span.set('title', shownStr + ' \u2022 ' +
     1065                    M.util.get_string('hide_verb', 'availability'));
     1066        };
    9481067    if(shown) {
    9491068        setShown.call(this);
     
    9901109 */
    9911110M.core_availability.EyeIcon.prototype.isHidden = function() {
    992     var suffix = this.individual ? '_individual' : '_all';
    993     var compare = M.str.availability['hidden' + suffix];
     1111    var suffix = this.individual ? '_individual' : '_all',
     1112        compare = M.util.get_string('hidden' + suffix, 'availability');
    9941113    return this.span.one('img').get('alt') === compare;
    9951114};
     
    10051124M.core_availability.DeleteIcon = function(toDelete) {
    10061125    this.span = Y.Node.create('<a class="availability-delete" href="#" title="' +
    1007             M.str.moodle['delete'] + '" role="button">');
     1126            M.util.get_string('delete', 'moodle') + '" role="button">');
    10081127    var img = Y.Node.create('<img src="' + M.util.image_url('t/delete', 'core') +
    1009             '" alt="' + M.str.moodle['delete'] + '" />');
     1128            '" alt="' + M.util.get_string('delete', 'moodle') + '" />');
    10101129    this.span.appendChild(img);
    10111130    var click = function(e) {
  • moodle/trunk/fuentes/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form-min.js

    r136 r1331  
    1 YUI.add("moodle-core_availability-form",function(e,t){M.core_availability=M.core_availability||{},M.core_availability.form={plugins:{},field:null,mainDiv:null,rootList:null,idCounter:0,init:function(t){for(var n in t){var r=t[n],i=M[r[0]].form;i.init.apply(i,r)}this.field=e.one("#id_availabilityconditionsjson"),this.field.setAttribute("aria-hidden","true"),this.mainDiv=e.Node.create('<div class="availability-field fcontainer"></div>'),this.field.insert(this.mainDiv,"after");var s=this.field.get("value"),o=null;if(s!=="")try{o=e.JSON.parse(s)}catch(u){this.field.set("value","")}this.rootList=new M.core_availability.List(o,!0),this.mainDiv.appendChild(this.rootList.node),this.update(),this.rootList.renumber(),this.mainDiv.setAttribute("aria-live","polite"),this.field.ancestor("form").on("submit",function(){this.mainDiv.all("input,textarea,select").set("disabled",!0)},this)},update:function(){var t=this.rootList.getValue(),n=[];this.rootList.fillErrors(n),n.length!==0&&(t.errors=n),this.field.set("value",e.JSON.stringify(t))}},M.core_availability.plugin={allowAdd:!1,init:function(e,t,n){var r=e.replace(/^availability_/,"");this.allowAdd=t,M.core_availability.form.plugins[r]=this,this.initInner.apply(this,n)},initInner:function(){},getNode:function(){throw"getNode not implemented"},fillValue:function(){throw"fillValue not implemented"},fillErrors:function(){},focusAfterAdd:function(e){var t=e.one("input:not([disabled]),select:not([disabled])");t.focus()}},M.core_availability.List=function(t,n,r){this.children=[],n!==undefined&&(this.root=n);var i=M.str.availability;this.node=e.Node.create('<div class="availability-list"><h3 class="accesshide"></h3><div class="availability-inner"><div class="availability-header">'+i.listheader_sign_before+' <label><span class="accesshide">'+i.label_sign+' </span><select class="availability-neg" title="'+i.label_sign+'">'+'<option value="">'+i.listheader_sign_pos+"</option>"+'<option value="!">'+i.listheader_sign_neg+"</option></select></label> "+'<span class="availability-single">'+i.listheader_single+"</span>"+'<span class="availability-multi">'+i.listheader_multi_before+' <label><span class="accesshide">'+i.label_multi+" </span>"+'<select class="availability-op" title="'+i.label_multi+'"><option value="&">'+i.listheader_multi_and+"</option>"+'<option value="|">'+i.listheader_multi_or+"</option></select></label> "+i.listheader_multi_after+"</span></div>"+'<div class="availability-children"></div>'+'<div class="availability-none">'+M.str.moodle.none+"</div>"+'<div class="availability-button"></div></div></div>'),n||this.node.addClass("availability-childlist"),this.inner=this.node.one("> .availability-inner");var s=!0;n?(t&&t.show!==undefined&&(s=t.show),this.eyeIcon=new M.core_availability.EyeIcon(!1,s),this.node.one(".availability-header").get("firstChild").insert(this.eyeIcon.span,"before")):r&&(t&&t.showc!==undefined&&(s=t.showc),this.eyeIcon=new M.core_availability.EyeIcon(!1,s),this.inner.insert(this.eyeIcon.span,"before"));if(!n){var o=new M.core_availability.DeleteIcon(this),u=this.node.one(".availability-none");u.appendChild(document.createTextNode(" ")),u.appendChild(o.span),u.appendChild(e.Node.create('<span class="label label-warning">'+M.str.availability.invalid+"</span>"))}var a=e.Node.create('<button type="button" class="btn btn-default">'+M.str.availability.addrestriction+"</button>");a.on("click",function(){this.clickAdd()},this),this.node.one("div.availability-button").appendChild(a);if(t){switch(t.op){case"&":case"|":this.node.one(".availability-neg").set("value","");break;case"!&":case"!|":this.node.one(".availability-neg").set("value","!")}switch(t.op){case"&":case"!&":this.node.one(".availability-op").set("value","&");break;case"|":case"!|":this.node.one(".availability-op").set("value","|")}for(var f=0;f<t.c.length;f++){var l=t.c[f];this.root&&t&&t.showc!==undefined&&(l.showc=t.showc[f]);var c;l.type!==undefined?c=new M.core_availability.Item(l,this.root):c=new M.core_availability.List(l,!1,this.root),this.addChild(c)}}this.node.one(".availability-neg").on("change",function(){M.core_availability.form.update(),this.updateHtml()},this),this.node.one(".availability-op").on("change",function(){M.core_availability.form.update(),this.updateHtml()},this),this.updateHtml()},M.core_availability.List.prototype.addChild=function(t){this.children.length>0&&this.inner.one(".availability-children").appendChild(e.Node.create('<div class="availability-connector"><span class="label"></span></div>')),this.children.push(t),this.inner.one(".availability-children").appendChild(t.node)},M.core_availability.List.prototype.focusAfterAdd=function(){this.inner.one("button").focus()},M.core_availability.List.prototype.isIndividualShowIcons=function(){if(!this.root)throw"Can only call this on root list";var e=this.node.one(".availability-neg").get("value")==="!",t=this.node.one(".availability-op").get("value")==="|";return!e&&!t||e&&t},M.core_availability.List.prototype.renumber=function(e){var t={count:this.children.length},n;e===undefined?(t.number="",n=""):(t.number=e+":",n=e+".");var r=M.util.get_string("setheading","availability",t);this.node.one("> h3").set("innerHTML",r);for(var i=0;i<this.children.length;i++){var s=this.children[i];s.renumber(n+(i+1))}},M.core_availability.List.prototype.updateHtml=function(){this.children.length>0?(this.inner.one("> .availability-children").removeAttribute("aria-hidden"),this.inner.one("> .availability-none").setAttribute("aria-hidden","true"),this.inner.one("> .availability-header").removeAttribute("aria-hidden"),this.children.length>1?(this.inner.one(".availability-single").setAttribute("aria-hidden","true"),this.inner.one(".availability-multi").removeAttribute("aria-hidden")):(this.inner.one(".availability-single").removeAttribute("aria-hidden"),this.inner.one(".availability-multi").setAttribute("aria-hidden","true"))):(this.inner.one("> .availability-children").setAttribute("aria-hidden","true"),this.inner.one("> .availability-none"
    2 ).removeAttribute("aria-hidden"),this.inner.one("> .availability-header").setAttribute("aria-hidden","true"));if(this.root){var e=this.isIndividualShowIcons();for(var t=0;t<this.children.length;t++){var n=this.children[t];e?n.eyeIcon.span.removeAttribute("aria-hidden"):n.eyeIcon.span.setAttribute("aria-hidden","true")}e?this.eyeIcon.span.setAttribute("aria-hidden","true"):this.eyeIcon.span.removeAttribute("aria-hidden")}var r;this.inner.one(".availability-op").get("value")==="&"?r=M.str.availability.and:r=M.str.availability.or,this.inner.all("> .availability-children > .availability-connector span.label").each(function(e){e.set("innerHTML",r)})},M.core_availability.List.prototype.deleteDescendant=function(e){for(var t=0;t<this.children.length;t++){var n=this.children[t];if(n===e){this.children.splice(t,1);var r=n.node;return this.children.length>0&&(r.previous(".availability-connector")?r.previous(".availability-connector").remove():r.next(".availability-connector").remove()),this.inner.one("> .availability-children").removeChild(r),M.core_availability.form.update(),this.updateHtml(),this.inner.one("> .availability-button").one("button").focus(),!0}if(n instanceof M.core_availability.List){var i=n.deleteDescendant(e);if(i)return!0}}return!1},M.core_availability.List.prototype.clickAdd=function(){var t=e.Node.create('<div><ul class="list-unstyled"></ul><div class="availability-buttons mdl-align"><button type="button" class="btn btn-default">'+M.str.moodle.cancel+"</button></div></div>"),n=t.one("button"),r={dialog:null},i=t.one("ul"),s,o,u,a;for(var f in M.core_availability.form.plugins){if(!M.core_availability.form.plugins[f].allowAdd)continue;s=e.Node.create('<li class="clearfix"></li>'),o="availability_addrestriction_"+f;var l=M.str["availability_"+f];u=e.Node.create('<button type="button" class="btn btn-default"id="'+o+'">'+l.title+"</button>"),u.on("click",this.getAddHandler(f,r),this),s.appendChild(u),a=e.Node.create('<label for="'+o+'">'+l.description+"</label>"),s.appendChild(a),i.appendChild(s)}s=e.Node.create('<li class="clearfix"></li>'),o="availability_addrestriction_list_",u=e.Node.create('<button type="button" class="btn btn-default"id="'+o+'">'+M.str.availability.condition_group+"</button>"),u.on("click",this.getAddHandler(null,r),this),s.appendChild(u),a=e.Node.create('<label for="'+o+'">'+M.str.availability.condition_group_info+"</label>"),s.appendChild(a),i.appendChild(s);var c={headerContent:M.str.availability.addrestriction,bodyContent:t,additionalBaseClass:"availability-dialogue",draggable:!0,modal:!0,closeButton:!1,width:"450px"};r.dialog=new M.core.dialogue(c),r.dialog.show(),n.on("click",function(){r.dialog.destroy(),this.inner.one("> .availability-button").one("button").focus()},this)},M.core_availability.List.prototype.getAddHandler=function(e,t){return function(){e?newItem=new M.core_availability.Item({type:e,creating:!0},this.root):newItem=new M.core_availability.List({c:[],showc:!0},!1,this.root),this.addChild(newItem),M.core_availability.form.update(),M.core_availability.form.rootList.renumber(),this.updateHtml(),t.dialog.destroy(),newItem.focusAfterAdd()}},M.core_availability.List.prototype.getValue=function(){var e={};e.op=this.node.one(".availability-neg").get("value")+this.node.one(".availability-op").get("value"),e.c=[];var t;for(t=0;t<this.children.length;t++)e.c.push(this.children[t].getValue());if(this.root)if(this.isIndividualShowIcons()){e.showc=[];for(t=0;t<this.children.length;t++)e.showc.push(!this.children[t].eyeIcon.isHidden())}else e.show=!this.eyeIcon.isHidden();return e},M.core_availability.List.prototype.fillErrors=function(e){this.children.length===0&&!this.root&&e.push("availability:error_list_nochildren");for(var t=0;t<this.children.length;t++)this.children[t].fillErrors(e)},M.core_availability.List.prototype.eyeIcon=null,M.core_availability.List.prototype.root=!1,M.core_availability.List.prototype.children=null,M.core_availability.List.prototype.node=null,M.core_availability.List.prototype.inner=null,M.core_availability.Item=function(t,n){this.pluginType=t.type,M.core_availability.form.plugins[t.type]===undefined?(this.plugin=null,this.pluginNode=e.Node.create('<div class="availability-warning">'+M.str.availability.missingplugin+"</div>")):(this.plugin=M.core_availability.form.plugins[t.type],this.pluginNode=this.plugin.getNode(t),this.pluginNode.addClass("availability_"+t.type)),this.node=e.Node.create('<div class="availability-item"><h3 class="accesshide"></h3></div>');if(n){var r=!0;t.showc!==undefined&&(r=t.showc),this.eyeIcon=new M.core_availability.EyeIcon(!0,r),this.node.appendChild(this.eyeIcon.span)}this.pluginNode.addClass("availability-plugincontrols"),this.node.appendChild(this.pluginNode);var i=new M.core_availability.DeleteIcon(this);this.node.appendChild(i.span),this.node.appendChild(document.createTextNode(" ")),this.node.appendChild(e.Node.create('<span class="label label-warning"/>'))},M.core_availability.Item.prototype.getValue=function(){return value={type:this.pluginType},this.plugin&&this.plugin.fillValue(value,this.pluginNode),value},M.core_availability.Item.prototype.fillErrors=function(e){var t=e.length;this.plugin?this.plugin.fillErrors(e,this.pluginNode):e.push("core_availability:item_unknowntype");var n=this.node.one("> .label-warning");e.length!==t&&!n.get("firstChild")?n.appendChild(document.createTextNode(M.str.availability.invalid)):e.length===t&&n.get("firstChild")&&n.get("firstChild").remove()},M.core_availability.Item.prototype.renumber=function(e){var t={number:e};this.plugin?t.type=M.str["availability_"+this.pluginType].title:t.type="["+this.pluginType+"]",t.number=e+":";var n=M.util.get_string("itemheading","availability",t);this.node.one("> h3").set("innerHTML",n)},M.core_availability.Item.prototype.focusAfterAdd=function(){this.plugin.focusAfterAdd(this.pluginNode)},M.core_availability.Item.prototype.pluginType=null,M.core_availability.Item.prototype.plugin=null,M.core_availability.Item.prototype.eyeIcon=
    3 null,M.core_availability.Item.prototype.node=null,M.core_availability.Item.prototype.pluginNode=null,M.core_availability.EyeIcon=function(t,n){this.individual=t,this.span=e.Node.create('<a class="availability-eye" href="#" role="button">');var r=e.Node.create("<img />");this.span.appendChild(r);var i=t?"_individual":"_all",s=function(){r.set("src",M.util.image_url("i/show","core")),r.set("alt",M.str.availability["hidden"+i]),this.span.set("title",M.str.availability["hidden"+i]+" \u2022 "+M.str.availability.show_verb)},o=function(){r.set("src",M.util.image_url("i/hide","core")),r.set("alt",M.str.availability["shown"+i]),this.span.set("title",M.str.availability["shown"+i]+" \u2022 "+M.str.availability.hide_verb)};n?o.call(this):s.call(this);var u=function(e){e.preventDefault(),this.isHidden()?o.call(this):s.call(this),M.core_availability.form.update()};this.span.on("click",u,this),this.span.on("key",u,"up:32",this),this.span.on("key",function(e){e.preventDefault()},"down:32",this)},M.core_availability.EyeIcon.prototype.individual=!1,M.core_availability.EyeIcon.prototype.span=null,M.core_availability.EyeIcon.prototype.isHidden=function(){var e=this.individual?"_individual":"_all",t=M.str.availability["hidden"+e];return this.span.one("img").get("alt")===t},M.core_availability.DeleteIcon=function(t){this.span=e.Node.create('<a class="availability-delete" href="#" title="'+M.str.moodle["delete"]+'" role="button">');var n=e.Node.create('<img src="'+M.util.image_url("t/delete","core")+'" alt="'+M.str.moodle["delete"]+'" />');this.span.appendChild(n);var r=function(e){e.preventDefault(),M.core_availability.form.rootList.deleteDescendant(t),M.core_availability.form.rootList.renumber()};this.span.on("click",r,this),this.span.on("key",r,"up:32",this),this.span.on("key",function(e){e.preventDefault()},"down:32",this)},M.core_availability.DeleteIcon.prototype.span=null},"@VERSION@",{requires:["base","node","event","panel","moodle-core-notification-dialogue","json"]});
     1YUI.add("moodle-core_availability-form",function(e,t){M.core_availability=M.core_availability||{},M.core_availability.form={plugins:{},field:null,mainDiv:null,rootList:null,idCounter:0,restrictByGroup:null,init:function(t){for(var n in t){var r=t[n],i=M[r[0]].form;i.init.apply(i,r)}this.field=e.one("#id_availabilityconditionsjson"),this.field.setAttribute("aria-hidden","true"),this.mainDiv=e.Node.create('<div class="availability-field fcontainer"></div>'),this.field.insert(this.mainDiv,"after");var s=this.field.get("value"),o=null;if(s!=="")try{o=e.JSON.parse(s)}catch(u){this.field.set("value","")}this.rootList=new M.core_availability.List(o,!0),this.mainDiv.appendChild(this.rootList.node),this.update(),this.rootList.renumber(),this.mainDiv.setAttribute("aria-live","polite"),this.field.ancestor("form").on("submit",function(){this.mainDiv.all("input,textarea,select").set("disabled",!0)},this),this.restrictByGroup=e.one("#restrictbygroup");if(this.restrictByGroup){this.restrictByGroup.on("click",this.addRestrictByGroup,this);var a=e.one("#id_groupmode"),f=e.one("#id_groupingid");a&&a.on("change",this.updateRestrictByGroup,this),f&&f.on("change",this.updateRestrictByGroup,this),this.updateRestrictByGroup()}},update:function(){var t=this.rootList.getValue(),n=[];this.rootList.fillErrors(n),n.length!==0&&(t.errors=n),this.field.set("value",e.JSON.stringify(t)),this.updateRestrictByGroup()},updateRestrictByGroup:function(){if(!this.restrictByGroup)return;if(this.rootList.getValue().op!=="&"){this.restrictByGroup.set("disabled",!0);return}var t=this.rootList.hasItemOfType("group")||this.rootList.hasItemOfType("grouping");if(t){this.restrictByGroup.set("disabled",!0);return}var n=e.one("#id_groupmode"),r=e.one("#id_groupingid");if((!n||Number(n.get("value"))===0)&&(!r||Number(r.get("value"))===0)){this.restrictByGroup.set("disabled",!0);return}this.restrictByGroup.set("disabled",!1)},addRestrictByGroup:function(t){t.preventDefault();var n=e.one("#id_groupingid"),r;n&&Number(n.get("value"))!==0?r=new M.core_availability.Item({type:"grouping",id:Number(n.get("value"))},!0):r=new M.core_availability.Item({type:"group"},!0),this.rootList.addChild(r),this.update(),this.rootList.renumber(),this.rootList.updateHtml()}},M.core_availability.plugin={allowAdd:!1,init:function(e,t,n){var r=e.replace(/^availability_/,"");this.allowAdd=t,M.core_availability.form.plugins[r]=this,this.initInner.apply(this,n)},initInner:function(){},getNode:function(){throw"getNode not implemented"},fillValue:function(){throw"fillValue not implemented"},fillErrors:function(){},focusAfterAdd:function(e){var t=e.one("input:not([disabled]),select:not([disabled])");t.focus()}},M.core_availability.List=function(t,n,r){this.children=[],n!==undefined&&(this.root=n),this.node=e.Node.create('<div class="availability-list"><h3 class="accesshide"></h3><div class="availability-inner"><div class="availability-header">'+M.util.get_string("listheader_sign_before","availability")+' <label><span class="accesshide">'+M.util.get_string("label_sign","availability")+' </span><select class="availability-neg" title="'+M.util.get_string("label_sign","availability")+'">'+'<option value="">'+M.util.get_string("listheader_sign_pos","availability")+"</option>"+'<option value="!">'+M.util.get_string("listheader_sign_neg","availability")+"</option></select></label> "+'<span class="availability-single">'+M.util.get_string("listheader_single","availability")+"</span>"+'<span class="availability-multi">'+M.util.get_string("listheader_multi_before","availability")+' <label><span class="accesshide">'+M.util.get_string("label_multi","availability")+" </span>"+'<select class="availability-op" title="'+M.util.get_string("label_multi","availability")+'"><option value="&">'+M.util.get_string("listheader_multi_and","availability")+"</option>"+'<option value="|">'+M.util.get_string("listheader_multi_or","availability")+"</option></select></label> "+M.util.get_string("listheader_multi_after","availability")+"</span></div>"+'<div class="availability-children"></div>'+'<div class="availability-none">'+M.util.get_string("none","moodle")+"</div>"+'<div class="availability-button"></div></div></div>'),n||this.node.addClass("availability-childlist"),this.inner=this.node.one("> .availability-inner");var i=!0;n?(t&&t.show!==undefined&&(i=t.show),this.eyeIcon=new M.core_availability.EyeIcon(!1,i),this.node.one(".availability-header").get("firstChild").insert(this.eyeIcon.span,"before")):r&&(t&&t.showc!==undefined&&(i=t.showc),this.eyeIcon=new M.core_availability.EyeIcon(!1,i),this.inner.insert(this.eyeIcon.span,"before"));if(!n){var s=new M.core_availability.DeleteIcon(this),o=this.node.one(".availability-none");o.appendChild(document.createTextNode(" ")),o.appendChild(s.span),o.appendChild(e.Node.create('<span class="label label-warning">'+M.util.get_string("invalid","availability")+"</span>"))}var u=e.Node.create('<button type="button" class="btn btn-default">'+M.util.get_string("addrestriction","availability")+"</button>");u.on("click",function(){this.clickAdd()},this),this.node.one("div.availability-button").appendChild(u);if(t){switch(t.op){case"&":case"|":this.node.one(".availability-neg").set("value","");break;case"!&":case"!|":this.node.one(".availability-neg").set("value","!")}switch(t.op){case"&":case"!&":this.node.one(".availability-op").set("value","&");break;case"|":case"!|":this.node.one(".availability-op").set("value","|")}for(var a=0;a<t.c.length;a++){var f=t.c[a];this.root&&t&&t.showc!==undefined&&(f.showc=t.showc[a]);var l;f.type!==undefined?l=new M.core_availability.Item(f,this.root):l=new M.core_availability.List(f,!1,this.root),this.addChild(l)}}this.node.one(".availability-neg").on("change",function(){M.core_availability.form.update(),this.updateHtml()},this),this.node.one(".availability-op").on("change",function(){M.core_availability.form.update(),this.updateHtml()},this),this.updateHtml()},M.core_availability.List.prototype.addChild=function(t){this.children
     2.length>0&&this.inner.one(".availability-children").appendChild(e.Node.create('<div class="availability-connector"><span class="label"></span></div>')),this.children.push(t),this.inner.one(".availability-children").appendChild(t.node)},M.core_availability.List.prototype.focusAfterAdd=function(){this.inner.one("button").focus()},M.core_availability.List.prototype.isIndividualShowIcons=function(){if(!this.root)throw"Can only call this on root list";var e=this.node.one(".availability-neg").get("value")==="!",t=this.node.one(".availability-op").get("value")==="|";return!e&&!t||e&&t},M.core_availability.List.prototype.renumber=function(e){var t={count:this.children.length},n;e===undefined?(t.number="",n=""):(t.number=e+":",n=e+".");var r=M.util.get_string("setheading","availability",t);this.node.one("> h3").set("innerHTML",r);for(var i=0;i<this.children.length;i++){var s=this.children[i];s.renumber(n+(i+1))}},M.core_availability.List.prototype.updateHtml=function(){this.children.length>0?(this.inner.one("> .availability-children").removeAttribute("aria-hidden"),this.inner.one("> .availability-none").setAttribute("aria-hidden","true"),this.inner.one("> .availability-header").removeAttribute("aria-hidden"),this.children.length>1?(this.inner.one(".availability-single").setAttribute("aria-hidden","true"),this.inner.one(".availability-multi").removeAttribute("aria-hidden")):(this.inner.one(".availability-single").removeAttribute("aria-hidden"),this.inner.one(".availability-multi").setAttribute("aria-hidden","true"))):(this.inner.one("> .availability-children").setAttribute("aria-hidden","true"),this.inner.one("> .availability-none").removeAttribute("aria-hidden"),this.inner.one("> .availability-header").setAttribute("aria-hidden","true"));if(this.root){var e=this.isIndividualShowIcons();for(var t=0;t<this.children.length;t++){var n=this.children[t];e?n.eyeIcon.span.removeAttribute("aria-hidden"):n.eyeIcon.span.setAttribute("aria-hidden","true")}e?this.eyeIcon.span.setAttribute("aria-hidden","true"):this.eyeIcon.span.removeAttribute("aria-hidden")}var r;this.inner.one(".availability-op").get("value")==="&"?r=M.util.get_string("and","availability"):r=M.util.get_string("or","availability"),this.inner.all("> .availability-children > .availability-connector span.label").each(function(e){e.set("innerHTML",r)})},M.core_availability.List.prototype.deleteDescendant=function(e){for(var t=0;t<this.children.length;t++){var n=this.children[t];if(n===e){this.children.splice(t,1);var r=n.node;return this.children.length>0&&(r.previous(".availability-connector")?r.previous(".availability-connector").remove():r.next(".availability-connector").remove()),this.inner.one("> .availability-children").removeChild(r),M.core_availability.form.update(),this.updateHtml(),this.inner.one("> .availability-button").one("button").focus(),!0}if(n instanceof M.core_availability.List){var i=n.deleteDescendant(e);if(i)return!0}}return!1},M.core_availability.List.prototype.clickAdd=function(){var t=e.Node.create('<div><ul class="list-unstyled"></ul><div class="availability-buttons mdl-align"><button type="button" class="btn btn-default">'+M.util.get_string("cancel","moodle")+"</button></div></div>"),n=t.one("button"),r={dialog:null},i=t.one("ul"),s,o,u,a;for(var f in M.core_availability.form.plugins){if(!M.core_availability.form.plugins[f].allowAdd)continue;s=e.Node.create('<li class="clearfix"></li>'),o="availability_addrestriction_"+f,u=e.Node.create('<button type="button" class="btn btn-default"id="'+o+'">'+M.util.get_string("title","availability_"+f)+"</button>"),u.on("click",this.getAddHandler(f,r),this),s.appendChild(u),a=e.Node.create('<label for="'+o+'">'+M.util.get_string("description","availability_"+f)+"</label>"),s.appendChild(a),i.appendChild(s)}s=e.Node.create('<li class="clearfix"></li>'),o="availability_addrestriction_list_",u=e.Node.create('<button type="button" class="btn btn-default"id="'+o+'">'+M.util.get_string("condition_group","availability")+"</button>"),u.on("click",this.getAddHandler(null,r),this),s.appendChild(u),a=e.Node.create('<label for="'+o+'">'+M.util.get_string("condition_group_info","availability")+"</label>"),s.appendChild(a),i.appendChild(s);var l={headerContent:M.util.get_string("addrestriction","availability"),bodyContent:t,additionalBaseClass:"availability-dialogue",draggable:!0,modal:!0,closeButton:!1,width:"450px"};r.dialog=new M.core.dialogue(l),r.dialog.show(),n.on("click",function(){r.dialog.destroy(),this.inner.one("> .availability-button").one("button").focus()},this)},M.core_availability.List.prototype.getAddHandler=function(e,t){return function(){var n;e?n=new M.core_availability.Item({type:e,creating:!0},this.root):n=new M.core_availability.List({c:[],showc:!0},!1,this.root),this.addChild(n),M.core_availability.form.update(),M.core_availability.form.rootList.renumber(),this.updateHtml(),t.dialog.destroy(),n.focusAfterAdd()}},M.core_availability.List.prototype.getValue=function(){var e={};e.op=this.node.one(".availability-neg").get("value")+this.node.one(".availability-op").get("value"),e.c=[];var t;for(t=0;t<this.children.length;t++)e.c.push(this.children[t].getValue());if(this.root)if(this.isIndividualShowIcons()){e.showc=[];for(t=0;t<this.children.length;t++)e.showc.push(!this.children[t].eyeIcon.isHidden())}else e.show=!this.eyeIcon.isHidden();return e},M.core_availability.List.prototype.fillErrors=function(e){this.children.length===0&&!this.root&&e.push("availability:error_list_nochildren");for(var t=0;t<this.children.length;t++)this.children[t].fillErrors(e)},M.core_availability.List.prototype.hasItemOfType=function(e){for(var t=0;t<this.children.length;t++){var n=this.children[t];if(n instanceof M.core_availability.List){if(n.hasItemOfType(e))return!0}else if(n.pluginType===e)return!0}return!1},M.core_availability.List.prototype.eyeIcon=null,M.core_availability.List.prototype.root=!1,M.core_availability.List.prototype.children=null,M.core_availability.List.prototype.node=null,M.core_availability
     3.List.prototype.inner=null,M.core_availability.Item=function(t,n){this.pluginType=t.type,M.core_availability.form.plugins[t.type]===undefined?(this.plugin=null,this.pluginNode=e.Node.create('<div class="availability-warning">'+M.util.get_string("missingplugin","availability")+"</div>")):(this.plugin=M.core_availability.form.plugins[t.type],this.pluginNode=this.plugin.getNode(t),this.pluginNode.addClass("availability_"+t.type)),this.node=e.Node.create('<div class="availability-item"><h3 class="accesshide"></h3></div>');if(n){var r=!0;t.showc!==undefined&&(r=t.showc),this.eyeIcon=new M.core_availability.EyeIcon(!0,r),this.node.appendChild(this.eyeIcon.span)}this.pluginNode.addClass("availability-plugincontrols"),this.node.appendChild(this.pluginNode);var i=new M.core_availability.DeleteIcon(this);this.node.appendChild(i.span),this.node.appendChild(document.createTextNode(" ")),this.node.appendChild(e.Node.create('<span class="label label-warning"/>'))},M.core_availability.Item.prototype.getValue=function(){var e={type:this.pluginType};return this.plugin&&this.plugin.fillValue(e,this.pluginNode),e},M.core_availability.Item.prototype.fillErrors=function(e){var t=e.length;this.plugin?this.plugin.fillErrors(e,this.pluginNode):e.push("core_availability:item_unknowntype");var n=this.node.one("> .label-warning");e.length!==t&&!n.get("firstChild")?n.appendChild(document.createTextNode(M.util.get_string("invalid","availability"))):e.length===t&&n.get("firstChild")&&n.get("firstChild").remove()},M.core_availability.Item.prototype.renumber=function(e){var t={number:e};this.plugin?t.type=M.util.get_string("title","availability_"+this.pluginType):t.type="["+this.pluginType+"]",t.number=e+":";var n=M.util.get_string("itemheading","availability",t);this.node.one("> h3").set("innerHTML",n)},M.core_availability.Item.prototype.focusAfterAdd=function(){this.plugin.focusAfterAdd(this.pluginNode)},M.core_availability.Item.prototype.pluginType=null,M.core_availability.Item.prototype.plugin=null,M.core_availability.Item.prototype.eyeIcon=null,M.core_availability.Item.prototype.node=null,M.core_availability.Item.prototype.pluginNode=null,M.core_availability.EyeIcon=function(t,n){this.individual=t,this.span=e.Node.create('<a class="availability-eye" href="#" role="button">');var r=e.Node.create("<img />");this.span.appendChild(r);var i=t?"_individual":"_all",s=function(){var e=M.util.get_string("hidden"+i,"availability");r.set("src",M.util.image_url("i/show","core")),r.set("alt",e),this.span.set("title",e+" \u2022 "+M.util.get_string("show_verb","availability"))},o=function(){var e=M.util.get_string("shown"+i,"availability");r.set("src",M.util.image_url("i/hide","core")),r.set("alt",e),this.span.set("title",e+" \u2022 "+M.util.get_string("hide_verb","availability"))};n?o.call(this):s.call(this);var u=function(e){e.preventDefault(),this.isHidden()?o.call(this):s.call(this),M.core_availability.form.update()};this.span.on("click",u,this),this.span.on("key",u,"up:32",this),this.span.on("key",function(e){e.preventDefault()},"down:32",this)},M.core_availability.EyeIcon.prototype.individual=!1,M.core_availability.EyeIcon.prototype.span=null,M.core_availability.EyeIcon.prototype.isHidden=function(){var e=this.individual?"_individual":"_all",t=M.util.get_string("hidden"+e,"availability");return this.span.one("img").get("alt")===t},M.core_availability.DeleteIcon=function(t){this.span=e.Node.create('<a class="availability-delete" href="#" title="'+M.util.get_string("delete","moodle")+'" role="button">');var n=e.Node.create('<img src="'+M.util.image_url("t/delete","core")+'" alt="'+M.util.get_string("delete","moodle")+'" />');this.span.appendChild(n);var r=function(e){e.preventDefault(),M.core_availability.form.rootList.deleteDescendant(t),M.core_availability.form.rootList.renumber()};this.span.on("click",r,this),this.span.on("key",r,"up:32",this),this.span.on("key",function(e){e.preventDefault()},"down:32",this)},M.core_availability.DeleteIcon.prototype.span=null},"@VERSION@",{requires:["base","node","event","panel","moodle-core-notification-dialogue","json"]});
  • moodle/trunk/fuentes/availability/yui/build/moodle-core_availability-form/moodle-core_availability-form.js

    r136 r1331  
    6666     */
    6767    idCounter : 0,
     68
     69    /**
     70     * The 'Restrict by group' button if present.
     71     *
     72     * @property restrictByGroup
     73     * @type Y.Node
     74     */
     75    restrictByGroup : null,
    6876
    6977    /**
     
    122130            this.mainDiv.all('input,textarea,select').set('disabled', true);
    123131        }, this);
     132
     133        // If the form has group mode and/or grouping options, there is a
     134        // 'add restriction' button there.
     135        this.restrictByGroup = Y.one('#restrictbygroup');
     136        if (this.restrictByGroup) {
     137            this.restrictByGroup.on('click', this.addRestrictByGroup, this);
     138            var groupmode = Y.one('#id_groupmode');
     139            var groupingid = Y.one('#id_groupingid');
     140            if (groupmode) {
     141                groupmode.on('change', this.updateRestrictByGroup, this);
     142            }
     143            if (groupingid) {
     144                groupingid.on('change', this.updateRestrictByGroup, this);
     145            }
     146            this.updateRestrictByGroup();
     147        }
    124148    },
    125149
     
    144168        // Set into hidden form field, JS-encoded.
    145169        this.field.set('value', Y.JSON.stringify(jsValue));
     170
     171        // Also update the restrict by group button if present.
     172        this.updateRestrictByGroup();
     173    },
     174
     175    /**
     176     * Updates the status of the 'restrict by group' button (enables or disables
     177     * it) based on current availability restrictions and group/grouping settings.
     178     */
     179    updateRestrictByGroup : function() {
     180        if (!this.restrictByGroup) {
     181            return;
     182        }
     183
     184        // If the root list is anything other than the default 'and' type, disable.
     185        if (this.rootList.getValue().op !== '&') {
     186            this.restrictByGroup.set('disabled', true);
     187            return;
     188        }
     189
     190        // If there's already a group restriction, disable it.
     191        var alreadyGot = this.rootList.hasItemOfType('group') ||
     192                this.rootList.hasItemOfType('grouping');
     193        if (alreadyGot) {
     194            this.restrictByGroup.set('disabled', true);
     195            return;
     196        }
     197
     198        // If the groupmode and grouping id aren't set, disable it.
     199        var groupmode = Y.one('#id_groupmode');
     200        var groupingid = Y.one('#id_groupingid');
     201        if ((!groupmode || Number(groupmode.get('value')) === 0) &&
     202                (!groupingid || Number(groupingid.get('value')) === 0)) {
     203            this.restrictByGroup.set('disabled', true);
     204            return;
     205        }
     206
     207        this.restrictByGroup.set('disabled', false);
     208    },
     209
     210    /**
     211     * Called when the user clicks on the 'restrict by group' button. This is
     212     * a special case that adds a group or grouping restriction.
     213     *
     214     * By default this restriction is not shown which makes it similar to the
     215     *
     216     * @param e Button click event
     217     */
     218    addRestrictByGroup : function(e) {
     219        // If you don't prevent default, it submits the form for some reason.
     220        e.preventDefault();
     221
     222        // Add the condition.
     223        var groupingid = Y.one('#id_groupingid');
     224        var newChild;
     225        if (groupingid && Number(groupingid.get('value')) !== 0) {
     226            // Add a grouping restriction if one is specified.
     227            newChild = new M.core_availability.Item(
     228                    {type : 'grouping', id : Number(groupingid.get('value'))}, true);
     229        } else {
     230            // Otherwise just add a group restriction.
     231            newChild = new M.core_availability.Item({type : 'group'}, true);
     232        }
     233
     234        // Refresh HTML.
     235        this.rootList.addChild(newChild);
     236        this.update();
     237        this.rootList.renumber();
     238        this.rootList.updateHtml();
    146239    }
    147240};
     
    261354        this.root = root;
    262355    }
    263     var strings = M.str.availability;
    264356    // Create DIV structure (without kids).
    265357    this.node = Y.Node.create('<div class="availability-list"><h3 class="accesshide"></h3>' +
    266358            '<div class="availability-inner">' +
    267             '<div class="availability-header">' + strings.listheader_sign_before +
    268             ' <label><span class="accesshide">' + strings.label_sign +
    269             ' </span><select class="availability-neg" title="' + strings.label_sign + '">' +
    270             '<option value="">' + strings.listheader_sign_pos + '</option>' +
    271             '<option value="!">' + strings.listheader_sign_neg + '</option></select></label> ' +
    272             '<span class="availability-single">' + strings.listheader_single + '</span>' +
    273             '<span class="availability-multi">' + strings.listheader_multi_before +
    274             ' <label><span class="accesshide">' + strings.label_multi + ' </span>' +
    275             '<select class="availability-op" title="' + strings.label_multi + '"><option value="&">' +
    276             strings.listheader_multi_and + '</option>' +
    277             '<option value="|">' + strings.listheader_multi_or + '</option></select></label> ' +
    278             strings.listheader_multi_after + '</span></div>' +
     359            '<div class="availability-header">' + M.util.get_string('listheader_sign_before', 'availability') +
     360            ' <label><span class="accesshide">' + M.util.get_string('label_sign', 'availability') +
     361            ' </span><select class="availability-neg" title="' + M.util.get_string('label_sign', 'availability') + '">' +
     362            '<option value="">' + M.util.get_string('listheader_sign_pos', 'availability') + '</option>' +
     363            '<option value="!">' + M.util.get_string('listheader_sign_neg', 'availability') + '</option></select></label> ' +
     364            '<span class="availability-single">' + M.util.get_string('listheader_single', 'availability') + '</span>' +
     365            '<span class="availability-multi">' + M.util.get_string('listheader_multi_before', 'availability') +
     366            ' <label><span class="accesshide">' + M.util.get_string('label_multi', 'availability') + ' </span>' +
     367            '<select class="availability-op" title="' + M.util.get_string('label_multi', 'availability') + '"><option value="&">' +
     368            M.util.get_string('listheader_multi_and', 'availability') + '</option>' +
     369            '<option value="|">' + M.util.get_string('listheader_multi_or', 'availability') + '</option></select></label> ' +
     370            M.util.get_string('listheader_multi_after', 'availability') + '</span></div>' +
    279371            '<div class="availability-children"></div>' +
    280             '<div class="availability-none">' + M.str.moodle.none + '</div>' +
     372            '<div class="availability-none">' + M.util.get_string('none', 'moodle') + '</div>' +
    281373            '<div class="availability-button"></div></div></div>');
    282374    if (!root) {
     
    314406        // Also if it's not the root, none is actually invalid, so add a label.
    315407        noneNode.appendChild(Y.Node.create('<span class="label label-warning">' +
    316                 M.str.availability.invalid + '</span>'));
     408                M.util.get_string('invalid', 'availability') + '</span>'));
    317409    }
    318410
    319411    // Create the button and add it.
    320412    var button = Y.Node.create('<button type="button" class="btn btn-default">' +
    321             M.str.availability.addrestriction + '</button>');
     413            M.util.get_string('addrestriction', 'availability') + '</button>');
    322414    button.on("click", function() { this.clickAdd(); }, this);
    323415    this.node.one('div.availability-button').appendChild(button);
     
    510602    var connectorText;
    511603    if (this.inner.one('.availability-op').get('value') === '&') {
    512         connectorText = M.str.availability.and;
     604        connectorText = M.util.get_string('and', 'availability');
    513605    } else {
    514         connectorText = M.str.availability.or;
     606        connectorText = M.util.get_string('or', 'availability');
    515607    }
    516608    this.inner.all('> .availability-children > .availability-connector span.label').each(function(span) {
     
    574666            '<ul class="list-unstyled"></ul>' +
    575667            '<div class="availability-buttons mdl-align">' +
    576             '<button type="button" class="btn btn-default">' + M.str.moodle.cancel +
     668            '<button type="button" class="btn btn-default">' + M.util.get_string('cancel', 'moodle') +
    577669            '</button></div></div>');
    578670    var cancel = content.one('button');
     
    590682        li = Y.Node.create('<li class="clearfix"></li>');
    591683        id = 'availability_addrestriction_' + type;
    592         var pluginStrings = M.str['availability_' + type];
    593684        button = Y.Node.create('<button type="button" class="btn btn-default"' +
    594                 'id="' + id + '">' + pluginStrings.title + '</button>');
     685                'id="' + id + '">' + M.util.get_string('title', 'availability_' + type) + '</button>');
    595686        button.on('click', this.getAddHandler(type, dialogRef), this);
    596687        li.appendChild(button);
    597688        label = Y.Node.create('<label for="' + id + '">' +
    598                 pluginStrings.description + '</label>');
     689                M.util.get_string('description', 'availability_' + type) + '</label>');
    599690        li.appendChild(label);
    600691        ul.appendChild(li);
     
    604695    id = 'availability_addrestriction_list_';
    605696    button = Y.Node.create('<button type="button" class="btn btn-default"' +
    606             'id="' + id + '">' + M.str.availability.condition_group + '</button>');
     697            'id="' + id + '">' + M.util.get_string('condition_group', 'availability') + '</button>');
    607698    button.on('click', this.getAddHandler(null, dialogRef), this);
    608699    li.appendChild(button);
    609700    label = Y.Node.create('<label for="' + id + '">' +
    610             M.str.availability.condition_group_info + '</label>');
     701            M.util.get_string('condition_group_info', 'availability') + '</label>');
    611702    li.appendChild(label);
    612703    ul.appendChild(li);
    613704
    614705    var config = {
    615         headerContent : M.str.availability.addrestriction,
     706        headerContent : M.util.get_string('addrestriction', 'availability'),
    616707        bodyContent : content,
    617708        additionalBaseClass : 'availability-dialogue',
     
    641732M.core_availability.List.prototype.getAddHandler = function(type, dialogRef) {
    642733    return function() {
     734        var newItem;
    643735        if (type) {
    644736            // Create an Item object to represent the child.
     
    713805
    714806/**
     807 * Checks whether the list contains any items of the given type name.
     808 *
     809 * @method hasItemOfType
     810 * @param {String} pluginType Required plugin type (name)
     811 * @return {Boolean} True if there is one
     812 */
     813M.core_availability.List.prototype.hasItemOfType = function(pluginType) {
     814    // Check each item.
     815    for (var i = 0; i < this.children.length; i++) {
     816        var child = this.children[i];
     817        if (child instanceof M.core_availability.List) {
     818            // Recursive call.
     819            if (child.hasItemOfType(pluginType)) {
     820                return true;
     821            }
     822        } else {
     823            if (child.pluginType === pluginType) {
     824                return true;
     825            }
     826        }
     827    }
     828    return false;
     829};
     830
     831/**
    715832 * Eye icon for this list (null if none).
    716833 *
     
    767884        this.plugin = null;
    768885        this.pluginNode = Y.Node.create('<div class="availability-warning">' +
    769                 M.str.availability.missingplugin + '</div>');
     886                M.util.get_string('missingplugin', 'availability') + '</div>');
    770887    } else {
    771888        // Plugin is known.
     
    811928 */
    812929M.core_availability.Item.prototype.getValue = function() {
    813     value = { 'type' : this.pluginType };
     930    var value = { 'type' : this.pluginType };
    814931    if (this.plugin) {
    815932        this.plugin.fillValue(value, this.pluginNode);
     
    838955    var errorLabel = this.node.one('> .label-warning');
    839956    if (errors.length !== before && !errorLabel.get('firstChild')) {
    840         errorLabel.appendChild(document.createTextNode(M.str.availability.invalid));
     957        errorLabel.appendChild(document.createTextNode(M.util.get_string('invalid', 'availability')));
    841958    } else if (errors.length === before && errorLabel.get('firstChild')) {
    842959        errorLabel.get('firstChild').remove();
     
    854971    var headingParams = { number: number };
    855972    if (this.plugin) {
    856         headingParams.type = M.str['availability_' + this.pluginType].title;
     973        headingParams.type = M.util.get_string('title', 'availability_' + this.pluginType);
    857974    } else {
    858975        headingParams.type = '[' + this.pluginType + ']';
     
    9331050
    9341051    // Set up button text and icon.
    935     var suffix = individual ? '_individual' : '_all';
    936     var setHidden = function() {
    937         icon.set('src', M.util.image_url('i/show', 'core'));
    938         icon.set('alt', M.str.availability['hidden' + suffix]);
    939         this.span.set('title', M.str.availability['hidden' + suffix] + ' \u2022 ' +
    940                 M.str.availability.show_verb);
    941     };
    942     var setShown = function() {
    943         icon.set('src', M.util.image_url('i/hide', 'core'));
    944         icon.set('alt', M.str.availability['shown' + suffix]);
    945         this.span.set('title', M.str.availability['shown' + suffix] + ' \u2022 ' +
    946                 M.str.availability.hide_verb);
    947     };
     1052    var suffix = individual ? '_individual' : '_all',
     1053        setHidden = function() {
     1054            var hiddenStr = M.util.get_string('hidden' + suffix, 'availability');
     1055            icon.set('src', M.util.image_url('i/show', 'core'));
     1056            icon.set('alt', hiddenStr);
     1057            this.span.set('title', hiddenStr + ' \u2022 ' +
     1058                    M.util.get_string('show_verb', 'availability'));
     1059        },
     1060        setShown = function() {
     1061            var shownStr = M.util.get_string('shown' + suffix, 'availability');
     1062            icon.set('src', M.util.image_url('i/hide', 'core'));
     1063            icon.set('alt', shownStr);
     1064            this.span.set('title', shownStr + ' \u2022 ' +
     1065                    M.util.get_string('hide_verb', 'availability'));
     1066        };
    9481067    if(shown) {
    9491068        setShown.call(this);
     
    9901109 */
    9911110M.core_availability.EyeIcon.prototype.isHidden = function() {
    992     var suffix = this.individual ? '_individual' : '_all';
    993     var compare = M.str.availability['hidden' + suffix];
     1111    var suffix = this.individual ? '_individual' : '_all',
     1112        compare = M.util.get_string('hidden' + suffix, 'availability');
    9941113    return this.span.one('img').get('alt') === compare;
    9951114};
     
    10051124M.core_availability.DeleteIcon = function(toDelete) {
    10061125    this.span = Y.Node.create('<a class="availability-delete" href="#" title="' +
    1007             M.str.moodle['delete'] + '" role="button">');
     1126            M.util.get_string('delete', 'moodle') + '" role="button">');
    10081127    var img = Y.Node.create('<img src="' + M.util.image_url('t/delete', 'core') +
    1009             '" alt="' + M.str.moodle['delete'] + '" />');
     1128            '" alt="' + M.util.get_string('delete', 'moodle') + '" />');
    10101129    this.span.appendChild(img);
    10111130    var click = function(e) {
  • moodle/trunk/fuentes/availability/yui/src/form/js/form.js

    r136 r1331  
    6464     */
    6565    idCounter : 0,
     66
     67    /**
     68     * The 'Restrict by group' button if present.
     69     *
     70     * @property restrictByGroup
     71     * @type Y.Node
     72     */
     73    restrictByGroup : null,
    6674
    6775    /**
     
    120128            this.mainDiv.all('input,textarea,select').set('disabled', true);
    121129        }, this);
     130
     131        // If the form has group mode and/or grouping options, there is a
     132        // 'add restriction' button there.
     133        this.restrictByGroup = Y.one('#restrictbygroup');
     134        if (this.restrictByGroup) {
     135            this.restrictByGroup.on('click', this.addRestrictByGroup, this);
     136            var groupmode = Y.one('#id_groupmode');
     137            var groupingid = Y.one('#id_groupingid');
     138            if (groupmode) {
     139                groupmode.on('change', this.updateRestrictByGroup, this);
     140            }
     141            if (groupingid) {
     142                groupingid.on('change', this.updateRestrictByGroup, this);
     143            }
     144            this.updateRestrictByGroup();
     145        }
    122146    },
    123147
     
    142166        // Set into hidden form field, JS-encoded.
    143167        this.field.set('value', Y.JSON.stringify(jsValue));
     168
     169        // Also update the restrict by group button if present.
     170        this.updateRestrictByGroup();
     171    },
     172
     173    /**
     174     * Updates the status of the 'restrict by group' button (enables or disables
     175     * it) based on current availability restrictions and group/grouping settings.
     176     */
     177    updateRestrictByGroup : function() {
     178        if (!this.restrictByGroup) {
     179            return;
     180        }
     181
     182        // If the root list is anything other than the default 'and' type, disable.
     183        if (this.rootList.getValue().op !== '&') {
     184            this.restrictByGroup.set('disabled', true);
     185            return;
     186        }
     187
     188        // If there's already a group restriction, disable it.
     189        var alreadyGot = this.rootList.hasItemOfType('group') ||
     190                this.rootList.hasItemOfType('grouping');
     191        if (alreadyGot) {
     192            this.restrictByGroup.set('disabled', true);
     193            return;
     194        }
     195
     196        // If the groupmode and grouping id aren't set, disable it.
     197        var groupmode = Y.one('#id_groupmode');
     198        var groupingid = Y.one('#id_groupingid');
     199        if ((!groupmode || Number(groupmode.get('value')) === 0) &&
     200                (!groupingid || Number(groupingid.get('value')) === 0)) {
     201            this.restrictByGroup.set('disabled', true);
     202            return;
     203        }
     204
     205        this.restrictByGroup.set('disabled', false);
     206    },
     207
     208    /**
     209     * Called when the user clicks on the 'restrict by group' button. This is
     210     * a special case that adds a group or grouping restriction.
     211     *
     212     * By default this restriction is not shown which makes it similar to the
     213     *
     214     * @param e Button click event
     215     */
     216    addRestrictByGroup : function(e) {
     217        // If you don't prevent default, it submits the form for some reason.
     218        e.preventDefault();
     219
     220        // Add the condition.
     221        var groupingid = Y.one('#id_groupingid');
     222        var newChild;
     223        if (groupingid && Number(groupingid.get('value')) !== 0) {
     224            // Add a grouping restriction if one is specified.
     225            newChild = new M.core_availability.Item(
     226                    {type : 'grouping', id : Number(groupingid.get('value'))}, true);
     227        } else {
     228            // Otherwise just add a group restriction.
     229            newChild = new M.core_availability.Item({type : 'group'}, true);
     230        }
     231
     232        // Refresh HTML.
     233        this.rootList.addChild(newChild);
     234        this.update();
     235        this.rootList.renumber();
     236        this.rootList.updateHtml();
    144237    }
    145238};
     
    259352        this.root = root;
    260353    }
    261     var strings = M.str.availability;
    262354    // Create DIV structure (without kids).
    263355    this.node = Y.Node.create('<div class="availability-list"><h3 class="accesshide"></h3>' +
    264356            '<div class="availability-inner">' +
    265             '<div class="availability-header">' + strings.listheader_sign_before +
    266             ' <label><span class="accesshide">' + strings.label_sign +
    267             ' </span><select class="availability-neg" title="' + strings.label_sign + '">' +
    268             '<option value="">' + strings.listheader_sign_pos + '</option>' +
    269             '<option value="!">' + strings.listheader_sign_neg + '</option></select></label> ' +
    270             '<span class="availability-single">' + strings.listheader_single + '</span>' +
    271             '<span class="availability-multi">' + strings.listheader_multi_before +
    272             ' <label><span class="accesshide">' + strings.label_multi + ' </span>' +
    273             '<select class="availability-op" title="' + strings.label_multi + '"><option value="&">' +
    274             strings.listheader_multi_and + '</option>' +
    275             '<option value="|">' + strings.listheader_multi_or + '</option></select></label> ' +
    276             strings.listheader_multi_after + '</span></div>' +
     357            '<div class="availability-header">' + M.util.get_string('listheader_sign_before', 'availability') +
     358            ' <label><span class="accesshide">' + M.util.get_string('label_sign', 'availability') +
     359            ' </span><select class="availability-neg" title="' + M.util.get_string('label_sign', 'availability') + '">' +
     360            '<option value="">' + M.util.get_string('listheader_sign_pos', 'availability') + '</option>' +
     361            '<option value="!">' + M.util.get_string('listheader_sign_neg', 'availability') + '</option></select></label> ' +
     362            '<span class="availability-single">' + M.util.get_string('listheader_single', 'availability') + '</span>' +
     363            '<span class="availability-multi">' + M.util.get_string('listheader_multi_before', 'availability') +
     364            ' <label><span class="accesshide">' + M.util.get_string('label_multi', 'availability') + ' </span>' +
     365            '<select class="availability-op" title="' + M.util.get_string('label_multi', 'availability') + '"><option value="&">' +
     366            M.util.get_string('listheader_multi_and', 'availability') + '</option>' +
     367            '<option value="|">' + M.util.get_string('listheader_multi_or', 'availability') + '</option></select></label> ' +
     368            M.util.get_string('listheader_multi_after', 'availability') + '</span></div>' +
    277369            '<div class="availability-children"></div>' +
    278             '<div class="availability-none">' + M.str.moodle.none + '</div>' +
     370            '<div class="availability-none">' + M.util.get_string('none', 'moodle') + '</div>' +
    279371            '<div class="availability-button"></div></div></div>');
    280372    if (!root) {
     
    312404        // Also if it's not the root, none is actually invalid, so add a label.
    313405        noneNode.appendChild(Y.Node.create('<span class="label label-warning">' +
    314                 M.str.availability.invalid + '</span>'));
     406                M.util.get_string('invalid', 'availability') + '</span>'));
    315407    }
    316408
    317409    // Create the button and add it.
    318410    var button = Y.Node.create('<button type="button" class="btn btn-default">' +
    319             M.str.availability.addrestriction + '</button>');
     411            M.util.get_string('addrestriction', 'availability') + '</button>');
    320412    button.on("click", function() { this.clickAdd(); }, this);
    321413    this.node.one('div.availability-button').appendChild(button);
     
    508600    var connectorText;
    509601    if (this.inner.one('.availability-op').get('value') === '&') {
    510         connectorText = M.str.availability.and;
     602        connectorText = M.util.get_string('and', 'availability');
    511603    } else {
    512         connectorText = M.str.availability.or;
     604        connectorText = M.util.get_string('or', 'availability');
    513605    }
    514606    this.inner.all('> .availability-children > .availability-connector span.label').each(function(span) {
     
    572664            '<ul class="list-unstyled"></ul>' +
    573665            '<div class="availability-buttons mdl-align">' +
    574             '<button type="button" class="btn btn-default">' + M.str.moodle.cancel +
     666            '<button type="button" class="btn btn-default">' + M.util.get_string('cancel', 'moodle') +
    575667            '</button></div></div>');
    576668    var cancel = content.one('button');
     
    588680        li = Y.Node.create('<li class="clearfix"></li>');
    589681        id = 'availability_addrestriction_' + type;
    590         var pluginStrings = M.str['availability_' + type];
    591682        button = Y.Node.create('<button type="button" class="btn btn-default"' +
    592                 'id="' + id + '">' + pluginStrings.title + '</button>');
     683                'id="' + id + '">' + M.util.get_string('title', 'availability_' + type) + '</button>');
    593684        button.on('click', this.getAddHandler(type, dialogRef), this);
    594685        li.appendChild(button);
    595686        label = Y.Node.create('<label for="' + id + '">' +
    596                 pluginStrings.description + '</label>');
     687                M.util.get_string('description', 'availability_' + type) + '</label>');
    597688        li.appendChild(label);
    598689        ul.appendChild(li);
     
    602693    id = 'availability_addrestriction_list_';
    603694    button = Y.Node.create('<button type="button" class="btn btn-default"' +
    604             'id="' + id + '">' + M.str.availability.condition_group + '</button>');
     695            'id="' + id + '">' + M.util.get_string('condition_group', 'availability') + '</button>');
    605696    button.on('click', this.getAddHandler(null, dialogRef), this);
    606697    li.appendChild(button);
    607698    label = Y.Node.create('<label for="' + id + '">' +
    608             M.str.availability.condition_group_info + '</label>');
     699            M.util.get_string('condition_group_info', 'availability') + '</label>');
    609700    li.appendChild(label);
    610701    ul.appendChild(li);
    611702
    612703    var config = {
    613         headerContent : M.str.availability.addrestriction,
     704        headerContent : M.util.get_string('addrestriction', 'availability'),
    614705        bodyContent : content,
    615706        additionalBaseClass : 'availability-dialogue',
     
    639730M.core_availability.List.prototype.getAddHandler = function(type, dialogRef) {
    640731    return function() {
     732        var newItem;
    641733        if (type) {
    642734            // Create an Item object to represent the child.
     
    711803
    712804/**
     805 * Checks whether the list contains any items of the given type name.
     806 *
     807 * @method hasItemOfType
     808 * @param {String} pluginType Required plugin type (name)
     809 * @return {Boolean} True if there is one
     810 */
     811M.core_availability.List.prototype.hasItemOfType = function(pluginType) {
     812    // Check each item.
     813    for (var i = 0; i < this.children.length; i++) {
     814        var child = this.children[i];
     815        if (child instanceof M.core_availability.List) {
     816            // Recursive call.
     817            if (child.hasItemOfType(pluginType)) {
     818                return true;
     819            }
     820        } else {
     821            if (child.pluginType === pluginType) {
     822                return true;
     823            }
     824        }
     825    }
     826    return false;
     827};
     828
     829/**
    713830 * Eye icon for this list (null if none).
    714831 *
     
    765882        this.plugin = null;
    766883        this.pluginNode = Y.Node.create('<div class="availability-warning">' +
    767                 M.str.availability.missingplugin + '</div>');
     884                M.util.get_string('missingplugin', 'availability') + '</div>');
    768885    } else {
    769886        // Plugin is known.
     
    809926 */
    810927M.core_availability.Item.prototype.getValue = function() {
    811     value = { 'type' : this.pluginType };
     928    var value = { 'type' : this.pluginType };
    812929    if (this.plugin) {
    813930        this.plugin.fillValue(value, this.pluginNode);
     
    836953    var errorLabel = this.node.one('> .label-warning');
    837954    if (errors.length !== before && !errorLabel.get('firstChild')) {
    838         errorLabel.appendChild(document.createTextNode(M.str.availability.invalid));
     955        errorLabel.appendChild(document.createTextNode(M.util.get_string('invalid', 'availability')));
    839956    } else if (errors.length === before && errorLabel.get('firstChild')) {
    840957        errorLabel.get('firstChild').remove();
     
    852969    var headingParams = { number: number };
    853970    if (this.plugin) {
    854         headingParams.type = M.str['availability_' + this.pluginType].title;
     971        headingParams.type = M.util.get_string('title', 'availability_' + this.pluginType);
    855972    } else {
    856973        headingParams.type = '[' + this.pluginType + ']';
     
    9311048
    9321049    // Set up button text and icon.
    933     var suffix = individual ? '_individual' : '_all';
    934     var setHidden = function() {
    935         icon.set('src', M.util.image_url('i/show', 'core'));
    936         icon.set('alt', M.str.availability['hidden' + suffix]);
    937         this.span.set('title', M.str.availability['hidden' + suffix] + ' \u2022 ' +
    938                 M.str.availability.show_verb);
    939     };
    940     var setShown = function() {
    941         icon.set('src', M.util.image_url('i/hide', 'core'));
    942         icon.set('alt', M.str.availability['shown' + suffix]);
    943         this.span.set('title', M.str.availability['shown' + suffix] + ' \u2022 ' +
    944                 M.str.availability.hide_verb);
    945     };
     1050    var suffix = individual ? '_individual' : '_all',
     1051        setHidden = function() {
     1052            var hiddenStr = M.util.get_string('hidden' + suffix, 'availability');
     1053            icon.set('src', M.util.image_url('i/show', 'core'));
     1054            icon.set('alt', hiddenStr);
     1055            this.span.set('title', hiddenStr + ' \u2022 ' +
     1056                    M.util.get_string('show_verb', 'availability'));
     1057        },
     1058        setShown = function() {
     1059            var shownStr = M.util.get_string('shown' + suffix, 'availability');
     1060            icon.set('src', M.util.image_url('i/hide', 'core'));
     1061            icon.set('alt', shownStr);
     1062            this.span.set('title', shownStr + ' \u2022 ' +
     1063                    M.util.get_string('hide_verb', 'availability'));
     1064        };
    9461065    if(shown) {
    9471066        setShown.call(this);
     
    9881107 */
    9891108M.core_availability.EyeIcon.prototype.isHidden = function() {
    990     var suffix = this.individual ? '_individual' : '_all';
    991     var compare = M.str.availability['hidden' + suffix];
     1109    var suffix = this.individual ? '_individual' : '_all',
     1110        compare = M.util.get_string('hidden' + suffix, 'availability');
    9921111    return this.span.one('img').get('alt') === compare;
    9931112};
     
    10031122M.core_availability.DeleteIcon = function(toDelete) {
    10041123    this.span = Y.Node.create('<a class="availability-delete" href="#" title="' +
    1005             M.str.moodle['delete'] + '" role="button">');
     1124            M.util.get_string('delete', 'moodle') + '" role="button">');
    10061125    var img = Y.Node.create('<img src="' + M.util.image_url('t/delete', 'core') +
    1007             '" alt="' + M.str.moodle['delete'] + '" />');
     1126            '" alt="' + M.util.get_string('delete', 'moodle') + '" />');
    10081127    this.span.appendChild(img);
    10091128    var click = function(e) {
Note: See TracChangeset for help on using the changeset viewer.