Merge branch 'MDL-69089-39' of git://github.com/aanabit/moodle into MOODLE_39_STABLE
authorAndrew Nicols <andrew@nicols.co.uk>
Wed, 19 Aug 2020 00:20:00 +0000 (08:20 +0800)
committerAndrew Nicols <andrew@nicols.co.uk>
Wed, 19 Aug 2020 00:20:00 +0000 (08:20 +0800)
12 files changed:
.travis.yml
admin/tool/mobile/classes/output/subscription.php
admin/tool/mobile/lang/en/tool_mobile.php
admin/tool/mobile/settings.php
auth/db/auth.php
auth/db/lang/en/auth_db.php
calendar/classes/external/week_day_exporter.php
calendar/templates/month_detailed.mustache
calendar/templates/month_mini.mustache
lang/en/calendar.php
mod/workshop/form/rubric/styles.css
question/type/ddimageortext/styles.css

index 67d70d5..40161c2 100644 (file)
@@ -174,7 +174,9 @@ before_script:
         # Enable test external resources
         sed -i \
           -e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTP_URL', 'http://127.0.0.1:8080');" \
+          -e "/require_once/i \\define('TEST_EXTERNAL_FILES_HTTPS_URL', 'http://127.0.0.1:8080');" \
           config.php ;
+
         # Redis cache store tests
         sed -i \
           -e "/require_once/i \\define('TEST_CACHESTORE_REDIS_TESTSERVERS', '127.0.0.1');" \
@@ -254,8 +256,6 @@ script:
       if [ "$TASK" = 'PHPUNIT' ];
       then
         vendor/bin/phpunit --fail-on-risky --disallow-test-output --verbose;
-        EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
-        echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
       fi
 
     - >
@@ -292,3 +292,11 @@ script:
           exit 1 ;
         fi
       fi
+
+after_script:
+    - >
+      if [ "$TASK" = 'PHPUNIT' ];
+      then
+        EXTTESTS_HITS=$(docker logs exttests 2>&1 | grep -Fv -e 'AH00558' -e '[pid 1]' | wc -l)
+        echo -e "\nTest local resources number of hits: ${EXTTESTS_HITS}.\n"
+      fi
index d8deaca..572a91a 100644 (file)
@@ -184,6 +184,13 @@ class subscription implements \renderable, \templatable {
                                     'type' => 'danger', 'message' => get_string('subscriptionfeaturenotapplied', 'tool_mobile')];
                             }
                             break;
+                        // Check QR automatic login.
+                        case 'qrautomaticlogin':
+                            if ($ms->qrcodetype == \tool_mobile\api::QR_CODE_LOGIN) {
+                                $feature['message'] = [
+                                    'type' => 'danger', 'message' => get_string('subscriptionfeaturenotapplied', 'tool_mobile')];
+                            }
+                            break;
                     }
                 }
             }
index bc7fc89..952e99b 100644 (file)
@@ -114,7 +114,7 @@ $string['qrcodeformobileapploginabout'] = 'Scan the QR code with your mobile app
 $string['qrcodeformobileappurlabout'] = 'Scan the QR code with your mobile app to fill in the site URL in your app.';
 $string['qrsiteadminsnotallowed'] = 'For security reasons login via QR code is not allowed for site administrators or if you are logged in as another user.';
 $string['qrcodetype'] = 'QR code access';
-$string['qrcodetype_desc'] = 'A QR code can be provided for mobile app users to scan and either have the site URL filled in or be automatically logged in without having to enter their credentials.';
+$string['qrcodetype_desc'] = 'A QR code can be provided for mobile app users to scan. This can be used to fill in the site URL, or where the site is secured using HTTPS, to automatically log the user in without having to enter their username and password.';
 $string['qrcodetypeurl'] = 'QR code with site URL';
 $string['qrcodetypelogin'] = 'QR code with automatic login';
 $string['readingthisemailgettheapp'] = 'Reading this in an email? <a href="{$a}">Download the mobile app and receive notifications on your mobile device</a>.';
