Commit 4e5e0aae authored by Gregor Anzelj's avatar Gregor Anzelj Committed by Robert Lyon

Bug 1743870: Moderate portfolios of regular users

Allow institution admins and site admins to immediately remove all
sharing options from a page (or collection if the page is within
a collection) that is deemed objectionable.

behatnotneeded

Change-Id: I23de7ed5c4678afe8a65e51b2aec06126948c637
parent 3c9c871d
......@@ -27,6 +27,7 @@ $params->sortdir = param_alpha('sortdir', 'asc');
$params->loggedin = param_alpha('loggedin', 'any');
$params->loggedindate = param_variable('loggedindate', null);
$params->duplicateemail = param_boolean('duplicateemail', false);
$params->objectionable = param_boolean('objectionable', false);
$offset = param_integer('offset', 0);
$limit = param_integer('limit', 10);
......
......@@ -30,6 +30,7 @@ $search = (object) array(
'loggedin' => param_alpha('loggedin', 'any'),
'loggedindate' => param_variable('loggedindate', strftime(get_string('strftimedatetimeshort'))),
'duplicateemail' => param_boolean('duplicateemail', false),
'objectionable' => param_boolean('objectionable', false),
'authname' => param_alpha('authname', null),
);
......
......@@ -34,7 +34,7 @@ if (!$USER->get('admin') && !$USER->is_institutional_admin($institution) &&
}
if (!$notallowed) {
// Get the institution selector to worl out what institutions they are allowed to see
// Get the institution selector to work out what institutions they are allowed to see
$institutionelement = get_institution_selector(true, false, true, ($allstaffstats || $userstaffstats), ($USER->get('admin') || $USER->get('staff')));
}
......
......@@ -160,6 +160,11 @@ $objectionform = pieform(objection_form());
if ($notrudeform = notrude_form()) {
$notrudeform = pieform($notrudeform);
}
// For for admin to review objection claim, add comment
// about objectionable content and possibly remove access
if ($stillrudeform = stillrude_form()) {
$stillrudeform = pieform($stillrudeform);
}
$viewbeingwatched = (int)record_exists('usr_watchlist_view', 'usr', $USER->get('id'), 'view', $viewid);
......@@ -212,13 +217,19 @@ $smarty->assign('feedback', $feedback);
$smarty->assign('hasfeed', $hasfeed);
$smarty->assign('feedlink', $feedlink);
$smarty->assign('userisowner', ($owner && $owner == $USER->get('id')));
if (isset($addfeedbackform)) {
$smarty->assign('enablecomments', 1);
$smarty->assign('addfeedbackform', $addfeedbackform);
}
$smarty->assign('objectionform', $objectionform);
$smarty->assign('notrudeform', $notrudeform);
if ($objectionform) {
$smarty->assign('objectionform', $objectionform);
$smarty->assign('notrudeform', $notrudeform);
$smarty->assign('stillrudeform', $stillrudeform);
$smarty->assign('objectedpage', $view->is_objectionable());
$smarty->assign('objector', $view->is_objectionable($USER->get('id')));
$smarty->assign('objectionreplied', $view->is_objectionable(null, true));
}
$smarty->assign('viewbeingwatched', $viewbeingwatched);
$smarty->assign('viewtitle', $view->get('title'));
$smarty->assign('viewdisplaytitle', $view->display_title(true, true, $view->display_author()));
......
......@@ -24,6 +24,7 @@ var UserSearch = (function($) {
self.rewriteCheckboxes();
self.rewriteLoggedInFilter();
self.rewriteDuplicateEmailFilter();
self.rewriteObjectionableContentFilter();
paginatorProxy.addObserver(self);
var oldparams = $.extend({}, pager.params);
......@@ -214,6 +215,14 @@ var UserSearch = (function($) {
});
};
this.rewriteObjectionableContentFilter = function() {
$('#objectionable').on("click", function() {
pager.params.offset = 0;
pager.params.objectionable = $(this).prop('checked');
pager.sendQuery();
});
};
this.connectSelectedUsersForm = function(i, formid) {
$('#' + formid + ' button').on("click", function() {
// Some of the selected users aren't on the page, so just add them all to the
......
......@@ -70,6 +70,20 @@ function objectionSuccess(form, data) {
if (jQuery('#report-form').length) {
jQuery('#report-form').modal('hide');
}
// Update the objection menu link to be message sent one
if (jQuery('#objection_link').length) {
jQuery('#objection_link').parent().html('<span class="nolink"><span class="icon icon-lg icon-flag text-danger left" role="presentation" aria-hidden="true"></span>' + get_string_ajax('objectionablematerialreported', 'mahara') + '</span>');
}
}
function reviewSuccess(form, data) {
jQuery('#review_form_message').val('');
formSuccess(form, data);
// close the form when the form is submited
// Using bootstrap modal
if (jQuery('#review-form').length) {
jQuery('#review-form').modal('hide');
}
}
function resetFeedbackReplyto() {
......
......@@ -137,6 +137,53 @@ To see the page, follow this link:
To see the reporter\'s profile, follow this link:
%s';
$string['objectionablereviewview'] = 'Review of objectionable content on page "%s" requested by %s';
$string['objectionablereviewviewartefact'] = 'Review of objectionable content on page "%s" in "%s" requested by %s';
$string['objectionablereviewviewhtml'] = '<div style="padding: 0.5em 0; border-bottom: 1px solid #999;">Review of objectionable content on "%s" requested by %s<br>%s</div>
<div style="margin: 1em 0;">%s</div>
<div style="font-size: smaller; border-top: 1px solid #999;">
<p>Request relates to: <a href="%s">%s</a></p>
<p>Requested by: <a href="%s">%s</a></p>
</div>';
$string['objectionablereviewviewtext'] = 'Review of objectionable content on "%s" requested by %s
%s
------------------------------------------------------------------------
%s
------------------------------------------------------------------------
To see the page, follow this link:
%s
To see the owner\'s profile, follow this link:
%s';
$string['objectionablereviewviewartefacthtml'] = '<div style="padding: 0.5em 0; border-bottom: 1px solid #999;">Review of objectionable content on "%s" in "%s" requested by %s<br>%s</div>
<div style="margin: 1em 0;">%s</div>
<div style="font-size: smaller; border-top: 1px solid #999;">
<p>Request relates to: <a href="%s">%s</a></p>
<p>Requested by: <a href="%s">%s</a></p>
</div>';
$string['objectionablereviewviewartefacttext'] = 'Review of objectionable content on %s in "%s" requested by %s
%s
------------------------------------------------------------------------
%s
------------------------------------------------------------------------
To see the page, follow this link:
%s
To see the owner\'s profile, follow this link:
%s';
$string['stillobjectionablecontent'] = 'The content contains objectionable material.
%s';
$string['stillobjectionablecontentsuspended'] = 'The access to the page has been temporarily revoked until the objectionable content is cleared up.';
$string['newgroupmembersubj'] = '%s is now a group member.';
$string['removedgroupmembersubj'] = '%s is no longer a group member.';
......
......@@ -1241,6 +1241,10 @@ $string['usershavenotloggedinsince'] = 'Users have not logged in since';
// Admin user search duplicate email filter
$string['duplicateemailfilter1'] = 'Duplicate email addresses';
// Admin user search objectionable content filter
$string['objectionable'] = 'Objectionable content';
$string['objectionablefilter'] = 'People with objectionable content';
$string['noemailfound'] = 'No email address found';
$string['lastlogin'] = 'Last login';
......
......@@ -91,6 +91,7 @@ $string['notfoundexception'] = 'The page you are looking for could not be found.
$string['accessdenied'] = 'Access denied';
$string['accessdeniedobjection'] = 'Access denied. The objection has already been resolved by another administrator.';
$string['accessdeniedsuspension'] = 'This portfolio is under review.';
$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.';
......
......@@ -78,9 +78,35 @@ $string['disabled'] = 'Disabled';
$string['complaint'] = 'Complaint';
$string['notifyadministrator'] = 'Notify administrator';
$string['notifyadministratorconfirm'] = 'Are you sure you wish to report this page as containing objectionable material?';
$string['notifyadministratorreview'] = 'Are you sure you are ready for the administrator to review this page again?';
$string['notobjectionable'] = 'Not objectionable';
$string['reportobjectionablematerial'] = 'Report objectionable material';
$string['objectionablematerialreported'] = 'Objectionable material reported';
$string['objectionablematerialreportedowner'] = 'Someone reported your page to contain objectionable content. Please review your page and make adjustments where needed.';
$string['objectionablematerialreportedreply'] = 'Click the "Review objectionable content" button to let your administrator know that you\'ve made changes or to ask for clarification.';
$string['objectionablematerialreportreplied'] = 'An administrator reviewed the page again and still finds it to contain objectionable content. Please check your notification for more information. You can then make changes and send a message to the administrator by clicking the "Review objectionable content" button or ask for clarification.';
$string['objectionreviewsent'] = 'Objection review has been sent to page owner. Click on "Still objectionable" if you want to adjust and send another review.';
$string['lastobjection'] = 'Last objection';
$string['objectionnotreviewed'] = 'Objection not yet reviewed';
$string['objectionnotreviewedreply'] = 'Reply to un-reviewed objection:
%s';
$string['lastobjectionartefact'] = 'Last objection for "%s"';
$string['replyingtoobjection'] = 'Replying to objection:
"%s"
%s';
$string['reportsent'] = 'Your report has been sent.';
$string['reviewrequestsent'] = 'Your review request has been sent.';
$string['stillobjectionable'] = 'Still objectionable';
$string['objectionreview'] = 'Review objectionable material';
$string['objectionreviewonview'] = 'Replying to objectionable material can only be done via the page';
$string['reviewcomplaint'] = 'Review of complaint';
$string['reviewcomplaintdesc'] = 'Enter a message that you would like to send along to give more details to the author on what they should change. If you leave the field empty, the original complaint will be sent instead.';
$string['reviewnotification'] = 'The administrator was notified to review the portfolio and check if objectionable material still exists.';
$string['reviewnotificationdesc'] = 'Please review if objectionable material still exists.';
$string['removeaccess'] = 'Remove access';
$string['removeaccessdesc'] = 'Revoke access to this page (and collection if the page is in one) immediately until the objectionable material has been removed.';
// responsive design strings
$string['tabs'] = 'Tabs';
$string['tab'] = 'tab';
......
......@@ -362,6 +362,25 @@ $string['reportdesccontent'] = '<ul>
<li>Number of unique users who made the modifications</li>
<li>Number of unique users over the total</li>
</ul>';
$string['reportdescobjectionable'] = "<ul>
<li>Page title</li>
<li>Artefact title</li>
<li>Objectionable content reporter</li>
<li>Reporter's name</li>
<li>Report description</li>
<li>Report date</li>
<li>Reviewer's name</li>
<li>Review description</li>
<li>Review date</li>
<li>Report status</li>
</ul>";
$string['reporter'] = 'Reporter';
$string['review'] = 'Review';
$string['reviewer'] = 'Reviewer';
$string['contentobjectionablereports'] = 'Objectionable content';
$string['status.0'] = '';
$string['status.1'] = 'Administrator needs to review';
$string['status.2'] = 'User needs to make changes';
// Institution reports
$string['informationreports'] = 'Information overview';
......
......@@ -82,6 +82,7 @@ $string['accessuntildate3'] = 'Nobody can see this page after %s.';
$string['accessbetweendates3'] = 'Nobody can see this page before %s or after %s.';
$string['artefactsinthisview'] = 'Artefacts in this page';
$string['whocanseethisview'] = 'Who can see this page';
$string['pending'] = 'Portfolio under review';
$string['view'] = 'page';
$string['panelmenu'] = 'Menu';
$string['vieworcollection'] = 'page or collection';
......
......@@ -963,6 +963,7 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
protected $artefact;
protected $reporter;
protected $ctime;
protected $review;
/**
* @param array $data Parameters:
......@@ -971,6 +972,7 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
* - artefact (int) (optional)
* - reporter (int)
* - ctime (int) (optional)
* - review (int) (optional)
*/
function __construct($data, $cron=false) {
parent::__construct($data, $cron);
......@@ -982,11 +984,21 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
require_once(get_config('docroot') . 'artefact/lib.php');
$this->artefact = artefact_instance_from_id($this->artefact);
}
// Notify institutional admins of the view owner
$adminusers = array();
if ($owner = $this->view->get('owner')) {
// Notify institutional admins of the view owner
if ($institutions = get_column('usr_institution', 'institution', 'usr', $owner)) {
$this->users = activity_get_users($this->get_id(), null, null, null, $institutions);
$adminusers = activity_get_users($this->get_id(), null, null, null, $institutions);
}
}
if (isset($data->touser) && !empty($data->touser)) {
// Notify user when admin updates objection
$owneruser = activity_get_users($this->get_id(), array($data->touser));
$this->users = array_merge($owneruser, $adminusers);
}
else if ($owner = $this->view->get('owner')) {
if (!empty($adminusers)) {
$this->users = $adminusers;
}
}
......@@ -1003,7 +1015,7 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
$this->strings = new stdClass();
if (empty($this->artefact)) {
$this->strings->subject = (object) array(
'key' => 'objectionablecontentview',
'key' => ($this->review ? 'objectionablereviewview' : 'objectionablecontentview'),
'section' => 'activity',
'args' => array($viewtitle, display_default_name($this->reporter)),
);
......@@ -1011,7 +1023,7 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
else {
$title = $this->artefact->get('title');
$this->strings->subject = (object) array(
'key' => 'objectionablecontentviewartefact',
'key' => ($this->review ? 'objectionablereviewviewartefact' : 'objectionablecontentviewartefact'),
'section' => 'activity',
'args' => array($viewtitle, $title, display_default_name($this->reporter)),
);
......@@ -1023,15 +1035,17 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
$reporterurl = profile_url($this->reporter);
$ctime = strftime(get_string_from_language($user->lang, 'strftimedaydatetime'), $this->ctime);
if (empty($this->artefact)) {
$key = ($this->review ? 'objectionablereviewviewtext' : 'objectionablecontentviewtext');
return get_string_from_language(
$user->lang, 'objectionablecontentviewtext', 'activity',
$user->lang, $key, 'activity',
$this->view->get('title'), display_default_name($this->reporter), $ctime,
$this->message, $this->view->get_url(true, true) . "&objection=1", $reporterurl
);
}
else {
$key = ($this->review ? 'objectionablereviewviewartefacttext' : 'objectionablecontentviewartefacttext');
return get_string_from_language(
$user->lang, 'objectionablecontentviewartefacttext', 'activity',
$user->lang, $key, 'activity',
$this->view->get('title'), $this->artefact->get('title'), display_default_name($this->reporter), $ctime,
$this->message, get_config('wwwroot') . "artefact/artefact.php?artefact=" . $this->artefact->get('id') . "&view=" . $this->view->get('id') . "&objection=1", $reporterurl
);
......@@ -1043,18 +1057,20 @@ class ActivityTypeObjectionable extends ActivityTypeAdmin {
$reportername = hsc(display_default_name($this->reporter));
$reporterurl = profile_url($this->reporter);
$ctime = strftime(get_string_from_language($user->lang, 'strftimedaydatetime'), $this->ctime);
$message = hsc($this->message);
$message = format_whitespace($this->message);
if (empty($this->artefact)) {
$key = ($this->review ? 'objectionablereviewviewhtml' : 'objectionablecontentviewhtml');
return get_string_from_language(
$user->lang, 'objectionablecontentviewhtml', 'activity',
$user->lang, $key, 'activity',
$viewtitle, $reportername, $ctime,
$message, $this->view->get_url(true, true) . "&objection=1", $viewtitle,
$reporterurl, $reportername
);
}
else {
$key = ($this->review ? 'objectionablereviewviewartefacthtml' : 'objectionablecontentviewartefacthtml');
return get_string_from_language(
$user->lang, 'objectionablecontentviewartefacthtml', 'activity',
$user->lang, $key, 'activity',
$viewtitle, hsc($this->artefact->get('title')), $reportername, $ctime,
$message, get_config('wwwroot') . "artefact/artefact.php?artefact=" . $this->artefact->get('id') . "&view=" . $this->view->get('id') . "&objection=1", hsc($this->artefact->get('title')),
$reporterurl, $reportername
......
......@@ -1252,12 +1252,18 @@
<FIELD NAME="reportedby" TYPE="int" LENGTH="10" NOTNULL="true" />
<FIELD NAME="report" TYPE="text" NOTNULL="true" />
<FIELD NAME="reportedtime" TYPE="datetime" NOTNULL="true" />
<FIELD NAME="reviewedby" TYPE="int" LENGTH="10" NOTNULL="false" />
<FIELD NAME="review" TYPE="text" NOTNULL="false" />
<FIELD NAME="reviewedtime" TYPE="datetime" NOTNULL="false" />
<FIELD NAME="resolvedby" TYPE="int" LENGTH="10" NOTNULL="false" />
<FIELD NAME="resolvedtime" TYPE="datetime" NOTNULL="false" />
<FIELD NAME="suspended" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
<FIELD NAME="status" TYPE="int" LENGTH="1" NOTNULL="true" DEFAULT="0" />
</FIELDS>
<KEYS>
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
<KEY NAME="primary" TYPE="primary" FIELDS="id" />
<KEY NAME="reporterfk" TYPE="foreign" FIELDS="reportedby" REFTABLE="usr" REFFIELDS="id" />
<KEY NAME="reviewerfk" TYPE="foreign" FIELDS="reviewedby" REFTABLE="usr" REFFIELDS="id" />
<KEY NAME="resolverfk" TYPE="foreign" FIELDS="resolvedby" REFTABLE="usr" REFFIELDS="id" />
</KEYS>
<INDEXES>
......
......@@ -5967,5 +5967,38 @@ function xmldb_core_upgrade($oldversion=0) {
add_field($table, $field);
}
if ($oldversion < 2018080901) {
log_debug('Add "suspended" and "status" to "objectionable" table');
$table = new XMLDBTable('objectionable');
$field = new XMLDBField('suspended');
$field->setAttributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, null, null, 0);
if (!field_exists($table, $field)) {
add_field($table, $field);
}
$field = new XMLDBField('status');
$field->setAttributes(XMLDB_TYPE_INTEGER, 1, null, XMLDB_NOTNULL, null, null, null, 0);
if (!field_exists($table, $field)) {
add_field($table, $field);
}
$field = new XMLDBField('reviewedby');
$field->setAttributes(XMLDB_TYPE_INTEGER, 10, null, null);
if (!field_exists($table, $field)) {
add_field($table, $field);
$key = new XMLDBKEY('reviewerfk');
$key->setAttributes(XMLDB_KEY_FOREIGN, array('reviewedby'), 'usr', array('id'));
add_key($table, $key);
}
$field = new XMLDBField('review');
$field->setAttributes(XMLDB_TYPE_TEXT, 'small', null, null);
if (!field_exists($table, $field)) {
add_field($table, $field);
}
$field = new XMLDBField('reviewedtime');
$field->setAttributes(XMLDB_TYPE_DATETIME, null, null);
if (!field_exists($table, $field)) {
add_field($table, $field);
}
}
return $status;
}
......@@ -2988,6 +2988,12 @@ function can_view_view($view, $user_id=null) {
else if ($view->get('group') && $user->get('admin')) {
return true;
}
$params = array('view', $view->get('id'));
$suspended = record_exists_select('objectionable', 'objecttype = ? AND objectid = ? AND suspended = 1', $params);
if ($suspended) {
return false;
}
}
......@@ -3323,6 +3329,46 @@ function _get_views_trim_list(&$list, &$users, $limit, &$results) {
return false;
}
/**
* Given a view id will return wether this view is suspended or not.
*
* @param mixed $view viewid or View to check
* @param bool $artefacts Whether to check if there are suspended artefacts on the view.
* If there are any then the view is treated as suspended.
*
* @returns boolean Wether the specified view is suspended or not.
*/
function is_view_suspended($view, $artefacts=true) {
require_once(get_config('libroot') . 'view.php');
if ($view instanceof View) {
$viewid = $view->get('id');
}
else {
$viewid = $view;
}
if ($artefacts) {
return get_field_sql("
SELECT SUM(suspended) FROM (
SELECT id, suspended FROM {objectionable}
WHERE objecttype = 'view' AND objectid = ?
AND resolvedtime IS NULL
UNION
SELECT o.id, suspended FROM {objectionable} o
JOIN {view_artefact} va ON va.artefact = o.objectid
WHERE objecttype = 'artefact' AND va.view = ?
AND resolvedtime IS NULL
) AS foo
", array($viewid, $viewid));
}
else {
return get_field_sql("
SELECT suspended FROM {objectionable}
WHERE objecttype = 'view' AND objectid = ? AND resolvedtime IS NULL
", array($viewid));
}
}
/**
* Checks if artefact or at least one of its ancestors is in view
*
......
This diff is collapsed.
......@@ -300,6 +300,33 @@ function get_admin_user_search_results($search, $offset, $limit) {
'string' => $duplicateemailartefacts
);
}
// Filter by users with objectionable content
if (!empty($search->objectionable)) {
$objectionableartefacts = get_column_sql('
SELECT u.id
FROM {usr} u
JOIN {artefact} a ON a.owner = u.id
JOIN {objectionable} o ON o.objectid = a.id
WHERE o.objecttype = \'artefact\' AND resolvedtime IS NULL
');
$objectionableviews = get_column_sql('
SELECT u.id
FROM {usr} u
JOIN {view} v ON v.owner = u.id
JOIN {objectionable} o ON o.objectid = v.id
WHERE o.objecttype = \'view\' AND resolvedtime IS NULL
');
$objectionable = array_unique(array_merge($objectionableartefacts, $objectionableviews));
if ($objectionable === false || !is_array($objectionable)) {
$objectionable = array();
}
$constraints[] = array(
'field' => 'objectionable',
'type' => 'in',
'string' => $objectionable
);
}
// Filter by viewable institutions:
global $USER;
......@@ -397,7 +424,7 @@ function get_admin_user_search_results($search, $offset, $limit) {
function build_admin_user_search_results($search, $offset, $limit) {
global $USER, $THEME;
$wantedparams = array('query', 'f', 'l', 'loggedin', 'loggedindate', 'duplicateemail', 'institution', 'authname');
$wantedparams = array('query', 'f', 'l', 'loggedin', 'loggedindate', 'duplicateemail', 'objection', 'institution', 'authname');
$params = array();
foreach ($search as $k => $v) {
if (!in_array($k, $wantedparams)) {
......
This diff is collapsed.
......@@ -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 = 2018080900;
$config->version = 2018080901;
$config->series = '18.10';
$config->release = '18.10dev';
$config->minupgradefrom = 2015030409;
......
......@@ -1358,11 +1358,39 @@ class View {
/**
* Returns true if the view is currently marked as objectionable
*
* @param integer $reporter User id of the person who made the report
* @param bool $replied Has an admin replied to the report
*
* @return boolean True if view is objectionable
*/
public function is_objectionable() {
$params = array('view', $this->id);
return record_exists_select('objectionable', 'objecttype = ? AND objectid = ? AND resolvedby IS NULL', $params);
public function is_objectionable($reporter=null, $replied=false) {
$wheresql = "";
if ($reporter) {
$wheresql = " AND reportedby = ?";
}
else if ($replied) {
require_once('objectionable.php');
$wheresql = " AND status = ?";
}
$sql = "SELECT id FROM {objectionable}
WHERE objecttype = ? AND objectid = ?
AND (resolvedby IS NULL OR resolvedby <= 0)" . $wheresql . "
UNION
SELECT o.id FROM {objectionable} o
JOIN {view_artefact} va ON va.artefact = o.objectid
WHERE o.objecttype = ? AND va.view = ?
AND (resolvedby IS NULL OR resolvedby <= 0)" . $wheresql;
if ($reporter) {
$params = array('view', $this->id, $reporter, 'artefact', $this->id, $reporter);
}
else if ($replied) {
$params = array('view', $this->id, OBJECTIONABLE_CHANGE, 'artefact', $this->id, OBJECTIONABLE_CHANGE);
}
else {
$params = array('view', $this->id, 'artefact', $this->id);
}
return record_exists_sql($sql, $params);
}
public function is_public() {
......@@ -4081,6 +4109,7 @@ class View {
$ua->accesstype = 'managesharing';
$data['manageaccess'] = array($ua);
$data['manageaccesssuspended'] = self::access_override_pending(array('id' => $data['vid'])) ? true : false;
if ($accesslist = get_records_sql_array('
SELECT va.*, g.name AS groupname, g.grouptype, i.displayname AS institutionname
......@@ -6624,6 +6653,12 @@ class View {
}
// Returns a boolean if access is pending/suspended or not
public static function access_override_pending($v) {
return is_view_suspended($v['id']);
}
/**
* Get all views & collections for a (user,group), grouped
* by their accesslists
......@@ -6649,6 +6684,7 @@ class View {
unset($data['views'][$k]);
}
}
// Remember one representative viewid in each collection
$viewindex = array();
......@@ -6656,13 +6692,15 @@ class View {
foreach ($data['collections'] as &$c) {
$view = current($c['views']);
$viewindex[$view['id']] = array('type' => 'collections', 'id' => $c['id']);
$c['access'] = self::access_override_description($view);
$c['viewid'] = $view['id'];
$c['access'] = self::access_override_description($view);
$c['pending'] = self::access_override_pending($view);
$c['viewid'] = $view['id'];
}
foreach ($data['views'] as &$v) {
$viewindex[$v['id']] = array('type' => 'views', 'id' => $v['id']);
$v['access'] = self::access_override_description($v);
$v['viewid'] = $v['id'];
$v['access'] = self::access_override_description($v);
$v['pending'] = self::access_override_pending($v);
$v['viewid'] = $v['id'];
}