Merge branch 'MDL-62309-master-optionalpolicies' of git://github.com/mudrd8mz/moodle
@ -39,6 +39,10 @@ $context = context_system::instance();
|
||||
$PAGE->set_context($context);
|
||||
$PAGE->set_url(new moodle_url('/admin/tool/policy/accept.php'));
|
||||
|
||||
if (!in_array($action, ['accept', 'decline', 'revoke'])) {
|
||||
throw new moodle_exception('invalidaccessparameter');
|
||||
}
|
||||
|
||||
if ($returnurl) {
|
||||
$returnurl = new moodle_url($returnurl);
|
||||
} else if (count($userids) == 1) {
|
||||
@ -59,14 +63,8 @@ if ($form->is_cancelled()) {
|
||||
redirect($returnurl);
|
||||
}
|
||||
|
||||
if ($action == 'revoke') {
|
||||
$title = get_string('revokedetails', 'tool_policy');
|
||||
} else {
|
||||
$title = get_string('consentdetails', 'tool_policy');
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('tool_policy');
|
||||
echo $output->header();
|
||||
echo $output->heading($title);
|
||||
echo $output->heading(get_string('statusformtitle'.$action, 'tool_policy'));
|
||||
$form->display();
|
||||
echo $output->footer();
|
||||
|
@ -1 +1 @@
|
||||
define(["jquery","core/str","core/modal_factory","core/modal_events","core/notification","core/fragment","core/ajax","core/yui"],function(a,b,c,d,e,f,g,h){"use strict";var i=function(a){this.contextid=a,this.init()};return i.prototype.modal=null,i.prototype.contextid=-1,i.prototype.stringKeys=[{key:"consentdetails",component:"tool_policy"},{key:"iagreetothepolicy",component:"tool_policy"},{key:"selectusersforconsent",component:"tool_policy"},{key:"ok"},{key:"revokedetails",component:"tool_policy"},{key:"irevokethepolicy",component:"tool_policy"}],i.prototype.currentTrigger=null,i.prototype.triggers={SINGLE:"a[data-action=acceptmodal]",BULK:"input[data-action=acceptmodal]"},i.prototype.init=function(){a(this.triggers.SINGLE).on("click",function(b){b.preventDefault(),this.currentTrigger=a(b.currentTarget);var c=a(b.currentTarget).attr("href"),d=c.slice(c.indexOf("?")+1);this.showFormModal(d)}.bind(this)),a(this.triggers.BULK).on("click",function(c){c.preventDefault(),this.currentTrigger=a(c.currentTarget);var d=a(c.currentTarget).closest("form");if(d.find('input[type=checkbox][name="userids[]"]:checked').length){var f=d.serialize();this.showFormModal(f)}else b.get_strings(this.stringKeys).done(function(a){e.alert("",a[2],a[3])})}.bind(this))},i.prototype.showFormModal=function(a){for(var d,f=a.split("&"),g=0;g<f.length;g++){var h=f[g].split("=");"action"==h[0]&&(d=h[1])}b.get_strings(this.stringKeys).done(function(b){var e,f;"revoke"==d?(e=b[4],f=b[5]):(e=b[0],f=b[1]),c.create({type:c.types.SAVE_CANCEL,title:e,body:""}).done(function(b){this.modal=b,this.setupFormModal(a,f)}.bind(this))}.bind(this)).fail(e.exception)},i.prototype.setupFormModal=function(a,b){var c=this.modal;c.setLarge(),c.setSaveButtonText(b),c.getRoot().on(d.hidden,this.destroy.bind(this)),c.setBody(this.getBody(a)),c.getRoot().on(d.save,this.submitForm.bind(this)),c.getRoot().on("submit","form",this.submitFormAjax.bind(this)),c.show()},i.prototype.getBody=function(a){"undefined"==typeof a&&(a={});var b={jsonformdata:JSON.stringify(a)};return f.loadFragment("tool_policy","accept_on_behalf",this.contextid,b)},i.prototype.submitFormAjax=function(a){a.preventDefault();var b=this.modal.getRoot().find("form").serialize(),c=g.call([{methodname:"tool_policy_submit_accept_on_behalf",args:{jsonformdata:JSON.stringify(b)}}]);c[0].done(function(a){a.validationerrors?this.modal.setBody(this.getBody(b)):this.close()}.bind(this)).fail(e.exception)},i.prototype.submitForm=function(a){a.preventDefault(),this.modal.getRoot().find("form").submit()},i.prototype.close=function(){this.destroy(),document.location.reload()},i.prototype.destroy=function(){h.use("moodle-core-formchangechecker",function(){M.core_formchangechecker.reset_form_dirty_state()}),this.modal.destroy(),this.currentTrigger.focus()},{getInstance:function(a){return new i(a)}}});
|
||||
define(["jquery","core/str","core/modal_factory","core/modal_events","core/notification","core/fragment","core/ajax","core/yui"],function(a,b,c,d,e,f,g,h){"use strict";var i=function(a){this.contextid=a,this.init()};return i.prototype.modal=null,i.prototype.contextid=-1,i.prototype.currentTrigger=null,i.prototype.triggers={SINGLE:"a[data-action=acceptmodal]",BULK:"input[data-action=acceptmodal]"},i.prototype.init=function(){a(this.triggers.SINGLE).on("click",function(b){b.preventDefault(),this.currentTrigger=a(b.currentTarget);var c=a(b.currentTarget).attr("href"),d=c.slice(c.indexOf("?")+1);this.showFormModal(d)}.bind(this)),a(this.triggers.BULK).on("click",function(c){c.preventDefault(),this.currentTrigger=a(c.currentTarget);var d=a(c.currentTarget).closest("form");if(d.find('input[type=checkbox][name="userids[]"]:checked').length){var f=d.serialize();this.showFormModal(f)}else b.get_strings([{key:"notice"},{key:"selectusersforconsent",component:"tool_policy"},{key:"ok"}]).then(function(a){e.alert(a[0],a[1],a[2])}).fail(e.exception)}.bind(this))},i.prototype.showFormModal=function(a){for(var d,f=a.split("&"),g=0;g<f.length;g++){var h=f[g].split("=");"action"==h[0]&&(d=h[1])}b.get_strings([{key:"statusformtitleaccept",component:"tool_policy"},{key:"iagreetothepolicy",component:"tool_policy"},{key:"statusformtitlerevoke",component:"tool_policy"},{key:"irevokethepolicy",component:"tool_policy"},{key:"statusformtitledecline",component:"tool_policy"},{key:"declinethepolicy",component:"tool_policy"}]).then(function(b){var e,f;return"accept"==d?(e=b[0],f=b[1]):"revoke"==d?(e=b[2],f=b[3]):"decline"==d&&(e=b[4],f=b[5]),c.create({type:c.types.SAVE_CANCEL,title:e,body:""}).done(function(b){this.modal=b,this.setupFormModal(a,f)}.bind(this))}.bind(this))["catch"](e.exception)},i.prototype.setupFormModal=function(a,b){var c=this.modal;c.setLarge(),c.setSaveButtonText(b),c.getRoot().on(d.hidden,this.destroy.bind(this)),c.setBody(this.getBody(a)),c.getRoot().on(d.save,this.submitForm.bind(this)),c.getRoot().on("submit","form",this.submitFormAjax.bind(this)),c.show()},i.prototype.getBody=function(a){"undefined"==typeof a&&(a={});var b={jsonformdata:JSON.stringify(a)};return f.loadFragment("tool_policy","accept_on_behalf",this.contextid,b)},i.prototype.submitFormAjax=function(a){a.preventDefault();var b=this.modal.getRoot().find("form").serialize(),c=g.call([{methodname:"tool_policy_submit_accept_on_behalf",args:{jsonformdata:JSON.stringify(b)}}]);c[0].done(function(a){a.validationerrors?this.modal.setBody(this.getBody(b)):this.close()}.bind(this)).fail(e.exception)},i.prototype.submitForm=function(a){a.preventDefault(),this.modal.getRoot().find("form").submit()},i.prototype.close=function(){this.destroy(),document.location.reload()},i.prototype.destroy=function(){h.use("moodle-core-formchangechecker",function(){M.core_formchangechecker.reset_form_dirty_state()}),this.modal.destroy(),this.currentTrigger.focus()},{getInstance:function(a){return new i(a)}}});
|
@ -52,36 +52,6 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/n
|
||||
*/
|
||||
AcceptOnBehalf.prototype.contextid = -1;
|
||||
|
||||
/**
|
||||
* @var {Array} strings
|
||||
* @private
|
||||
*/
|
||||
AcceptOnBehalf.prototype.stringKeys = [
|
||||
{
|
||||
key: 'consentdetails',
|
||||
component: 'tool_policy'
|
||||
},
|
||||
{
|
||||
key: 'iagreetothepolicy',
|
||||
component: 'tool_policy'
|
||||
},
|
||||
{
|
||||
key: 'selectusersforconsent',
|
||||
component: 'tool_policy'
|
||||
},
|
||||
{
|
||||
key: 'ok'
|
||||
},
|
||||
{
|
||||
key: 'revokedetails',
|
||||
component: 'tool_policy'
|
||||
},
|
||||
{
|
||||
key: 'irevokethepolicy',
|
||||
component: 'tool_policy'
|
||||
}
|
||||
];
|
||||
|
||||
/**
|
||||
* @var {object} currentTrigger The triggered HTML jQuery object
|
||||
* @private
|
||||
@ -121,9 +91,14 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/n
|
||||
var formData = form.serialize();
|
||||
this.showFormModal(formData);
|
||||
} else {
|
||||
Str.get_strings(this.stringKeys).done(function(strings) {
|
||||
Notification.alert('', strings[2], strings[3]);
|
||||
});
|
||||
Str.get_strings([
|
||||
{key: 'notice'},
|
||||
{key: 'selectusersforconsent', component: 'tool_policy'},
|
||||
{key: 'ok'}
|
||||
]).then(function(strings) {
|
||||
Notification.alert(strings[0], strings[1], strings[2]);
|
||||
return;
|
||||
}).fail(Notification.exception);
|
||||
}
|
||||
}.bind(this));
|
||||
};
|
||||
@ -143,18 +118,28 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/n
|
||||
}
|
||||
}
|
||||
// Fetch the title string.
|
||||
Str.get_strings(this.stringKeys).done(function(strings) {
|
||||
Str.get_strings([
|
||||
{key: 'statusformtitleaccept', component: 'tool_policy'},
|
||||
{key: 'iagreetothepolicy', component: 'tool_policy'},
|
||||
{key: 'statusformtitlerevoke', component: 'tool_policy'},
|
||||
{key: 'irevokethepolicy', component: 'tool_policy'},
|
||||
{key: 'statusformtitledecline', component: 'tool_policy'},
|
||||
{key: 'declinethepolicy', component: 'tool_policy'}
|
||||
]).then(function(strings) {
|
||||
var title;
|
||||
var saveText;
|
||||
if (action == 'revoke') {
|
||||
title = strings[4];
|
||||
saveText = strings[5];
|
||||
} else {
|
||||
if (action == 'accept') {
|
||||
title = strings[0];
|
||||
saveText = strings[1];
|
||||
} else if (action == 'revoke') {
|
||||
title = strings[2];
|
||||
saveText = strings[3];
|
||||
} else if (action == 'decline') {
|
||||
title = strings[4];
|
||||
saveText = strings[5];
|
||||
}
|
||||
// Create the modal.
|
||||
ModalFactory.create({
|
||||
return ModalFactory.create({
|
||||
type: ModalFactory.types.SAVE_CANCEL,
|
||||
title: title,
|
||||
body: ''
|
||||
@ -163,7 +148,7 @@ define(['jquery', 'core/str', 'core/modal_factory', 'core/modal_events', 'core/n
|
||||
this.setupFormModal(formData, saveText);
|
||||
}.bind(this));
|
||||
}.bind(this))
|
||||
.fail(Notification.exception);
|
||||
.catch(Notification.exception);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -177,21 +177,23 @@ class acceptances_table extends \table_sql {
|
||||
$filterstatus = $this->acceptancesfilter->get_status_filter();
|
||||
if ($filterstatus == 1) {
|
||||
$this->sql->from .= " $join AND a{$v}.status=1";
|
||||
} else if ($filterstatus == 2) {
|
||||
$this->sql->from .= " $join AND a{$v}.status=0";
|
||||
} else {
|
||||
$this->sql->from .= " LEFT $join";
|
||||
}
|
||||
|
||||
$this->sql->from .= " LEFT JOIN {user} m ON m.id = a{$v}.usermodified AND m.id <> u.id AND a{$v}.status = 1";
|
||||
$this->sql->from .= " LEFT JOIN {user} m ON m.id = a{$v}.usermodified AND m.id <> u.id AND a{$v}.status IS NOT NULL";
|
||||
|
||||
$this->sql->params['versionid' . $v] = $v;
|
||||
|
||||
if ($filterstatus === 0) {
|
||||
$this->sql->where .= " AND (a{$v}.status IS NULL OR a{$v}.status = 0)";
|
||||
$this->sql->where .= " AND a{$v}.status IS NULL";
|
||||
}
|
||||
|
||||
$this->add_column_header('status' . $v, get_string('agreed', 'tool_policy'), true, 'mdl-align');
|
||||
$this->add_column_header('timemodified', get_string('agreedon', 'tool_policy'));
|
||||
$this->add_column_header('usermodified' . $v, get_string('agreedby', 'tool_policy'));
|
||||
$this->add_column_header('status' . $v, get_string('response', 'tool_policy'));
|
||||
$this->add_column_header('timemodified', get_string('responseon', 'tool_policy'));
|
||||
$this->add_column_header('usermodified' . $v, get_string('responseby', 'tool_policy'));
|
||||
$this->add_column_header('note', get_string('acceptancenote', 'tool_policy'), false);
|
||||
}
|
||||
|
||||
@ -207,11 +209,13 @@ class acceptances_table extends \table_sql {
|
||||
$join = "JOIN {tool_policy_acceptances} a{$v} ON a{$v}.userid = u.id AND a{$v}.policyversionid=:versionid{$v}";
|
||||
if ($filterstatus == 1) {
|
||||
$this->sql->from .= " {$join} AND a{$v}.status=1";
|
||||
} else if ($filterstatus == 2) {
|
||||
$this->sql->from .= " {$join} AND a{$v}.status=0";
|
||||
} else {
|
||||
$this->sql->from .= " LEFT {$join}";
|
||||
}
|
||||
$this->sql->params['versionid' . $v] = $v;
|
||||
$this->add_column_header('status' . $v, $versionname, true, 'mdl-align');
|
||||
$this->add_column_header('status' . $v, $versionname);
|
||||
$statusall[] = "COALESCE(a{$v}.status, 0)";
|
||||
}
|
||||
$this->sql->fields .= ",".join('+', $statusall)." AS statusall";
|
||||
@ -219,7 +223,7 @@ class acceptances_table extends \table_sql {
|
||||
if ($filterstatus === 0) {
|
||||
$statussql = [];
|
||||
foreach ($this->versionids as $v => $versionname) {
|
||||
$statussql[] = "a{$v}.status IS NULL OR a{$v}.status = 0";
|
||||
$statussql[] = "a{$v}.status IS NULL";
|
||||
}
|
||||
$this->sql->where .= " AND (u.policyagreed = 0 OR ".join(" OR ", $statussql).")";
|
||||
}
|
||||
@ -420,7 +424,7 @@ class acceptances_table extends \table_sql {
|
||||
echo \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'returnurl',
|
||||
'value' => $this->get_return_url()]);
|
||||
foreach (array_keys($this->versionids) as $versionid) {
|
||||
echo \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => "versionids[{$versionid}]",
|
||||
echo \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'versionids[]',
|
||||
'value' => $versionid]);
|
||||
}
|
||||
}
|
||||
@ -433,6 +437,7 @@ class acceptances_table extends \table_sql {
|
||||
public function wrap_html_finish() {
|
||||
global $PAGE;
|
||||
if ($this->canagreeany) {
|
||||
echo \html_writer::empty_tag('input', ['type' => 'hidden', 'name' => 'action', 'value' => 'accept']);
|
||||
echo \html_writer::empty_tag('input', ['type' => 'submit', 'data-action' => 'acceptmodal',
|
||||
'value' => get_string('consentbulk', 'tool_policy'), 'class' => 'btn btn-primary m-t-1']);
|
||||
$PAGE->requires->js_call_amd('tool_policy/acceptmodal', 'getInstance', [\context_system::instance()->id]);
|
||||
@ -529,10 +534,15 @@ class acceptances_table extends \table_sql {
|
||||
$onbehalf = false;
|
||||
$versions = $versionid ? [$versionid => $this->versionids[$versionid]] : $this->versionids; // List of versions.
|
||||
$accepted = []; // List of versionids that user has accepted.
|
||||
$declined = [];
|
||||
|
||||
foreach ($versions as $v => $name) {
|
||||
if (!empty($row->{'status' . $v})) {
|
||||
$accepted[] = $v;
|
||||
if ($row->{'status' . $v} !== null) {
|
||||
if (empty($row->{'status' . $v})) {
|
||||
$declined[] = $v;
|
||||
} else {
|
||||
$accepted[] = $v;
|
||||
}
|
||||
$agreedby = $row->{'usermodified' . $v};
|
||||
if ($agreedby && $agreedby != $row->id) {
|
||||
$onbehalf = true;
|
||||
@ -540,25 +550,13 @@ class acceptances_table extends \table_sql {
|
||||
}
|
||||
}
|
||||
|
||||
if ($versionid) {
|
||||
$str = new \lang_string($accepted ? 'yes' : 'no');
|
||||
} else {
|
||||
$str = new \lang_string('acceptancecount', 'tool_policy', (object)[
|
||||
'agreedcount' => count($accepted),
|
||||
'policiescount' => count($versions)
|
||||
]);
|
||||
}
|
||||
$ua = new user_agreement($row->id, $accepted, $declined, $this->get_return_url(), $versions, $onbehalf, $row->canaccept);
|
||||
|
||||
if ($this->is_downloading()) {
|
||||
return $str->out();
|
||||
return $ua->export_for_download();
|
||||
|
||||
} else {
|
||||
$s = $this->output->render(new user_agreement($row->id, $accepted, $this->get_return_url(),
|
||||
$versions, $onbehalf, $row->canaccept));
|
||||
if (!$versionid) {
|
||||
$s .= '<br>' . \html_writer::link(new \moodle_url('/admin/tool/policy/user.php',
|
||||
['userid' => $row->id, 'returnurl' => $this->get_return_url()]), $str);
|
||||
}
|
||||
return $s;
|
||||
return $this->output->render($ua);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,6 +131,8 @@ class api {
|
||||
|
||||
$policies = [];
|
||||
$versions = [];
|
||||
$optcache = \cache::make('tool_policy', 'policy_optional');
|
||||
|
||||
$rs = $DB->get_recordset_sql($sql, $params);
|
||||
|
||||
foreach ($rs as $r) {
|
||||
@ -149,6 +151,8 @@ class api {
|
||||
}
|
||||
|
||||
$versions[$r->id][$versiondata->id] = $versiondata;
|
||||
|
||||
$optcache->set($versiondata->id, $versiondata->optional);
|
||||
}
|
||||
|
||||
$rs->close();
|
||||
@ -309,8 +313,8 @@ class api {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Users have access to all the policies they have ever accepted.
|
||||
if (static::is_user_version_accepted($userid, $policy->id)) {
|
||||
// Users have access to all the policies they have ever accepted/declined.
|
||||
if (static::is_user_version_accepted($userid, $policy->id) !== null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -719,20 +723,22 @@ class api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns version acceptance for this user.
|
||||
* Did the user accept the given policy version?
|
||||
*
|
||||
* @param int $userid User identifier.
|
||||
* @param int $versionid Policy version identifier.
|
||||
* @param array|null $acceptances Iist of policy version acceptances indexed by versionid.
|
||||
* @return bool True if this user has accepted this policy version; false otherwise.
|
||||
* @param array|null $acceptances Pre-loaded list of policy version acceptances indexed by versionid.
|
||||
* @return bool|null True/false if this user accepted/declined the policy; null otherwise.
|
||||
*/
|
||||
public static function is_user_version_accepted($userid, $versionid, $acceptances = null) {
|
||||
|
||||
$acceptance = static::get_user_version_acceptance($userid, $versionid, $acceptances);
|
||||
|
||||
if (!empty($acceptance)) {
|
||||
return $acceptance->status;
|
||||
return (bool) $acceptance->status;
|
||||
}
|
||||
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -754,14 +760,14 @@ class api {
|
||||
if (isset($acceptances[$policy->currentversion->id])) {
|
||||
$policy->currentversion->acceptance = $acceptances[$policy->currentversion->id];
|
||||
} else {
|
||||
$policy->currentversion->acceptance = 0;
|
||||
$policy->currentversion->acceptance = null;
|
||||
}
|
||||
$versions[] = $policy->currentversion;
|
||||
}
|
||||
foreach ($policy->archivedversions as $version) {
|
||||
if ($version->audience != policy_version::AUDIENCE_GUESTS
|
||||
&& static::can_user_view_policy_version($version, $userid)) {
|
||||
$version->acceptance = isset($acceptances[$version->id]) ? $acceptances[$version->id] : 0;
|
||||
$version->acceptance = isset($acceptances[$version->id]) ? $acceptances[$version->id] : null;
|
||||
$versions[] = $version;
|
||||
}
|
||||
}
|
||||
@ -774,14 +780,19 @@ class api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user can accept policies for themselves or on behalf of another user
|
||||
* Check if given policies can be accepted by the current user (eventually on behalf of the other user)
|
||||
*
|
||||
* @param int $userid
|
||||
* @param bool $throwexception
|
||||
* Currently, the version ids are not relevant and the check is based on permissions only. In the future, additional
|
||||
* conditions can be added (such as policies applying to certain users only).
|
||||
*
|
||||
* @param array $versionids int[] List of policy version ids to check
|
||||
* @param int $userid Accepting policies on this user's behalf (defaults to accepting on self)
|
||||
* @param bool $throwexception Throw exception instead of returning false
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_accept_policies($userid = null, $throwexception = false) {
|
||||
public static function can_accept_policies(array $versionids, $userid = null, $throwexception = false) {
|
||||
global $USER;
|
||||
|
||||
if (!isloggedin() || isguestuser()) {
|
||||
if ($throwexception) {
|
||||
throw new \moodle_exception('noguest');
|
||||
@ -789,6 +800,7 @@ class api {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$userid) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
@ -814,15 +826,48 @@ class api {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if user can revoke policies for themselves or on behalf of another user
|
||||
* Check if given policies can be declined by the current user (eventually on behalf of the other user)
|
||||
*
|
||||
* @param int $userid
|
||||
* @param bool $throwexception
|
||||
* Only optional policies can be declined. Otherwise, the permissions are same as for accepting policies.
|
||||
*
|
||||
* @param array $versionids int[] List of policy version ids to check
|
||||
* @param int $userid Declining policies on this user's behalf (defaults to declining by self)
|
||||
* @param bool $throwexception Throw exception instead of returning false
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_revoke_policies($userid = null, $throwexception = false) {
|
||||
public static function can_decline_policies(array $versionids, $userid = null, $throwexception = false) {
|
||||
|
||||
foreach ($versionids as $versionid) {
|
||||
if (static::get_agreement_optional($versionid) == policy_version::AGREEMENT_COMPULSORY) {
|
||||
// Compulsory policies can't be declined (that is what makes them compulsory).
|
||||
if ($throwexception) {
|
||||
throw new \moodle_exception('errorpolicyversioncompulsory', 'tool_policy');
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return static::can_accept_policies($versionids, $userid, $throwexception);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if acceptances to given policies can be revoked by the current user (eventually on behalf of the other user)
|
||||
*
|
||||
* Revoking optional policies is controlled by the same rules as declining them. Compulsory policies can be revoked
|
||||
* only by users with the permission to accept policies on other's behalf. The reasoning behind this is to make sure
|
||||
* the user communicates with the site's privacy officer and is well aware of all consequences of the decision (such
|
||||
* as losing right to access the site).
|
||||
*
|
||||
* @param array $versionids int[] List of policy version ids to check
|
||||
* @param int $userid Revoking policies on this user's behalf (defaults to revoking by self)
|
||||
* @param bool $throwexception Throw exception instead of returning false
|
||||
* @return bool
|
||||
*/
|
||||
public static function can_revoke_policies(array $versionids, $userid = null, $throwexception = false) {
|
||||
global $USER;
|
||||
|
||||
// Guests' acceptance is not stored so there is nothing to revoke.
|
||||
if (!isloggedin() || isguestuser()) {
|
||||
if ($throwexception) {
|
||||
throw new \moodle_exception('noguest');
|
||||
@ -830,32 +875,84 @@ class api {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!$userid) {
|
||||
$userid = $USER->id;
|
||||
|
||||
// Sort policies into two sets according the optional flag.
|
||||
$compulsory = [];
|
||||
$optional = [];
|
||||
|
||||
foreach ($versionids as $versionid) {
|
||||
$agreementoptional = static::get_agreement_optional($versionid);
|
||||
if ($agreementoptional == policy_version::AGREEMENT_COMPULSORY) {
|
||||
$compulsory[] = $versionid;
|
||||
} else if ($agreementoptional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
$optional[] = $versionid;
|
||||
} else {
|
||||
throw new \coding_exception('Unexpected optional flag value');
|
||||
}
|
||||
}
|
||||
|
||||
// At the moment, current users can't revoke their own policies.
|
||||
// Check capability to revoke on behalf as the real user.
|
||||
$realuser = manager::get_realuser();
|
||||
$usercontext = \context_user::instance($userid);
|
||||
if ($throwexception) {
|
||||
require_capability('tool/policy:acceptbehalf', $usercontext, $realuser);
|
||||
return;
|
||||
} else {
|
||||
return has_capability('tool/policy:acceptbehalf', $usercontext, $realuser);
|
||||
// Check if the user can revoke the optional policies from the list.
|
||||
if ($optional) {
|
||||
if (!static::can_decline_policies($optional, $userid, $throwexception)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the user can revoke the compulsory policies from the list.
|
||||
if ($compulsory) {
|
||||
if (!$userid) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
|
||||
$realuser = manager::get_realuser();
|
||||
$usercontext = \context_user::instance($userid);
|
||||
if ($throwexception) {
|
||||
require_capability('tool/policy:acceptbehalf', $usercontext, $realuser);
|
||||
return;
|
||||
} else {
|
||||
return has_capability('tool/policy:acceptbehalf', $usercontext, $realuser);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Accepts the current revisions of all policies that the user has not yet accepted
|
||||
* Mark the given policy versions as accepted by the user.
|
||||
*
|
||||
* @param array|int $policyversionid
|
||||
* @param int|null $userid
|
||||
* @param string|null $note
|
||||
* @param string|null $lang
|
||||
* @param array|int $policyversionid Policy version id(s) to set acceptance status for.
|
||||
* @param int|null $userid Id of the user accepting the policy version, defaults to the current one.
|
||||
* @param string|null $note Note to be recorded.
|
||||
* @param string|null $lang Language in which the policy was shown, defaults to the current one.
|
||||
*/
|
||||
public static function accept_policies($policyversionid, $userid = null, $note = null, $lang = null) {
|
||||
static::set_acceptances_status($policyversionid, $userid, $note, $lang, 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the given policy versions as declined by the user.
|
||||
*
|
||||
* @param array|int $policyversionid Policy version id(s) to set acceptance status for.
|
||||
* @param int|null $userid Id of the user accepting the policy version, defaults to the current one.
|
||||
* @param string|null $note Note to be recorded.
|
||||
* @param string|null $lang Language in which the policy was shown, defaults to the current one.
|
||||
*/
|
||||
public static function decline_policies($policyversionid, $userid = null, $note = null, $lang = null) {
|
||||
static::set_acceptances_status($policyversionid, $userid, $note, $lang, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the given policy versions as accepted or declined by the user.
|
||||
*
|
||||
* @param array|int $policyversionid Policy version id(s) to set acceptance status for.
|
||||
* @param int|null $userid Id of the user accepting the policy version, defaults to the current one.
|
||||
* @param string|null $note Note to be recorded.
|
||||
* @param string|null $lang Language in which the policy was shown, defaults to the current one.
|
||||
* @param int $status The acceptance status, defaults to 1 = accepted
|
||||
*/
|
||||
protected static function set_acceptances_status($policyversionid, $userid = null, $note = null, $lang = null, $status = 1) {
|
||||
global $DB, $USER;
|
||||
|
||||
// Validate arguments and capabilities.
|
||||
if (empty($policyversionid)) {
|
||||
return;
|
||||
@ -865,18 +962,22 @@ class api {
|
||||
if (!$userid) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
self::can_accept_policies($userid, true);
|
||||
self::can_accept_policies([$policyversionid], $userid, true);
|
||||
|
||||
// Retrieve the list of policy versions that need agreement (do not update existing agreements).
|
||||
list($sql, $params) = $DB->get_in_or_equal($policyversionid, SQL_PARAMS_NAMED);
|
||||
$sql = "SELECT v.id AS versionid, a.*
|
||||
FROM {tool_policy_versions} v
|
||||
LEFT JOIN {tool_policy_acceptances} a ON a.userid = :userid AND a.policyversionid = v.id
|
||||
WHERE (a.id IS NULL or a.status <> 1) AND v.id " . $sql;
|
||||
$needacceptance = $DB->get_records_sql($sql, ['userid' => $userid] + $params);
|
||||
LEFT JOIN {tool_policy_acceptances} a ON a.userid = :userid AND a.policyversionid = v.id
|
||||
WHERE v.id $sql AND (a.id IS NULL OR a.status <> :status)";
|
||||
|
||||
$needacceptance = $DB->get_records_sql($sql, $params + [
|
||||
'userid' => $userid,
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
$realuser = manager::get_realuser();
|
||||
$updatedata = ['status' => 1, 'lang' => $lang ?: current_language(),
|
||||
$updatedata = ['status' => $status, 'lang' => $lang ?: current_language(),
|
||||
'timemodified' => time(), 'usermodified' => $realuser->id, 'note' => $note];
|
||||
foreach ($needacceptance as $versionid => $currentacceptance) {
|
||||
unset($currentacceptance->versionid);
|
||||
@ -911,23 +1012,30 @@ class api {
|
||||
$user = $DB->get_record('user', ['id' => $user], 'id, policyagreed');
|
||||
}
|
||||
|
||||
$sql = "SELECT d.id, a.status
|
||||
$sql = "SELECT d.id, v.optional, a.status
|
||||
FROM {tool_policy} d
|
||||
INNER JOIN {tool_policy_versions} v ON v.policyid = d.id AND v.id = d.currentversionid
|
||||
LEFT JOIN {tool_policy_acceptances} a ON a.userid = :userid AND a.policyversionid = v.id
|
||||
WHERE (v.audience = :audience OR v.audience = :audienceall)";
|
||||
INNER JOIN {tool_policy_versions} v ON v.policyid = d.id AND v.id = d.currentversionid
|
||||
LEFT JOIN {tool_policy_acceptances} a ON a.userid = :userid AND a.policyversionid = v.id
|
||||
WHERE (v.audience = :audience OR v.audience = :audienceall)";
|
||||
|
||||
$params = [
|
||||
'audience' => policy_version::AUDIENCE_LOGGEDIN,
|
||||
'audienceall' => policy_version::AUDIENCE_ALL,
|
||||
'userid' => $user->id
|
||||
];
|
||||
$policies = $DB->get_records_sql_menu($sql, $params);
|
||||
$acceptedpolicies = array_filter($policies);
|
||||
$policyagreed = (count($policies) == count($acceptedpolicies)) ? 1 : 0;
|
||||
|
||||
if ($user->policyagreed != $policyagreed) {
|
||||
$user->policyagreed = $policyagreed;
|
||||
$DB->set_field('user', 'policyagreed', $policyagreed, ['id' => $user->id]);
|
||||
$allresponded = true;
|
||||
foreach ($DB->get_records_sql($sql, $params) as $policyacceptance) {
|
||||
if ($policyacceptance->optional == policy_version::AGREEMENT_COMPULSORY && empty($policyacceptance->status)) {
|
||||
$allresponded = false;
|
||||
} else if ($policyacceptance->optional == policy_version::AGREEMENT_OPTIONAL && $policyacceptance->status === null) {
|
||||
$allresponded = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ($user->policyagreed != $allresponded) {
|
||||
$user->policyagreed = $allresponded;
|
||||
$DB->set_field('user', 'policyagreed', $allresponded, ['id' => $user->id]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -943,7 +1051,7 @@ class api {
|
||||
if (!$userid) {
|
||||
$userid = $USER->id;
|
||||
}
|
||||
self::can_accept_policies($userid, true);
|
||||
self::can_accept_policies([$policyversionid], $userid, true);
|
||||
|
||||
if ($currentacceptance = $DB->get_record('tool_policy_acceptances',
|
||||
['policyversionid' => $policyversionid, 'userid' => $userid])) {
|
||||
@ -963,7 +1071,7 @@ class api {
|
||||
* @param \core\event\user_created $event
|
||||
*/
|
||||
public static function create_acceptances_user_created(\core\event\user_created $event) {
|
||||
global $CFG, $DB;
|
||||
global $USER, $CFG, $DB;
|
||||
|
||||
// Do nothing if not set as the site policies handler.
|
||||
if (empty($CFG->sitepolicyhandler) || $CFG->sitepolicyhandler !== 'tool_policy') {
|
||||
@ -977,28 +1085,59 @@ class api {
|
||||
if (!$user->policyagreed) {
|
||||
return;
|
||||
}
|
||||
// Remove the presignup cache after the user account is created.
|
||||
|
||||
// Cleanup our bits in the presignup cache (we can not rely on them at this stage any more anyway).
|
||||
$cache = \cache::make('core', 'presignup');
|
||||
$cache->delete('tool_policy_userpolicyagreed');
|
||||
$cache->delete('tool_policy_viewedpolicies');
|
||||
$cache->delete('tool_policy_policyversionidsagreed');
|
||||
|
||||
// Get all active policies.
|
||||
$currentpolicyversions = static::get_current_versions_ids(policy_version::AUDIENCE_LOGGEDIN);
|
||||
// Save active policies as accepted by the user.
|
||||
if (!empty($currentpolicyversions)) {
|
||||
// Mark all compulsory policies as implicitly accepted during the signup.
|
||||
if ($policyversions = static::list_current_versions(policy_version::AUDIENCE_LOGGEDIN)) {
|
||||
$acceptances = array();
|
||||
foreach ($currentpolicyversions as $policy) {
|
||||
$now = time();
|
||||
foreach ($policyversions as $policyversion) {
|
||||
if ($policyversion->optional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
continue;
|
||||
}
|
||||
$acceptances[] = array(
|
||||
'policyversionid' => $policy,
|
||||
'policyversionid' => $policyversion->id,
|
||||
'userid' => $userid,
|
||||
'status' => 1,
|
||||
'lang' => $lang,
|
||||
'usermodified' => 0,
|
||||
'timecreated' => time(),
|
||||
'timemodified' => time()
|
||||
'usermodified' => isset($USER->id) ? $USER->id : 0,
|
||||
'timecreated' => $now,
|
||||
'timemodified' => $now,
|
||||
);
|
||||
}
|
||||
$DB->insert_records('tool_policy_acceptances', $acceptances);
|
||||
}
|
||||
|
||||
static::update_policyagreed($userid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the optional flag for the given policy version.
|
||||
*
|
||||
* Optimised for being called multiple times by making use of a request cache. The cache is normally populated as a
|
||||
* side effect of calling {@link self::list_policies()} and in most cases should be warm enough for hits.
|
||||
*
|
||||
* @param int $versionid
|
||||
* @return int policy_version::AGREEMENT_COMPULSORY | policy_version::AGREEMENT_OPTIONAL
|
||||
*/
|
||||
public static function get_agreement_optional($versionid) {
|
||||
global $DB;
|
||||
|
||||
$optcache = \cache::make('tool_policy', 'policy_optional');
|
||||
|
||||
$hit = $optcache->get($versionid);
|
||||
|
||||
if ($hit === false) {
|
||||
$flags = $DB->get_records_menu('tool_policy_versions', null, '', 'id, optional');
|
||||
$optcache->set_many($flags);
|
||||
$hit = $flags[$versionid];
|
||||
}
|
||||
|
||||
return $hit;
|
||||
}
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ class accept_policy extends \moodleform {
|
||||
* Defines the form fields.
|
||||
*/
|
||||
public function definition() {
|
||||
global $PAGE;
|
||||
global $PAGE, $USER;
|
||||
$mform = $this->_form;
|
||||
|
||||
if (empty($this->_customdata['userids']) || !is_array($this->_customdata['userids'])) {
|
||||
@ -53,10 +53,10 @@ class accept_policy extends \moodleform {
|
||||
if (empty($this->_customdata['versionids']) || !is_array($this->_customdata['versionids'])) {
|
||||
throw new \moodle_exception('missingparam', '', '', 'versionids');
|
||||
}
|
||||
$revoke = (!empty($this->_customdata['action']) && $this->_customdata['action'] == 'revoke');
|
||||
$action = $this->_customdata['action'];
|
||||
$userids = clean_param_array($this->_customdata['userids'], PARAM_INT);
|
||||
$versionids = clean_param_array($this->_customdata['versionids'], PARAM_INT);
|
||||
$usernames = $this->validate_and_get_users($userids, $revoke);
|
||||
$usernames = $this->validate_and_get_users($versionids, $userids, $action);
|
||||
$versionnames = $this->validate_and_get_versions($versionids);
|
||||
|
||||
foreach ($usernames as $userid => $name) {
|
||||
@ -78,22 +78,36 @@ class accept_policy extends \moodleform {
|
||||
get_string('policydochdrpolicy', 'tool_policy');
|
||||
$mform->addElement('static', 'policy', $policyacceptancelabel, join(', ', $versionnames));
|
||||
|
||||
if ($revoke) {
|
||||
if ($action === 'revoke') {
|
||||
$mform->addElement('static', 'ack', '', get_string('revokeacknowledgement', 'tool_policy'));
|
||||
$mform->addElement('hidden', 'action', 'revoke');
|
||||
$mform->setType('action', PARAM_ALPHA);
|
||||
} else {
|
||||
} else if ($action === 'accept') {
|
||||
$mform->addElement('static', 'ack', '', get_string('acceptanceacknowledgement', 'tool_policy'));
|
||||
$mform->addElement('hidden', 'action', 'accept');
|
||||
} else if ($action === 'decline') {
|
||||
$mform->addElement('static', 'ack', '', get_string('declineacknowledgement', 'tool_policy'));
|
||||
$mform->addElement('hidden', 'action', 'decline');
|
||||
} else {
|
||||
throw new \moodle_exception('invalidaccessparameter');
|
||||
}
|
||||
|
||||
$mform->setType('action', PARAM_ALPHA);
|
||||
|
||||
if (count($usernames) == 1 && isset($usernames[$USER->id])) {
|
||||
// No need to display the acknowledgement if the users are giving/revoking acceptance on their own.
|
||||
$mform->removeElement('ack');
|
||||
}
|
||||
|
||||
$mform->addElement('textarea', 'note', get_string('acceptancenote', 'tool_policy'));
|
||||
$mform->setType('note', PARAM_NOTAGS);
|
||||
|
||||
if (!empty($this->_customdata['showbuttons'])) {
|
||||
if ($revoke) {
|
||||
if ($action === 'revoke') {
|
||||
$this->add_action_buttons(true, get_string('irevokethepolicy', 'tool_policy'));
|
||||
} else {
|
||||
} else if ($action === 'accept') {
|
||||
$this->add_action_buttons(true, get_string('iagreetothepolicy', 'tool_policy'));
|
||||
} else if ($action === 'decline') {
|
||||
$this->add_action_buttons(true, get_string('declinethepolicy', 'tool_policy'));
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,12 +117,14 @@ class accept_policy extends \moodleform {
|
||||
/**
|
||||
* Validate userids and return usernames
|
||||
*
|
||||
* @param array $versionids int[] List of policy version ids to process.
|
||||
* @param array $userids
|
||||
* @param boolean $revoke True if policies will be revoked; false when policies will be accepted.
|
||||
* @param string $action accept|decline|revoke
|
||||
* @return array (userid=>username)
|
||||
*/
|
||||
protected function validate_and_get_users($userids, $revoke = false) {
|
||||
protected function validate_and_get_users($versionids, $userids, $action) {
|
||||
global $DB;
|
||||
|
||||
$usernames = [];
|
||||
list($sql, $params) = $DB->get_in_or_equal($userids, SQL_PARAMS_NAMED);
|
||||
$params['usercontextlevel'] = CONTEXT_USER;
|
||||
@ -126,10 +142,12 @@ class accept_policy extends \moodleform {
|
||||
throw new \moodle_exception('noguest');
|
||||
}
|
||||
\context_helper::preload_from_record($user);
|
||||
if ($revoke) {
|
||||
api::can_revoke_policies($userid, true);
|
||||
} else {
|
||||
api::can_accept_policies($userid, true);
|
||||
if ($action === 'revoke') {
|
||||
api::can_revoke_policies($versionids, $userid, true);
|
||||
} else if ($action === 'accept') {
|
||||
api::can_accept_policies($versionids, $userid, true);
|
||||
} else if ($action === 'decline') {
|
||||
api::can_decline_policies($versionids, $userid, true);
|
||||
}
|
||||
$usernames[$userid] = fullname($user);
|
||||
}
|
||||
@ -166,14 +184,15 @@ class accept_policy extends \moodleform {
|
||||
*/
|
||||
public function process() {
|
||||
if ($data = $this->get_data()) {
|
||||
$revoke = (!empty($data->action) && $data->action == 'revoke');
|
||||
foreach ($data->userids as $userid) {
|
||||
if ($revoke) {
|
||||
if ($data->action === 'revoke') {
|
||||
foreach ($data->versionids as $versionid) {
|
||||
\tool_policy\api::revoke_acceptance($versionid, $userid, $data->note);
|
||||
}
|
||||
} else {
|
||||
} else if ($data->action === 'accept') {
|
||||
\tool_policy\api::accept_policies($data->versionids, $userid, $data->note);
|
||||
} else if ($data->action === 'decline') {
|
||||
\tool_policy\api::decline_policies($data->versionids, $userid, $data->note);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -91,6 +91,8 @@ class policydoc extends moodleform {
|
||||
|
||||
$mform->addElement('selectyesno', 'agreementstyle', get_string('policypriorityagreement', 'tool_policy'));
|
||||
|
||||
$mform->addElement('selectyesno', 'optional', get_string('policydocoptional', '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');
|
||||
|
@ -50,9 +50,6 @@ class acceptances implements renderable, templatable {
|
||||
/** @var moodle_url */
|
||||
protected $returnurl;
|
||||
|
||||
/** @var bool */
|
||||
protected $canrevoke;
|
||||
|
||||
/**
|
||||
* Contructor.
|
||||
*
|
||||
@ -62,7 +59,6 @@ class acceptances implements renderable, templatable {
|
||||
public function __construct($userid, $returnurl = null) {
|
||||
$this->userid = $userid;
|
||||
$this->returnurl = $returnurl ? (new moodle_url($returnurl))->out(false) : null;
|
||||
$this->canrevoke = \tool_policy\api::can_revoke_policies($this->userid);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -76,19 +72,20 @@ class acceptances implements renderable, templatable {
|
||||
$data->hasonbehalfagreements = false;
|
||||
$data->pluginbaseurl = (new moodle_url('/admin/tool/policy'))->out(false);
|
||||
$data->returnurl = $this->returnurl;
|
||||
$data->canrevoke = $this->canrevoke;
|
||||
|
||||
// Get the list of policies and versions that current user is able to see
|
||||
// and the respective acceptance records for the selected user.
|
||||
$policies = api::get_policies_with_acceptances($this->userid);
|
||||
$versionids = [];
|
||||
|
||||
$canviewfullnames = has_capability('moodle/site:viewfullnames', \context_system::instance());
|
||||
foreach ($policies as $policy) {
|
||||
|
||||
foreach ($policy->versions as $version) {
|
||||
$versionids[$version->id] = $version->id;
|
||||
unset($version->summary);
|
||||
unset($version->content);
|
||||
$version->iscurrent = ($version->status == policy_version::STATUS_ACTIVE);
|
||||
$version->isoptional = ($version->optional == policy_version::AGREEMENT_OPTIONAL);
|
||||
$version->name = $version->name;
|
||||
$version->revision = $version->revision;
|
||||
$returnurl = new moodle_url('/admin/tool/policy/user.php', ['userid' => $this->userid]);
|
||||
@ -98,12 +95,17 @@ class acceptances implements renderable, templatable {
|
||||
'returnurl' => $returnurl->out(false),
|
||||
]))->out(false);
|
||||
|
||||
if (!empty($version->acceptance->status)) {
|
||||
if ($version->acceptance !== null) {
|
||||
$acceptance = $version->acceptance;
|
||||
$version->timeaccepted = userdate($acceptance->timemodified, get_string('strftimedatetime'));
|
||||
$onbehalf = $acceptance->usermodified && $acceptance->usermodified != $this->userid;
|
||||
$version->agreement = new user_agreement($this->userid, [$version->id], $returnurl,
|
||||
[$version->id => $version->name], $onbehalf);
|
||||
if ($version->acceptance->status == 1) {
|
||||
$version->agreement = new user_agreement($this->userid, [$version->id], [], $returnurl,
|
||||
[$version->id => $version->name], $onbehalf);
|
||||
} else {
|
||||
$version->agreement = new user_agreement($this->userid, [], [$version->id], $returnurl,
|
||||
[$version->id => $version->name], $onbehalf);
|
||||
}
|
||||
if ($onbehalf) {
|
||||
$usermodified = (object)['id' => $acceptance->usermodified];
|
||||
username_load_fields_from_object($usermodified, $acceptance, 'mod');
|
||||
@ -114,7 +116,7 @@ class acceptances implements renderable, templatable {
|
||||
}
|
||||
$version->note = format_text($acceptance->note);
|
||||
} else if ($version->iscurrent) {
|
||||
$version->agreement = new user_agreement($this->userid, [], $returnurl, [$version->id => $version->name]);
|
||||
$version->agreement = new user_agreement($this->userid, [], [], $returnurl, [$version->id => $version->name]);
|
||||
}
|
||||
if (isset($version->agreement)) {
|
||||
$version->agreement = $version->agreement->export_for_template($output);
|
||||
@ -133,6 +135,8 @@ class acceptances implements renderable, templatable {
|
||||
}
|
||||
|
||||
$data->policies = array_values($policies);
|
||||
$data->canrevoke = \tool_policy\api::can_revoke_policies(array_keys($versionids), $this->userid);
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
@ -94,11 +94,9 @@ class acceptances_filter implements \templatable, \renderable {
|
||||
switch ((int)$parts[1]) {
|
||||
case self::FILTER_POLICYID:
|
||||
case self::FILTER_VERSIONID:
|
||||
$value = (int)$parts[2];
|
||||
break;
|
||||
case self::FILTER_CAPABILITY_ACCEPT:
|
||||
case self::FILTER_STATUS:
|
||||
$value = (int)(bool)$parts[2];
|
||||
$value = (int)$parts[2];
|
||||
break;
|
||||
case self::FILTER_ROLE:
|
||||
$value = (int)$parts[2];
|
||||
@ -408,8 +406,9 @@ class acceptances_filter implements \templatable, \renderable {
|
||||
|
||||
// Status.
|
||||
$statuses = [
|
||||
self::FILTER_STATUS.':2' => get_string('filterstatusdeclined', 'tool_policy'),
|
||||
self::FILTER_STATUS.':1' => get_string('filterstatusyes', 'tool_policy'),
|
||||
self::FILTER_STATUS.':0' => get_string('filterstatusno', 'tool_policy'),
|
||||
self::FILTER_STATUS.':0' => get_string('filterstatuspending', 'tool_policy'),
|
||||
];
|
||||
if (($currentstatus = $this->get_status_filter()) !== null) {
|
||||
$selectedoptions[] = $key = self::FILTER_STATUS . ':' . $currentstatus;
|
||||
|
@ -57,6 +57,9 @@ class page_agreedocs implements renderable, templatable {
|
||||
/** @var array $agreedocs List of policy identifiers which the user has agreed using the form. */
|
||||
protected $agreedocs = null;
|
||||
|
||||
/** @var array $declinedocs List of policy identifiers that the user declined. */
|
||||
protected $declinedocs = null;
|
||||
|
||||
/** @var string $action Form action to identify when user agreeds policies. */
|
||||
protected $action = null;
|
||||
|
||||
@ -80,15 +83,17 @@ class page_agreedocs implements renderable, templatable {
|
||||
*
|
||||
* @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 array $declinedocs List of policy version ids that the user declined.
|
||||
* @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(array $listdocs, array $agreedocs = [], $behalfid = 0, $action = null) {
|
||||
public function __construct(array $listdocs, array $agreedocs = [], array $declinedocs = [], $behalfid = 0, $action = null) {
|
||||
global $USER;
|
||||
$realuser = manager::get_realuser();
|
||||
|
||||
$this->listdocs = $listdocs;
|
||||
$this->agreedocs = $agreedocs;
|
||||
$this->declinedocs = $declinedocs;
|
||||
$this->action = $action;
|
||||
$this->isexistinguser = isloggedin() && !isguestuser();
|
||||
|
||||
@ -99,11 +104,23 @@ class page_agreedocs implements renderable, templatable {
|
||||
}
|
||||
|
||||
$this->policies = api::list_current_versions(policy_version::AUDIENCE_LOGGEDIN);
|
||||
|
||||
if (!$this->isexistinguser) {
|
||||
// During the signup, show compulsory policies only.
|
||||
foreach ($this->policies as $ix => $policyversion) {
|
||||
if ($policyversion->optional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
unset($this->policies[$ix]);
|
||||
}
|
||||
}
|
||||
$this->policies = array_values($this->policies);
|
||||
}
|
||||
|
||||
if (empty($this->behalfid)) {
|
||||
$userid = $USER->id;
|
||||
} else {
|
||||
$userid = $this->behalfid;
|
||||
}
|
||||
|
||||
$this->accept_and_revoke_policies();
|
||||
$this->prepare_global_page_access($userid);
|
||||
$this->prepare_user_acceptances($userid);
|
||||
@ -120,25 +137,30 @@ class page_agreedocs implements renderable, templatable {
|
||||
if ($this->isexistinguser) {
|
||||
// Existing user.
|
||||
if (!empty($this->action) && confirm_sesskey()) {
|
||||
// The form has been sent. Update policies acceptances according to $this->agreedocs.
|
||||
// The form has been sent, update policies acceptances.
|
||||
$lang = current_language();
|
||||
// Accept / revoke policies.
|
||||
$acceptversionids = array();
|
||||
$acceptversionids = [];
|
||||
$declineversionids = [];
|
||||
|
||||
foreach ($this->policies as $policy) {
|
||||
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 (in_array($policy->id, $this->declinedocs)) {
|
||||
$declineversionids[] = $policy->id;
|
||||
} else {
|
||||
// If the policy was displayed but not agreed, revoke the eventually given acceptance.
|
||||
// If the policy was displayed but not answered, revoke the eventually given acceptance.
|
||||
api::revoke_acceptance($policy->id, $this->behalfid);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Accept all policy docs saved in $acceptversionids.
|
||||
|
||||
api::accept_policies($acceptversionids, $this->behalfid, null, $lang);
|
||||
api::decline_policies($declineversionids, $this->behalfid, null, $lang);
|
||||
|
||||
// Show a message to let know the user he/she must agree all the policies.
|
||||
if (count($acceptversionids) != count($this->policies)) {
|
||||
if ((count($acceptversionids) + count($declineversionids)) != count($this->policies)) {
|
||||
$message = (object) [
|
||||
'type' => 'error',
|
||||
'text' => get_string('mustagreetocontinue', 'tool_policy')
|
||||
@ -205,16 +227,25 @@ class page_agreedocs implements renderable, templatable {
|
||||
*/
|
||||
protected function redirect_to_policies($userid, $returnurl = null) {
|
||||
|
||||
// Make a list of all policies that the user has not accepted yet.
|
||||
// Make a list of all policies that the user has not answered yet.
|
||||
$allpolicies = $this->policies;
|
||||
|
||||
if ($this->isexistinguser) {
|
||||
$acceptances = api::get_user_acceptances($userid);
|
||||
foreach ($allpolicies as $ix => $policy) {
|
||||
if (api::is_user_version_accepted($userid, $policy->id, $acceptances)) {
|
||||
$isaccepted = api::is_user_version_accepted($userid, $policy->id, $acceptances);
|
||||
if ($isaccepted) {
|
||||
// The user has accepted this policy, do not show it again.
|
||||
unset($allpolicies[$ix]);
|
||||
} else if ($isaccepted === false && $policy->optional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
// The user declined this policy but the agreement was optional, do not show it.
|
||||
unset($allpolicies[$ix]);
|
||||
} else {
|
||||
// The user has not answered the policy yet, or the agreement is compulsory. Show it.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
$presignupcache = \cache::make('core', 'presignup');
|
||||
$acceptances = $presignupcache->get('tool_policy_policyversionidsagreed');
|
||||
@ -321,7 +352,7 @@ class page_agreedocs implements renderable, templatable {
|
||||
// Check for correct user capabilities.
|
||||
if ($this->isexistinguser) {
|
||||
// For existing users, it's needed to check if they have the capability for accepting policies.
|
||||
api::can_accept_policies($this->behalfid, true);
|
||||
api::can_accept_policies($this->listdocs, $this->behalfid, true);
|
||||
} else {
|
||||
// For new users, the behalfid parameter is ignored.
|
||||
if ($this->behalfid) {
|
||||
@ -377,18 +408,24 @@ class page_agreedocs implements renderable, templatable {
|
||||
if ($this->isexistinguser) {
|
||||
// Existing user.
|
||||
$versionagreed = false;
|
||||
$versiondeclined = false;
|
||||
$acceptances = api::get_user_acceptances($userid);
|
||||
$policy->versionacceptance = api::get_user_version_acceptance($userid, $policy->id, $acceptances);
|
||||
if (!empty($policy->versionacceptance)) {
|
||||
// The policy version has ever been agreed. Check if status = 1 to know if still is accepted.
|
||||
$versionagreed = $policy->versionacceptance->status;
|
||||
// The policy version has ever been replied to before. Check if status = 1 to know if still is accepted.
|
||||
if ($policy->versionacceptance->status) {
|
||||
$versionagreed = true;
|
||||
} else {
|
||||
$versiondeclined = true;
|
||||
}
|
||||
if ($versionagreed) {
|
||||
if ($policy->versionacceptance->lang != $lang) {
|
||||
// Add a message because this version has been accepted in a different language than the current one.
|
||||
$policy->versionlangsagreed = get_string('policyversionacceptedinotherlang', 'tool_policy');
|
||||
}
|
||||
if ($policy->versionacceptance->usermodified != $userid && $USER->id == $userid) {
|
||||
// Add a message because this version has been accepted in behalf of current user.
|
||||
$usermodified = $policy->versionacceptance->usermodified;
|
||||
if ($usermodified && $usermodified != $userid && $USER->id == $userid) {
|
||||
// Add a message because this version has been accepted on behalf of current user.
|
||||
$policy->versionbehalfsagreed = get_string('policyversionacceptedinbehalf', 'tool_policy');
|
||||
}
|
||||
}
|
||||
@ -396,8 +433,10 @@ class page_agreedocs implements renderable, templatable {
|
||||
} else {
|
||||
// New user.
|
||||
$versionagreed = in_array($policy->id, $this->agreedocs);
|
||||
$versiondeclined = false;
|
||||
}
|
||||
$policy->versionagreed = $versionagreed;
|
||||
$policy->versiondeclined = $versiondeclined;
|
||||
$policy->policylink = html_writer::link($policy->url, $policy->name);
|
||||
$policy->policymodal = $policymodal;
|
||||
}
|
||||
|
@ -159,6 +159,12 @@ class page_managedocs_list implements renderable, templatable {
|
||||
$version->statustext = html_writer::span($version->statustext, 'label');
|
||||
}
|
||||
|
||||
if ($version->optional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
$version->optionaltext = get_string('policydocoptionalyes', 'tool_policy');
|
||||
} else {
|
||||
$version->optionaltext = get_string('policydocoptionalno', 'tool_policy');
|
||||
}
|
||||
|
||||
$version->indented = $isindented;
|
||||
|
||||
$editbaseurl = new moodle_url('/admin/tool/policy/editpolicydoc.php', [
|
||||
|
@ -65,9 +65,10 @@ class page_nopermission implements renderable, templatable {
|
||||
/**
|
||||
* Prepare the page for rendering.
|
||||
*
|
||||
* @param array $versionids int[] List of policy version ids that were checked.
|
||||
* @param int $behalfid The userid to consent policies as (such as child's id).
|
||||
*/
|
||||
public function __construct($behalfid) {
|
||||
public function __construct(array $versionids, $behalfid) {
|
||||
global $USER;
|
||||
|
||||
$behalfid = $behalfid ?: $USER->id;
|
||||
@ -79,7 +80,7 @@ class page_nopermission implements renderable, templatable {
|
||||
|
||||
if (!empty($USER->id)) {
|
||||
// For existing users, it's needed to check if they have the capability for accepting policies.
|
||||
$this->haspermissionagreedocs = api::can_accept_policies($this->behalfid);
|
||||
$this->haspermissionagreedocs = api::can_accept_policies($versionids, $this->behalfid);
|
||||
}
|
||||
|
||||
$this->policies = api::list_current_versions(policy_version::AUDIENCE_LOGGEDIN);
|
||||
|
@ -169,10 +169,18 @@ class page_viewdoc implements renderable, templatable {
|
||||
unset($data->returnurl);
|
||||
$data->accepturl = (new moodle_url('/admin/tool/policy/index.php', [
|
||||
'listdoc[]' => $this->policy->id,
|
||||
'agreedoc[]' => $this->policy->id,
|
||||
'status'.$this->policy->id => 1,
|
||||
'submit' => 'accept',
|
||||
'sesskey' => sesskey(),
|
||||
]))->out(false);
|
||||
if ($this->policy->optional == policy_version::AGREEMENT_OPTIONAL) {
|
||||
$data->declineurl = (new moodle_url('/admin/tool/policy/index.php', [
|
||||
'listdoc[]' => $this->policy->id,
|
||||
'status'.$this->policy->id => 0,
|
||||
'submit' => 'decline',
|
||||
'sesskey' => sesskey(),
|
||||
]))->out(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,6 +56,9 @@ class user_agreement implements \templatable, \renderable {
|
||||
/** @var array */
|
||||
protected $accepted;
|
||||
|
||||
/** @var array */
|
||||
protected $declined;
|
||||
|
||||
/** @var bool */
|
||||
protected $canaccept;
|
||||
|
||||
@ -67,25 +70,35 @@ class user_agreement implements \templatable, \renderable {
|
||||
*
|
||||
* @param int $userid
|
||||
* @param array $accepted list of ids of accepted versions
|
||||
* @param array $declined list of ids of declined versions
|
||||
* @param moodle_url $pageurl
|
||||
* @param array $versions list of versions (id=>name)
|
||||
* @param bool $onbehalf whether at least one version was accepted by somebody else on behalf of the user
|
||||
* @param bool $canaccept does the current user have permission to accept the policy on behalf of user $userid
|
||||
* @param bool $canaccept does the current user have permission to accept/decline the policy on behalf of user $userid
|
||||
* @param bool $canrevoke does the current user have permission to revoke the policy on behalf of user $userid
|
||||
*/
|
||||
public function __construct($userid, $accepted, moodle_url $pageurl, $versions, $onbehalf = false,
|
||||
public function __construct($userid, array $accepted, array $declined, moodle_url $pageurl, $versions, $onbehalf = false,
|
||||
$canaccept = null, $canrevoke = null) {
|
||||
|
||||
// Make sure that all ids in $accepted and $declined are present in $versions.
|
||||
if (array_diff(array_merge($accepted, $declined), array_keys($versions))) {
|
||||
throw new \coding_exception('Policy version ids mismatch');
|
||||
}
|
||||
|
||||
$this->userid = $userid;
|
||||
$this->onbehalf = $onbehalf;
|
||||
$this->pageurl = $pageurl;
|
||||
$this->versions = $versions;
|
||||
$this->accepted = $accepted;
|
||||
$this->declined = $declined;
|
||||
$this->canaccept = $canaccept;
|
||||
|
||||
if (count($this->accepted) < count($this->versions) && $canaccept === null) {
|
||||
$this->canaccept = \tool_policy\api::can_accept_policies($this->userid);
|
||||
$this->canaccept = \tool_policy\api::can_accept_policies(array_keys($this->versions), $this->userid);
|
||||
}
|
||||
if (count($this->accepted) == count($this->versions) && $canrevoke === null) {
|
||||
$this->canrevoke = \tool_policy\api::can_revoke_policies($this->userid);
|
||||
|
||||
if (count($this->accepted) > 0 && $canrevoke === null) {
|
||||
$this->canrevoke = \tool_policy\api::can_revoke_policies(array_keys($this->versions), $this->userid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,35 +109,237 @@ class user_agreement implements \templatable, \renderable {
|
||||
* @return stdClass
|
||||
*/
|
||||
public function export_for_template(\renderer_base $output) {
|
||||
$data = [
|
||||
'status' => count($this->accepted) == count($this->versions),
|
||||
'onbehalf' => $this->onbehalf,
|
||||
'canaccept' => $this->canaccept,
|
||||
'canrevoke' => $this->canrevoke,
|
||||
|
||||
$data = (object)[
|
||||
'statusicon' => '',
|
||||
'statustext' => '',
|
||||
'statuslink' => '',
|
||||
'actions' => [],
|
||||
];
|
||||
if (!$data['status'] && $this->canaccept) {
|
||||
$linkparams = ['userids[0]' => $this->userid];
|
||||
foreach (array_diff(array_keys($this->versions), $this->accepted) as $versionid) {
|
||||
$linkparams["versionids[{$versionid}]"] = $versionid;
|
||||
|
||||
if (count($this->versions) == 1) {
|
||||
// We represent one particular policy's agreement status.
|
||||
$versionname = reset($this->versions);
|
||||
$versionid = key($this->versions);
|
||||
|
||||
$actionaccept = (object)[
|
||||
'text' => get_string('useracceptanceactionaccept', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactionacceptone', 'tool_policy', $versionname),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => (new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'versionids[]' => $versionid,
|
||||
'action' => 'accept',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]))->out(false),
|
||||
];
|
||||
|
||||
$actionrevoke = (object)[
|
||||
'text' => get_string('useracceptanceactionrevoke', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactionrevokeone', 'tool_policy', $versionname),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => (new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'versionids[]' => $versionid,
|
||||
'action' => 'revoke',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]))->out(false),
|
||||
];
|
||||
|
||||
$actiondecline = (object)[
|
||||
'text' => get_string('useracceptanceactiondecline', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactiondeclineone', 'tool_policy', $versionname),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => (new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'versionids[]' => $versionid,
|
||||
'action' => 'decline',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]))->out(false),
|
||||
];
|
||||
|
||||
if ($this->accepted) {
|
||||
$data->statusicon = 'agreed';
|
||||
|
||||
if ($this->onbehalf) {
|
||||
$data->statustext = get_string('acceptancestatusacceptedbehalf', 'tool_policy');
|
||||
} else {
|
||||
$data->statustext = get_string('acceptancestatusaccepted', 'tool_policy');
|
||||
}
|
||||
|
||||
if ($this->canrevoke) {
|
||||
$data->actions[] = $actionrevoke;
|
||||
}
|
||||
|
||||
} else if ($this->declined) {
|
||||
$data->statusicon = 'declined';
|
||||
|
||||
if ($this->onbehalf) {
|
||||
$data->statustext = get_string('acceptancestatusdeclinedbehalf', 'tool_policy');
|
||||
} else {
|
||||
$data->statustext = get_string('acceptancestatusdeclined', 'tool_policy');
|
||||
}
|
||||
|
||||
if ($this->canaccept) {
|
||||
$data->actions[] = $actionaccept;
|
||||
}
|
||||
|
||||
} else {
|
||||
$data->statusicon = 'pending';
|
||||
$data->statustext = get_string('acceptancestatuspending', 'tool_policy');
|
||||
|
||||
if ($this->canaccept) {
|
||||
$data->actions[] = $actionaccept;
|
||||
$data->actions[] = $actiondecline;
|
||||
}
|
||||
}
|
||||
$linkparams['returnurl'] = $this->pageurl->out_as_local_url(false);
|
||||
$link = new \moodle_url('/admin/tool/policy/accept.php', $linkparams);
|
||||
$data['acceptlink'] = $link->out(false);
|
||||
} else if ($data['status'] && $this->canrevoke) {
|
||||
$linkparams = ['userids[0]' => $this->userid];
|
||||
foreach (array_keys($this->versions) as $versionid) {
|
||||
$linkparams["versionids[{$versionid}]"] = $versionid;
|
||||
|
||||
} else if (count($this->versions) > 1) {
|
||||
// We represent the summary status for multiple policies.
|
||||
|
||||
$data->actions[] = (object)[
|
||||
'text' => get_string('useracceptanceactiondetails', 'tool_policy'),
|
||||
'url' => (new \moodle_url('/admin/tool/policy/user.php', [
|
||||
'userid' => $this->userid,
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]))->out(false),
|
||||
];
|
||||
|
||||
// Prepare the action link to accept all pending policies.
|
||||
$accepturl = new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'action' => 'accept',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]);
|
||||
|
||||
foreach (array_diff(array_keys($this->versions), $this->accepted, $this->declined) as $ix => $versionid) {
|
||||
$accepturl->param('versionids['.$ix.']', $versionid);
|
||||
}
|
||||
|
||||
$actionaccept = (object)[
|
||||
'text' => get_string('useracceptanceactionaccept', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactionacceptpending', 'tool_policy'),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => $accepturl->out(false),
|
||||
];
|
||||
|
||||
// Prepare the action link to revoke all agreed policies.
|
||||
$revokeurl = new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'action' => 'revoke',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]);
|
||||
|
||||
foreach ($this->accepted as $ix => $versionid) {
|
||||
$revokeurl->param('versionids['.$ix.']', $versionid);
|
||||
}
|
||||
|
||||
$actionrevoke = (object)[
|
||||
'text' => get_string('useracceptanceactionrevoke', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactionrevokeall', 'tool_policy'),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => $revokeurl->out(false),
|
||||
];
|
||||
|
||||
// Prepare the action link to decline all pending policies.
|
||||
$declineurl = new \moodle_url('/admin/tool/policy/accept.php', [
|
||||
'userids[]' => $this->userid,
|
||||
'action' => 'decline',
|
||||
'returnurl' => $this->pageurl->out_as_local_url(false),
|
||||
]);
|
||||
|
||||
foreach (array_diff(array_keys($this->versions), $this->accepted, $this->declined) as $ix => $versionid) {
|
||||
$declineurl->param('versionids['.$ix.']', $versionid);
|
||||
}
|
||||
|
||||
$actiondecline = (object)[
|
||||
'text' => get_string('useracceptanceactiondecline', 'tool_policy'),
|
||||
'title' => get_string('useracceptanceactiondeclinepending', 'tool_policy'),
|
||||
'data' => 'acceptmodal',
|
||||
'url' => $declineurl->out(false),
|
||||
];
|
||||
|
||||
$countversions = count($this->versions);
|
||||
$countaccepted = count($this->accepted);
|
||||
$countdeclined = count($this->declined);
|
||||
|
||||
if ($countaccepted == $countversions) {
|
||||
// All policies accepted.
|
||||
$data->statusicon = 'agreed';
|
||||
$data->statustext = get_string('acceptancestatusaccepted', 'tool_policy');
|
||||
|
||||
if ($this->canrevoke) {
|
||||
$data->actions[] = $actionrevoke;
|
||||
}
|
||||
|
||||
} else if ($countdeclined == $countversions) {
|
||||
// All policies declined.
|
||||
$data->statusicon = 'declined';
|
||||
$data->statustext = get_string('acceptancestatusdeclined', 'tool_policy');
|
||||
|
||||
} else if ($countaccepted + $countdeclined == $countversions) {
|
||||
// All policies responded, only some of them accepted.
|
||||
$data->statusicon = 'partial';
|
||||
$data->statustext = get_string('acceptancestatuspartial', 'tool_policy');
|
||||
|
||||
if ($this->accepted && $this->canrevoke) {
|
||||
$data->actions[] = $actionrevoke;
|
||||
}
|
||||
|
||||
} else {
|
||||
// Some policies are pending.
|
||||
$data->statusicon = 'pending';
|
||||
$data->statustext = get_string('acceptancestatuspending', 'tool_policy');
|
||||
|
||||
if ($this->canaccept) {
|
||||
$data->actions[] = $actionaccept;
|
||||
$data->actions[] = $actiondecline;
|
||||
}
|
||||
}
|
||||
$linkparams['returnurl'] = $this->pageurl->out_as_local_url(false);
|
||||
$linkparams['action'] = 'revoke';
|
||||
$link = new \moodle_url('/admin/tool/policy/accept.php', $linkparams);
|
||||
$data['revokelink'] = $link->out(false);
|
||||
}
|
||||
$data['singleversion'] = count($this->versions) == 1;
|
||||
if ($data['singleversion']) {
|
||||
$firstversion = reset($this->versions);
|
||||
$data['versionname'] = $firstversion;
|
||||
}
|
||||
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Describe the status with a plain text for downloading purposes.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function export_for_download() {
|
||||
|
||||
if (count($this->versions) == 1) {
|
||||
if ($this->accepted) {
|
||||
if ($this->onbehalf) {
|
||||
return get_string('acceptancestatusacceptedbehalf', 'tool_policy');
|
||||
} else {
|
||||
return get_string('acceptancestatusaccepted', 'tool_policy');
|
||||
}
|
||||
|
||||
} else if ($this->declined) {
|
||||
if ($this->onbehalf) {
|
||||
return get_string('acceptancestatusdeclinedbehalf', 'tool_policy');
|
||||
} else {
|
||||
return get_string('acceptancestatusdeclined', 'tool_policy');
|
||||
}
|
||||
|
||||
} else {
|
||||
return get_string('acceptancestatuspending', 'tool_policy');
|
||||
}
|
||||
|
||||
} else if (count($this->versions) > 1) {
|
||||
if (count($this->accepted) == count($this->versions)) {
|
||||
return get_string('acceptancestatusaccepted', 'tool_policy');
|
||||
|
||||
} else if (count($this->declined) == count($this->versions)) {
|
||||
return get_string('acceptancestatusdeclined', 'tool_policy');
|
||||
|
||||
} else if (count($this->accepted) > 0 || count($this->declined) > 0) {
|
||||
return get_string('acceptancestatuspartial', 'tool_policy');
|
||||
|
||||
} else {
|
||||
return get_string('acceptancestatuspending', 'tool_policy');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -75,6 +75,12 @@ class policy_version extends persistent {
|
||||
/** @var int Policy to be accepted on its own page before reaching the consent page. */
|
||||
const AGREEMENTSTYLE_OWNPAGE = 1;
|
||||
|
||||
/** @var int Users must agree to the policy in order to use the site. */
|
||||
const AGREEMENT_COMPULSORY = 0;
|
||||
|
||||
/** @var int Users may or may not agree to the policy. */
|
||||
const AGREEMENT_OPTIONAL = 1;
|
||||
|
||||
/**
|
||||
* Return the definition of the properties of this model.
|
||||
*
|
||||
@ -120,6 +126,14 @@ class policy_version extends persistent {
|
||||
],
|
||||
'default' => self::AGREEMENTSTYLE_CONSENTPAGE,
|
||||
],
|
||||
'optional' => [
|
||||
'type' => PARAM_INT,
|
||||
'choices' => [
|
||||
self::AGREEMENT_OPTIONAL,
|
||||
self::AGREEMENT_COMPULSORY,
|
||||
],
|
||||
'default' => self::AGREEMENT_COMPULSORY,
|
||||
],
|
||||
'revision' => [
|
||||
'type' => PARAM_TEXT,
|
||||
'default' => '',
|
||||
@ -154,4 +168,26 @@ class policy_version extends persistent {
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to execute after an update.
|
||||
*
|
||||
* @param bool $result Whether or not the update was successful (but it always is)
|
||||
*/
|
||||
protected function after_update($result) {
|
||||
|
||||
$optcache = \cache::make('tool_policy', 'policy_optional');
|
||||
$optcache->delete($this->raw_get('id'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Hook to execute after an update.
|
||||
*
|
||||
* @param bool $result Whether or not the update was successful (but it always is)
|
||||
*/
|
||||
protected function after_delete($result) {
|
||||
|
||||
$optcache = \cache::make('tool_policy', 'policy_optional');
|
||||
$optcache->delete($this->raw_get('id'));
|
||||
}
|
||||
}
|
||||
|
@ -79,26 +79,37 @@ class handler extends \core_privacy\local\sitepolicy\handler {
|
||||
*/
|
||||
public static function accept() {
|
||||
global $USER, $DB;
|
||||
|
||||
if (!isloggedin()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ($USER->policyagreed) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isguestuser()) {
|
||||
// Accepts all policies with a current version for logged users on behalf of the current user.
|
||||
if (!$versions = api::get_current_versions_ids(policy_version::AUDIENCE_LOGGEDIN)) {
|
||||
return false;
|
||||
}
|
||||
api::accept_policies(array_values($versions));
|
||||
if (isguestuser()) {
|
||||
// For guests, agreement is stored in the session only.
|
||||
$USER->policyagreed = 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!isguestuser()) {
|
||||
// For the guests agreement in stored in session only, for other users - in DB.
|
||||
$DB->set_field('user', 'policyagreed', 1, array('id' => $USER->id));
|
||||
// Find all compulsory policies and mark them as accepted.
|
||||
$compulsory = [];
|
||||
foreach (api::list_current_versions(policy_version::AUDIENCE_LOGGEDIN) as $policyversion) {
|
||||
if ($policyversion->optional == policy_version::AGREEMENT_COMPULSORY) {
|
||||
$compulsory[] = $policyversion->id;
|
||||
}
|
||||
}
|
||||
|
||||
if ($compulsory) {
|
||||
api::accept_policies($compulsory);
|
||||
}
|
||||
|
||||
// Mark policies as agreed.
|
||||
$DB->set_field('user', 'policyagreed', 1, array('id' => $USER->id));
|
||||
$USER->policyagreed = 1;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -110,7 +121,7 @@ class handler extends \core_privacy\local\sitepolicy\handler {
|
||||
public static function signup_form($mform) {
|
||||
if (static::is_defined()) {
|
||||
// This plugin displays policies to the user who is signing up before the signup form is shown.
|
||||
// By the time user has access to signup form they have already agreed to the policies.
|
||||
// By the time user has access to signup form they have already agreed to all compulsory policies.
|
||||
$mform->addElement('hidden', 'policyagreed', 1);
|
||||
$mform->setType('policyagreed', PARAM_INT);
|
||||
}
|
||||
|
88
admin/tool/policy/classes/test/helper.php
Normal file
@ -0,0 +1,88 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Provides the {@link \tool_policy\test\helper} class.
|
||||
*
|
||||
* @package tool_policy
|
||||
* @category test
|
||||
* @copyright 2018 David Mudrák <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
namespace tool_policy\test;
|
||||
|
||||
use tool_policy\api;
|
||||
use tool_policy\policy_version;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
/**
|
||||
* Provides some helper methods for unit-tests.
|
||||
*
|
||||
* @copyright 2018 David Mudrák <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class helper {
|
||||
|
||||
/**
|
||||
* Helper method that creates a new policy for testing
|
||||
*
|
||||
* @param array $params
|
||||
* @return policy_version
|
||||
*/
|
||||
public static function add_policy($params = []) {
|
||||
static $counter = 0;
|
||||
$counter++;
|
||||
|
||||
$defaults = [
|
||||
'name' => 'Policy '.$counter,
|
||||
'summary_editor' => ['text' => "P$counter summary", 'format' => FORMAT_HTML, 'itemid' => 0],
|
||||
'content_editor' => ['text' => "P$counter content", 'format' => FORMAT_HTML, 'itemid' => 0],
|
||||
];
|
||||
|
||||
$params = (array)$params + $defaults;
|
||||
$formdata = api::form_policydoc_data(new policy_version(0));
|
||||
foreach ($params as $key => $value) {
|
||||
$formdata->$key = $value;
|
||||
}
|
||||
return api::form_policydoc_add($formdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that prepare a policy document with some versions.
|
||||
*
|
||||
* @param int $numversions The number of policy versions to create.
|
||||
* @return array Array with all the policy versions created.
|
||||
*/
|
||||
public static function create_versions($numversions = 2) {
|
||||
// Prepare a policy document with some versions.
|
||||
$policy = self::add_policy([
|
||||
'name' => 'Test policy',
|
||||
'revision' => 'v1',
|
||||
]);
|
||||
|
||||
for ($i = 2; $i <= $numversions; $i++) {
|
||||
$formdata = api::form_policydoc_data($policy);
|
||||
$formdata->revision = 'v'.$i;
|
||||
api::form_policydoc_update_new($formdata);
|
||||
}
|
||||
|
||||
$list = api::list_policies($policy->get('policyid'));
|
||||
|
||||
return $list[0]->draftversions;
|
||||
}
|
||||
}
|
32
admin/tool/policy/db/caches.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?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/>.
|
||||
|
||||
/**
|
||||
* Defined caches used internally by the plugin.
|
||||
*
|
||||
* @package tool_policy
|
||||
* @category cache
|
||||
* @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();
|
||||
|
||||
$definitions = [
|
||||
'policy_optional' => [
|
||||
'mode' => cache_store::MODE_REQUEST,
|
||||
],
|
||||
];
|
@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<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."
|
||||
<XMLDB PATH="admin/tool/policy/db" VERSION="20180918" 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"
|
||||
>
|
||||
@ -27,6 +27,7 @@
|
||||
<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="optional" TYPE="int" LENGTH="3" NOTNULL="true" DEFAULT="0" SEQUENCE="false" COMMENT="0 - the policy must be accepted to use the site, 1 - accepting the policy is optional"/>
|
||||
<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"/>
|
||||
|
@ -48,6 +48,17 @@ function xmldb_tool_policy_upgrade($oldversion) {
|
||||
upgrade_plugin_savepoint(true, 2018082900, 'tool', 'policy');
|
||||
}
|
||||
|
||||
if ($oldversion < 2018091800) {
|
||||
// Add field "optional" to the table "tool_policy_versions".
|
||||
$table = new xmldb_table('tool_policy_versions');
|
||||
$field = new xmldb_field('optional', XMLDB_TYPE_INTEGER, '3', null, XMLDB_NOTNULL, null, '0', 'agreementstyle');
|
||||
|
||||
if (!$dbman->field_exists($table, $field)) {
|
||||
$dbman->add_field($table, $field);
|
||||
}
|
||||
|
||||
upgrade_plugin_savepoint(true, 2018091800, 'tool', 'policy');
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
*
|
||||
* Script parameters:
|
||||
* 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.
|
||||
* statusXX=<int> Acceptance status to be set for the policy version with id XX.
|
||||
* behalfid=<id> The user id to view the policy version as (such as child's id).
|
||||
*
|
||||
* @package tool_policy
|
||||
@ -39,35 +39,50 @@ require(__DIR__.'/../../../config.php');
|
||||
$submit = optional_param('submit', null, PARAM_NOTAGS);
|
||||
$cancel = optional_param('cancel', null, PARAM_NOTAGS);
|
||||
$listdocs = optional_param_array('listdoc', [], PARAM_INT);
|
||||
$agreedocs = optional_param_array('agreedoc', [], PARAM_INT);
|
||||
$behalfid = optional_param('userid', null, PARAM_INT);
|
||||
|
||||
$agreedocs = [];
|
||||
$declinedocs = [];
|
||||
|
||||
foreach ($listdocs as $pvid) {
|
||||
$status = optional_param('status'.$pvid, null, PARAM_INT);
|
||||
if ($status === 1) {
|
||||
$agreedocs[] = $pvid;
|
||||
} else if ($status === 0) {
|
||||
$declinedocs[] = $pvid;
|
||||
}
|
||||
}
|
||||
|
||||
$listdocs = array_values(array_unique($listdocs));
|
||||
$agreedocs = array_values(array_unique($agreedocs));
|
||||
$declinedocs = array_values(array_unique($declinedocs));
|
||||
|
||||
$PAGE->set_context(context_system::instance());
|
||||
$PAGE->set_pagelayout('standard');
|
||||
$PAGE->set_url('/admin/tool/policy/index.php');
|
||||
$PAGE->set_popup_notification_allowed(false);
|
||||
|
||||
if (array_diff($agreedocs, $listdocs)) {
|
||||
if (array_diff($agreedocs, $listdocs) || array_diff($declinedocs, $listdocs)) {
|
||||
throw new moodle_exception('invalidaccessparameter');
|
||||
}
|
||||
|
||||
if (isloggedin() && !isguestuser()) {
|
||||
// Existing user.
|
||||
$haspermissionagreedocs = api::can_accept_policies($behalfid);
|
||||
$haspermissionagreedocs = api::can_accept_policies($listdocs, $behalfid);
|
||||
} else {
|
||||
// New user.
|
||||
$haspermissionagreedocs = true;
|
||||
}
|
||||
|
||||
if (!$haspermissionagreedocs) {
|
||||
$outputpage = new \tool_policy\output\page_nopermission($behalfid);
|
||||
$outputpage = new \tool_policy\output\page_nopermission($listdocs, $behalfid);
|
||||
} else if ($cancel) {
|
||||
redirect(new moodle_url('/'));
|
||||
} else {
|
||||
if (!$behalfid && \core\session\manager::is_loggedinas()) {
|
||||
$behalfid = $USER->id;
|
||||
}
|
||||
$outputpage = new \tool_policy\output\page_agreedocs($listdocs, $agreedocs, $behalfid, $submit);
|
||||
$outputpage = new \tool_policy\output\page_agreedocs($listdocs, $agreedocs, $declinedocs, $behalfid, $submit);
|
||||
}
|
||||
|
||||
$output = $PAGE->get_renderer('tool_policy');
|
||||
|
@ -26,40 +26,36 @@
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$string['acceptanceacknowledgement'] = 'I acknowledge that I have received a request to give consent on behalf of the above user(s).';
|
||||
$string['acceptancecount'] = '{$a->agreedcount} of {$a->policiescount}';
|
||||
$string['acceptancenote'] = 'Remarks';
|
||||
$string['acceptancepolicies'] = 'Policies';
|
||||
$string['acceptancessavedsucessfully'] = 'The agreements have been saved successfully.';
|
||||
$string['acceptancestatusaccepted'] = 'Accepted';
|
||||
$string['acceptancestatusacceptedbehalf'] = 'Accepted on user\'s behalf';
|
||||
$string['acceptancestatusdeclined'] = 'Declined';
|
||||
$string['acceptancestatusdeclinedbehalf'] = 'Declined on user\'s behalf';
|
||||
$string['acceptancestatusoverall'] = 'Overall';
|
||||
$string['acceptancestatuspartial'] = 'Partially accepted';
|
||||
$string['acceptancestatuspending'] = 'Pending';
|
||||
$string['acceptanceusers'] = 'Users';
|
||||
$string['actions'] = 'Actions';
|
||||
$string['activate'] = 'Set status to "Active"';
|
||||
$string['activating'] = 'Activating a policy';
|
||||
$string['activateconfirm'] = '<p>You are about to activate policy <em>\'{$a->name}\'</em> and make the version <em>\'{$a->revision}\'</em> the current one.</p><p>All users will be required to agree to this new policy version to be able to use the site.</p>';
|
||||
$string['activateconfirmyes'] = 'Activate';
|
||||
$string['agreed'] = 'Agreed';
|
||||
$string['agreedby'] = 'Agreed by';
|
||||
$string['agreedno'] = 'Consent not given';
|
||||
$string['agreednowithlink'] = 'Consent not given; click to give consent on behalf of user for {$a}';
|
||||
$string['agreednowithlinkall'] = 'Consent not given; click to give consent on behalf of user for all policies';
|
||||
$string['agreedon'] = 'Agreed on';
|
||||
$string['agreedyes'] = 'Agreed';
|
||||
$string['agreedyesonbehalf'] = 'Consent given on behalf of user';
|
||||
$string['agreedyesonbehalfwithlink'] = 'Consent given on behalf of user; click to withdraw user consent for {$a}';
|
||||
$string['agreedyesonbehalfwithlinkall'] = 'Consent given on behalf of user; click to withdraw user consent for all policies';
|
||||
$string['agreedyeswithlink'] = 'Consent given; click to withdraw user consent for {$a}';
|
||||
$string['agreedyeswithlinkall'] = 'Consent given; click to withdraw user consent for all policies';
|
||||
$string['agreepolicies'] = 'Please agree to the following policies';
|
||||
$string['backtoprevious'] = 'Go back to previous page';
|
||||
$string['backtotop'] = 'Back to top';
|
||||
$string['cachedef_policy_optional'] = 'Cache of the optional/compulsory flag for policy versions';
|
||||
$string['consentbulk'] = 'Consent';
|
||||
$string['consentdetails'] = 'Give consent on behalf of user(s)';
|
||||
$string['consentpagetitle'] = 'Consent';
|
||||
$string['contactdpo'] = 'For any questions about the policies please contact the privacy officer.';
|
||||
$string['dataproc'] = 'Personal data processing';
|
||||
$string['declineacknowledgement'] = 'I acknowledge that I have received a request to decline consent on behalf of the above user(s).';
|
||||
$string['declinethepolicy'] = 'Decline user consent';
|
||||
$string['deleting'] = 'Deleting a version';
|
||||
$string['deleteconfirm'] = '<p>Are you sure you want to delete policy <em>\'{$a->name}\'</em>?</p><p>This operation can not be undone.</p>';
|
||||
$string['editingpolicydocument'] = 'Editing policy';
|
||||
$string['errorpolicyversioncompulsory'] = 'Compulsory policies cannot be declined!';
|
||||
$string['errorpolicyversionnotfound'] = 'There isn\'t any policy version with this identifier.';
|
||||
$string['errorsaveasdraft'] = 'Minor change can not be saved as draft';
|
||||
$string['errorusercantviewpolicyversion'] = 'The user doesn\'t have access to this policy version.';
|
||||
@ -71,13 +67,15 @@ $string['filterrevision'] = 'Version: {$a}';
|
||||
$string['filterrevisionstatus'] = 'Version: {$a->name} ({$a->status})';
|
||||
$string['filterrole'] = 'Role: {$a}';
|
||||
$string['filters'] = 'Filters';
|
||||
$string['filterstatusno'] = 'Status: Not agreed';
|
||||
$string['filterstatusdeclined'] = 'Status: Declined';
|
||||
$string['filterstatuspending'] = 'Status: Pending';
|
||||
$string['filterstatusyes'] = 'Status: Agreed';
|
||||
$string['filterplaceholder'] = 'Search keyword or select filter';
|
||||
$string['filterpolicy'] = 'Policy: {$a}';
|
||||
$string['guestconsent:continue'] = 'Continue';
|
||||
$string['guestconsentmessage'] = 'If you continue browsing this website, you agree to our policies:';
|
||||
$string['iagree'] = 'I agree to the {$a}';
|
||||
$string['idontagree'] = 'No thanks, I decline {$a}';
|
||||
$string['iagreetothepolicy'] = 'Give consent';
|
||||
$string['inactivate'] = 'Set status to "Inactive"';
|
||||
$string['inactivating'] = 'Inactivating a policy';
|
||||
@ -91,7 +89,7 @@ $string['minorchangeinfo'] = 'A minor change does not alter the meaning of the p
|
||||
$string['managepolicies'] = 'Manage policies';
|
||||
$string['movedown'] = 'Move down';
|
||||
$string['moveup'] = 'Move up';
|
||||
$string['mustagreetocontinue'] = 'Before continuing you must agree to all these policies.';
|
||||
$string['mustagreetocontinue'] = 'Before continuing you need to acknowledge all these policies.';
|
||||
$string['newpolicy'] = 'New policy';
|
||||
$string['newversion'] = 'New version';
|
||||
$string['noactivepolicies'] = 'There are no policies with an active version.';
|
||||
@ -119,6 +117,9 @@ $string['policydoccontent'] = 'Full policy';
|
||||
$string['policydochdrpolicy'] = 'Policy';
|
||||
$string['policydochdrversion'] = 'Document version';
|
||||
$string['policydocname'] = 'Name';
|
||||
$string['policydocoptional'] = 'Agreement optional';
|
||||
$string['policydocoptionalyes'] = 'Optional';
|
||||
$string['policydocoptionalno'] = 'Compulsory';
|
||||
$string['policydocrevision'] = 'Version';
|
||||
$string['policydocsummary'] = 'Summary';
|
||||
$string['policydocsummary_help'] = 'This text should provide a summary of the policy, potentially in a simplified and easily accessible form, using clear and plain language.';
|
||||
@ -160,18 +161,33 @@ $string['privacy:metadata:versions:contentformat'] = 'The format of the content
|
||||
$string['privacysettings'] = 'Privacy settings';
|
||||
$string['readpolicy'] = 'Please read our {$a}';
|
||||
$string['refertofullpolicytext'] = 'Please refer to the full {$a} if you would like to review the text.';
|
||||
$string['response'] = 'Response';
|
||||
$string['responseby'] = 'Respondent';
|
||||
$string['responseon'] = 'Date';
|
||||
$string['revokeacknowledgement'] = 'I acknowledge that I have received a request to withdraw consent on behalf of the above user(s).';
|
||||
$string['revokedetails'] = 'Withdraw user consent';
|
||||
$string['save'] = 'Save';
|
||||
$string['saveasdraft'] = 'Save as draft';
|
||||
$string['selectuser'] = 'Select user {$a}';
|
||||
$string['selectusersforconsent'] = 'Select users to give consent on behalf of';
|
||||
$string['selectusersforconsent'] = 'Select users to give consent on behalf of.';
|
||||
$string['settodraft'] = 'Create a new draft';
|
||||
$string['status'] = 'Policy status';
|
||||
$string['statusformtitleaccept'] = 'Accepting policy';
|
||||
$string['statusformtitledecline'] = 'Declining policy';
|
||||
$string['statusformtitlerevoke'] = 'Withdrawing policy';
|
||||
$string['statusinfo'] = 'A policy with \'Active\' status requires users to give their consent, either when they first log in, or in the case of existing users when they next log in.';
|
||||
$string['status0'] = 'Draft';
|
||||
$string['status1'] = 'Active';
|
||||
$string['status2'] = 'Inactive';
|
||||
$string['useracceptanceactionaccept'] = 'Accept';
|
||||
$string['useracceptanceactionacceptone'] = 'Accept {$a}';
|
||||
$string['useracceptanceactionacceptpending'] = 'Accept pending policies';
|
||||
$string['useracceptanceactiondecline'] = 'Decline';
|
||||
$string['useracceptanceactiondeclineone'] = 'Decline {$a}';
|
||||
$string['useracceptanceactiondeclinepending'] = 'Decline pending policies';
|
||||
$string['useracceptanceactiondetails'] = 'Details';
|
||||
$string['useracceptanceactionrevoke'] = 'Withdraw';
|
||||
$string['useracceptanceactionrevokeall'] = 'Withdraw accepted policies';
|
||||
$string['useracceptanceactionrevokeone'] = 'Withdraw acceptance of {$a}';
|
||||
$string['useracceptancecount'] = '{$a->agreedcount} of {$a->userscount} ({$a->percent}%)';
|
||||
$string['useracceptancecountna'] = 'N/A';
|
||||
$string['useracceptances'] = 'User agreements';
|
||||
|
@ -204,9 +204,10 @@ function tool_policy_pluginfile($course, $cm, $context, $filearea, $args, $force
|
||||
*/
|
||||
function tool_policy_get_fontawesome_icon_map() {
|
||||
return [
|
||||
'tool_policy:agreedno' => 'fa-times text-danger',
|
||||
'tool_policy:agreedyes' => 'fa-check text-success',
|
||||
'tool_policy:agreedyesonbehalf' => 'fa-check text-info',
|
||||
'tool_policy:agreed' => 'fa-check text-success',
|
||||
'tool_policy:declined' => 'fa-times text-danger',
|
||||
'tool_policy:pending' => 'fa-clock-o text-warning',
|
||||
'tool_policy:partial' => 'fa-exclamation-triangle text-warning',
|
||||
'tool_policy:level' => 'fa-level-up fa-rotate-90 text-muted',
|
||||
];
|
||||
}
|
||||
|
Before Width: | Height: | Size: 234 B After Width: | Height: | Size: 234 B |
Before Width: | Height: | Size: 445 B After Width: | Height: | Size: 445 B |
Before Width: | Height: | Size: 234 B |
@ -1,3 +0,0 @@
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
|
||||
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
|
||||
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-0.1 0 16 16" preserveAspectRatio="xMinYMid meet" overflow="visible"><path d="M6.4 11.1c-2-2.5-3.7-4-3.7-4L0 9.8C5 13.1 8.1 16 8.1 16s.2-.7.6-1.8c.9-2.7 3.2-8.1 7.1-14.2-4.6 3.7-7.7 8.2-9.4 11.1z" fill="#FFB844"/></svg>
|
Before Width: | Height: | Size: 448 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 517 B After Width: | Height: | Size: 517 B |
BIN
admin/tool/policy/pix/partial.png
Normal file
After Width: | Height: | Size: 530 B |
61
admin/tool/policy/pix/partial.svg
Normal file
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
preserveAspectRatio="xMinYMid meet"
|
||||
overflow="visible"
|
||||
version="1.1"
|
||||
id="svg956"
|
||||
sodipodi:docname="warning.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06"
|
||||
inkscape:export-filename="/home/mudrd8mz/www/html/mdk/m36/admin/tool/policy/pix/warning.png"
|
||||
inkscape:export-xdpi="96"
|
||||
inkscape:export-ydpi="96">
|
||||
<metadata
|
||||
id="metadata962">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs960" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1624"
|
||||
inkscape:window-height="911"
|
||||
id="namedview958"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-0.06779661"
|
||||
inkscape:cy="7.3559322"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg956" />
|
||||
<path
|
||||
d="M7 .7L.2 14.1c-.5 1 0 1.8 1.1 1.8h13.2c1.1 0 1.6-.8 1.1-1.8L8.8.7C8.3-.2 7.5-.2 7 .7zm2.4 12.7c0 .8-.7 1.5-1.5 1.5s-1.5-.7-1.5-1.5.7-1.5 1.5-1.5 1.5.6 1.5 1.5zm-.2-7.5v4c0 .5-.5 1-1 1h-.6c-.5 0-1-.5-1-1v-4c0-.6.5-1 1-1h.6c.6 0 1 .4 1 1z"
|
||||
fill="#999"
|
||||
id="path954"
|
||||
style="fill:#ffb844;fill-opacity:1" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.0 KiB |
BIN
admin/tool/policy/pix/pending.png
Normal file
After Width: | Height: | Size: 594 B |
58
admin/tool/policy/pix/pending.svg
Normal file
@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 16 16"
|
||||
preserveAspectRatio="xMinYMid meet"
|
||||
overflow="visible"
|
||||
version="1.1"
|
||||
id="svg5917"
|
||||
sodipodi:docname="agreedpending.svg"
|
||||
inkscape:version="0.92.2 5c3e80d, 2017-08-06">
|
||||
<metadata
|
||||
id="metadata5923">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<defs
|
||||
id="defs5921" />
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1026"
|
||||
id="namedview5919"
|
||||
showgrid="false"
|
||||
inkscape:zoom="14.75"
|
||||
inkscape:cx="-0.06779661"
|
||||
inkscape:cy="7.3559322"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="25"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg5917" />
|
||||
<path
|
||||
d="M8 0C3.6 0 0 3.6 0 8s3.6 8 8 8 8-3.6 8-8-3.6-8-8-8zm0 14c-3.3 0-6-2.7-6-6s2.7-6 6-6 6 2.7 6 6-2.7 6-6 6zm4-6c0 .6-.4 1-1 1H8c-.6 0-1-.4-1-1V4c0-.6.4-1 1-1s1 .4 1 1v3h2c.6 0 1 .4 1 1z"
|
||||
fill="#999"
|
||||
id="path5915"
|
||||
style="fill:#ffb844;fill-opacity:1" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.8 KiB |
@ -43,6 +43,8 @@
|
||||
"revision": "2.0",
|
||||
"hasarchived": true,
|
||||
"timeaccepted": "1 Mar 2018",
|
||||
"iscurrent": true,
|
||||
"isoptional": false,
|
||||
"agreement": {
|
||||
"onbehalf": false,
|
||||
"status": false,
|
||||
@ -60,6 +62,8 @@
|
||||
"note": "Based on parent's agreement via email",
|
||||
"hasarchived": false,
|
||||
"timeaccepted": "15 Feb 2018",
|
||||
"iscurrent": true,
|
||||
"isoptional": false,
|
||||
"agreement": {
|
||||
"onbehalf": true,
|
||||
"status": true,
|
||||
@ -80,10 +84,10 @@
|
||||
<tr>
|
||||
<th>{{#str}} policydocname, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} policydocrevision, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} agreed, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} agreedon, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} response, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} responseon, tool_policy {{/str}}</th>
|
||||
{{#hasonbehalfagreements}}
|
||||
<th>{{#str}} agreedby, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} responseby, tool_policy {{/str}}</th>
|
||||
<th>{{#str}} acceptancenote, tool_policy {{/str}}</th>
|
||||
{{/hasonbehalfagreements}}
|
||||
<th></th>
|
||||
@ -106,7 +110,8 @@
|
||||
</td>
|
||||
<td>
|
||||
<a href="{{viewurl}}">{{{revision}}}</a>
|
||||
{{#iscurrent}}<span class="label label-success">{{#str}} status1, tool_policy {{/str}}{{/iscurrent}}
|
||||
{{#iscurrent}}<span class="label label-success">{{#str}} status1, tool_policy {{/str}}</span>{{/iscurrent}}
|
||||
{{#isoptional}}<span class="label label-info">{{#str}} policydocoptionalyes, tool_policy {{/str}}</span>{{/isoptional}}
|
||||
</td>
|
||||
<td>
|
||||
{{>tool_policy/user_agreement}}
|
||||
|
@ -80,6 +80,8 @@
|
||||
|
||||
{{#policies}}
|
||||
|
||||
<input value="{{id}}" name="listdoc[]" type="hidden">
|
||||
|
||||
<div class="agreedoc-policy clearfix m-t-2 m-b-1">
|
||||
<h3>{{{name}}}</h3>
|
||||
<div class="agreedoc-content">
|
||||
@ -90,11 +92,27 @@
|
||||
{{# str }}refertofullpolicytext, tool_policy, {{{policymodal}}} {{/ str }}
|
||||
</div>
|
||||
<div class="agreedoc-form m-t-1">
|
||||
{{#optional}}
|
||||
<div class="agreedoc-radios">
|
||||
<div class="agreedoc-radios-1">
|
||||
<label>
|
||||
<input type="radio" name="status{{id}}" value="1" {{#versionagreed}}checked="{{.}}"{{/versionagreed}}>
|
||||
{{# str }}iagree, tool_policy, {{{name}}} {{/ str }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="agreedoc-radios-0">
|
||||
<label>
|
||||
<input type="radio" name="status{{id}}" value="0" {{#versiondeclined}}checked="{{.}}"{{/versiondeclined}}>
|
||||
{{# str }}idontagree, tool_policy, {{{name}}} {{/ str }}
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
{{/optional}}
|
||||
{{^optional}}
|
||||
<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>
|
||||
<input value="1" name="status{{id}}" {{#versionagreed}}checked="{{.}}"{{/versionagreed}} type="checkbox">
|
||||
{{# str }}iagree, tool_policy, {{{name}}} {{/ str }}
|
||||
<i class="icon fa fa-exclamation-circle text-danger fa-fw" title="{{# str }} required {{/ str }}" ></i>
|
||||
</label>
|
||||
</div>
|
||||
@ -106,6 +124,7 @@
|
||||
<li><small>{{{.}}}</small></li>
|
||||
{{/versionbehalfsagreed}}
|
||||
</ul>
|
||||
{{/optional}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -45,6 +45,7 @@
|
||||
"typetext": "Site policy",
|
||||
"audiencetext": "All users",
|
||||
"statustext": "Active",
|
||||
"optionaltext": "Optional",
|
||||
"revision": "1.0",
|
||||
"timemodified": 1521531208,
|
||||
"acceptancescounturl": "#",
|
||||
@ -56,6 +57,7 @@
|
||||
"typetext": "Site policy",
|
||||
"audiencetext": "All users",
|
||||
"statustext": "Draft",
|
||||
"optionaltext": "Compulsory",
|
||||
"revision": "2.0",
|
||||
"timemodified": 1521531208,
|
||||
"acceptancescounttext": "N/A"
|
||||
@ -85,7 +87,6 @@
|
||||
<th scope="col">{{#str}} policydocname, tool_policy {{/str}}</th>
|
||||
<th scope="col">{{#str}} status, tool_policy {{/str}}</th>
|
||||
<th scope="col">{{#str}} policydocrevision, tool_policy {{/str}}</th>
|
||||
<th scope="col">{{#str}} lastmodified, core {{/str}}</th>
|
||||
{{#canviewacceptances}}
|
||||
<th scope="col">{{#str}} usersaccepted, tool_policy {{/str}}</th>
|
||||
{{/canviewacceptances}}
|
||||
@ -105,7 +106,7 @@
|
||||
{{/indented}}
|
||||
<div {{#indented}}style="margin-left: 24px" {{/indented}}>
|
||||
<div>{{{name}}}</div>
|
||||
<div class="text-muted, muted"><small>{{{typetext}}}, {{{audiencetext}}}</small></div>
|
||||
<div class="text-muted, muted"><small>{{{typetext}}}, {{{audiencetext}}}, {{{optionaltext}}}</small></div>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
@ -113,9 +114,13 @@
|
||||
</td>
|
||||
<td>
|
||||
{{revision}}
|
||||
</td>
|
||||
<td>
|
||||
{{#userdate}} {{timemodified}}, {{#str}} strftimedatetime, core_langconfig {{/str}} {{/userdate}}
|
||||
<div class="text-muted, muted">
|
||||
<small>
|
||||
<time title="{{#str}} lastmodified, core {{/str}}" datetime="{{#userdate}} {{timemodified}}, %Y-%m-%dT%T%z {{/userdate}}">
|
||||
{{#userdate}} {{timemodified}}, {{#str}} strftimedatetime, core_langconfig {{/str}} {{/userdate}}
|
||||
</time>
|
||||
</small>
|
||||
</div>
|
||||
</td>
|
||||
{{#canviewacceptances}}
|
||||
<td>
|
||||
|
@ -92,6 +92,9 @@
|
||||
{{#accepturl}}
|
||||
<a role="button" href="{{accepturl}}" class="btn btn-primary">{{#str}} iagree, tool_policy, {{{policy.name}}} {{/str}}</a>
|
||||
{{/accepturl}}
|
||||
{{#declineurl}}
|
||||
<a role="button" href="{{declineurl}}" class="btn btn-link">{{#str}} idontagree, tool_policy, {{{policy.name}}} {{/str}}</a>
|
||||
{{/declineurl}}
|
||||
|
||||
<div class="pull-right">
|
||||
<a href="#top">
|
||||
|
@ -26,67 +26,30 @@
|
||||
-
|
||||
|
||||
Context variables required for this template:
|
||||
* status
|
||||
* onbehalf
|
||||
* canaccept
|
||||
* acceptlink
|
||||
* statusicon
|
||||
* statustext
|
||||
* actions
|
||||
- url
|
||||
- data
|
||||
- text
|
||||
- title
|
||||
|
||||
Example context (json):
|
||||
{
|
||||
"status": false,
|
||||
"onbehalf": false,
|
||||
"canaccept": true,
|
||||
"canrevoke": true,
|
||||
"acceptlink": "/",
|
||||
"revokelink": "/",
|
||||
"singleversion": false,
|
||||
"versionname": ""
|
||||
"statusicon": "accepted",
|
||||
"statustext": "Accepted",
|
||||
"actions": {
|
||||
"url": "/admin/tool/policy/accept.php?param=value",
|
||||
"data": "acceptmodal",
|
||||
"text": "Withdraw",
|
||||
"title": "Withdraw acceptance of Site policy"
|
||||
}
|
||||
}
|
||||
}}
|
||||
{{#status}}
|
||||
{{#canrevoke}}
|
||||
{{#singleversion}}
|
||||
{{#onbehalf}}
|
||||
<a href="{{revokelink}}" data-action="acceptmodal">{{#pix}}agreedyesonbehalf, tool_policy,
|
||||
{{#str}} agreedyesonbehalfwithlink, tool_policy, {{{versionname}}} {{/str}}{{/pix}}</a>
|
||||
{{/onbehalf}}
|
||||
{{^onbehalf}}
|
||||
<a href="{{revokelink}}" data-action="acceptmodal">{{#pix}}agreedyes, tool_policy,
|
||||
{{#str}} agreedyeswithlink, tool_policy, {{{versionname}}} {{/str}}{{/pix}}</a>
|
||||
{{/onbehalf}}
|
||||
{{/singleversion}}
|
||||
{{^singleversion}}
|
||||
{{#onbehalf}}
|
||||
<a href="{{revokelink}}" data-action="acceptmodal">{{#pix}}agreedyesonbehalf, tool_policy,
|
||||
{{#str}} agreedyesonbehalfwithlinkall, tool_policy {{/str}}{{/pix}}</a>
|
||||
{{/onbehalf}}
|
||||
{{^onbehalf}}
|
||||
<a href="{{revokelink}}" data-action="acceptmodal">{{#pix}}agreedyes, tool_policy,
|
||||
{{#str}} agreedyeswithlinkall, tool_policy {{/str}}{{/pix}}</a>
|
||||
{{/onbehalf}}
|
||||
{{/singleversion}}
|
||||
{{/canrevoke}}
|
||||
|
||||
{{^canrevoke}}
|
||||
{{#onbehalf}}
|
||||
<span>{{#pix}}agreedyesonbehalf, tool_policy, {{#str}} agreedyesonbehalf, tool_policy {{/str}}{{/pix}}</span>
|
||||
{{/onbehalf}}
|
||||
{{^onbehalf}}
|
||||
<span>{{#pix}}agreedyes, tool_policy, {{#str}} agreedyes, tool_policy {{/str}}{{/pix}}</span>
|
||||
{{/onbehalf}}
|
||||
{{/canrevoke}}
|
||||
{{/status}}
|
||||
|
||||
{{^status}}
|
||||
{{#canaccept}}
|
||||
{{#singleversion}}
|
||||
<a href="{{acceptlink}}" data-action="acceptmodal">{{#pix}}agreedno, tool_policy, {{#str}} agreednowithlink, tool_policy, {{{versionname}}} {{/str}}{{/pix}}</a>
|
||||
{{/singleversion}}
|
||||
{{^singleversion}}
|
||||
<a href="{{acceptlink}}" data-action="acceptmodal">{{#pix}}agreedno, tool_policy, {{#str}} agreednowithlinkall, tool_policy {{/str}}{{/pix}}</a>
|
||||
{{/singleversion}}
|
||||
{{/canaccept}}
|
||||
{{^canaccept}}
|
||||
<span>{{#pix}}agreedno, tool_policy, {{#str}} agreedno, tool_policy {{/str}}{{/pix}}</span>
|
||||
{{/canaccept}}
|
||||
{{/status}}
|
||||
<span class="tool_policy-user_agreement-icon">{{#pix}} {{statusicon}}, tool_policy{{/pix}}</span>
|
||||
<span class="tool_policy-user_agreement-status">{{statustext}}</span>
|
||||
<span class="tool_policy-user_agreement-actions">
|
||||
{{#actions}}
|
||||
<a href="{{url}}" title="{{title}}" data-action="{{data}}"><small>{{text}}</small></a>
|
||||
{{/actions}}
|
||||
</span>
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
use tool_policy\api;
|
||||
use tool_policy\policy_version;
|
||||
use tool_policy\test\helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
@ -207,9 +208,9 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$policy1 = $this->add_policy(['audience' => policy_version::AUDIENCE_LOGGEDIN]);
|
||||
$policy2 = $this->add_policy(['audience' => policy_version::AUDIENCE_GUESTS]);
|
||||
$policy3 = $this->add_policy();
|
||||
$policy1 = helper::add_policy(['audience' => policy_version::AUDIENCE_LOGGEDIN]);
|
||||
$policy2 = helper::add_policy(['audience' => policy_version::AUDIENCE_GUESTS]);
|
||||
$policy3 = helper::add_policy();
|
||||
|
||||
api::make_current($policy1->get('id'));
|
||||
api::make_current($policy2->get('id'));
|
||||
@ -242,54 +243,6 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$policy3->get('policyid') => $policy3->get('id')], $ids);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that creates a new policy for testing
|
||||
*
|
||||
* @param array $params
|
||||
* @return policy_version
|
||||
*/
|
||||
protected function add_policy($params = []) {
|
||||
static $counter = 0;
|
||||
$counter++;
|
||||
|
||||
$defaults = [
|
||||
'name' => 'Policy '.$counter,
|
||||
'summary_editor' => ['text' => "P$counter summary", 'format' => FORMAT_HTML, 'itemid' => 0],
|
||||
'content_editor' => ['text' => "P$counter content", 'format' => FORMAT_HTML, 'itemid' => 0],
|
||||
];
|
||||
|
||||
$params = (array)$params + $defaults;
|
||||
$formdata = api::form_policydoc_data(new policy_version(0));
|
||||
foreach ($params as $key => $value) {
|
||||
$formdata->$key = $value;
|
||||
}
|
||||
return api::form_policydoc_add($formdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that prepare a policy document with some versions.
|
||||
*
|
||||
* @param int $numversions The number of policy versions to create.
|
||||
* @return array Array with all the policy versions created.
|
||||
*/
|
||||
protected function create_versions($numversions = 2) {
|
||||
// Prepare a policy document with some versions.
|
||||
$policy = self::add_policy([
|
||||
'name' => 'Test policy',
|
||||
'revision' => 'v1',
|
||||
]);
|
||||
|
||||
for ($i = 2; $i <= $numversions; $i++) {
|
||||
$formdata = api::form_policydoc_data($policy);
|
||||
$formdata->revision = 'v'.$i;
|
||||
api::form_policydoc_update_new($formdata);
|
||||
}
|
||||
|
||||
$list = api::list_policies($policy->get('policyid'));
|
||||
|
||||
return $list[0]->draftversions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link api::can_user_view_policy_version()} method.
|
||||
*/
|
||||
@ -326,7 +279,7 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
// Prepare a policy document with some versions.
|
||||
list($policy1, $policy2, $policy3) = $this->create_versions(3);
|
||||
list($policy1, $policy2, $policy3) = helper::create_versions(3);
|
||||
|
||||
// Normally users do not have access to policy drafts.
|
||||
$this->assertFalse(api::can_user_view_policy_version($policy1, null, $child->id));
|
||||
@ -368,6 +321,164 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$this->assertTrue(api::can_user_view_policy_version($policy3, null, $parent->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link api::can_accept_policies()} method.
|
||||
*/
|
||||
public function test_can_accept_policies() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$child = $this->getDataGenerator()->create_user();
|
||||
$parent = $this->getDataGenerator()->create_user();
|
||||
$officer = $this->getDataGenerator()->create_user();
|
||||
$manager = $this->getDataGenerator()->create_user();
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$childcontext = context_user::instance($child->id);
|
||||
|
||||
$roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves');
|
||||
$roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child');
|
||||
$roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents');
|
||||
$rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents');
|
||||
|
||||
assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleofficerid, $syscontext->id);
|
||||
assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id);
|
||||
assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id);
|
||||
|
||||
role_assign($roleminorid, $child->id, $syscontext->id);
|
||||
role_assign($roleparentid, $parent->id, $childcontext->id);
|
||||
role_assign($roleofficerid, $officer->id, $syscontext->id);
|
||||
role_assign($rolemanagerid, $manager->id, $syscontext->id);
|
||||
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
$policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
$policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
$policy3 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
$policy4 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
|
||||
$mixed = [$policy1->id, $policy2->id, $policy3->id, $policy4->id];
|
||||
$compulsory = [$policy1->id, $policy2->id];
|
||||
$optional = [$policy3->id, $policy4->id];
|
||||
|
||||
// Normally users can accept all policies.
|
||||
$this->setUser($user);
|
||||
$this->assertTrue(api::can_accept_policies($mixed));
|
||||
$this->assertTrue(api::can_accept_policies($compulsory));
|
||||
$this->assertTrue(api::can_accept_policies($optional));
|
||||
|
||||
// Digital minors can be set to not be able to accept policies themselves.
|
||||
$this->setUser($child);
|
||||
$this->assertFalse(api::can_accept_policies($mixed));
|
||||
$this->assertFalse(api::can_accept_policies($compulsory));
|
||||
$this->assertFalse(api::can_accept_policies($optional));
|
||||
|
||||
// The parent can accept optional policies on child's behalf.
|
||||
$this->setUser($parent);
|
||||
$this->assertTrue(api::can_accept_policies($mixed, $child->id));
|
||||
$this->assertTrue(api::can_accept_policies($compulsory, $child->id));
|
||||
$this->assertTrue(api::can_accept_policies($optional, $child->id));
|
||||
|
||||
// Officers and managers can accept on other user's behalf.
|
||||
$this->setUser($officer);
|
||||
$this->assertTrue(api::can_accept_policies($mixed, $parent->id));
|
||||
$this->assertTrue(api::can_accept_policies($compulsory, $parent->id));
|
||||
$this->assertTrue(api::can_accept_policies($optional, $parent->id));
|
||||
|
||||
$this->setUser($manager);
|
||||
$this->assertTrue(api::can_accept_policies($mixed, $parent->id));
|
||||
$this->assertTrue(api::can_accept_policies($compulsory, $parent->id));
|
||||
$this->assertTrue(api::can_accept_policies($optional, $parent->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link api::can_decline_policies()} method.
|
||||
*/
|
||||
public function test_can_decline_policies() {
|
||||
global $CFG;
|
||||
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$user = $this->getDataGenerator()->create_user();
|
||||
$child = $this->getDataGenerator()->create_user();
|
||||
$parent = $this->getDataGenerator()->create_user();
|
||||
$officer = $this->getDataGenerator()->create_user();
|
||||
$manager = $this->getDataGenerator()->create_user();
|
||||
|
||||
$syscontext = context_system::instance();
|
||||
$childcontext = context_user::instance($child->id);
|
||||
|
||||
$roleminorid = create_role('Digital minor', 'digiminor', 'Not old enough to accept site policies themselves');
|
||||
$roleparentid = create_role('Parent', 'parent', 'Can accept policies on behalf of their child');
|
||||
$roleofficerid = create_role('Policy officer', 'policyofficer', 'Can see all acceptances but can\'t edit policy documents');
|
||||
$rolemanagerid = create_role('Policy manager', 'policymanager', 'Can manage policy documents');
|
||||
|
||||
assign_capability('tool/policy:accept', CAP_PROHIBIT, $roleminorid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleparentid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $roleofficerid, $syscontext->id);
|
||||
assign_capability('tool/policy:viewacceptances', CAP_ALLOW, $roleofficerid, $syscontext->id);
|
||||
assign_capability('tool/policy:acceptbehalf', CAP_ALLOW, $rolemanagerid, $syscontext->id);
|
||||
assign_capability('tool/policy:managedocs', CAP_ALLOW, $rolemanagerid, $syscontext->id);
|
||||
|
||||
role_assign($roleminorid, $child->id, $syscontext->id);
|
||||
role_assign($roleparentid, $parent->id, $childcontext->id);
|
||||
role_assign($roleofficerid, $officer->id, $syscontext->id);
|
||||
role_assign($rolemanagerid, $manager->id, $syscontext->id);
|
||||
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
$policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
$policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
$policy3 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
$policy4 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
|
||||
$mixed = [$policy1->id, $policy2->id, $policy3->id, $policy4->id];
|
||||
$compulsory = [$policy1->id, $policy2->id];
|
||||
$optional = [$policy3->id, $policy4->id];
|
||||
|
||||
// Normally users can decline only optional policies.
|
||||
$this->setUser($user);
|
||||
$this->assertFalse(api::can_decline_policies($mixed));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory));
|
||||
$this->assertTrue(api::can_decline_policies($optional));
|
||||
|
||||
// If they can't accept them, they can't decline them too.
|
||||
$this->setUser($child);
|
||||
$this->assertFalse(api::can_decline_policies($mixed));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory));
|
||||
$this->assertFalse(api::can_decline_policies($optional));
|
||||
|
||||
// The parent can decline optional policies on child's behalf.
|
||||
$this->setUser($parent);
|
||||
$this->assertFalse(api::can_decline_policies($mixed, $child->id));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory, $child->id));
|
||||
$this->assertTrue(api::can_decline_policies($optional, $child->id));
|
||||
|
||||
// Even officers or managers cannot decline compulsory policies.
|
||||
$this->setUser($officer);
|
||||
$this->assertFalse(api::can_decline_policies($mixed));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory));
|
||||
$this->assertTrue(api::can_decline_policies($optional));
|
||||
$this->assertFalse(api::can_decline_policies($mixed, $child->id));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory, $child->id));
|
||||
$this->assertTrue(api::can_decline_policies($optional, $child->id));
|
||||
|
||||
$this->setUser($manager);
|
||||
$this->assertFalse(api::can_decline_policies($mixed));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory));
|
||||
$this->assertTrue(api::can_decline_policies($optional));
|
||||
$this->assertFalse(api::can_decline_policies($mixed, $child->id));
|
||||
$this->assertFalse(api::can_decline_policies($compulsory, $child->id));
|
||||
$this->assertTrue(api::can_decline_policies($optional, $child->id));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link api::can_revoke_policies()} method.
|
||||
*/
|
||||
@ -406,32 +517,48 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
|
||||
accesslib_clear_all_caches_for_unit_testing();
|
||||
|
||||
// Prepare a policy document with some versions.
|
||||
list($policy1, $policy2, $policy3) = $this->create_versions(3);
|
||||
$policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
$policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
|
||||
$versionids = [$policy1->id, $policy2->id];
|
||||
|
||||
// Guests cannot revoke anything.
|
||||
$this->setGuestUser();
|
||||
$this->assertFalse(api::can_revoke_policies($versionids));
|
||||
|
||||
// Normally users do not have access to revoke policies.
|
||||
$this->setUser($user);
|
||||
$this->assertFalse(api::can_revoke_policies($user->id));
|
||||
$this->assertFalse(api::can_revoke_policies($versionids, $user->id));
|
||||
$this->setUser($child);
|
||||
$this->assertFalse(api::can_revoke_policies($child->id));
|
||||
$this->assertFalse(api::can_revoke_policies($versionids, $child->id));
|
||||
|
||||
// The parent can revoke the policy on behalf of her child (but not her own policies).
|
||||
// Optional policies can be revoked if the user can accept them.
|
||||
$this->setUser($user);
|
||||
$this->assertTrue(api::can_revoke_policies([$policy2->id]));
|
||||
$this->assertTrue(api::can_revoke_policies([$policy2->id], $user->id));
|
||||
$this->setUser($child);
|
||||
$this->assertFalse(api::can_revoke_policies([$policy2->id]));
|
||||
$this->assertFalse(api::can_revoke_policies([$policy2->id], $child->id));
|
||||
|
||||
// The parent can revoke the policy on behalf of her child (but not her own policies, unless they are optional).
|
||||
$this->setUser($parent);
|
||||
$this->assertFalse(api::can_revoke_policies($parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($child->id));
|
||||
$this->assertFalse(api::can_revoke_policies($versionids, $parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $child->id));
|
||||
$this->assertTrue(api::can_revoke_policies([$policy2->id]));
|
||||
$this->assertTrue(api::can_revoke_policies([$policy2->id], $child->id));
|
||||
|
||||
// Officers and managers can revoke everything.
|
||||
$this->setUser($officer);
|
||||
$this->assertTrue(api::can_revoke_policies($officer->id));
|
||||
$this->assertTrue(api::can_revoke_policies($child->id));
|
||||
$this->assertTrue(api::can_revoke_policies($parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($manager->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $officer->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $child->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $manager->id));
|
||||
|
||||
$this->setUser($manager);
|
||||
$this->assertTrue(api::can_revoke_policies($manager->id));
|
||||
$this->assertTrue(api::can_revoke_policies($child->id));
|
||||
$this->assertTrue(api::can_revoke_policies($parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($officer->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $manager->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $child->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $parent->id));
|
||||
$this->assertTrue(api::can_revoke_policies($versionids, $officer->id));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -467,19 +594,26 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$policy1 = $this->add_policy()->to_record();
|
||||
$policy1 = helper::add_policy()->to_record();
|
||||
api::make_current($policy1->id);
|
||||
$policy2 = $this->add_policy()->to_record();
|
||||
$policy2 = helper::add_policy()->to_record();
|
||||
api::make_current($policy2->id);
|
||||
$policy3 = helper::add_policy(['optional' => true])->to_record();
|
||||
api::make_current($policy3->id);
|
||||
|
||||
// Accept policy on behalf of somebody else.
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
|
||||
// Accepting just compulsory policies is not enough, we want to hear explicitly about the optional one, too.
|
||||
api::accept_policies([$policy1->id, $policy2->id], $user1->id);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
|
||||
// Optional policy does not need to be accepted, but it must be answered explicitly.
|
||||
api::decline_policies([$policy3->id], $user1->id);
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
|
||||
// Now revoke.
|
||||
// Revoke previous agreement to a compulsory policy.
|
||||
api::revoke_acceptance($policy1->id, $user1->id);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
|
||||
@ -493,6 +627,12 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user2->id]));
|
||||
|
||||
api::accept_policies([$policy2->id]);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user2->id]));
|
||||
|
||||
api::decline_policies([$policy3->id]);
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user2->id]));
|
||||
|
||||
api::accept_policies([$policy3->id]);
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user2->id]));
|
||||
}
|
||||
|
||||
@ -507,14 +647,14 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
|
||||
// Introducing a new policy.
|
||||
list($policy1v1, $policy1v2) = $this->create_versions(2);
|
||||
list($policy1v1, $policy1v2) = helper::create_versions(2);
|
||||
api::make_current($policy1v1->id);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
api::accept_policies([$policy1v1->id], $user1->id);
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
|
||||
// Introducing another policy.
|
||||
$policy2v1 = $this->add_policy()->to_record();
|
||||
$policy2v1 = helper::add_policy()->to_record();
|
||||
api::make_current($policy2v1->id);
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
api::accept_policies([$policy2v1->id], $user1->id);
|
||||
@ -599,7 +739,7 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
|
||||
$CFG->sitepolicyhandler = 'tool_policy';
|
||||
|
||||
$policy = $this->add_policy()->to_record();
|
||||
$policy = helper::add_policy()->to_record();
|
||||
api::make_current($policy->id);
|
||||
|
||||
// User has not accepted any policies.
|
||||
@ -632,4 +772,44 @@ class tool_policy_api_testcase extends advanced_testcase {
|
||||
|
||||
require_login(null, false, null, false, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the three-state logic of the value returned by {@link api::is_user_version_accepted()}.
|
||||
*/
|
||||
public function test_is_user_version_accepted() {
|
||||
|
||||
$preloadedacceptances = [
|
||||
4 => (object) [
|
||||
'policyversionid' => 4,
|
||||
'mainuserid' => 13,
|
||||
'status' => 1,
|
||||
],
|
||||
6 => (object) [
|
||||
'policyversionid' => 6,
|
||||
'mainuserid' => 13,
|
||||
'status' => 0,
|
||||
],
|
||||
];
|
||||
|
||||
$this->assertTrue(api::is_user_version_accepted(13, 4, $preloadedacceptances));
|
||||
$this->assertFalse(api::is_user_version_accepted(13, 6, $preloadedacceptances));
|
||||
$this->assertNull(api::is_user_version_accepted(13, 5, $preloadedacceptances));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the functionality of {@link api::get_agreement_optional()}.
|
||||
*/
|
||||
public function test_get_agreement_optional() {
|
||||
global $DB;
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
$policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
api::make_current($policy1->id);
|
||||
$policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
api::make_current($policy2->id);
|
||||
|
||||
$this->assertEquals(api::get_agreement_optional($policy1->id), policy_version::AGREEMENT_OPTIONAL);
|
||||
$this->assertEquals(api::get_agreement_optional($policy2->id), policy_version::AGREEMENT_COMPULSORY);
|
||||
}
|
||||
}
|
||||
|
@ -41,9 +41,9 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I set the field "I agree to the This site policy" to "1"
|
||||
And I press "Next"
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And "Agreed" "icon" should exist in the "User One" "table_row"
|
||||
And "Agreed" "icon" should exist in the "Max Manager" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "User Two" "table_row"
|
||||
And "Accepted" "text" should exist in the "User One" "table_row"
|
||||
And "Accepted" "text" should exist in the "Max Manager" "table_row"
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
|
||||
Scenario: Agree on behalf of another user as a manager, single policy, javascript off
|
||||
Given I log in as "admin"
|
||||
@ -57,17 +57,17 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I press "Next"
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I click on "1 of 4 (25%)" "link" in the "This site policy" "table_row"
|
||||
And I click on "Consent not given" "link" in the "User One" "table_row"
|
||||
Then I should see "Give consent"
|
||||
And I click on "Accept This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Accepting policy"
|
||||
And I should see "User One"
|
||||
And I should see "This site policy"
|
||||
And I should see "I acknowledge that I have received a request to give consent on behalf of the above user(s)."
|
||||
And I set the field "Remarks" to "Consent received from a parent"
|
||||
And I press "Give consent"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Max Manager" "link" should exist in the "User One" "table_row"
|
||||
And "Consent received from a parent" "text" should exist in the "User One" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "User Two" "table_row"
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Agree on behalf of another user as a manager, single policy, javascript on
|
||||
@ -83,17 +83,17 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I should not see "Next"
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I click on "1 of 4 (25%)" "link" in the "This site policy" "table_row"
|
||||
And I click on "Consent not given" "link" in the "User One" "table_row"
|
||||
And I click on "Accept This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Give consent"
|
||||
And I should see "User One"
|
||||
And I should see "This site policy"
|
||||
And I should see "I acknowledge that I have received a request to give consent on behalf of the above user(s)."
|
||||
And I set the field "Remarks" to "Consent received from a parent"
|
||||
And I press "Give consent"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Max Manager" "link" should exist in the "User One" "table_row"
|
||||
And "Consent received from a parent" "text" should exist in the "User One" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "User Two" "table_row"
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
|
||||
Scenario: View acceptances made by users on their own, multiple policies
|
||||
Given I log in as "admin"
|
||||
@ -119,19 +119,19 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I set the field "I agree to the This privacy policy" to "1"
|
||||
And I press "Next"
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And "Agreed" "icon" should exist in the "User One" "table_row"
|
||||
And "Consent not given" "icon" should not exist in the "User One" "table_row"
|
||||
And "Agreed" "icon" should exist in the "Max Manager" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "User Two" "table_row"
|
||||
And "Agreed" "icon" should not exist in the "User Two" "table_row"
|
||||
And I click on "2 of 2" "link" in the "User One" "table_row"
|
||||
And "Agreed" "icon" should exist in the "This site policy" "table_row"
|
||||
And "Agreed" "icon" should exist in the "This privacy policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "User One" "table_row"
|
||||
And "Pending" "text" should not exist in the "User One" "table_row"
|
||||
And "Accepted" "text" should exist in the "Max Manager" "table_row"
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
And "Accepted" "text" should not exist in the "User Two" "table_row"
|
||||
And I click on "Details" "link" in the "User One" "table_row"
|
||||
And "Accepted" "text" should exist in the "This site policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This privacy policy" "table_row"
|
||||
And I am on site homepage
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And I click on "0 of 2" "link" in the "User Two" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "This site policy" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "This privacy policy" "table_row"
|
||||
And I click on "Details" "link" in the "User Two" "table_row"
|
||||
And "Pending" "text" should exist in the "This site policy" "table_row"
|
||||
And "Pending" "text" should exist in the "This privacy policy" "table_row"
|
||||
|
||||
Scenario: Agree on behalf of another user as a manager, multiple policies, javascript off
|
||||
Given I log in as "admin"
|
||||
@ -150,20 +150,20 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I set the field "I agree to the This privacy policy" to "1"
|
||||
And I press "Next"
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And I click on "Consent not given; click to give consent on behalf of user for This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Give consent"
|
||||
And I click on "Accept This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Accepting policy"
|
||||
And I should see "User One"
|
||||
And I should see "This site policy"
|
||||
And I should see "I acknowledge that I have received a request to give consent on behalf of the above user(s)."
|
||||
And I set the field "Remarks" to "Consent received from a parent"
|
||||
And I press "Give consent"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And "Consent not given; click to give consent on behalf of user for This privacy policy" "icon" should exist in the "User One" "table_row"
|
||||
And I click on "1 of 2" "link" in the "User One" "table_row"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "This site policy" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Pending" "text" should exist in the "User One" "table_row"
|
||||
And I click on "Details" "link" in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "This site policy" "table_row"
|
||||
And "Max Manager" "link" should exist in the "This site policy" "table_row"
|
||||
And "Consent received from a parent" "text" should exist in the "This site policy" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "This privacy policy" "table_row"
|
||||
And "Pending" "text" should exist in the "This privacy policy" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Agree on behalf of another user as a manager, multiple policies, javascript on
|
||||
@ -183,20 +183,20 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I set the field "I agree to the This privacy policy" to "1"
|
||||
And I press "Next"
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And I click on "Consent not given; click to give consent on behalf of user for This site policy" "link" in the "User One" "table_row"
|
||||
And I click on "Accept This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Give consent"
|
||||
And I should see "User One"
|
||||
And I should see "This site policy"
|
||||
And I should see "I acknowledge that I have received a request to give consent on behalf of the above user(s)."
|
||||
And I set the field "Remarks" to "Consent received from a parent"
|
||||
And I press "Give consent"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And "Consent not given; click to give consent on behalf of user for This privacy policy" "icon" should exist in the "User One" "table_row"
|
||||
And I click on "1 of 2" "link" in the "User One" "table_row"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "This site policy" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Pending" "text" should exist in the "User One" "table_row"
|
||||
And I click on "Details" "link" in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "This site policy" "table_row"
|
||||
And "Max Manager" "link" should exist in the "This site policy" "table_row"
|
||||
And "Consent received from a parent" "text" should exist in the "This site policy" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "This privacy policy" "table_row"
|
||||
And "Pending" "text" should exist in the "This privacy policy" "table_row"
|
||||
|
||||
Scenario: Policies and agreements profile link visible for current user
|
||||
Given I log in as "user1"
|
||||
@ -207,14 +207,14 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
# User can see his own agreements link in the profile.
|
||||
Then I should see "Policies and agreements"
|
||||
And I follow "Policies and agreements"
|
||||
And "Agreed" "icon" should exist in the "This site policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This site policy" "table_row"
|
||||
# User can't see agreements link in other user profiles.
|
||||
And I am on "Course1" course homepage
|
||||
And I navigate to course participants
|
||||
And I follow "User Two"
|
||||
And I should not see "Policies and agreements"
|
||||
|
||||
Scenario: Policies and agreements profile link visible also for users who can access on behaf of others
|
||||
Scenario: Policies and agreements profile link visible also for users who can access on behalf of others
|
||||
Given I log in as "admin"
|
||||
And I set the following system permissions of "Manager" role:
|
||||
| capability | permission |
|
||||
@ -248,18 +248,18 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I press "Continue"
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I click on "1 of 4 (25%)" "link" in the "This site policy" "table_row"
|
||||
And I click on "Consent not given" "link" in the "User One" "table_row"
|
||||
Then I should see "Give consent"
|
||||
And I click on "Accept This site policy" "link" in the "User One" "table_row"
|
||||
Then I should see "Accepting policy"
|
||||
And I should see "User One"
|
||||
And I should see "This site policy"
|
||||
And I should see "I acknowledge that I have received a request to give consent on behalf of the above user(s)."
|
||||
And I set the field "Remarks" to "Consent received from a parent"
|
||||
And I press "Give consent"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Max Manager" "link" should not exist in the "User One" "table_row"
|
||||
And "Admin User" "link" should exist in the "User One" "table_row"
|
||||
And "Consent received from a parent" "text" should exist in the "User One" "table_row"
|
||||
And "Consent not given" "icon" should exist in the "User Two" "table_row"
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Bulk agree on behalf of another users as a manager, multiple policies, javascript on
|
||||
@ -281,16 +281,14 @@ Feature: Viewing acceptances reports and accepting on behalf of other users
|
||||
And I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
And I click on "Select" "checkbox" in the "User One" "table_row"
|
||||
And I press "Consent"
|
||||
And I should see "Give consent on behalf of user(s)"
|
||||
And I should see "Accepting policy"
|
||||
And I should see "One"
|
||||
And I press "Cancel"
|
||||
And I should not see "Give consent on behalf of user(s)"
|
||||
And I should not see "Accepting policy"
|
||||
And I click on "Select" "checkbox" in the "User Two" "table_row"
|
||||
And I press "Consent"
|
||||
And I should see "Give consent on behalf of user(s)"
|
||||
And I should see "Accepting policy"
|
||||
And I should see "User One, User Two"
|
||||
When I press "Give consent"
|
||||
Then "Consent given on behalf of user" "icon" should exist in the "User One" "table_row"
|
||||
And I should see "2 of 2" in the "User One" "table_row"
|
||||
And "Consent given on behalf of user" "icon" should exist in the "User Two" "table_row"
|
||||
And I should see "2 of 2" in the "User Two" "table_row"
|
||||
Then "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User Two" "table_row"
|
||||
|
@ -52,6 +52,7 @@ class behat_tool_policy extends behat_base {
|
||||
* - Summary: Policy summary text.
|
||||
* - Content: Policy full text.
|
||||
* - Agreement style (agreementstyle): 0 - On the consent page, 1 - On its own page
|
||||
* - Agreement optional (optional): 0 - Compulsory policy, 1 - Optional policy
|
||||
*
|
||||
* @param TableNode $data
|
||||
*/
|
||||
@ -71,6 +72,7 @@ class behat_tool_policy extends behat_base {
|
||||
'content',
|
||||
'summary',
|
||||
'agreementstyle',
|
||||
'optional',
|
||||
];
|
||||
|
||||
// Associative array "policy identifier" => id in the database .
|
||||
|
@ -113,7 +113,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "This site policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This site policy" "table_row"
|
||||
And I log out
|
||||
|
||||
Scenario: Accept policy on sign up, multiple policies
|
||||
@ -172,8 +172,8 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "This site policy" "table_row"
|
||||
And "Agreed" "icon" should exist in the "This privacy policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This site policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This privacy policy" "table_row"
|
||||
And I should not see "This guests policy"
|
||||
And I log out
|
||||
|
||||
@ -225,7 +225,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "This site policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "This site policy" "table_row"
|
||||
And I log out
|
||||
|
||||
Scenario: Accept policy on sign up, do not accept all policies
|
||||
@ -252,12 +252,12 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
And I set the field "I agree to the This privacy policy" to "0"
|
||||
And I press "Next"
|
||||
Then I should see "Please agree to the following policies"
|
||||
And I should see "Before continuing you must agree to all these policies."
|
||||
And I should see "Before continuing you need to acknowledge all these policies."
|
||||
# Confirm that a notification is displayed if only some policies are accepted.
|
||||
When I set the field "I agree to the This site policy" to "1"
|
||||
And I set the field "I agree to the This privacy policy" to "0"
|
||||
Then I should see "Please agree to the following policies"
|
||||
And I should see "Before continuing you must agree to all these policies."
|
||||
And I should see "Before continuing you need to acknowledge all these policies."
|
||||
|
||||
Scenario: Accept policy on login, do not accept all policies
|
||||
Given the following config values are set as admin:
|
||||
@ -284,12 +284,12 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
And I set the field "I agree to the This privacy policy" to "0"
|
||||
And I press "Next"
|
||||
Then I should see "Please agree to the following policies"
|
||||
And I should see "Before continuing you must agree to all these policies."
|
||||
And I should see "Before continuing you need to acknowledge all these policies."
|
||||
# Confirm that a notification is displayed if only some policies are accepted.
|
||||
When I set the field "I agree to the This site policy" to "1"
|
||||
And I set the field "I agree to the This privacy policy" to "0"
|
||||
Then I should see "Please agree to the following policies"
|
||||
And I should see "Before continuing you must agree to all these policies."
|
||||
And I should see "Before continuing you need to acknowledge all these policies."
|
||||
# Confirm that user can not browse the site (edit their profile).
|
||||
When I follow "Profile" in the user menu
|
||||
Then I should see "Please agree to the following policies"
|
||||
@ -319,7 +319,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
And I set the field "I agree to the This privacy policy" to "1"
|
||||
And I press "Next"
|
||||
Then I should not see "Please agree to the following policies"
|
||||
And I should not see "Before continuing you must agree to all these policies."
|
||||
And I should not see "Before continuing you need to acknowledge all these policies."
|
||||
# Confirm that user can login and browse the site (edit their profile).
|
||||
When I open my profile in edit mode
|
||||
Then the field "First name" matches value "User"
|
||||
@ -661,7 +661,7 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "This site policy" "table_row"
|
||||
And "Accepted" "text" 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.
|
||||
@ -730,10 +730,10 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "Accepted" "text" should exist in the "Privacy policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "Cookies policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "Terms of Service" "table_row"
|
||||
And "Accepted" "text" 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.
|
||||
@ -788,10 +788,10 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "Accepted" "text" should exist in the "Privacy policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "Cookies policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "Terms of Service" "table_row"
|
||||
And "Accepted" "text" 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.
|
||||
@ -822,9 +822,9 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "Accepted" "text" should exist in the "Privacy policy" "table_row"
|
||||
And "Accepted" "text" should exist in the "Terms of Service" "table_row"
|
||||
And "Accepted" "text" should exist in the "Digital maturity declaration" "table_row"
|
||||
And "Cookies policy" "table_row" should not exist
|
||||
And I log out
|
||||
|
||||
@ -872,8 +872,8 @@ Feature: User must accept policy managed by this plugin when logging in and sign
|
||||
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 "Accepted" "text" should exist in the "Digital maturity declaration" "table_row"
|
||||
And "Accepted" "text" 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
|
||||
|
@ -35,8 +35,8 @@ Feature: Manage policies
|
||||
And "Save as draft" "button" should not exist
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Draft | v1 | N/A |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Draft | v1 | N/A |
|
||||
And I log out
|
||||
|
||||
Scenario: Create new policy and save as active
|
||||
@ -51,8 +51,8 @@ Feature: Manage policies
|
||||
| Active | 1 |
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Active | v1 | 0 of 4 (0%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Active | v1 | 0 of 4 (0%) |
|
||||
And I log out
|
||||
|
||||
Scenario: Edit active policy and save as minor change
|
||||
@ -74,8 +74,8 @@ Feature: Manage policies
|
||||
And I set the field "Minor change" to "1"
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Active | v1 amended | 1 of 4 (25%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Active | v1 amended | 1 of 4 (25%) |
|
||||
And I log out
|
||||
|
||||
Scenario: Edit active policy and save as draft
|
||||
@ -92,9 +92,9 @@ Feature: Manage policies
|
||||
And I set the field "Version" to "v2"
|
||||
And I press "Save as draft"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Active | v1 | 1 of 4 (25%) |
|
||||
| Policy1 Site policy, All users | Draft | v2 | N/A |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Active | v1 | 1 of 4 (25%) |
|
||||
| Policy1 Site policy, All users, Compulsory | Draft | v2 | N/A |
|
||||
And I log out
|
||||
|
||||
Scenario: Edit active policy and save as new active version
|
||||
@ -112,8 +112,8 @@ Feature: Manage policies
|
||||
And I set the field "Version" to "v2"
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users | Active | v2 | 0 of 4 (0%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users, Compulsory | Active | v2 | 0 of 4 (0%) |
|
||||
And I should not see "Policy1"
|
||||
And I should not see "v1"
|
||||
And I open the action menu in "Policy2" "table_row"
|
||||
@ -121,8 +121,8 @@ Feature: Manage policies
|
||||
And I should see "Policy2 previous versions"
|
||||
And I should not see "v2"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Inactive | v1 | 1 of 4 (25%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Inactive | v1 | 1 of 4 (25%) |
|
||||
And I log out
|
||||
|
||||
Scenario: Edit draft policy and save as draft
|
||||
@ -141,8 +141,8 @@ Feature: Manage policies
|
||||
And "Save as draft" "button" should not exist
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Draft | v2 | N/A |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Draft | v2 | N/A |
|
||||
And I should not see "v1"
|
||||
And I open the action menu in "Policy1" "table_row"
|
||||
And "View previous versions" "link" should not exist
|
||||
@ -160,8 +160,8 @@ Feature: Manage policies
|
||||
And I set the field "Active" to "1"
|
||||
And I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Active | v2 | 0 of 4 (0%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Active | v2 | 0 of 4 (0%) |
|
||||
And I should not see "v1"
|
||||
And I open the action menu in "Policy1" "table_row"
|
||||
And "View previous versions" "link" should not exist
|
||||
@ -178,8 +178,8 @@ Feature: Manage policies
|
||||
Then I should see "All users will be required to agree to this new policy version to be able to use the site."
|
||||
And I press "Continue"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Active | v1 | 0 of 4 (0%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Active | v1 | 0 of 4 (0%) |
|
||||
And I open the action menu in "Policy1" "table_row"
|
||||
And "View previous versions" "link" should not exist
|
||||
And I log out
|
||||
@ -198,8 +198,8 @@ Feature: Manage policies
|
||||
Then I should see "You are about to inactivate policy"
|
||||
And I press "Continue"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Inactive | v1 | 1 of 4 (25%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Inactive | v1 | 1 of 4 (25%) |
|
||||
And I open the action menu in "Policy1" "table_row"
|
||||
And I click on "Create a new draft" "link" in the "Policy1" "table_row"
|
||||
And I set the field "Version" to "v2"
|
||||
@ -212,16 +212,16 @@ Feature: Manage policies
|
||||
And "Save as draft" "button" should not exist
|
||||
And I press "Save"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users | Draft | v2 | N/A |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users, Compulsory | Draft | v2 | N/A |
|
||||
And I should not see "v1"
|
||||
And I should not see "Policy1"
|
||||
And I open the action menu in "Policy2" "table_row"
|
||||
And I click on "View previous versions" "link" in the "Policy2" "table_row"
|
||||
And I should see "Policy2 previous versions"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Inactive | v1 | 1 of 4 (25%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Inactive | v1 | 1 of 4 (25%) |
|
||||
And I should not see "v2"
|
||||
And I log out
|
||||
|
||||
@ -244,16 +244,16 @@ Feature: Manage policies
|
||||
And I set the field "Active" to "1"
|
||||
And I press "Save"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users | Active | v2 | 0 of 4 (0%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy2 Site policy, All users, Compulsory | Active | v2 | 0 of 4 (0%) |
|
||||
And I should not see "v1"
|
||||
And I should not see "Policy1"
|
||||
And I open the action menu in "Policy2" "table_row"
|
||||
And I click on "View previous versions" "link" in the "Policy2" "table_row"
|
||||
And I should see "Policy2 previous versions"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users | Inactive | v1 | 1 of 4 (25%) |
|
||||
| Name | Policy status | Version | Agreements |
|
||||
| Policy1 Site policy, All users, Compulsory | Inactive | v1 | 1 of 4 (25%) |
|
||||
And I should not see "v2"
|
||||
And I log out
|
||||
|
||||
|
264
admin/tool/policy/tests/behat/optional.feature
Normal file
@ -0,0 +1,264 @@
|
||||
@tool @tool_policy
|
||||
Feature: Optional policies
|
||||
In order to exercise my privacy rights
|
||||
As a user
|
||||
I should be able to decline policy statements and withdraw my previously given consent to them
|
||||
|
||||
Background:
|
||||
Given the following config values are set as admin:
|
||||
| sitepolicyhandler | tool_policy |
|
||||
And the following "users" exist:
|
||||
| username | firstname | lastname | email |
|
||||
| user1 | User | One | one@example.com |
|
||||
| user2 | User | Two | two@example.com |
|
||||
| manager | Max | Manager | man@example.com |
|
||||
And the following "role assigns" exist:
|
||||
| user | role | contextlevel | reference |
|
||||
| manager | manager | System | |
|
||||
And the following "courses" exist:
|
||||
| fullname | shortname |
|
||||
| Course1 | C1 |
|
||||
And the following "course enrolments" exist:
|
||||
| user | course | role |
|
||||
| user1 | C1 | student |
|
||||
| user2 | C1 | student |
|
||||
|
||||
Scenario: Configuring a policy as optional
|
||||
Given I log in as "manager"
|
||||
And I navigate to "Users > Privacy and policies > Manage policies" in site administration
|
||||
And I follow "New policy"
|
||||
# Policies are compulsory by default.
|
||||
And the field "Agreement optional" matches value "No"
|
||||
# Optional status can be set when creating a new policy.
|
||||
And I set the following fields to these values:
|
||||
| Name | ConsentPageOptional1 |
|
||||
| Version | v1 |
|
||||
| Summary | Policy summary |
|
||||
| Full policy | Full text |
|
||||
| Active | 1 |
|
||||
| Show policy before showing other policies | No |
|
||||
| Agreement optional | Yes |
|
||||
When I press "Save"
|
||||
Then the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version |
|
||||
| ConsentPageOptional1 Site policy, All users, Optional | Active | v1 |
|
||||
# Optional status can be edited.
|
||||
And I open the action menu in "ConsentPageOptional1" "table_row"
|
||||
And I click on "Edit" "link" in the "ConsentPageOptional1" "table_row"
|
||||
And I set the field "Agreement optional" to "No"
|
||||
And I set the field "Minor change" to "1"
|
||||
And I press "Save"
|
||||
And the following should exist in the "tool-policy-managedocs-wrapper" table:
|
||||
| Name | Policy status | Version |
|
||||
| ConsentPageOptional1 Site policy, All users, Compulsory | Active | v1 |
|
||||
|
||||
Scenario: Compulsory policies must be accepted prior signup, optional policies just after it
|
||||
Given the following config values are set as admin:
|
||||
| registerauth | email |
|
||||
| passwordpolicy | 0 |
|
||||
And the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| ConsentPageOptional1 | full text1 | short text1 | 0 | 1 |
|
||||
| ConsentPageOptional2 | full text2 | short text2 | 0 | 1 |
|
||||
| ConsentPageCompulsory1 | full text3 | short text3 | 0 | 0 |
|
||||
| OwnPageCompulsory1 | full text4 | short text4 | 1 | 0 |
|
||||
| OwnPageOptional1 | full text5 | short text5 | 1 | 1 |
|
||||
And I am on site homepage
|
||||
And I follow "Log in"
|
||||
And I press "Create new account"
|
||||
# Compulsory policies displayed on own page are shown first and must be agreed.
|
||||
And I should see "OwnPageCompulsory1" in the "region-main" "region"
|
||||
And I should see "short text4" in the "region-main" "region"
|
||||
And I should see "full text4" in the "region-main" "region"
|
||||
And I press "I agree to the OwnPageCompulsory1"
|
||||
# Compulsory policies displayed on the consent page are shown next and must be agreed.
|
||||
And I should see "ConsentPageCompulsory1"
|
||||
And I should see "short text3" in the "region-main" "region"
|
||||
And I should see "full text3" in the "region-main" "region"
|
||||
And I press "Next"
|
||||
And I should see "Please agree to the following policies"
|
||||
And I set the field "I agree to the ConsentPageCompulsory1" to "1"
|
||||
And I press "Next"
|
||||
# The signup form can be submitted and a new account created.
|
||||
And I set the following fields to these values:
|
||||
| Username | user3 |
|
||||
| Password | user3 |
|
||||
| Email address | user3@address.invalid |
|
||||
| Email (again) | user3@address.invalid |
|
||||
| First name | User3 |
|
||||
| Surname | L3 |
|
||||
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 user3@address.invalid"
|
||||
And I confirm email for "user3"
|
||||
And I should see "Thanks, User3 L3"
|
||||
And I should see "Your registration has been confirmed"
|
||||
When I press "Continue"
|
||||
# After confirming the new account, the user is logged in and asked to accept or decline the optional policies.
|
||||
# First come policies displayed on their own page.
|
||||
Then I should see "OwnPageOptional1"
|
||||
And I should see "short text5" in the "region-main" "region"
|
||||
And I should see "full text5" in the "region-main" "region"
|
||||
And I press "No thanks, I decline OwnPageOptional1"
|
||||
# Then come policies displayed on the consent page.
|
||||
And I should see "ConsentPageOptional1" in the "region-main" "region"
|
||||
And I should see "short text1" in the "region-main" "region"
|
||||
And I should see "full text1" in the "region-main" "region"
|
||||
And I press "Next"
|
||||
And I should see "ConsentPageOptional2" in the "region-main" "region"
|
||||
And I should see "short text2" in the "region-main" "region"
|
||||
And I should see "full text2" in the "region-main" "region"
|
||||
And I press "Next"
|
||||
And I should see "Please agree to the following policies"
|
||||
And I set the field "I agree to the ConsentPageOptional1" to "1"
|
||||
And I set the field "No thanks, I decline ConsentPageOptional2" to "0"
|
||||
And I press "Next"
|
||||
# Accepted and declined policies are shown in the profile.
|
||||
And I follow "Profile" in the user menu
|
||||
And I follow "Policies and agreements"
|
||||
And "Accepted" "text" should exist in the "ConsentPageCompulsory1" "table_row"
|
||||
And "Accepted" "text" should exist in the "ConsentPageOptional1" "table_row"
|
||||
And "Accepted" "text" should exist in the "OwnPageCompulsory1" "table_row"
|
||||
And "Declined" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Declined" "text" should exist in the "ConsentPageOptional2" "table_row"
|
||||
|
||||
Scenario: When a new optional policy is added, users are asked to accept/decline it on their next login
|
||||
Given the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| ConsentPageOptional1 | full text1 | short text1 | 0 | 1 |
|
||||
| OwnPageOptional1 | full text5 | short text5 | 1 | 1 |
|
||||
When I log in as "user1"
|
||||
# First come policies displayed on their own page.
|
||||
Then I should see "OwnPageOptional1"
|
||||
And I should see "short text5" in the "region-main" "region"
|
||||
And I should see "full text5" in the "region-main" "region"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
# Then come policies displayed on the consent page.
|
||||
And I should see "ConsentPageOptional1" in the "region-main" "region"
|
||||
And I should see "short text1" in the "region-main" "region"
|
||||
And I should see "full text1" in the "region-main" "region"
|
||||
And I press "Next"
|
||||
And I should see "Please agree to the following policies"
|
||||
And I set the field "No thanks, I decline ConsentPageOptional1" to "0"
|
||||
And I press "Next"
|
||||
# Accepted and declined policies are shown in the profile.
|
||||
And I follow "Profile" in the user menu
|
||||
And I follow "Policies and agreements"
|
||||
And "Accepted" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Declined" "text" should exist in the "ConsentPageOptional1" "table_row"
|
||||
|
||||
Scenario: Users can withdraw an accepted optional policy and re-accept it again (js off)
|
||||
Given the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| OwnPageOptional1 | full text1 | short text1 | 1 | 1 |
|
||||
And I log in as "user1"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
And I follow "Profile" in the user menu
|
||||
And I follow "Policies and agreements"
|
||||
And "Accepted" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Withdraw" "link" should exist in the "OwnPageOptional1" "table_row"
|
||||
When I click on "Withdraw acceptance of OwnPageOptional1" "link" in the "OwnPageOptional1" "table_row"
|
||||
Then I should see "Withdrawing policy"
|
||||
And I should see "User One"
|
||||
And I should see "OwnPageOptional1"
|
||||
And I press "Withdraw user consent"
|
||||
And "Declined" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Accept" "link" should exist in the "OwnPageOptional1" "table_row"
|
||||
And I click on "Accept OwnPageOptional1" "link" in the "OwnPageOptional1" "table_row"
|
||||
And I should see "Accepting policy"
|
||||
And I should see "User One"
|
||||
And I should see "OwnPageOptional1"
|
||||
And I press "Give consent"
|
||||
And "Accepted" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
|
||||
@javascript
|
||||
Scenario: Users can withdraw an accepted optional policy and re-accept it again (js on)
|
||||
Given the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| OwnPageOptional1 | full text1 | short text1 | 1 | 1 |
|
||||
And I log in as "user1"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
And I follow "Profile" in the user menu
|
||||
And I follow "Policies and agreements"
|
||||
And "Accepted" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Withdraw" "link" should exist in the "OwnPageOptional1" "table_row"
|
||||
When I click on "Withdraw acceptance of OwnPageOptional1" "link" in the "OwnPageOptional1" "table_row"
|
||||
Then I should see "Withdrawing policy"
|
||||
And I should see "User One"
|
||||
And I should see "OwnPageOptional1"
|
||||
And I press "Withdraw user consent"
|
||||
And "Declined" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
And "Accept" "link" should exist in the "OwnPageOptional1" "table_row"
|
||||
And I click on "Accept OwnPageOptional1" "link" in the "OwnPageOptional1" "table_row"
|
||||
And I should see "Accepting policy"
|
||||
And I should see "User One"
|
||||
And I should see "OwnPageOptional1"
|
||||
And I press "Give consent"
|
||||
And "Accepted" "text" should exist in the "OwnPageOptional1" "table_row"
|
||||
|
||||
Scenario: Managers can see accepted, declined and pending acceptances of optional policies
|
||||
Given the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| OwnPageOptional1 | full text1 | short text1 | 1 | 1 |
|
||||
| OwnPageOptional2 | full text2 | short text2 | 1 | 1 |
|
||||
And I log in as "user1"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
And I press "No thanks, I decline OwnPageOptional2"
|
||||
And I log out
|
||||
And I log in as "manager"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
And I press "I agree to the OwnPageOptional2"
|
||||
When I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
# User One has accepted just some policies.
|
||||
Then "Partially accepted" "text" should exist in the "User One" "table_row"
|
||||
And "Details" "link" should exist in the "User One" "table_row"
|
||||
# User Two did not have a chance to respond to the new policies yet.
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
And "Details" "link" should exist in the "User Two" "table_row"
|
||||
# Max Manager accepted all and can also change status of own acceptances.
|
||||
And "Accepted" "text" should exist in the "Max Manager" "table_row"
|
||||
And "Details" "link" should exist in the "Max Manager" "table_row"
|
||||
And "Withdraw accepted policies" "link" should exist in the "Max Manager" "table_row"
|
||||
And "Withdraw acceptance of OwnPageOptional1" "link" should exist in the "Max Manager" "table_row"
|
||||
And "Withdraw acceptance of OwnPageOptional2" "link" should exist in the "Max Manager" "table_row"
|
||||
|
||||
Scenario: Administrators can see accepted, declined and pending acceptances of optional policies and also change them on behalf of other users
|
||||
Given the following policies exist:
|
||||
| Name | Content | Summary | Agreementstyle | Optional |
|
||||
| OwnPageOptional1 | full text1 | short text1 | 1 | 1 |
|
||||
| OwnPageOptional2 | full text2 | short text2 | 1 | 1 |
|
||||
And I log in as "user1"
|
||||
And I press "I agree to the OwnPageOptional1"
|
||||
And I press "No thanks, I decline OwnPageOptional2"
|
||||
And I log out
|
||||
And I log in as "admin"
|
||||
When I navigate to "Users > Privacy and policies > User agreements" in site administration
|
||||
# User One has accepted just some policies.
|
||||
Then "Partially accepted" "text" should exist in the "User One" "table_row"
|
||||
And "Details" "link" should exist in the "User One" "table_row"
|
||||
And "Withdraw acceptance of OwnPageOptional1" "link" should exist in the "User One" "table_row"
|
||||
And "Accept OwnPageOptional2" "link" should exist in the "User One" "table_row"
|
||||
# User Two did not have a chance to respond to the new policies yet.
|
||||
And "Pending" "text" should exist in the "User Two" "table_row"
|
||||
And "Accept pending policies" "link" should exist in the "User Two" "table_row"
|
||||
And "Decline pending policies" "link" should exist in the "User Two" "table_row"
|
||||
And "Accept OwnPageOptional1" "link" should exist in the "User Two" "table_row"
|
||||
And "Decline OwnPageOptional1" "link" should exist in the "User Two" "table_row"
|
||||
And "Accept OwnPageOptional2" "link" should exist in the "User Two" "table_row"
|
||||
And "Decline OwnPageOptional2" "link" should exist in the "User Two" "table_row"
|
||||
# Accept all policies on Max Manager's behalf.
|
||||
And I click on "Accept pending policies" "link" in the "Max Manager" "table_row"
|
||||
And I press "Give consent"
|
||||
And "Accepted" "text" should exist in the "Max Manager" "table_row"
|
||||
# Decline all policies on User Two's behalf.
|
||||
And I click on "Decline pending policies" "link" in the "User Two" "table_row"
|
||||
And I press "Decline user consent"
|
||||
And "Declined on user's behalf" "text" should exist in the "User Two" "table_row"
|
||||
And "Accepted" "text" should not exist in the "User Two" "table_row"
|
||||
And "Pending" "text" should not exist in the "User Two" "table_row"
|
||||
# Accept policy on User One's behalf.
|
||||
And I click on "Accept OwnPageOptional2" "link" in the "User One" "table_row"
|
||||
And I press "Give consent"
|
||||
And "Accepted on user's behalf" "text" should exist in the "User One" "table_row"
|
||||
And "Declined" "text" should not exist in the "User One" "table_row"
|
||||
And "Pending" "text" should not exist in the "User One" "table_row"
|
137
admin/tool/policy/tests/sitepolicy_handler_test.php
Normal file
@ -0,0 +1,137 @@
|
||||
<?php
|
||||
// This file is part of Moodle - http://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/>.
|
||||
|
||||
/**
|
||||
* Provides the {@link tool_policy_sitepolicy_handler_testcase} class.
|
||||
*
|
||||
* @package tool_policy
|
||||
* @category test
|
||||
* @copyright 2018 David Mudrák <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
|
||||
use tool_policy\api;
|
||||
use tool_policy\policy_version;
|
||||
use tool_policy\privacy\local\sitepolicy\handler;
|
||||
use tool_policy\test\helper;
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
global $CFG;
|
||||
|
||||
/**
|
||||
* Unit tests for the {@link \tool_policy\privacy\local\sitepolicy\handler} class.
|
||||
*
|
||||
* @copyright 2018 David Mudrak <david@moodle.com>
|
||||
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
|
||||
*/
|
||||
class tool_policy_sitepolicy_handler_testcase extends advanced_testcase {
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link \tool_policy\privacy\local\sitepolicy\handler::get_redirect_url()} method.
|
||||
*/
|
||||
public function test_get_redirect_url() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// No redirect for guests.
|
||||
$this->assertNull(handler::get_redirect_url(true));
|
||||
|
||||
// No redirect if there is no policy.
|
||||
$this->assertNull(handler::get_redirect_url());
|
||||
|
||||
// No redirect if no policy for logged in users.
|
||||
$policy1 = helper::add_policy(['audience' => policy_version::AUDIENCE_GUESTS])->to_record();
|
||||
api::make_current($policy1->id);
|
||||
$this->assertNull(handler::get_redirect_url());
|
||||
|
||||
// URL only when there is actually some policy to show.
|
||||
$policy2 = helper::add_policy(['audience' => policy_version::AUDIENCE_LOGGEDIN])->to_record();
|
||||
api::make_current($policy2->id);
|
||||
$this->assertInstanceOf('moodle_url', handler::get_redirect_url());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link \tool_policy\privacy\local\sitepolicy\handler::get_embed_url()} method.
|
||||
*/
|
||||
public function test_get_embed_url() {
|
||||
$this->resetAfterTest();
|
||||
$this->setAdminUser();
|
||||
|
||||
// No embed if there is no policy.
|
||||
$this->assertNull(handler::get_embed_url());
|
||||
$this->assertNull(handler::get_embed_url(true));
|
||||
|
||||
$policy1 = helper::add_policy(['audience' => policy_version::AUDIENCE_GUESTS])->to_record();
|
||||
api::make_current($policy1->id);
|
||||
|
||||
// Policy exists for guests only.
|
||||
$this->assertNull(handler::get_embed_url());
|
||||
$this->assertInstanceOf('moodle_url', handler::get_embed_url(true));
|
||||
|
||||
$policy2 = helper::add_policy(['audience' => policy_version::AUDIENCE_LOGGEDIN])->to_record();
|
||||
api::make_current($policy2->id);
|
||||
|
||||
// Some policy exists for all users.
|
||||
$this->assertInstanceOf('moodle_url', handler::get_embed_url());
|
||||
$this->assertInstanceOf('moodle_url', handler::get_embed_url(true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test behaviour of the {@link \tool_policy\privacy\local\sitepolicy\handler::accept()} method.
|
||||
*/
|
||||
public function test_accept() {
|
||||
global $DB, $USER;
|
||||
$this->resetAfterTest();
|
||||
|
||||
// False if not logged in.
|
||||
$this->setUser(0);
|
||||
$this->assertFalse(handler::accept());
|
||||
|
||||
// Guests accept policies implicitly by continuing to use the site.
|
||||
$this->setGuestUser();
|
||||
$this->assertTrue(handler::accept());
|
||||
|
||||
// Create one compulsory and one optional policy.
|
||||
$this->setAdminUser();
|
||||
$policy1 = helper::add_policy(['optional' => policy_version::AGREEMENT_COMPULSORY])->to_record();
|
||||
api::make_current($policy1->id);
|
||||
$policy2 = helper::add_policy(['optional' => policy_version::AGREEMENT_OPTIONAL])->to_record();
|
||||
api::make_current($policy2->id);
|
||||
|
||||
$user1 = $this->getDataGenerator()->create_user();
|
||||
$this->assertEquals(0, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
$this->assertEmpty($DB->get_records('tool_policy_acceptances', ['userid' => $user1->id]));
|
||||
|
||||
$this->setUser($user1->id);
|
||||
$this->assertEquals(0, $USER->policyagreed);
|
||||
|
||||
// Only the compulsory policy is marked as accepted when accepting via the handler.
|
||||
$this->assertTrue(handler::accept());
|
||||
$this->assertEquals(1, $DB->get_field('user', 'policyagreed', ['id' => $user1->id]));
|
||||
$this->assertEquals(1, $USER->policyagreed);
|
||||
$this->assertEquals(1, $DB->count_records('tool_policy_acceptances', ['userid' => $user1->id]));
|
||||
$this->assertTrue($DB->record_exists('tool_policy_acceptances', ['userid' => $user1->id,
|
||||
'policyversionid' => $policy1->id]));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test presence of the {@link \tool_policy\privacy\local\sitepolicy\handler::signup_form()} method.
|
||||
*/
|
||||
public function test_signup_form() {
|
||||
$this->assertTrue(method_exists('\tool_policy\privacy\local\sitepolicy\handler', 'signup_form'));
|
||||
}
|
||||
}
|
@ -24,6 +24,6 @@
|
||||
|
||||
defined('MOODLE_INTERNAL') || die();
|
||||
|
||||
$plugin->version = 2018082900; // The current plugin version (Date: YYYYMMDDXX).
|
||||
$plugin->version = 2018100100; // 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).
|
||||
|