Commit f83fb54d authored by Robert Lyon's avatar Robert Lyon Committed by Gerrit Code Review

Merge changes from topic 'GDPR'

* changes:
  Bug 1734174: Users Privacy Statement page
  Bug 1734174: Create usr_agreement table
  Bug 1734182: Change menu from 'Privacy statement' to 'Legal'
  Bug 1734182: Displaying the existing site/institution privacy within table
  Bug 1734182: Add view/edit logic to institution privacy statement
  Bug 1734182: Add the first privacy statement of an institution
  Bug 1734182: Display the site privacy on institution privacy page
  Bug 1734182: Add the edit/view logic to the site privacy page
  Bug 1734182: Display the Privacy Statement on page /privacy.php
  Bug 1734182: Display all versions of the site privacy statement
  Bug 1734170: add new admin menu item 'Privacy'
  Bug 1734182: Move privacy to site_content_version table
  Bug 1734182: Add privacy to the site_content_version table
parents 0405658c 9cfbb97a
<?php
/**
*
* @package mahara
* @subpackage admin
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('MENUITEM', 'settings/privacy');
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'account');
define('SECTION_PAGE', 'userprivacy');
require(dirname(dirname(__FILE__)) . '/init.php');
require_once(get_config('docroot') . 'lib/user.php');
define('TITLE', get_string('privacy', 'admin'));
if (!is_logged_in()) {
throw new AccessDeniedException();
}
// Get all institutions of a user.
$userinstitutions = array_keys($USER->get('institutions'));
// Include the 'mahara' institution so that we may show the site privacy statement as well.
array_push($userinstitutions, 'mahara');
// Get all the latest privacy statement (institution and site) the user has agreed to.
$data = get_latest_privacy_versions($userinstitutions);
// JQuery logic for panel hide/show.
// Needed here because there are multiple dropdown panels on this page.
$js = <<< EOF
function showPanel(el) {
elementid = $(el).attr('id');
$("#dropdown" + elementid).toggleClass("collapse");
}
EOF;
$smarty = smarty();
setpageicon($smarty, 'icon-umbrella');
$smarty->assign('results', $data);
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->display('account/userprivacy.tpl');
<?php
/**
*
* @package mahara
* @subpackage admin
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('ADMIN', 1);
define('MENUITEM', 'configsite/privacy');
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'privacy');
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
define('TITLE', get_string('legal', 'admin'));
define('SUBSECTIONHEADING', get_string('privacy', 'admin'));
$versionid = param_integer('id', null);
if (!is_logged_in()) {
throw new AccessDeniedException();
}
$data = get_records_sql_assoc("
SELECT s.id, s.version, u.firstname, u.lastname, u.id AS userid, s.content, s.ctime
FROM {site_content_version} s
LEFT JOIN {usr} u ON s.author = u.id
WHERE s.institution = ?
ORDER BY s.id DESC", array('mahara'));
if ($versionid) {
if ($pageoptions = get_record('site_content_version', 'id', $versionid, 'institution', 'mahara')) {
$form = pieform(array(
'name' => 'editsitepage',
'jsform' => false,
'jssuccesscallback' => 'contentSaved',
'elements' => array(
'version' => array(
'type' => 'text',
'title' => get_string('version', 'admin'),
'description' => get_string('lastversion', 'admin', $pageoptions->version),
'defaultvalue' => '',
'rules' => array(
'required' => true,
'maxlength' => 15
)
),
'pageinstitution' => array('type' => 'hidden', 'value' => 'mahara'),
'pagetext' => array(
'name' => 'pagetext',
'type' => 'wysiwyg',
'rows' => 25,
'cols' => 100,
'title' => get_string('pagetext', 'admin'),
'defaultvalue' => $pageoptions->content,
'rules' => array(
'maxlength' => 65536,
'required' => true
)
),
'submit' => array(
'class' => 'btn-primary',
'type' => 'submitcancel',
'value' => array(get_string('savechanges', 'admin'), get_string('cancel')),
'goto' => get_config('wwwroot') . 'admin/site/privacy.php',
),
)
));
}
else {
throw new ViewNotFoundException(get_string('siteprivacystatementnotfound', 'error', $versionid));
}
}
function editsitepage_validate(Pieform $form, $values) {
// Check if the version entered by the user already exists.
if (record_exists('site_content_version', 'institution', $values['pageinstitution'], 'version', $values['version'])) {
$form->set_error('version', get_string('versionalreadyexist', 'admin', $values['version']));
}
}
function editsitepage_submit(Pieform $form, $values) {
global $USER, $SESSION;
$id = get_field('site_content_version', 'id', 'version', $values['version']);
require_once('embeddedimage.php');
// Update the pagetext with any embedded image info
$pagetext = EmbeddedImage::prepare_embedded_images($values['pagetext'], 'staticpages', $id);
$data = new StdClass;
$data->content = $pagetext;
$data->author = $USER->get('id');
$data->institution = $values['pageinstitution'];
$data->ctime = db_format_timestamp(time());
$data->version = $values['version'];
$data->type = 'privacy';
try {
insert_record('site_content_version', $data);
$SESSION->add_ok_msg(get_string('pagesaved', 'admin'));
}
catch (SQLException $e) {
$SESSION->add_ok_msg(get_string('savefailed', 'admin'));
}
redirect(get_config('wwwroot').'admin/site/privacy.php');
}
if ($versionid && $pageoptions) {
$smarty = smarty(array('adminsitepages'), array(), array('admin' => array('discardpageedits')));
$smarty->assign('pageeditform', $form);
$smarty->assign('content', $pageoptions->content);
$smarty->assign('version', $pageoptions->version);
}
else {
$smarty = smarty();
}
setpageicon($smarty, 'icon-umbrella');
$smarty->assign('results', $data);
$smarty->assign('latestversion', reset($data)->version);
$smarty->assign('versionid', $versionid);
$smarty->assign('latestprivacyid', reset($data)->id);
$smarty->display('admin/site/privacy.tpl');
<?php
/**
*
* @package mahara
* @subpackage admin
* @author Stacey Walker
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
define('INTERNAL', 1);
define('INSTITUTIONALADMIN', 1);
require(dirname(dirname(dirname(__FILE__))) . '/init.php');
define('SECTION_PLUGINTYPE', 'core');
define('SECTION_PLUGINNAME', 'admin');
define('SECTION_PAGE', 'institutionprivacy');
define('MENUITEM', 'manageinstitutions/privacy');
require_once('institution.php');
define('TITLE', get_string('legal', 'admin'));
define('SUBSECTIONHEADING', get_string('privacy', 'admin'));
$versionid = param_integer('id', null);
if (!is_logged_in()) {
throw new AccessDeniedException();
}
$institutionelement = get_institution_selector(false);
if (empty($institutionelement)) {
$smarty = smarty();
$smarty->display('admin/users/noinstitutions.tpl');
exit;
}
$institution = param_alphanum('institution', null);
if (!$institution || !$USER->can_edit_institution($institution)) {
$institution = empty($institutionelement['value']) ? $institutionelement['defaultvalue'] : $institutionelement['value'];
}
else if (!empty($institution)) {
$institutionelement['defaultvalue'] = $institution;
}
$institutionselector = pieform(array(
'name' => 'usertypeselect',
'class' => 'form-inline',
'elements' => array(
'institution' => $institutionelement,
)
));
$wwwroot = get_config('wwwroot');
// The "Add one" link displayed when an institution has no privay statement of its own.
$href = $wwwroot . 'admin/users/institutionprivacy.php?institution=' . $institution . '&id=0';
$privacies = get_records_sql_assoc("
SELECT s.id, s.version, u.firstname, u.lastname, u.id AS userid, s.content, s.ctime
FROM {site_content_version} s
LEFT JOIN {usr} u ON s.author = u.id
WHERE s.institution = ?
ORDER BY s.id DESC", array($institution));
$form = false;
if ($versionid !== null) {
$pageoptions = get_record('site_content_version', 'id', $versionid, 'institution', $institution);
if ($versionid === 0 || $pageoptions) {
$form = pieform(array(
'name' => 'editsitepage',
'jsform' => false,
'jssuccesscallback' => 'contentSaved',
'elements' => array(
'version' => array(
'type' => 'text',
'title' => get_string('version', 'admin'),
'description' => $pageoptions ? get_string('lastversion', 'admin', $pageoptions->version) : '',
'defaultvalue' => '',
'rules' => array(
'required' => true,
'maxlength' => 15
)
),
'pageinstitution' => array('type' => 'hidden', 'value' => $institution),
'pagetext' => array(
'name' => 'pagetext',
'type' => 'wysiwyg',
'rows' => 25,
'cols' => 100,
'title' => get_string('pagetext', 'admin'),
'defaultvalue' => $pageoptions ? $pageoptions->content : '',
'rules' => array(
'maxlength' => 65536,
'required' => true
)
),
'submit' => array(
'class' => 'btn-primary',
'type' => 'submitcancel',
'value' => array(get_string('savechanges', 'admin'), get_string('cancel')),
'goto' => get_config('wwwroot') . 'admin/users/institutionprivacy.php?institution=' . $institution,
),
)
));
}
else {
throw new ViewNotFoundException(get_string('institutionprivacystatementnotfound', 'error', $institutionelement['options'][$institution], $versionid));
}
}
function editsitepage_validate(Pieform $form, $values) {
// Check if the version entered by the user already exists
if (record_exists('site_content_version', 'institution', $values['pageinstitution'], 'version', $values['version'])) {
$form->set_error('version', get_string('versionalreadyexist', 'admin', $values['version']));
}
}
function editsitepage_submit(Pieform $form, $values) {
global $USER, $SESSION;
$id = get_field('site_content_version', 'id', 'version', $values['version']);
require_once('embeddedimage.php');
// Update the pagetext with any embedded image info
$pagetext = EmbeddedImage::prepare_embedded_images($values['pagetext'], 'staticpages', $id);
$data = new StdClass;
$data->content = $pagetext;
$data->author = $USER->get('id');
$data->institution = $values['pageinstitution'];
$data->ctime = db_format_timestamp(time());
$data->version = $values['version'];
$data->type = 'privacy';
try {
insert_record('site_content_version', $data);
$SESSION->add_ok_msg(get_string('pagesaved', 'admin'));
}
catch (SQLException $e) {
$SESSION->add_ok_msg(get_string('savefailed', 'admin'));
}
redirect(get_config('wwwroot').'admin/users/institutionprivacy.php?institution=' . $values['pageinstitution']);
}
// Site privacy to display in an expandable panel
$siteprivacycontent = get_record_sql("
SELECT s.content, s.ctime
FROM {site_content_version} s
WHERE s.institution = ?
ORDER BY s.id DESC
LIMIT 1", array('mahara'));
$js = <<< EOF
jQuery(function($) {
function reloadUsers() {
window.location.href = '{$wwwroot}admin/users/institutionprivacy.php?institution=' + $('#usertypeselect_institution').val();
}
$('#usertypeselect_institution').on('change', reloadUsers);
});
EOF;
$smarty = smarty();
setpageicon($smarty, 'icon-umbrella');
$smarty->assign('INLINEJAVASCRIPT', $js);
$smarty->assign('href', $href);
$smarty->assign('siteprivacycontent', $siteprivacycontent);
$smarty->assign('lastupdated', get_string('lastupdatedon', 'blocktype.externalfeed', format_date(strtotime($siteprivacycontent->ctime))));
$smarty->assign('versionid', $versionid);
$smarty->assign('privacies', $privacies);
$smarty->assign('pageeditform', $form);
$smarty->assign('institution', $institution);
$smarty->assign('latestversion', $privacies ? reset($privacies)->version : 0);
$smarty->assign('latestprivacyid', $privacies ? reset($privacies)->id : 0);
$smarty->assign('version', $versionid && $pageoptions ? $pageoptions->version : '');
$smarty->assign('institutionselector', $institutionselector);
$smarty->display('admin/users/institutionprivacy.tpl');
......@@ -182,6 +182,8 @@ if ($institution || $add) {
delete_records('institution_config', 'institution', $values['i']);
delete_records('usr_custom_layout', 'institution', $values['i']);
delete_records('usr_registration', 'institution', $values['i']);
delete_records('site_content_version', 'institution', $values['i']);
delete_records('oauth_server_registry', 'institution', $values['i']);
delete_records('institution', 'name', $values['i']);
db_commit();
......
......@@ -88,6 +88,8 @@ $string['staticpageinstitutionbad'] = "You can't access and/or edit static pages
$string['usedefault'] = 'Use site default';
$string['usedefaultdescription3'] = 'Use the site\'s default text for the selected page type.';
$string['staticpagesdescription'] = 'Edit the content of static pages in Mahara (Home, Terms and Conditions, etc.)';
$string['institutionprivacypagedescription'] = 'Edit the privacy statement for your institution, which is displayed in addition to the site privacy statement. The version you edited last becomes the current privacy statement automatically. You see the current site privacy statement as reference.';
$string['noinstitutionprivacy'] = 'There is no privacy statement for this institution yet.';
$string['menus'] = 'Menus';
$string['menusdescription'] = 'Manage the links and files within the "Links and resources" and footer menus';
$string['sitefiles'] = 'Site files';
......@@ -494,11 +496,13 @@ $string['pagename'] = 'Page name';
$string['pagesaved'] = 'Page saved';
$string['pagetext'] = 'Page text';
$string['privacy'] = 'Privacy statement';
$string['legal'] = 'Legal';
$string['savechanges'] = 'Save changes';
$string['savefailed'] = 'Save failed';
$string['sitepageloaded'] = 'Site page loaded';
$string['termsandconditions'] = 'Terms and conditions';
$string['uploadcopyright'] = 'Upload copyright statement';
$string['privacypagedescription'] = 'Edit the privacy statement for the entire site. The version you edited last becomes the current privacy statement automatically.';
// Links and resources menu editor
$string['sitefile'] = 'Site file';
......@@ -1318,3 +1322,19 @@ $string['nobehatfeaturefiles'] = 'No behat feature files found';
$string['behatmatchingrows'] = '%s in ';
$string['behatnocore'] = 'Unable to read core behat steps from behat.yml file';
$string['behatstepnotused'] = 'This behat step is not currently used';
// Privacy Statement section
$string['author'] = 'Author';
$string['content'] = 'Content';
$string['creationdate'] = 'Creation date';
$string['version'] = 'Version';
$string['viewversion'] = 'View version %s';
$string['editversion'] = 'Edit version %s';
$string['lastversion'] = 'Privacy statements must have unique version names of up to 15 characters. The latest version for this privacy statement is "%s".';
$string['versionalreadyexist'] = 'A privacy statement with the version name "%s" already exists.';
$string['siteprivacystatement'] = 'Site privacy statement';
$string['addoneversionlink'] = '<a href="%s">Add one</a> if you need it.';
$string['versionfor'] = 'Privacy statement for version "%s" is as follows:';
$string['institutionprivacystatement'] = 'Institution privacy statement';
$string['userprivacypagedescription'] = 'Displayed are the current privacy statements to which you consented.';
$string['lastupdated'] = 'Last updated on';
......@@ -94,7 +94,8 @@ $string['accessdeniedobjection'] = 'Access denied. The objection has already bee
$string['accessdeniedexception'] = 'You do not have access to view this page.';
$string['accessdeniednourlsecret'] = 'You do not have access to this functionality. Please provide the value for "urlsecret" from your config.php file as part of the URL.';
$string['accessdeniedbadge'] = 'You do not have access to view this badge.';
$string['siteprivacystatementnotfound'] = 'Site privacy statement with id %s not found.';
$string['institutionprivacystatementnotfound'] = 'Privacy statement for "%s" with id %s not found.';
$string['viewnotfoundexceptiontitle'] = 'Page not found';
$string['viewnotfoundexceptionmessage'] = 'You tried to access a page that does not exist.';
$string['viewnotfound'] = 'Page with id %s not found.';
......
......@@ -1394,5 +1394,19 @@
<KEY NAME="authorfk" TYPE="foreign" FIELDS="author" REFTABLE="usr" REFFIELDS="id" />
</KEYS>
</TABLE>
<TABLE NAME="usr_agreement">
<FIELDS>
<FIELD NAME="id" TYPE="int" LENGTH="10" NOTNULL="true" SEQUENCE="true" />
<FIELD NAME="usr" TYPE="int" LENGTH="10" NOTNULL="true"/>
<FIELD NAME="sitecontentid" TYPE="int" LENGTH="10" NOTNULL="true"/>
<FIELD NAME="ctime" TYPE="datetime" NOTNULL="true" />
<FIELD NAME="agreed" TYPE="int" LENGTH="1" NOTNULL="true" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
<KEY NAME="usrfk" TYPE="foreign" FIELDS="usr" REFTABLE="usr" REFFIELDS="id"/>
<KEY NAME="sitecontentfk" TYPE="foreign" FIELDS="sitecontentid" REFTABLE="site_content_version" REFFIELDS="id"/>
</KEYS>
</TABLE>
</TABLES>
</XMLDB>
......@@ -5609,5 +5609,42 @@ function xmldb_core_upgrade($oldversion=0) {
create_table($table);
}
if ($oldversion < 2018010700) {
log_debug('Move the site Privacy statement from the site_content table to the site_content_version table');
if ($records = get_records_array('site_content', 'name', 'privacy')) {
foreach ($records as $data) {
$record = new stdClass;
$record->type = 'privacy';
$record->content = $data->content;
$record->author = $data->mauthor;
$record->institution = $data->institution;
$record->version = '1.0';
$record->ctime = db_format_timestamp(time());
insert_record('site_content_version', $record);
delete_records('site_content', 'id', $data->id);
}
}
}
if ($oldversion < 2018011000) {
log_debug('Create "usr_agreement" table');
$table = new XMLDBTable('usr_agreement');
$table->addFieldInfo('id', XMLDB_TYPE_INTEGER, 10, null, XMLDB_NOTNULL, XMLDB_SEQUENCE);
$table->addFieldInfo('usr', XMLDB_TYPE_INTEGER, 10, null, true);
$table->addFieldInfo('sitecontentid', XMLDB_TYPE_INTEGER, 10, null, true);
$table->addFieldInfo('ctime', XMLDB_TYPE_DATETIME, null, null, XMLDB_NOTNULL);
$table->addFieldInfo('agreed', XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL);
$table->addKeyInfo('primary', XMLDB_KEY_PRIMARY, array('id'));
$table->addKeyInfo('usrfk', XMLDB_KEY_FOREIGN, array('usr'), 'usr', array('id'));
$table->addKeyInfo('sitecontentfk', XMLDB_KEY_FOREIGN, array('sitecontentid'), 'site_content_version', array('id'));
create_table($table);
}
return $status;
}
......@@ -756,15 +756,27 @@ function core_install_lastcoredata_defaults() {
$now = db_format_timestamp(time());
foreach ($pages as $name) {
$page = new stdClass();
$page->name = $name;
$page->ctime = $now;
$page->institution = 'mahara';
$page->content = get_string($name . 'defaultcontent', 'install', get_string('staticpageconfigdefault', 'install'));
$page->name = $name;
$page->mtime = $now;
$page->mauthor = $userid;
$page->content = get_string($page->name . 'defaultcontent', 'install', get_string('staticpageconfigdefault', 'install'));
$page->institution = 'mahara';
insert_record('site_content', $page);
}
$versionedpages = site_content_version_pages();
foreach ($versionedpages as $name) {
$page = new stdClass();
$page->ctime = $now;
$page->institution = 'mahara';
$page->content = get_string($name . 'defaultcontent', 'install', get_string('staticpageconfigdefault', 'install'));
$page->type = $name;
$page->author = $userid;
$page->version = '1.0';
insert_record('site_content_version', $page);
}
// install the default layout options
install_view_layout_defaults();
......
......@@ -3218,3 +3218,25 @@ function get_site_admins() {
// just in case there is something horribly wrong.
return false;
}
/**
* Returns a list of the latest privacy statements of each institution the current user belongs to.
*
* @param $institutions an array of the institutions to which the current user belongs to.
* @returns array of stdclass objects containing the latest privacy statements the user has agreed to.
*/
function get_latest_privacy_versions($institutions = array()) {
global $USER;
// Get the latest Privacy Statements the user has agreed to.
$latestversions = get_records_sql_assoc("
SELECT s.id, s.version, s.content, s.ctime, s.institution
FROM {site_content_version} s
INNER JOIN (SELECT MAX(id) as current, institution
FROM {site_content_version}
GROUP BY institution) s2 ON s.institution = s2.institution AND s.id = s2.current
JOIN {usr_agreement} u ON s2.current = u.sitecontentid AND u.usr = ?
WHERE s.institution IN (" . join(',',array_map('db_quote',$institutions)) . ")", array($USER->get('id')));
return $latestversions;
}
......@@ -16,7 +16,7 @@ $config = new stdClass();
// See https://wiki.mahara.org/wiki/Developer_Area/Version_Numbering_Policy
// For upgrades on stable branches, increment the version by one. On master, use the date.
$config->version = 2018010600;
$config->version = 2018011000;
$config->series = '18.04';
$config->release = '18.04dev';
$config->minupgradefrom = 2015030409;
......
......@@ -2265,6 +2265,12 @@ function admin_nav() {
'title' => get_string('staticpages', 'admin'),
'weight' => 20
),
'configsite/privacy' => array(
'path' => 'configsite/privacy',
'url' => 'admin/site/privacy.php',
'title' => get_string('legal', 'admin'),
'weight' => 25,
),
'configsite/sitemenu' => array(
'path' => 'configsite/sitemenu',
'url' => 'admin/site/menu.php',
......@@ -2413,6 +2419,12 @@ function admin_nav() {
'title' => get_string('staticpages', 'admin'),
'weight' => 15
),
'manageinstitutions/privacy' => array(
'path' => 'manageinstitutions/privacy',
'url' => 'admin/users/institutionprivacy.php',
'title' => get_string('legal', 'admin'),
'weight' => 17
),
'manageinstitutions/institutionusers' => array(
'path' => 'manageinstitutions/institutionusers',
'url' => 'admin/users/institutionusers.php',
......@@ -2631,6 +2643,12 @@ function institutional_admin_nav() {
'title' => get_string('staticpages', 'admin'),
'weight' => 15
),
'manageinstitutions/privacy' => array(
'path' => 'manageinstitutions/privacy',
'url' => 'admin/users/institutionprivacy.php',
'title' => get_string('legal', 'admin'),
'weight' => 17
),
'manageinstitutions/institutionusers' => array(
'path' => 'manageinstitutions/institutionusers',
'url' => 'admin/users/institutionusers.php',
......@@ -3023,11 +3041,17 @@ function right_nav() {
'weight' => 10,
'iconclass' => 'user'
),
'settings/privacy' => array(
'path' => 'settings/privacy',
'url' => 'account/userprivacy.php',
'title' => get_string('privacy', 'admin'),
'weight' => 30
),
'settings/notifications' => array(
'path' => 'settings/notifications',
'url' => 'account/activity/preferences/index.php',
'title' => get_string('notifications'),
'weight' => 30,
'weight' => 40,
'iconclass' => 'flag'
),
);
......@@ -3188,7 +3212,15 @@ function site_menu() {
* @return array of names
*/
function site_content_pages() {
return array('about', 'home', 'loggedouthome', 'privacy', 'termsandconditions');
return array('about', 'home', 'loggedouthome', 'termsandconditions');
}
/**
* Returns the list of site versioned content pages
* @return array of names
*/
function site_content_version_pages() {
return array('privacy');
}
function get_site_page_content($pagename) {
......
......@@ -14,6 +14,13 @@ define('PUBLIC', 1);
require('init.php');
define('TITLE', get_string('privacystatement'));
$privacycontent = get_field_sql("
SELECT s.content
FROM {site_content_version} s
WHERE s.institution = ?
ORDER BY s.version DESC
LIMIT 1", array('mahara'));
$smarty = smarty();
$smarty->assign('page_content', get_site_page_content('privacy'));
$smarty->assign('page_content', $privacycontent);
$smarty->display('sitepage.tpl');
{include file="header.tpl"}
<div class="lead">{str tag="userprivacypagedescription" section="admin"}</div>
{foreach from=$results item=result key=key}
<div class="panel panel-default" id="{$result->id}" onclick="showPanel(this)">
<div class="last form-group collapsible-group">
<fieldset class="pieform-fieldset last collapsible">
<legend>
<h4>
<a href="#dropdown" data-toggle="collapse" aria-expanded="false" aria-controls="dropdown" class="collapsed">
{if $result->institution == 'mahara'}
{str tag="siteprivacystatement" section="admin"}
{else}
{str tag="institutionprivacystatement" section="admin"}
{/if}
<span class="icon icon-chevron-down collapse-indicator right pull-right"> </span>
</a>
</h4>
</legend>
<div class="fieldset-body collapse" id="dropdown{$result->id}">
<span class="text-midtone pull-right">{str tag="lastupdated" section="admin"} {$result->ctime|date_format:'%d %B %Y %H:%M %p'}</span>
<br>
{$result->content|safe}
</div>
</fieldset>
</div>
</div>
{/foreach}
{include file="footer.tpl"}
{include file="header.tpl"}
{if $versionid && $version == $latestversion}
<div class="lead">{str tag="privacypagedescription" section="admin"}</div>
{if $pageeditform}
<div class="col-md-9">
<div class="panel panel-default">
<div class="panel-body">
{$pageeditform|safe}
</div>
</div>
</div>
{/if}
</div>
{else}
<div class="lead">{str tag="privacypagedescription" section="admin"}</div>
<div class="row">
<div class="col-md-12">
<div class="panel panel-default view-container">
<div class="table-responsive">
<table id="adminstitutionslist" class="fullwidth table table-striped">
<thead>
<tr>
<th>{str tag="version" section="admin"}</th>
<th>{str tag="author" section="admin"}</th>
<th>{str tag="content" section="admin"}</th>
<th>{str tag="creationdate" section="admin"}</th>
<th><span class="accessible-hidden sr-only">{str tag=edit}</span></th>
</tr>
</thead>
<tbody>
{foreach from=$results item=result key=key}
<tr>
<td>{$result->version}</td>
<td>{if $result->firstname === NULL}
{str tag=default}
{else}
<a href="{$WWWROOT}user/view.php?id={$result->userid}">