Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,43 +11,72 @@
|
||||
namespace IPS\Content\Api\GraphQL;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DomainException;
|
||||
use Exception;
|
||||
use IPS\Api\GraphQL\SafeException;
|
||||
use IPS\Content\Comment;
|
||||
use IPS\Content\Item;
|
||||
use IPS\Content\Reaction;
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\Content\Search\SearchContent;
|
||||
use IPS\core\Reports\Report;
|
||||
use IPS\core\Reports\Types;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\File;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Request;
|
||||
use IPS\Settings;
|
||||
use IPS\Text\Parser;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Base mutator class for comments
|
||||
*/
|
||||
abstract class _CommentMutator extends ContentMutator
|
||||
abstract class CommentMutator extends ContentMutator
|
||||
{
|
||||
|
||||
/**
|
||||
* Report comment
|
||||
* Revoke Comment Report
|
||||
*
|
||||
* @param array $args Arguments
|
||||
* @param Comment $comment Comment
|
||||
*
|
||||
* @return Comment
|
||||
*/
|
||||
protected function _revokeCommentReport( array $args, \IPS\Content\Comment $comment )
|
||||
protected function _revokeCommentReport( array $args, Comment $comment ): Comment
|
||||
{
|
||||
try
|
||||
{
|
||||
$report = \IPS\Db::i()->select( '*', 'core_rc_reports', array( 'id=? AND report_by=? AND date_reported > ?', $args['reportID'], \IPS\Member::loggedIn()->member_id, time() - ( \IPS\Settings::i()->automoderation_report_again_mins * 60 ) ) )->first();
|
||||
$report = Db::i()->select( '*', 'core_rc_reports', array( 'id=? AND report_by=? AND date_reported > ?', $args['reportID'], Member::loggedIn()->member_id, time() - ( Settings::i()->automoderation_report_again_mins * 60 ) ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
catch( UnderflowException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_REPORT', '1F295/1', 403 );
|
||||
throw new SafeException( 'NO_REPORT', '1F295/1', 403 );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$index = \IPS\core\Reports\Report::load( $report['rid'] );
|
||||
$index = Report::load( $report['rid'] );
|
||||
}
|
||||
catch( \OutofRangeException $e )
|
||||
catch( OutofRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_REPORT', '1F295/1', 403 );
|
||||
throw new SafeException( 'NO_REPORT', '1F295/1', 403 );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_rc_reports', array( 'id=?', $args['reportID'] ) );
|
||||
Db::i()->delete( 'core_rc_reports', array( 'id=?', $args['reportID'] ) );
|
||||
|
||||
/* Recalculate, we may have dropped below the threshold needed to hide a thing */
|
||||
$index->runAutomaticModeration();
|
||||
@@ -61,42 +90,46 @@ abstract class _CommentMutator extends ContentMutator
|
||||
/**
|
||||
* Report comment
|
||||
*
|
||||
* @param array $args Arguments
|
||||
* @param Comment $comment Comment
|
||||
*
|
||||
* @return Comment
|
||||
*/
|
||||
protected function _reportComment( array $args, \IPS\Content\Comment $comment )
|
||||
protected function _reportComment( array $args, Comment $comment ): Comment
|
||||
{
|
||||
$class = $this->class;
|
||||
$canReport = $comment->canReport();
|
||||
|
||||
if ( $canReport !== TRUE AND !( $canReport == 'report_err_already_reported' AND \IPS\Settings::i()->automoderation_enabled ) )
|
||||
if ( $canReport !== TRUE AND !( $canReport == 'report_err_already_reported' AND Settings::i()->automoderation_enabled ) )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'CANNOT_REPORT', '1F295/1', 403 );
|
||||
throw new SafeException( 'CANNOT_REPORT', '1F295/1', 403 );
|
||||
}
|
||||
|
||||
$itemIdColumn = $class::$databaseColumnId;
|
||||
$idColumn = $comment::$databaseColumnId;
|
||||
|
||||
if ( \IPS\Member::loggedIn()->member_id and \IPS\Settings::i()->automoderation_enabled )
|
||||
if ( Member::loggedIn()->member_id and Settings::i()->automoderation_enabled )
|
||||
{
|
||||
/* Has this member already reported this in the past 24 hours */
|
||||
try {
|
||||
$index = \IPS\core\Reports\Report::loadByClassAndId( \get_class( $comment ), $comment->$idColumn );
|
||||
$report = \IPS\Db::i()->select( '*', 'core_rc_reports', array( 'rid=? and report_by=? and date_reported > ?', $index->id, \IPS\Member::loggedIn()->member_id, time() - ( \IPS\Settings::i()->automoderation_report_again_mins * 60 ) ) );
|
||||
$index = Report::loadByClassAndId( get_class( $comment ), $comment->$idColumn );
|
||||
$report = Db::i()->select( '*', 'core_rc_reports', array( 'rid=? and report_by=? and date_reported > ?', $index->id, Member::loggedIn()->member_id, time() - ( Settings::i()->automoderation_report_again_mins * 60 ) ) );
|
||||
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'ALREADY_REPORTED', '1F295/1', 403 );
|
||||
throw new SafeException( 'ALREADY_REPORTED', '1F295/1', 403 );
|
||||
}
|
||||
catch( \Exception $e ) {
|
||||
if( $e instanceof \IPS\Api\GraphQL\SafeException ){
|
||||
catch( Exception $e ) {
|
||||
if( $e instanceof SafeException ){
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
if( !\in_array( $args['reason'], array_keys( \IPS\core\Reports\Types::roots() ) ) && $args['reason'] !== 0 )
|
||||
if( !in_array( $args['reason'], array_keys( Types::roots() ) ) && $args['reason'] !== 0 )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_REASON', '1F295/1', 403 );
|
||||
throw new SafeException( 'INVALID_REASON', '1F295/1', 403 );
|
||||
}
|
||||
}
|
||||
|
||||
if( !\IPS\Settings::i()->automoderation_enabled )
|
||||
if( !Settings::i()->automoderation_enabled )
|
||||
{
|
||||
$args['reason'] = 0;
|
||||
}
|
||||
@@ -107,9 +140,9 @@ abstract class _CommentMutator extends ContentMutator
|
||||
{
|
||||
$comment->report( $args['additionalInfo'], $args['reason'] );
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'REPORT_FAILED', '1F295/1', 403 );
|
||||
throw new SafeException( 'REPORT_FAILED', '1F295/1', 403 );
|
||||
}
|
||||
|
||||
|
||||
@@ -120,18 +153,18 @@ abstract class _CommentMutator extends ContentMutator
|
||||
* Comment reactions
|
||||
*
|
||||
* @param int $reactionID ID of reaction to add
|
||||
* @param \IPS\Content\Comment $comment The comment to add a reaction on
|
||||
* @param Comment $comment The comment to add a reaction on
|
||||
* @return void
|
||||
*/
|
||||
protected function _reactComment( $reactionID, \IPS\Content\Comment $comment )
|
||||
protected function _reactComment( int $reactionID, Comment $comment ): void
|
||||
{
|
||||
try
|
||||
{
|
||||
$reaction = \IPS\Content\Reaction::load( $reactionID );
|
||||
$reaction = Reaction::load( $reactionID );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_REACTION', '1F295/1', 403 );
|
||||
throw new SafeException( 'INVALID_REACTION', '1F295/1', 403 );
|
||||
}
|
||||
|
||||
$comment->react( $reaction );
|
||||
@@ -140,43 +173,44 @@ abstract class _CommentMutator extends ContentMutator
|
||||
/**
|
||||
* Remove comment reaction
|
||||
*
|
||||
* @param \IPS\Content\Comment $comment The comment to remove the reaction on
|
||||
* @param Comment $comment The comment to remove the reaction on
|
||||
* @return void
|
||||
*/
|
||||
protected function _unreactComment( \IPS\Content\Comment $comment )
|
||||
protected function _unreactComment( Comment $comment ): void
|
||||
{
|
||||
try {
|
||||
$comment->removeReaction();
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_REACTIONS', '1F295/1', 403 );
|
||||
throw new SafeException( 'NO_REACTIONS', '1F295/1', 403 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create
|
||||
*
|
||||
* @param array $commentData Array of data used to generate comment
|
||||
* @param \IPS\Content\Item $item Content Item
|
||||
* @param string $postKey Post key
|
||||
* @return \IPS\Content\Comment
|
||||
* @param array $commentData Array of data used to generate comment
|
||||
* @param Item $item Content Item
|
||||
* @param string|null $postKey Post key
|
||||
* @param Comment|null $replyTo Reply To
|
||||
* @return Comment
|
||||
*/
|
||||
protected function _createComment( array $commentData, \IPS\Content\Item $item, string $postKey = NULL, $replyTo = NULL )
|
||||
protected function _createComment( array $commentData, Item $item, string|null $postKey = NULL, Comment|null $replyTo = NULL ): Comment
|
||||
{
|
||||
/* Work out the date */
|
||||
$date = \IPS\DateTime::create();
|
||||
$date = DateTime::create();
|
||||
$hidden = false;
|
||||
$quoteHtml = '';
|
||||
|
||||
if( $replyTo !== NULL && $replyTo instanceof \IPS\Content\Comment ){
|
||||
if( $replyTo instanceof Comment ){
|
||||
try {
|
||||
$idField = $replyTo::$databaseColumnId;
|
||||
$app = $replyTo::$application;
|
||||
$replyToItem = $replyTo->item();
|
||||
$contentType = $replyToItem::$module;
|
||||
$itemClassSafe = str_replace( '\\', '_', mb_substr( $replyTo::$itemClass, 4 ) );
|
||||
$citationLang = \IPS\Member::loggedIn()->language()->get('_date_just_now_c') . ', ' . $replyTo->mapped('author_name');
|
||||
$citationLang = Member::loggedIn()->language()->get('_date_just_now_c') . ', ' . $replyTo->mapped('author_name');
|
||||
|
||||
$quoteHtml = <<<HTML
|
||||
<blockquote class="ipsQuote" data-ipsquote="" data-ipsquote-contentapp="{$app}" data-ipsquote-contentclass="{$itemClassSafe}" data-ipsquote-contentcommentid="{$replyTo->mapped('id')}" data-ipsquote-contentid="{$replyTo->item()->mapped('id')}" data-ipsquote-contenttype="{$contentType}" data-ipsquote-timestamp="{$replyTo->mapped('date')}" data-ipsquote-userid="{$replyTo->author()->member_id}" data-ipsquote-username="{$replyTo->mapped('author_name')}">
|
||||
@@ -186,7 +220,7 @@ abstract class _CommentMutator extends ContentMutator
|
||||
<div class='ipsQuote_contents'>{$replyTo->mapped('content')}</div>
|
||||
</blockquote>
|
||||
HTML;
|
||||
} catch ( \Exception $err ) {
|
||||
} catch ( Exception $err ) {
|
||||
// If something goes wrong here, it isn't a big deal - just continue without the quote
|
||||
}
|
||||
}
|
||||
@@ -199,14 +233,14 @@ HTML;
|
||||
{
|
||||
$this->_addAttachmentsToContent( $postKey, $commentData['content'] );
|
||||
}
|
||||
catch ( \DomainException $e )
|
||||
catch ( DomainException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'ATTACHMENTS_TOO_LARGE', '2S400/2', 403 );
|
||||
throw new SafeException( 'ATTACHMENTS_TOO_LARGE', '2S400/2', 403 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse */
|
||||
$content = $quoteHtml . \IPS\Text\Parser::parseStatic( $commentData['content'], TRUE, md5( $postKey . ':' ), \IPS\Member::loggedIn(), $item::$application . '_' . mb_ucfirst( $item::$module ) );
|
||||
$content = $quoteHtml . Parser::parseStatic( $commentData['content'], array( md5( $postKey . ':' ) ), Member::loggedIn(), $item::$application . '_' . IPS::mb_ucfirst( $item::$module ) );
|
||||
|
||||
/* Create post */
|
||||
$class = $this->class;
|
||||
@@ -216,40 +250,40 @@ HTML;
|
||||
}
|
||||
else
|
||||
{*/
|
||||
$comment = $class::create( $item, $content, FALSE, \IPS\Member::loggedIn()->member_id ? NULL : \IPS\Member::loggedIn()->real_name, NULL, \IPS\Member::loggedIn(), $date, \IPS\Request::i()->ipAddress() );
|
||||
$comment = $class::create( $item, $content, FALSE, Member::loggedIn()->member_id ? NULL : Member::loggedIn()->real_name, NULL, Member::loggedIn(), $date, Request::i()->ipAddress() );
|
||||
/*}*/
|
||||
$itemIdColumn = $item::$databaseColumnId;
|
||||
$commentIdColumn = $comment::$databaseColumnId;
|
||||
\IPS\File::claimAttachments( "{$postKey}:", $item->$itemIdColumn, $comment->$commentIdColumn );
|
||||
File::claimAttachments( "{$postKey}:", $item->$itemIdColumn, $comment->$commentIdColumn );
|
||||
|
||||
/* Index */
|
||||
if ( $item instanceof \IPS\Content\Searchable )
|
||||
if( SearchContent::isSearchable( $item ) )
|
||||
{
|
||||
if ( $item::$firstCommentRequired and !$comment->isFirst() )
|
||||
{
|
||||
if ( \in_array( 'IPS\Content\Searchable', class_implements( $class ) ) )
|
||||
if( SearchContent::isSearchable( $class ) )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( $item->firstComment() );
|
||||
Index::i()->index( $item->firstComment() );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( $item );
|
||||
Index::i()->index( $item );
|
||||
}
|
||||
}
|
||||
if ( $comment instanceof \IPS\Content\Searchable )
|
||||
if( SearchContent::isSearchable( $comment ) )
|
||||
{
|
||||
\IPS\Content\Search\Index::i()->index( $comment );
|
||||
Index::i()->index( $comment );
|
||||
}
|
||||
|
||||
/* Hide */
|
||||
if ( isset( $commentData['hidden'] ) and \IPS\Member::loggedIn()->member_id and $comment->canHide() )
|
||||
if ( isset( $commentData['hidden'] ) and Member::loggedIn()->member_id and $comment->canHide() )
|
||||
{
|
||||
$comment->hide( \IPS\Member::loggedIn() );
|
||||
$comment->hide( Member::loggedIn() );
|
||||
}
|
||||
|
||||
/* Mark it as read */
|
||||
if( $item instanceof \IPS\Content\ReadMarkers )
|
||||
if( IPS::classUsesTrait( $item, 'IPS\Content\ReadMarkers' ) )
|
||||
{
|
||||
$item->markRead();
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user