Version 5.0.0 beta 4
This commit is contained in:
1 parent
e86153356a
commit
2f24f9de48
276 files changed
+8614
-6044
No files matched your search
@@ -14,6 +14,7 @@ namespace IPS\core\Reports;
|
||||
|
||||
use Exception;
|
||||
use InvalidArgumentException;
|
||||
use IPS\Application;
|
||||
use IPS\Content;
|
||||
use IPS\Content\Comment;
|
||||
use IPS\Content\Item;
|
||||
@@ -21,10 +22,13 @@ use IPS\Content\ReadMarkers;
|
||||
use IPS\core\Reports\Comment as ReportComment;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Email;
|
||||
use IPS\Http\Url;
|
||||
use IPS\IPS;
|
||||
use IPS\Log;
|
||||
use IPS\Member;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Notification;
|
||||
use IPS\Session;
|
||||
use IPS\Settings;
|
||||
use IPS\Theme;
|
||||
@@ -53,7 +57,14 @@ class Report extends Item
|
||||
* @brief Const No type selected
|
||||
*/
|
||||
const TYPE_MESSAGE = 0;
|
||||
|
||||
|
||||
/**
|
||||
* @brief Const Reported content statuses
|
||||
*/
|
||||
const STATUS_NEW = 1;
|
||||
const STATUS_OPEN = 2;
|
||||
const STATUS_CLOSED = 3;
|
||||
const STATUS_REJECTED = 4;
|
||||
|
||||
/* !\IPS\Patterns\ActiveRecord */
|
||||
|
||||
@@ -137,7 +148,210 @@ class Report extends Item
|
||||
* @var bool
|
||||
*/
|
||||
public static bool $skipIndexNow = TRUE;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get all the report types for this report index
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getReportedTypes(): array
|
||||
{
|
||||
$reportedTypes = [];
|
||||
$reportTypes = [];
|
||||
foreach ( Types::roots() as $type )
|
||||
{
|
||||
$reportTypes[ $type->id ] = $type->_title;
|
||||
}
|
||||
|
||||
foreach ( Db::i()->select( '*', 'core_rc_reports', ['rid=? and report_type > 0', $this->id] ) as $report )
|
||||
{
|
||||
if ( isset( $reportTypes[ $report['report_type'] ] ) )
|
||||
{
|
||||
$reportedTypes[ $report['report_type'] ] = $reportTypes[ $report['report_type'] ];
|
||||
}
|
||||
}
|
||||
|
||||
return $reportedTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the status of the report
|
||||
*
|
||||
* @param int $status
|
||||
* @param int $authorNotification
|
||||
* @param null $member
|
||||
* @return void
|
||||
*/
|
||||
public function changeStatus( int $status, int $authorNotification=0, $member=null ): void
|
||||
{
|
||||
$member = $member ?: Member::loggedIn();
|
||||
$this->status = $status;
|
||||
$this->save();
|
||||
|
||||
/* We only need to notify if there is an outcome */
|
||||
if ( $status == static::STATUS_CLOSED or static::STATUS_REJECTED )
|
||||
{
|
||||
$forNotifications = [];
|
||||
$forEmails = [];
|
||||
|
||||
/* Now go through all the individual reports and see if we need to notify anyone */
|
||||
foreach ( Db::i()->select( '*', 'core_rc_reports', ['rid=?', $this->id] ) as $report )
|
||||
{
|
||||
if ( !$report['report_type'] )
|
||||
{
|
||||
/* We have not selected a reason, no nothing to worry about */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Get the report type object */
|
||||
try
|
||||
{
|
||||
$reportType = Types::load( $report['report_type'] );
|
||||
$reportMember = Member::load( $report['report_by'] );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( $report['report_by'] )
|
||||
{
|
||||
/* We have a member */
|
||||
$forNotifications[$report['report_type']][] = [$reportMember, $reportType, $report];
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( $report['guest_email'] )
|
||||
{
|
||||
/* We have an email */
|
||||
$forEmails[$report['report_type']][] = [$reportType, $report];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Members */
|
||||
foreach ( $forNotifications as $typeId => $data )
|
||||
{
|
||||
foreach ( $data as $reportData )
|
||||
{
|
||||
$reportMember = $reportData[0];
|
||||
$reportType = $reportData[1];
|
||||
$userReport = $reportData[2];
|
||||
|
||||
if ( $this->getReportOutcomeBlurb( $userReport['id'] ) )
|
||||
{
|
||||
$notification = new Notification( Application::load( 'core' ), 'report_outcome', $this, [$this, $reportType, $userReport], ['reportType' => $reportType->id, 'userReport' => $userReport] );
|
||||
$notification->recipients->attach( $reportMember );
|
||||
$notification->send();
|
||||
Log::debug( "Sent notification to {$reportMember->name}", 'reports_notification' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Guests */
|
||||
foreach ( $forEmails as $typeId => $data )
|
||||
{
|
||||
foreach ( $data as $reportData )
|
||||
{
|
||||
$reportType = $reportData[0];
|
||||
$guestEmail = $reportData[1]['guest_email'];
|
||||
$userReport = $reportData[1];
|
||||
|
||||
if ( $guestEmail and $this->getReportOutcomeBlurb( $userReport['id'] ) )
|
||||
{
|
||||
Email::buildFromTemplate( 'core', 'notification_report_outcome', [$this, $reportType, $userReport], Email::TYPE_LIST )->send( $guestEmail );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Content author? */
|
||||
if ( $authorNotification )
|
||||
{
|
||||
try
|
||||
{
|
||||
$class = $this->_data['class'];
|
||||
$thing = $class::load( $this->_data['content_id'] );
|
||||
$content = ( $thing instanceof Comment ) ? $thing->truncated() : $thing->mapped( 'title' );
|
||||
|
||||
if ( $thing->author() and $thing->author()->email )
|
||||
{
|
||||
$authorContent = static::getAuthorNotifications();
|
||||
|
||||
if ( isset( $authorContent[ $authorNotification ] ) )
|
||||
{
|
||||
$notificationContent = $authorContent[$authorNotification]['text'];
|
||||
|
||||
/* Substitutions */
|
||||
$subs = [
|
||||
'name' => $thing->author()->name,
|
||||
'content' => trim( $content ),
|
||||
'link' => (string) $thing->url(),
|
||||
'reason' => implode( ', ', $this->getReportedTypes() )
|
||||
];
|
||||
|
||||
foreach( $subs as $key => $value )
|
||||
{
|
||||
$notificationContent = str_replace( '{' . $key . '}', $value, $notificationContent );
|
||||
}
|
||||
|
||||
Email::buildFromTemplate( 'core', 'notification_report_content_author', [$this, $thing, $notificationContent], Email::TYPE_LIST )->send( $thing->author()->email );
|
||||
}
|
||||
}
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Post a comment on the report */
|
||||
$content = $member->language()->addToStack( 'update_report_status_content', FALSE, array( 'sprintf' => array( $member->language()->addToStack( 'report_status_' . $this->status ) ) ) );
|
||||
$member->language()->parseOutputForDisplay( $content );
|
||||
|
||||
$comment = ReportComment::create( $this, $content, TRUE, NULL, NULL, $member, new DateTime );
|
||||
$comment->save();
|
||||
|
||||
/* And add to the moderator log */
|
||||
Session::i()->modLog( 'modlog__action_update_report_status', array( $this->url()->__toString() => FALSE ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the author notifications
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function getAuthorNotifications(): array
|
||||
{
|
||||
$return = [];
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_rc_author_notification_text', [], 'title ASC' ) as $row )
|
||||
{
|
||||
$return[ $row['id'] ] = $row;
|
||||
}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the report outcome blurb
|
||||
*
|
||||
* @param int $userReportId
|
||||
* @return string
|
||||
*/
|
||||
public function getReportOutcomeBlurb( int $userReportId ): string
|
||||
{
|
||||
try
|
||||
{
|
||||
$userReport = Db::i()->select( '*', 'core_rc_reports', array( 'id=?', $userReportId ) )->first();
|
||||
$reportType = Types::load( $userReport['report_type'] );
|
||||
return $this->status === static::STATUS_REJECTED ? $reportType->getRejectedNotificationText( Member::load( $userReport['report_by'] ) ) : $reportType->getCompletedNotificationText( Member::load( $userReport['report_by'] ) );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Should posting this increment the poster's post count?
|
||||
*
|
||||
@@ -389,18 +603,7 @@ class Report extends Item
|
||||
{
|
||||
if ( mb_substr( $action, 0, -1 ) === 'report_status_' )
|
||||
{
|
||||
$this->status = mb_substr( $action, -1 );
|
||||
$this->save();
|
||||
|
||||
/* Post a comment on the report */
|
||||
$content = Member::loggedIn()->language()->addToStack( 'update_report_status_content', FALSE, array( 'sprintf' => array( Member::loggedIn()->language()->addToStack( 'report_status_' . $this->status ) ) ) );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $content );
|
||||
|
||||
$comment = ReportComment::create( $this, $content, true, null, null, Member::loggedIn(), new DateTime );
|
||||
$comment->save();
|
||||
|
||||
/* And add to the moderator log */
|
||||
Session::i()->modLog( 'modlog__action_update_report_status', array( $this->url()->__toString() => FALSE ) );
|
||||
$this->changeStatus( (int) mb_substr( $action, -1 ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -415,7 +618,7 @@ class Report extends Item
|
||||
*/
|
||||
public function customMultimodActions(): array
|
||||
{
|
||||
return array_diff( array( 'report_status_1', 'report_status_2', 'report_status_3', ), array( 'report_status_' . $this->status ) );
|
||||
return array_diff( array( 'report_status_1', 'report_status_2', 'report_status_3', 'report_status_4'), array( 'report_status_' . $this->status ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -446,6 +649,11 @@ class Report extends Item
|
||||
'action' => 'report_status_3',
|
||||
'icon' => 'check-circle',
|
||||
'label' => 'report_status_3'
|
||||
),
|
||||
array(
|
||||
'action' => 'report_status_4',
|
||||
'icon' => 'archive',
|
||||
'label' => 'report_status_4'
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@@ -80,7 +80,30 @@ class Types extends Model
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static ?string $titleLangPrefix = 'automaticmod_types_';
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the completed notification text (hits the DB to get the real value, not the hash key)
|
||||
* @param Member|null $member
|
||||
* @return string
|
||||
*/
|
||||
public function getCompletedNotificationText( \IPS\Member|null $member=null ): string
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
return $member->language()->get( 'automaticmod_types_notify_complete_' . $this->id, 'core' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rejected notification text (hits the DB to get the real value, not the hash key)
|
||||
* @param Member|null $member
|
||||
* @return string
|
||||
*/
|
||||
public function getRejectedNotificationText( \IPS\Member|null $member=null ): string
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
return $member->language()->get( 'automaticmod_types_notify_reject_' . $this->id, 'core' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Form
|
||||
*
|
||||
@@ -90,6 +113,8 @@ class Types extends Model
|
||||
public function form( Form &$form ) : void
|
||||
{
|
||||
$form->add( new Translatable( 'automaticmod_types_title', NULL, TRUE, array( 'app' => 'core', 'key' => ( $this->id ? 'automaticmod_types_' . $this->id : NULL ) ) ) );
|
||||
$form->add( new Translatable( 'automaticmod_types_notify_complete', NULL, FALSE, array( 'textArea' => true, 'app' => 'core', 'key' => ( $this->id ? 'automaticmod_types_notify_complete_' . $this->id : NULL ) ) ) );
|
||||
$form->add( new Translatable( 'automaticmod_types_notify_reject', NULL, FALSE, array( 'textArea' => true, 'app' => 'core', 'key' => ( $this->id ? 'automaticmod_types_notify_reject_' . $this->id : NULL ) ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,8 +132,11 @@ class Types extends Model
|
||||
|
||||
/* Save the title */
|
||||
Lang::saveCustom( 'core', 'automaticmod_types_' . $this->id, $values['automaticmod_types_title'] );
|
||||
|
||||
unset( $values['automaticmod_types_title'] );
|
||||
|
||||
/* Save the notification text */
|
||||
Lang::saveCustom( 'core', 'automaticmod_types_notify_complete_' . $this->id, $values['automaticmod_types_notify_complete'] );
|
||||
Lang::saveCustom( 'core', 'automaticmod_types_notify_reject_' . $this->id, $values['automaticmod_types_notify_reject'] );
|
||||
unset( $values['automaticmod_types_title'], $values['automaticmod_types_notify_complete'], $values['automaticmod_types_notify_reject'] );
|
||||
|
||||
return parent::formatFormValues( $values );
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user