api::policy_content_field_options());
$mform->addRule('content_editor', null, 'required', null, 'client');
+ $mform->addElement('selectyesno', 'agreementstyle', get_string('policypriorityagreement', 'tool_policy'));
+
if (!$formdata->id || $formdata->status == policy_version::STATUS_DRAFT) {
// Creating a new version or editing a draft/archived version.
$mform->addElement('hidden', 'minorchange');
/** @var array $policies List of public policies objects with information about the user acceptance. */
protected $policies = null;
+ /** @var array List of policy version ids that were displayed to the user to agree with. */
+ protected $listdocs = null;
+
/** @var array $agreedocs List of policy identifiers which the user has agreed using the form. */
protected $agreedocs = null;
/**
* Prepare the page for rendering.
*
- * @param array $agreedocs Array with the policy identifiers which the user has agreed using the form.
+ * @param array $listdocs List of policy version ids that were displayed to the user to agree with.
+ * @param array $agreedocs List of policy version ids that the user actually agreed with.
* @param int $behalfid The userid to accept the policy versions as (such as child's id).
* @param string $action Form action to identify when user agreeds policies.
*/
- public function __construct($agreedocs = null, $behalfid = 0, $action = null) {
+ public function __construct(array $listdocs, array $agreedocs = [], $behalfid = 0, $action = null) {
global $USER;
$realuser = manager::get_realuser();
+ $this->listdocs = $listdocs;
$this->agreedocs = $agreedocs;
- if (empty($this->agreedocs)) {
- $this->agreedocs = [];
- }
-
$this->action = $action;
-
$this->isexistinguser = isloggedin() && !isguestuser();
+
$behalfid = $behalfid ?: $USER->id;
if ($realuser->id != $behalfid) {
$this->behalfuser = core_user::get_user($behalfid, '*', MUST_EXIST);
// Accept / revoke policies.
$acceptversionids = array();
foreach ($this->policies as $policy) {
- if (in_array($policy->id, $this->agreedocs)) {
- // Save policy version doc to accept it.
- $acceptversionids[] = $policy->id;
- } else {
- // Revoke policy doc.
- api::revoke_acceptance($policy->id, $this->behalfid);
+ if (in_array($policy->id, $this->listdocs)) {
+ if (in_array($policy->id, $this->agreedocs)) {
+ // Save policy version doc to accept it.
+ $acceptversionids[] = $policy->id;
+ } else {
+ // If the policy was displayed but not agreed, revoke the eventually given acceptance.
+ api::revoke_acceptance($policy->id, $this->behalfid);
+ }
}
}
// Accept all policy docs saved in $acceptversionids.
} else {
// New user.
if (!empty($this->action) && confirm_sesskey()) {
- // The form has been sent.
$currentpolicyversionids = [];
+ $presignupcache = \cache::make('core', 'presignup');
+ $acceptances = $presignupcache->get('tool_policy_policyversionidsagreed');
+ if (!$acceptances) {
+ $acceptances = [];
+ }
foreach ($this->policies as $policy) {
$currentpolicyversionids[] = $policy->id;
+ if (in_array($policy->id, $this->listdocs)) {
+ if (in_array($policy->id, $this->agreedocs)) {
+ $acceptances[] = $policy->id;
+ } else {
+ $acceptances = array_values(array_diff($acceptances, [$policy->id]));
+ }
+ }
}
// If the user has accepted all the policies, add it to the session to let continue with the signup process.
- $this->signupuserpolicyagreed = empty(array_diff($currentpolicyversionids, $this->agreedocs));
- \cache::make('core', 'presignup')->set('tool_policy_userpolicyagreed',
- $this->signupuserpolicyagreed);
+ $this->signupuserpolicyagreed = empty(array_diff($currentpolicyversionids, $acceptances));
+ $presignupcache->set('tool_policy_userpolicyagreed', $this->signupuserpolicyagreed);
+ $presignupcache->set('tool_policy_policyversionidsagreed', $acceptances);
} else if (empty($this->policies)) {
// There are no policies to agree to. Update the policyagreed value to avoid show empty consent page.
\cache::make('core', 'presignup')->set('tool_policy_userpolicyagreed', 1);
* @param moodle_url $returnurl URL to return after shown the policy docs.
*/
protected function redirect_to_policies($userid, $returnurl = null) {
+
+ // Make a list of all policies that the user has not accepted yet.
$allpolicies = $this->policies;
+
if ($this->isexistinguser) {
$acceptances = api::get_user_acceptances($userid);
- foreach ($allpolicies as $policy) {
+ foreach ($allpolicies as $ix => $policy) {
if (api::is_user_version_accepted($userid, $policy->id, $acceptances)) {
- // If this version is accepted by the user, remove from the pending policies list.
- unset($allpolicies[array_search($policy, $allpolicies)]);
+ unset($allpolicies[$ix]);
+ }
+ }
+ } else {
+ $presignupcache = \cache::make('core', 'presignup');
+ $acceptances = $presignupcache->get('tool_policy_policyversionidsagreed');
+ if ($acceptances) {
+ foreach ($allpolicies as $ix => $policy) {
+ if (in_array($policy->id, $acceptances)) {
+ unset($allpolicies[$ix]);
+ }
}
}
}
if (!empty($allpolicies)) {
+ // Check if some of the to-be-accepted policies should be agreed on their own page.
+ foreach ($allpolicies as $policy) {
+ if ($policy->agreementstyle == policy_version::AGREEMENTSTYLE_OWNPAGE) {
+ if (empty($returnurl)) {
+ $returnurl = (new moodle_url('/admin/tool/policy/index.php'))->out_as_local_url(false);
+ }
+ $urlparams = ['versionid' => $policy->id, 'returnurl' => $returnurl];
+ redirect(new moodle_url('/admin/tool/policy/view.php', $urlparams));
+ }
+ }
+
$currentpolicyversionids = [];
foreach ($allpolicies as $policy) {
$currentpolicyversionids[] = $policy->id;
];
redirect(new moodle_url('/admin/tool/policy/view.php', $urlparams));
}
+ } else {
+ $this->redirect_to_previous_url();
}
}
}
}
- $data->policies = array_values($this->policies);
+ // Filter out policies already shown on their own page, keep just policies to be shown here on the consent page.
+ $data->policies = array_values(array_filter($this->policies, function ($policy) {
+ return $policy->agreementstyle == policy_version::AGREEMENTSTYLE_CONSENTPAGE;
+ }));
// If viewing docs in behalf of other user, get his/her full name and profile link.
if (!empty($this->behalfuser)) {
* @return stdClass
*/
public function export_for_template(renderer_base $output) {
+ global $USER;
$data = (object) [
'pluginbaseurl' => (new moodle_url('/admin/tool/policy'))->out(false),
$data->editurl = (new moodle_url('/admin/tool/policy/editpolicydoc.php', $paramsurl))->out(false);
}
+ if ($this->policy->agreementstyle == policy_version::AGREEMENTSTYLE_OWNPAGE) {
+ if (!api::is_user_version_accepted($USER->id, $this->policy->id)) {
+ unset($data->returnurl);
+ $data->accepturl = (new moodle_url('/admin/tool/policy/index.php', [
+ 'listdoc[]' => $this->policy->id,
+ 'agreedoc[]' => $this->policy->id,
+ 'submit' => 'accept',
+ 'sesskey' => sesskey(),
+ ]))->out(false);
+ }
+ }
+
$data->policy = clone($this->policy);
return $data;
/** @var int Policy version has been archived. */
const STATUS_ARCHIVED = 2;
+ /** @var int Policy to be accepted together with others on the consent page. */
+ const AGREEMENTSTYLE_CONSENTPAGE = 0;
+
+ /** @var int Policy to be accepted on its own page before reaching the consent page. */
+ const AGREEMENTSTYLE_OWNPAGE = 1;
+
/**
* Return the definition of the properties of this model.
*
'policyid' => [
'type' => PARAM_INT,
],
+ 'agreementstyle' => [
+ 'type' => PARAM_INT,
+ 'choices' => [
+ self::AGREEMENTSTYLE_CONSENTPAGE,
+ self::AGREEMENTSTYLE_OWNPAGE,
+ ],
+ 'default' => self::AGREEMENTSTYLE_CONSENTPAGE,
+ ],
'revision' => [
'type' => PARAM_TEXT,
'default' => '',
<?xml version="1.0" encoding="UTF-8" ?>
-<XMLDB PATH="admin/tool/policy/db" VERSION="20180307" COMMENT="The plugin allows to manage various policy documents that users have to accept to use the site."
+<XMLDB PATH="admin/tool/policy/db" VERSION="20180829" COMMENT="The plugin allows to manage various policy documents that users have to accept to use the site."
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="../../../../lib/xmldb/xmldb.xsd"
>
<FIELD NAME="timecreated" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Timestamp of when the policy version was created."/>
<FIELD NAME="timemodified" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="Timestamp of when the policy version was last modified."/>
<FIELD NAME="policyid" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="false" COMMENT="ID of the policy document we are version of."/>
+ <FIELD NAME="agreementstyle" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="How this agreement should flow: 0 - on the consent page, 1 - on a separate page before reaching the consent page."/>
<FIELD NAME="revision" TYPE="char" LENGTH="1333" NOTNULL="true" SEQUENCE="false" COMMENT="Human readable version of the policy document"/>
<FIELD NAME="summary" TYPE="text" NOTNULL="true" SEQUENCE="false" COMMENT="Policy text summary"/>
<FIELD NAME="summaryformat" TYPE="int" LENGTH="3" NOTNULL="true" SEQUENCE="false" COMMENT="Format of the summary field"/>
--- /dev/null
+<?php
+// This file is part of Moodle - https://moodle.org/
+//
+// Moodle is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// Moodle is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
+
+/**
+ * Plugin upgrade steps are defined here.
+ *
+ * @package tool_policy
+ * @category upgrade
+ * @copyright 2018 David Mudrák <david@moodle.com>
+ * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
+ */
+
+defined('MOODLE_INTERNAL') || die();
+
+/**
+ * Execute the plugin upgrade steps from the given old version.
+ *
+ * @param int $oldversion
+ * @return bool
+ */
+function xmldb_tool_policy_upgrade($oldversion) {
+ global $DB;
+
+ $dbman = $DB->get_manager();
+
+ if ($oldversion < 2018082900) {
+ // Add field agreementstyle to the table tool_policy_versions.
+ $table = new xmldb_table('tool_policy_versions');
+ $field = new xmldb_field('agreementstyle', XMLDB_TYPE_INTEGER, '3', null, XMLDB_NOTNULL, null, '0', 'policyid');
+
+ if (!$dbman->field_exists($table, $field)) {
+ $dbman->add_field($table, $field);
+ }
+
+ upgrade_plugin_savepoint(true, 2018082900, 'tool', 'policy');
+ }
+
+ return true;
+}
+
* Show a user the policy documents to be agreed to.
*
* Script parameters:
- * agreedoc=<array> Policy version id which have been accepted by the user.
+ * listdoc=<array> List of policy version ids that were displayed to the user to accept.
+ * agreedoc=<array> List of policy version ids that were accepted by the user.
* behalfid=<id> The user id to view the policy version as (such as child's id).
*
* @package tool_policy
$submit = optional_param('submit', null, PARAM_NOTAGS);
$cancel = optional_param('cancel', null, PARAM_NOTAGS);
-$agreedocs = optional_param_array('agreedoc', null, PARAM_INT);
+$listdocs = optional_param_array('listdoc', [], PARAM_INT);
+$agreedocs = optional_param_array('agreedoc', [], PARAM_INT);
$behalfid = optional_param('userid', null, PARAM_INT);
$PAGE->set_context(context_system::instance());
$PAGE->set_url('/admin/tool/policy/index.php');
$PAGE->set_popup_notification_allowed(false);
+if (array_diff($agreedocs, $listdocs)) {
+ throw new moodle_exception('invalidaccessparameter');
+}
+
if (isloggedin() && !isguestuser()) {
// Existing user.
$haspermissionagreedocs = api::can_accept_policies($behalfid);
if (!$behalfid && \core\session\manager::is_loggedinas()) {
$behalfid = $USER->id;
}
- $outputpage = new \tool_policy\output\page_agreedocs($agreedocs, $behalfid, $submit);
+ $outputpage = new \tool_policy\output\page_agreedocs($listdocs, $agreedocs, $behalfid, $submit);
}
$output = $PAGE->get_renderer('tool_policy');
$string['policydoctype99'] = 'Other policy';
$string['policydocuments'] = 'Policy documents';
$string['policynamedversion'] = 'Policy {$a->name} (version {$a->revision} - {$a->id})';
+$string['policypriorityagreement'] = 'Show policy before showing other policies';
$string['policyversionacceptedinbehalf'] = 'Consent for this policy has been given on your behalf.';
$string['policyversionacceptedinotherlang'] = 'Consent for this policy version has been given in a different language.';
$string['previousversions'] = '{$a} previous versions';
&& empty($USER->policyagreed)
&& (isguestuser() || !isloggedin())) {
$output = $PAGE->get_renderer('tool_policy');
- $page = new \tool_policy\output\guestconsent();
-
- $message = $output->render($page);
+ try {
+ $page = new \tool_policy\output\guestconsent();
+ $message = $output->render($page);
+ } catch (dml_read_exception $e) {
+ // During upgrades, the new plugin code with new SQL could be in place but the DB not upgraded yet.
+ $message = null;
+ }
}
return $message;
<div class="agreedoc-form m-t-1">
<div class="agreedoc-checkbox">
<label>
+ <input value="{{id}}" name="listdoc[]" type="hidden" >
<input value="{{id}}" name="agreedoc[]" {{#versionagreed}}checked="{{.}}"{{/versionagreed}} type="checkbox">
<strong>{{# str }}iagree, tool_policy, {{{name}}} {{/ str }}</strong>
<i class="icon fa fa-exclamation-circle text-danger fa-fw" title="{{# str }} required {{/ str }}" ></i>
"content": "Policy <em>content</em>"
},
"returnurl": "#",
- "editurl": "#"
+ "editurl": "#",
+ "accepturl": "#"
}
}}
{{#editurl}}
<a role="button" href="{{editurl}}" class="btn">{{#str}} edit {{/str}}</a>
{{/editurl}}
+ {{#accepturl}}
+ <a role="button" href="{{accepturl}}" class="btn btn-primary">{{#str}} iagree, tool_policy, {{{policy.name}}} {{/str}}</a>
+ {{/accepturl}}
<div class="pull-right">
<a href="#top">
* - Type: 0 - site policy, 1 - privacy policy, 2 - third party policy, 99 - other.
* - Summary: Policy summary text.
* - Content: Policy full text.
+ * - Agreement style (agreementstyle): 0 - On the consent page, 1 - On its own page
*
* @param TableNode $data
*/
'type',
'content',
'summary',
+ 'agreementstyle',
];
// Associative array "policy identifier" => id in the database .
And I follow "Policies and agreements"
And "Agreed" "icon" should exist in the "This site policy" "table_row"
And I log out
+
+ Scenario: Accepting policies on sign up, multiple policies with different style of giving ageement.
+ Given the following config values are set as admin:
+ | registerauth | email |
+ | passwordpolicy | 0 |
+ | sitepolicyhandler | tool_policy |
+ And the following policies exist:
+ | name | summary | content | agreementstyle |
+ | Privacy policy | We scan your thoughts | Here goes content. | 0 |
+ | Digital maturity declaration | You declare be old enough | Here goes content. | 1 |
+ | Cookies policy | We eat cookies, srsly | Here goes content. | 0 |
+ | Terms of Service | We teach, you learn | Here goes content. | 1 |
+ And I am on site homepage
+ And I follow "Log in"
+ When I press "Create new account"
+ # The first policy with the agreement style "on its own page" must be accepted first.
+ Then I should see "Digital maturity declaration" in the "region-main" "region"
+ And I should see "You declare be old enough"
+ And I should see "Here goes content."
+ And I press "I agree to the Digital maturity declaration"
+ # The second policy with the agreement style "on its own page" must be accepted now.
+ And I should see "Terms of Service" in the "region-main" "region"
+ And I should see "We teach, you learn"
+ And I should see "Here goes content."
+ And I press "I agree to the Terms of Service"
+ # Only now we see the remaining consent page policies.
+ And I should see "Policy 1 out of 2"
+ And I should see "Privacy policy" in the "region-main" "region"
+ And I should see "We scan your thoughts"
+ And I should see "Here goes content."
+ And I press "Next"
+ And I should see "Policy 2 out of 2"
+ And I should see "Cookies policy" in the "region-main" "region"
+ And I should see "We eat cookies, srsly"
+ And I should see "Here goes content."
+ And I press "Next"
+ And I should see "Please agree to the following policies"
+ And I should see "Privacy policy"
+ And I should see "Cookies policy"
+ And I should not see "Digital maturity declaration" in the "region-main" "region"
+ And I should not see "Terms of Service" in the "region-main" "region"
+ And I should not see "Here goes content."
+ And I set the field "I agree to the Privacy policy" to "1"
+ And I set the field "I agree to the Cookies policy" to "1"
+ And I press "Next"
+ And I should see "New account"
+ And I set the following fields to these values:
+ | Username | user1 |
+ | Password | user1 |
+ | Email address | user1@address.invalid |
+ | Email (again) | user1@address.invalid |
+ | First name | User1 |
+ | Surname | L1 |
+ And I press "Create my new account"
+ And I should see "Confirm your account"
+ And I should see "An email should have been sent to your address at user1@address.invalid"
+ And I confirm email for "user1"
+ And I should see "Thanks, User1 L1"
+ And I should see "Your registration has been confirmed"
+ And I open my profile in edit mode
+ And the field "First name" matches value "User1"
+ And I log out
+ # Confirm that user can login and browse the site.
+ And I log in as "user1"
+ And I follow "Profile" in the user menu
+ # User can see his own agreements in the profile.
+ And I follow "Policies and agreements"
+ And "Agreed" "icon" should exist in the "Privacy policy" "table_row"
+ And "Agreed" "icon" should exist in the "Cookies policy" "table_row"
+ And "Agreed" "icon" should exist in the "Terms of Service" "table_row"
+ And "Agreed" "icon" should exist in the "Digital maturity declaration" "table_row"
+ And I log out
+
+ Scenario: Accepting policies on login, multiple policies with different style of giving ageement.
+ Given the following config values are set as admin:
+ | sitepolicyhandler | tool_policy |
+ And the following policies exist:
+ | name | summary | content | agreementstyle |
+ | Digital maturity declaration | You declare be old enough | Here goes content. | 1 |
+ | Privacy policy | We scan your thoughts | Here goes content. | 0 |
+ | Terms of Service | We teach, you learn | Here goes content. | 1 |
+ | Cookies policy | We eat cookies, srsly | Here goes content. | 0 |
+ And the following "users" exist:
+ | username | firstname | lastname | email |
+ | user1 | User | One | user1@example.com |
+ And I log in as "user1"
+ # The first policy with the agreement style "on its own page" must be accepted first.
+ Then I should see "Digital maturity declaration" in the "region-main" "region"
+ And I should see "You declare be old enough"
+ And I should see "Here goes content."
+ And I press "I agree to the Digital maturity declaration"
+ # The second policy with the agreement style "on its own page" must be accepted now.
+ And I should see "Terms of Service" in the "region-main" "region"
+ And I should see "We teach, you learn"
+ And I should see "Here goes content."
+ # If the user logs out now, only the first policy is accepted and we return to the same page.
+ And I log out
+ And I log in as "user1"
+ And I should see "Terms of Service" in the "region-main" "region"
+ And I should see "We teach, you learn"
+ And I should see "Here goes content."
+ And I press "I agree to the Terms of Service"
+ # Only now we see the remaining consent page policies.
+ And I should see "Policy 1 out of 2"
+ And I should see "Privacy policy" in the "region-main" "region"
+ And I should see "We scan your thoughts"
+ And I should see "Here goes content."
+ And I press "Next"
+ And I should see "Policy 2 out of 2"
+ And I should see "Cookies policy" in the "region-main" "region"
+ And I should see "We eat cookies, srsly"
+ And I should see "Here goes content."
+ And I press "Next"
+ And I should see "Please agree to the following policies"
+ And I should see "Privacy policy"
+ And I should see "Cookies policy"
+ And I should not see "Digital maturity declaration" in the "region-main" "region"
+ And I should not see "Terms of Service" in the "region-main" "region"
+ And I should not see "Here goes content."
+ And I set the field "I agree to the Privacy policy" to "1"
+ And I set the field "I agree to the Cookies policy" to "1"
+ And I press "Next"
+ And I follow "Profile" in the user menu
+ # User can see his own agreements in the profile.
+ And I follow "Policies and agreements"
+ And "Agreed" "icon" should exist in the "Privacy policy" "table_row"
+ And "Agreed" "icon" should exist in the "Cookies policy" "table_row"
+ And "Agreed" "icon" should exist in the "Terms of Service" "table_row"
+ And "Agreed" "icon" should exist in the "Digital maturity declaration" "table_row"
+ And I log out
+
+ Scenario: Accepting policies on login, all and loggedin policies to be accepted on their own page.
+ Given the following config values are set as admin:
+ | sitepolicyhandler | tool_policy |
+ And the following policies exist:
+ | name | summary | content | agreementstyle | audience |
+ | Privacy policy | We scan your thoughts | Here goes content. | 1 | all |
+ | Digital maturity declaration | You declare be old enough | Here goes content. | 1 | loggedin |
+ | Cookies policy | We eat cookies, srsly | Here goes content. | 1 | guest |
+ | Terms of Service | We teach, you learn | Here goes content. | 1 | all |
+ And the following "users" exist:
+ | username | firstname | lastname | email |
+ | user1 | User | One | user1@example.com |
+ And I log in as "user1"
+ # All the policies to be displayed one by one with a button to accept each of them prior seeing the next.
+ Then I should see "Privacy policy" in the "region-main" "region"
+ And I should see "We scan your thoughts"
+ And I should see "Here goes content."
+ And I press "I agree to the Privacy policy"
+ And I should see "Digital maturity declaration" in the "region-main" "region"
+ And I should see "You declare be old enough"
+ And I should see "Here goes content."
+ And I press "I agree to the Digital maturity declaration"
+ And I should see "Terms of Service" in the "region-main" "region"
+ And I should see "We teach, you learn"
+ And I should see "Here goes content."
+ And I press "I agree to the Terms of Service"
+ And I follow "Profile" in the user menu
+ And I follow "Policies and agreements"
+ And "Agreed" "icon" should exist in the "Privacy policy" "table_row"
+ And "Agreed" "icon" should exist in the "Terms of Service" "table_row"
+ And "Agreed" "icon" should exist in the "Digital maturity declaration" "table_row"
+ And "Cookies policy" "table_row" should not exist
+ And I log out
+
+ Scenario: Accepting policies on sign up, policies to be accepted on their own page.
+ Given the following config values are set as admin:
+ | registerauth | email |
+ | passwordpolicy | 0 |
+ | sitepolicyhandler | tool_policy |
+ And the following policies exist:
+ | name | summary | content | agreementstyle | audience |
+ | Privacy policy | We scan your thoughts | Here goes content. | 1 | guest |
+ | Digital maturity declaration | You declare be old enough | Here goes content. | 1 | all |
+ | Cookies policy | We eat cookies, srsly | Here goes content. | 1 | loggedin |
+ | Terms of Service | We teach, you learn | Here goes content. | 1 | guest |
+ And I am on site homepage
+ And I follow "Log in"
+ When I press "Create new account"
+ # All the policies to be displayed one by one with a button to accept each of them prior seeing the next.
+ Then I should see "Digital maturity declaration" in the "region-main" "region"
+ And I should see "You declare be old enough"
+ And I should see "Here goes content."
+ And I press "I agree to the Digital maturity declaration"
+ And I should see "Cookies policy" in the "region-main" "region"
+ And I should see "We eat cookies, srsly"
+ And I press "I agree to the Cookies policy"
+ And I should see "New account"
+ And I set the following fields to these values:
+ | Username | user1 |
+ | Password | user1 |
+ | Email address | user1@address.invalid |
+ | Email (again) | user1@address.invalid |
+ | First name | User1 |
+ | Surname | L1 |
+ And I press "Create my new account"
+ And I should see "Confirm your account"
+ And I should see "An email should have been sent to your address at user1@address.invalid"
+ And I confirm email for "user1"
+ And I should see "Thanks, User1 L1"
+ And I should see "Your registration has been confirmed"
+ And I open my profile in edit mode
+ And the field "First name" matches value "User1"
+ And I log out
+ # Confirm that user can login and browse the site.
+ And I log in as "user1"
+ And I follow "Profile" in the user menu
+ # User can see his own agreements in the profile.
+ And I follow "Policies and agreements"
+ And "Agreed" "icon" should exist in the "Digital maturity declaration" "table_row"
+ And "Agreed" "icon" should exist in the "Cookies policy" "table_row"
+ And "Privacy policy" "table_row" should not exist
+ And "Terms of Service" "table_row" should not exist
+ And I log out
defined('MOODLE_INTERNAL') || die();
-$plugin->version = 2018051400; // The current plugin version (Date: YYYYMMDDXX).
+$plugin->version = 2018082900; // The current plugin version (Date: YYYYMMDDXX).
$plugin->requires = 2018050800; // Requires this Moodle version.
$plugin->component = 'tool_policy'; // Full name of the plugin (used for diagnostics).
text-align: center;
}
-
-.initialbarlabel {
- display: inline-block;
- width: 6em;
- float: left;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-
-
/* Moodle Dialogue Settings (moodle-core-dialogue) */
.moodle-dialogue-base .moodle-dialogue-lightbox {
background-color: $gray;
white-space: nowrap;
text-align: center; }
-.initialbarlabel {
- display: inline-block;
- width: 6em;
- float: left;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap; }
-
/* Moodle Dialogue Settings (moodle-core-dialogue) */
.moodle-dialogue-base .moodle-dialogue-lightbox {
background-color: #495057; }
]
}
}}
-<div class="initialbar {{class}} d-flex">
- <span class="initialbarlabel">{{title}}</span>
- <ul class="pagination pagination-sm">
- {{#current}}
- <li class="initialbarall page-item">
- <a class="page-link" href="{{url}}">{{all}}</a>
- </li>
- {{/current}}
- {{^current}}
- <li class="initialbarall page-item active">
- <a class="page-link">{{all}}</a>
- </li>
- {{/current}}
- </ul>
- <div class="initialbargroups d-flex">
+<div class="initialbar {{class}} d-flex flex-wrap justify-content-center justify-content-md-start">
+ <span class="initialbarlabel mr-2">{{title}}</span>
+
+ <div class="initialbargroups d-flex flex-wrap justify-content-center justify-content-md-start">
+ <ul class="pagination pagination-sm">
+ {{#current}}
+ <li class="initialbarall page-item">
+ <a class="page-link" href="{{url}}">{{all}}</a>
+ </li>
+ {{/current}}
+ {{^current}}
+ <li class="initialbarall page-item active">
+ <a class="page-link">{{all}}</a>
+ </li>
+ {{/current}}
+ </ul>
{{#group}}
<ul class="pagination pagination-sm">
-
{{#letter}}
{{#selected}}
<li class="page-item active {{name}}"><span class="page-link">{{name}}</span></li>