/applications/vanilla/controllers/class.moderationcontroller.php
PHP | 327 lines | 216 code | 40 blank | 71 comment | 47 complexity | 939434421b4728bb01a9aec041f9b776 MD5 | raw file
- <?php if (!defined('APPLICATION')) exit();
- /*
- Copyright 2008, 2009 Vanilla Forums Inc.
- This file is part of Garden.
- Garden 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.
- Garden is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of empCHANTABILITY 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 Garden. If not, see <http://www.gnu.org/licenses/>.
- Contact Vanilla Forums Inc. at support [at] vanillaforums [dot] com
- */
- /**
- * Moderation Controller
- *
- * @package Vanilla
- */
-
- /**
- * Handles content moderation
- *
- * @since 2.0.18
- * @package Vanilla
- */
- class ModerationController extends VanillaController {
-
- /**
- * Looks at the user's attributes and form postback to see if any comments
- * have been checked for administration, and if so, puts an inform message on
- * the screen to take action.
- */
- public function CheckedComments() {
- $this->DeliveryType(DELIVERY_TYPE_BOOL);
- $this->DeliveryMethod(DELIVERY_METHOD_JSON);
- ModerationController::InformCheckedComments($this);
- $this->Render();
- }
-
- /**
- * Looks at the user's attributes and form postback to see if any discussions
- * have been checked for administration, and if so, puts an inform message on
- * the screen to take action.
- */
- public function CheckedDiscussions() {
- $this->DeliveryType(DELIVERY_TYPE_BOOL);
- $this->DeliveryMethod(DELIVERY_METHOD_JSON);
- ModerationController::InformCheckedDiscussions($this);
- $this->Render();
- }
- /**
- * Looks at the user's attributes and form postback to see if any comments
- * have been checked for administration, and if so, adds an inform message to
- * $Sender to take action.
- */
- public static function InformCheckedComments($Sender) {
- $Session = Gdn::Session();
- $HadCheckedComments = FALSE;
- $TransientKey = GetValue('TransientKey', $_POST);
- if ($Session->IsValid() && $Session->ValidateTransientKey($TransientKey)) {
- // Form was posted, so accept changes to checked items.
- $DiscussionID = GetValue('DiscussionID', $_POST, 0);
- $CheckIDs = GetValue('CheckIDs', $_POST);
- if (empty($CheckIDs))
- $CheckIDs = array();
- $CheckIDs = (array)$CheckIDs;
-
- $CheckedComments = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedComments', array());
- if (!is_array($CheckedComments))
- $CheckedComments = array();
-
- if (!array_key_exists($DiscussionID, $CheckedComments)) {
- $CheckedComments[$DiscussionID] = array();
- } else {
- // Were there checked comments in this discussion before the form was posted?
- $HadCheckedComments = count($CheckedComments[$DiscussionID]) > 0;
- }
- foreach ($CheckIDs as $Check) {
- if (GetValue('checked', $Check)) {
- if (!ArrayHasValue($CheckedComments, $Check['checkId']))
- $CheckedComments[$DiscussionID][] = $Check['checkId'];
- } else {
- RemoveValueFromArray($CheckedComments[$DiscussionID], $Check['checkId']);
- }
- }
-
- if (count($CheckedComments[$DiscussionID]) == 0)
- unset($CheckedComments[$DiscussionID]);
-
- Gdn::UserModel()->SaveAttribute($Session->User->UserID, 'CheckedComments', $CheckedComments);
- } else if ($Session->IsValid()) {
- // No form posted, just retrieve checked items for display
- $DiscussionID = property_exists($Sender, 'DiscussionID') ? $Sender->DiscussionID : 0;
- $CheckedComments = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedComments', array());
- if (!is_array($CheckedComments))
- $CheckedComments = array();
-
- }
- // Retrieve some information about the checked items
- $CountDiscussions = count($CheckedComments);
- $CountComments = 0;
- foreach ($CheckedComments as $DiscID => $Comments) {
- if ($DiscID == $DiscussionID)
- $CountComments += count($Comments); // Sum of comments in this discussion
- }
- if ($CountComments > 0) {
- $SelectionMessage = Wrap(sprintf(
- 'You have selected %1$s in this discussion.',
- Plural($CountComments, '%s comment', '%s comments')
- ), 'div');
- $ActionMessage = T('Take Action:');
- // Can the user delete the comment?
- $DiscussionModel = new DiscussionModel();
- $Discussion = $DiscussionModel->GetID($DiscussionID);
- if ($Session->CheckPermission('Vanilla.Comments.Delete', TRUE, 'Category', $Discussion->CategoryID))
- $ActionMessage .= ' '.Anchor(T('Delete'), 'vanilla/moderation/confirmcommentdeletes/'.$DiscussionID, 'Delete Popup');
-
- $Sender->EventArguments['SelectionMessage'] = &$SelectionMessage;
- $Sender->EventArguments['ActionMessage'] = &$ActionMessage;
- $Sender->EventArguments['Discussion'] = $Discussion;
- $Sender->FireEvent('BeforeCheckComments');
- $ActionMessage .= ' '.Anchor(T('Cancel'), 'vanilla/moderation/clearcommentselections/'.$DiscussionID.'/{TransientKey}/?Target={SelfUrl}', 'CancelAction');
-
- $Sender->InformMessage(
- $SelectionMessage
- .Wrap($ActionMessage, 'div', array('class' => 'Actions')),
- array(
- 'CssClass' => 'NoDismiss',
- 'id' => 'CheckSummary'
- )
- );
- } else if ($HadCheckedComments) {
- // Remove the message completely if there were previously checked comments in this discussion, but none now
- $Sender->InformMessage('', array('id' => 'CheckSummary'));
- }
- }
-
- /**
- * Looks at the user's attributes and form postback to see if any discussions
- * have been checked for administration, and if so, adds an inform message to
- * $Sender to take action.
- */
- public static function InformCheckedDiscussions($Sender) {
- $Session = Gdn::Session();
- $HadCheckedDiscussions = FALSE;
- $TransientKey = GetValue('TransientKey', $_POST);
- if ($Session->IsValid() && $Session->ValidateTransientKey($TransientKey)) {
- // Form was posted, so accept changes to checked items.
- $CheckIDs = GetValue('CheckIDs', $_POST);
- if (empty($CheckIDs))
- $CheckIDs = array();
- $CheckIDs = (array)$CheckIDs;
-
- $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
- if (!is_array($CheckedDiscussions))
- $CheckedDiscussions = array();
-
- // Were there checked discussions before the form was posted?
- $HadCheckedDiscussions = count($CheckedDiscussions) > 0;
- foreach ($CheckIDs as $Check) {
- if (GetValue('checked', $Check)) {
- if (!ArrayHasValue($CheckedDiscussions, $Check['checkId']))
- $CheckedDiscussions[] = $Check['checkId'];
- } else {
- RemoveValueFromArray($CheckedDiscussions, $Check['checkId']);
- }
- }
-
- Gdn::UserModel()->SaveAttribute($Session->User->UserID, 'CheckedDiscussions', $CheckedDiscussions);
- } else if ($Session->IsValid()) {
- // No form posted, just retrieve checked items for display
- $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
- if (!is_array($CheckedDiscussions))
- $CheckedDiscussions = array();
-
- }
- // Retrieve some information about the checked items
- $CountDiscussions = count($CheckedDiscussions);
- if ($CountDiscussions > 0) {
- $SelectionMessage = Wrap(sprintf(
- 'You have selected %1$s.',
- Plural($CountDiscussions, '%s discussion', '%s discussions')
- ), 'div');
- $ActionMessage = T('Take Action:');
- $ActionMessage .= ' '.Anchor(T('Delete'), 'vanilla/moderation/confirmdiscussiondeletes/', 'Delete Popup');
-
- $Sender->EventArguments['SelectionMessage'] = &$SelectionMessage;
- $Sender->EventArguments['ActionMessage'] = &$ActionMessage;
- $Sender->FireEvent('BeforeCheckDiscussions');
- $ActionMessage .= ' '.Anchor(T('Cancel'), 'vanilla/moderation/cleardiscussionselections/{TransientKey}/?Target={SelfUrl}', 'CancelAction');
-
- $Sender->InformMessage(
- $SelectionMessage
- .Wrap($ActionMessage, 'div', array('class' => 'Actions')),
- array(
- 'CssClass' => 'NoDismiss',
- 'id' => 'CheckSummary'
- )
- );
- } else if ($HadCheckedDiscussions) {
- // Remove the message completely if there were previously checked comments in this discussion, but none now
- $Sender->InformMessage('', array('id' => 'CheckSummary'));
- }
- }
-
- /**
- * Remove all comments checked for administration from the user's attributes.
- */
- public function ClearCommentSelections($DiscussionID = '', $TransientKey = '') {
- $Session = Gdn::Session();
- if ($Session->ValidateTransientKey($TransientKey)) {
- $CheckedComments = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedComments', array());
- unset($CheckedComments[$DiscussionID]);
- Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedComments', $CheckedComments);
- }
- Redirect(GetIncomingValue('Target', '/discussions'));
- }
- /**
- * Remove all discussions checked for administration from the user's attributes.
- */
- public function ClearDiscussionSelections($TransientKey = '') {
- $Session = Gdn::Session();
- if ($Session->ValidateTransientKey($TransientKey))
- Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
- Redirect(GetIncomingValue('Target', '/discussions'));
- }
-
- /**
- * Form to confirm that the administrator wants to delete the selected
- * comments (and has permission to do so).
- */
- public function ConfirmCommentDeletes($DiscussionID = '') {
- $Session = Gdn::Session();
- $this->Form = new Gdn_Form();
- $DiscussionModel = new DiscussionModel();
- $Discussion = $DiscussionModel->GetID($DiscussionID);
- if (!$Discussion)
- return;
-
- // Verify that the user has permission to perform the delete
- $this->Permission('Vanilla.Comment.Delete', TRUE, 'Category', $Discussion->CategoryID);
- $this->Title(T('Confirm'));
-
- $CheckedComments = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedComments', array());
- if (!is_array($CheckedComments))
- $CheckedComments = array();
-
- $CommentIDs = array();
- $DiscussionIDs = array();
- foreach ($CheckedComments as $DiscID => $Comments) {
- foreach ($Comments as $Comment) {
- if (substr($Comment, 0, 11) == 'Discussion_')
- $DiscussionIDs[] = str_replace('Discussion_', '', $Comment);
- else if ($DiscID == $DiscussionID)
- $CommentIDs[] = str_replace('Comment_', '', $Comment);
- }
- }
- $CountCheckedComments = count($CommentIDs);
- $this->SetData('CountCheckedComments', $CountCheckedComments);
-
- if ($this->Form->AuthenticatedPostBack()) {
- // Delete the selected comments
- $CommentModel = new CommentModel();
- foreach ($CommentIDs as $CommentID) {
- $CommentModel->Delete($CommentID);
- }
- // Clear selections
- unset($CheckedComments[$DiscussionID]);
- Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedComments', $CheckedComments);
- ModerationController::InformCheckedComments($this);
- $this->RedirectUrl = 'discussions';
- }
-
- $this->Render();
- }
-
- /**
- * Form to confirm that the administrator wants to delete the selected
- * discussions (and has permission to do so).
- */
- public function ConfirmDiscussionDeletes() {
- $Session = Gdn::Session();
- $this->Form = new Gdn_Form();
- $DiscussionModel = new DiscussionModel();
-
- // Verify that the user has permission to perform the deletes
- $this->Permission('Vanilla.Comment.Delete', TRUE, 'Category', 'any');
- $this->Title(T('Confirm'));
-
- $CheckedDiscussions = Gdn::UserModel()->GetAttribute($Session->User->UserID, 'CheckedDiscussions', array());
- if (!is_array($CheckedDiscussions))
- $CheckedDiscussions = array();
- $DiscussionIDs = $CheckedDiscussions;
- $CountCheckedDiscussions = count($DiscussionIDs);
- $this->SetData('CountCheckedDiscussions', $CountCheckedDiscussions);
-
- // Check permissions on each discussion to make sure the user has permission to delete them
- $AllowedDiscussions = array();
- $DiscussionData = $DiscussionModel->SQL->Select('DiscussionID, CategoryID')->From('Discussion')->WhereIn('DiscussionID', $DiscussionIDs)->Get();
- foreach ($DiscussionData->Result() as $Discussion) {
- if ($Session->CheckPermission('Vanilla.Discussions.Delete', TRUE, 'Category', $Discussion->CategoryID))
- $AllowedDiscussions[] = $Discussion->DiscussionID;
- }
- $this->SetData('CountAllowed', count($AllowedDiscussions));
- $CountNotAllowed = $CountCheckedDiscussions - count($AllowedDiscussions);
- $this->SetData('CountNotAllowed', $CountNotAllowed);
- if ($this->Form->AuthenticatedPostBack()) {
- // Delete the selected discussions (that the user has permission to delete).
- foreach ($AllowedDiscussions as $DiscussionID) {
- $DiscussionModel->Delete($DiscussionID);
- }
- // Clear selections
- Gdn::UserModel()->SaveAttribute($Session->UserID, 'CheckedDiscussions', FALSE);
- ModerationController::InformCheckedDiscussions($this);
- $this->RedirectUrl = 'discussions';
- }
-
- $this->Render();
- }
- }