index c2cee8c..19a8798 100644 (file)
@@ -94,11 +94,17 @@ if ($hassiteconfig) {
     $options = [
         tool_mobile\api::QR_CODE_DISABLED => new lang_string('qrcodedisabled', 'tool_mobile'),
         tool_mobile\api::QR_CODE_URL => new lang_string('qrcodetypeurl', 'tool_mobile'),
-        tool_mobile\api::QR_CODE_LOGIN => new lang_string('qrcodetypelogin', 'tool_mobile'),
     ];
+    $qrcodetypedefault = tool_mobile\api::QR_CODE_URL;
+
+    if (is_https()) {   // Allow QR login for https sites.
+        $options[tool_mobile\api::QR_CODE_LOGIN] = new lang_string('qrcodetypelogin', 'tool_mobile');
+        $qrcodetypedefault = tool_mobile\api::QR_CODE_LOGIN;
+    }
+
     $temp->add(new admin_setting_configselect('tool_mobile/qrcodetype',
                 new lang_string('qrcodetype', 'tool_mobile'),
-                new lang_string('qrcodetype_desc', 'tool_mobile'), tool_mobile\api::QR_CODE_LOGIN, $options));
+                new lang_string('qrcodetype_desc', 'tool_mobile'), $qrcodetypedefault, $options));
 
     $temp->add(new admin_setting_configtext('tool_mobile/forcedurlscheme',
                 new lang_string('forcedurlscheme_key', 'tool_mobile'),
index 5c2fe8c..13da0f4 100644 (file)
@@ -603,9 +603,12 @@ class auth_plugin_db extends auth_plugin_base {
             }
         }
         if (!empty($update)) {
-            $authdb->Execute("UPDATE {$this->config->table}
-                                 SET ".implode(',', $update)."
-                               WHERE {$this->config->fielduser}='".$this->ext_addslashes($extusername)."'");
+            $sql = "UPDATE {$this->config->table}
+                       SET ".implode(',', $update)."
+                     WHERE {$this->config->fielduser} = ?";
+            if (!$authdb->Execute($sql, array($this->ext_addslashes($extusername)))) {
+                print_error('auth_dbupdateerror', 'auth_db');
+            }
         }
         $authdb->Close();
         return true;
index d3f8a83..75c5c26 100644 (file)
@@ -74,5 +74,6 @@ $string['auth_dbcannotconnect'] = 'Cannot connect to external database.';
 $string['auth_dbcannotreadtable'] = 'Cannot read external table.';
 $string['auth_dbtableempty'] = 'External table is empty.';
 $string['auth_dbcolumnlist'] = 'External table contains the following columns:<br />{$a}';
+$string['auth_dbupdateerror'] = 'Error updating external database.';
 $string['pluginname'] = 'External database';
 $string['privacy:metadata'] = 'The External database authentication plugin does not store any personal data.';
index 98ad278..80ddbf0 100644 (file)
@@ -86,6 +86,9 @@ class week_day_exporter extends day_exporter {
                 'type' => PARAM_RAW,
                 'default' => '',
             ],
+            'daytitle' => [
+                'type' => PARAM_RAW,
+            ]
         ]);
 
         return $return;
@@ -104,6 +107,8 @@ class week_day_exporter extends day_exporter {
             $return['popovertitle'] = $popovertitle;
         }
 
+        $return['daytitle'] = $this->get_day_title();
+
         return $return;
     }
 
@@ -141,4 +146,24 @@ class week_day_exporter extends day_exporter {
 
         return $title;
     }
+
+    /**
+     * Get the title for this day.
+     *
+     * @return string
+     */
+    protected function get_day_title(): string {
+        $userdate = userdate($this->data[0], get_string('strftimedayshort'));
+
+        $numevents = count($this->related['events']);
+        if ($numevents == 1) {
+            $title = get_string('dayeventsone', 'calendar', $userdate);
+        } else if ($numevents) {
+            $title = get_string('dayeventsmany', 'calendar', ['num' => $numevents, 'day' => $userdate]);
+        } else {
+            $title = get_string('dayeventsnone', 'calendar', $userdate);
+        }
+
+        return $title;
+    }
 }
index a88f65e..ba01dfe 100644 (file)
@@ -46,8 +46,9 @@
         <thead>
             <tr>
                 {{# daynames }}
-                <th class="header text-xs-center" aria-label="{{fullname}}">
-                    {{shortname}}
+                <th class="header text-xs-center">
+                    <span class="sr-only">{{fullname}}</span>
+                    <span aria-hidden="true">{{shortname}}</span>
                 </th>
                 {{/ daynames }}
             </tr>
@@ -71,6 +72,7 @@
                         data-region="day"
                         data-new-event-timestamp="{{neweventtimestamp}}">
                         <div class="d-none d-md-block hidden-phone text-xs-center">
+                            <span class="sr-only">{{daytitle}}</span>
                             {{#hasevents}}
                                 <a data-action="view-day-link" href="#" class="aalink day" aria-label="{{viewdaylinktitle}}"
                                     data-year="{{date.year}}" data-month="{{date.mon}}" data-day="{{mday}}"
@@ -78,7 +80,7 @@
                                     data-timestamp="{{timestamp}}">{{mday}}</a>
                             {{/hasevents}}
                             {{^hasevents}}
-                                {{mday}}
+                                <span aria-hidden="true">{{mday}}</span>
                             {{/hasevents}}
                             {{#hasevents}}
                                 <div data-region="day-content">
                             {{/hasevents}}
                         </div>
                         <div class="d-md-none hidden-desktop hidden-tablet">
+                            <span class="sr-only">{{daytitle}}</span>
                             {{#hasevents}}
                                 <a data-action="view-day-link" href="#" class="day aalink" aria-label="{{viewdaylinktitle}}"
                                     data-year="{{date.year}}" data-month="{{date.mon}}" data-day="{{mday}}"
                                     data-timestamp="{{timestamp}}">{{mday}}</a>
                             {{/hasevents}}
                             {{^hasevents}}
-                                    {{mday}}
+                                <span aria-hidden="true">{{mday}}</span>
                             {{/hasevents}}
                         </div>
                     </td>
index ff10a74..4ff2656 100644 (file)
@@ -78,8 +78,9 @@
         <thead>
           <tr>
                 {{# daynames }}
-                <th class="header text-xs-center" scope="col" aria-label="{{fullname}}">
-                    {{shortname}}
+                <th class="header text-xs-center">
+                    <span class="sr-only">{{fullname}}</span>
+                    <span aria-hidden="true">{{shortname}}</span>
                 </th>
                 {{/ daynames }}
             </tr>
                         This is the timestamp for this month.
                         }} data-day-timestamp="{{timestamp}}"{{!
                     }}>{{!
-                        }}{{#popovertitle}}
+                        }}<span class="sr-only">{{daytitle}}</span>
+                        {{#popovertitle}}
                             {{< core_calendar/minicalendar_day_link }}
                                 {{$day}}{{mday}}{{/day}}
                                 {{$url}}{{viewdaylink}}{{/url}}
                             {{/ core_calendar/minicalendar_day_link }}
                         {{/popovertitle}}{{!
                         }}{{^popovertitle}}
-                            {{mday}}
+                            <span aria-hidden="true">{{mday}}</span>
                         {{/popovertitle}}{{!
                     }}</td>
                 {{/days}}
index 6f1c4f9..e10e573 100644 (file)
@@ -52,6 +52,9 @@ $string['courses'] = 'Courses';
 $string['customexport'] = 'Custom range ({$a->timestart} - {$a->timeend})';
 $string['daily'] = 'Daily';
 $string['day'] = 'Day';
+$string['dayeventsmany'] = '{$a->num} events, {$a->day}';
+$string['dayeventsnone'] = 'No events, {$a}';
+$string['dayeventsone'] = '1 event, {$a}';
 $string['daynext'] = 'Next day';
 $string['dayprev'] = 'Previous day';
 $string['dayviewfor'] = 'Day view for:';
index b8ff382..3413fbc 100644 (file)
     display: none;
 }
 
-.path-mod-workshop #id_rubric-grid-wrapper .rubric-grid {
+.path-mod-workshop .mform.frozen #id_rubric-grid-wrapper,
+.path-mod-workshop #id_rubric-grid-wrapper {
     margin-left: auto;
     margin-right: auto;
+    width: 100%;
+}
+
+.path-mod-workshop .mform.frozen #id_rubric-grid-wrapper .checkbox,
+.path-mod-workshop .assessmentform.rubric.grid #id_rubric-grid-wrapper .checkbox {
+    max-width: 100%;
+    flex: 0 0 100%;
+    text-align: left;
 }
 
 .path-mod-workshop .mform.frozen #id_rubric-grid-wrapper .fitem .felement,
index 3b93673..b0df2fd 100644 (file)
@@ -26,6 +26,7 @@ form.mform fieldset#id_previewareaheader div.ddarea {
 .que.ddimageortext div.droparea .dropzones {
     position: absolute;
     top: 0;
+    /*rtl:ignore*/
     left: 0;
 }