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
+63
-49
@@ -11,9 +11,24 @@
|
||||
namespace IPS\Content;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Api\Webhook;
|
||||
use IPS\Application;
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Notification;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function get_class;
|
||||
use function in_array;
|
||||
use function is_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;
|
||||
}
|
||||
|
||||
@@ -25,43 +40,36 @@ trait Solvable
|
||||
/**
|
||||
* Container has solvable enabled
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public function containerAllowsSolvable()
|
||||
{
|
||||
throw new \BadMethodCallException;
|
||||
}
|
||||
abstract public function containerAllowsSolvable(): bool;
|
||||
|
||||
/**
|
||||
* Container has solvable enabled
|
||||
*
|
||||
* @return string
|
||||
* @return bool
|
||||
*/
|
||||
public function containerAllowsMemberSolvable()
|
||||
{
|
||||
throw new \BadMethodCallException;
|
||||
}
|
||||
abstract public function containerAllowsMemberSolvable(): bool;
|
||||
|
||||
/**
|
||||
* Any container has solvable enabled?
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static function anyContainerAllowsSolvable()
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
abstract public static function anyContainerAllowsSolvable(): bool;
|
||||
|
||||
/**
|
||||
* Toggle the solve value of a comment
|
||||
*
|
||||
* @param int $commentId The comment ID
|
||||
* @param boolean $value TRUE/FALSE value
|
||||
* @param \IPS\Member $member The member (null for currently logged in member)
|
||||
* @param Member|null $member The member (null for currently logged in member)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function toggleSolveComment( $commentId, $value, \IPS\Member $member = NULL )
|
||||
public function toggleSolveComment( int $commentId, bool $value, ?Member $member = NULL ): void
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
$commentClass = static::$commentClass;
|
||||
$commentIdField = $commentClass::$databaseColumnId;
|
||||
@@ -82,27 +90,29 @@ trait Solvable
|
||||
$oldComment->setSolved( FALSE );
|
||||
$oldComment->save();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array( 'comment_class=? AND comment_id=?', $commentClass, $oldComment->$commentIdField ) );
|
||||
Db::i()->delete( 'core_solved_index', array( 'comment_class=? AND comment_id=? AND type=?', $commentClass, $oldComment->$commentIdField, 'solved' ) );
|
||||
}
|
||||
catch( \Exception $e ) { }
|
||||
catch( Exception ) { }
|
||||
}
|
||||
|
||||
$this->$solvedField = $comment->$commentIdField;
|
||||
$this->save();
|
||||
|
||||
\IPS\Db::i()->insert( 'core_solved_index', array(
|
||||
Db::i()->insert( 'core_solved_index', array(
|
||||
'member_id' => (int) $comment->author()->member_id,
|
||||
'app' => $commentClass::$application,
|
||||
'comment_class' => $commentClass,
|
||||
'comment_id' => $comment->$commentIdField,
|
||||
'item_id' => $this->$idField,
|
||||
'solved_date' => time()
|
||||
'solved_date' => time(),
|
||||
'type' => 'solved',
|
||||
'node_id' => $comment->item()->container()->_id
|
||||
) );
|
||||
|
||||
/* Send the "solution to your topic" notification but only if we didn't post the solution, we're not marking the solution, we can view the content, and the user isn't ignored */
|
||||
if ( $this->author()->member_id AND $comment->author() != $this->author() AND $this->author() != $member AND $this->canView( $this->author() ) AND !$this->author()->isIgnoring( $comment->author(), 'posts' ) )
|
||||
if ( $this->author()->member_id AND $comment->author() != $this->author() AND $this->author() !== $member AND $this->canView( $this->author() ) AND !$this->author()->isIgnoring( $comment->author(), 'posts' ) )
|
||||
{
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'mine_solved', $this, array( $this, $comment, $member ), array(), TRUE, NULL );
|
||||
$notification = new Notification( Application::load('core'), 'mine_solved', $this, array( $this, $comment, $member ), array(), TRUE, NULL );
|
||||
$notification->recipients->attach( $this->author() );
|
||||
$notification->send();
|
||||
}
|
||||
@@ -110,7 +120,7 @@ trait Solvable
|
||||
/* Send the "you solved the topic" notification but only if we didn't mark the solution */
|
||||
if ( $comment->author()->member_id AND $comment->author() != $member )
|
||||
{
|
||||
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'my_solution', $this, array( $this, $comment, $member ), array(), TRUE, NULL );
|
||||
$notification = new Notification( Application::load('core'), 'my_solution', $this, array( $this, $comment, $member ), array(), TRUE, NULL );
|
||||
$notification->recipients->attach( $comment->author() );
|
||||
$notification->send();
|
||||
}
|
||||
@@ -120,32 +130,32 @@ trait Solvable
|
||||
'comment' => $comment,
|
||||
'markedBy' => $member
|
||||
];
|
||||
\IPS\Api\Webhook::fire( 'content_marked_solved', $payload );
|
||||
Webhook::fire( 'content_marked_solved', $payload );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->$solvedField = 0;
|
||||
$this->save();
|
||||
|
||||
\IPS\Db::i()->delete( 'core_solved_index', array( 'comment_class=? and comment_id=?', $commentClass, $comment->$commentIdField ) );
|
||||
Db::i()->delete( 'core_solved_index', array( 'comment_class=? and comment_id=? AND type=?', $commentClass, $comment->$commentIdField, 'solved' ) );
|
||||
|
||||
$memberIds = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '`member`', 'core_notifications', array( \IPS\Db::i()->in( 'notification_key', array( 'mine_solved', 'my_solution' ) ) . ' AND item_class=? AND item_id=?', (string) \get_class( $this ), (int) $this->$idField ) ) as $memberToRecount )
|
||||
foreach( Db::i()->select( '`member`', 'core_notifications', array( Db::i()->in( 'notification_key', array( 'mine_solved', 'my_solution' ) ) . ' AND item_class=? AND item_id=?', get_class( $this ), (int) $this->$idField ) ) as $memberToRecount )
|
||||
{
|
||||
$memberIds[ $memberToRecount ] = $memberToRecount;
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'core_notifications', array( \IPS\Db::i()->in( 'notification_key', array( 'mine_solved', 'my_solution' ) ) . ' AND item_class=? AND item_id=?', (string) \get_class( $this ), (int) $this->$idField ) );
|
||||
Db::i()->delete( 'core_notifications', array( Db::i()->in( 'notification_key', array( 'mine_solved', 'my_solution' ) ) . ' AND item_class=? AND item_id=?', get_class( $this ), (int) $this->$idField ) );
|
||||
|
||||
foreach( $memberIds as $memberToRecount )
|
||||
{
|
||||
\IPS\Member::load( $memberToRecount )->recountNotifications();
|
||||
Member::load( $memberToRecount )->recountNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/* Update search index */
|
||||
\IPS\Content\Search\Index::i()->index( $comment );
|
||||
Index::i()->index( $comment );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -154,7 +164,7 @@ trait Solvable
|
||||
* @param array $items Item data (will be an array containing values from basicDataColumns())
|
||||
* @return array
|
||||
*/
|
||||
public static function searchResultExtraData( $items )
|
||||
public static function searchResultExtraData( array $items ): array
|
||||
{
|
||||
$itemIds = array();
|
||||
$idField = static::$databaseColumnId;
|
||||
@@ -167,7 +177,7 @@ trait Solvable
|
||||
}
|
||||
}
|
||||
|
||||
if ( \count( $itemIds ) )
|
||||
if ( count( $itemIds ) )
|
||||
{
|
||||
foreach ( static::getItemsWithPermission( array(array( $idField . ' IN(' . implode( ',', $itemIds ) . ')') ), NULL, NULL ) as $row )
|
||||
{
|
||||
@@ -185,7 +195,7 @@ trait Solvable
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isSolved()
|
||||
public function isSolved(): bool
|
||||
{
|
||||
return ( ( $this->containerAllowsMemberSolvable() OR $this->containerAllowsSolvable() ) and $this->mapped('solved_comment_id') );
|
||||
}
|
||||
@@ -193,14 +203,14 @@ trait Solvable
|
||||
/**
|
||||
* Is this a non-admin/mod but can solve this item?
|
||||
*
|
||||
* @param \IPS\Member|null $member The member (null for currently logged in member)
|
||||
* @param Member|null $member The member (null for currently logged in member)
|
||||
* @return boolean
|
||||
*/
|
||||
public function isNotModeratorButCanSolve( \IPS\Member $member = NULL ): bool
|
||||
public function isNotModeratorButCanSolve( ?Member $member = NULL ): bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if ( $this->canSolve( $member ) and $member === $this->author() and $this->containerAllowsMemberSolvable() and ! $member->modPermissions() )
|
||||
if ( $this->canSolve( $member ) and $member->member_id === $this->author()->member_id and $this->containerAllowsMemberSolvable() and ! $member->modPermissions() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -211,12 +221,17 @@ trait Solvable
|
||||
/**
|
||||
* Can user solve this item?
|
||||
*
|
||||
* @param \IPS\Member|null $member The member (null for currently logged in member)
|
||||
* @param Member|null $member The member (null for currently logged in member)
|
||||
* @return bool
|
||||
*/
|
||||
public function canSolve( \IPS\Member $member = NULL )
|
||||
public function canSolve( ?Member $member = NULL ): bool
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
if( !$this->actionEnabled( 'solve', $member ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$member = $member ?: Member::loggedIn();
|
||||
|
||||
if( isset( static::$archiveClass ) AND method_exists( $this, 'isArchived' ) AND $this->isArchived() )
|
||||
{
|
||||
@@ -231,7 +246,7 @@ trait Solvable
|
||||
|
||||
if ( $this->containerAllowsSolvable() )
|
||||
{
|
||||
if ( $member === $this->author() and $this->containerAllowsMemberSolvable() )
|
||||
if ( $member->member_id === $this->author()->member_id and $this->containerAllowsMemberSolvable() )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
@@ -253,9 +268,9 @@ trait Solvable
|
||||
( $member->modPermission( $container::$modPerm ) === TRUE or $member->modPermission( $container::$modPerm ) === -1 )
|
||||
or
|
||||
(
|
||||
\is_array( $member->modPermission( $container::$modPerm ) )
|
||||
is_array( $member->modPermission( $container::$modPerm ) )
|
||||
and
|
||||
\in_array( $this->container()->_id, $member->modPermission( $container::$modPerm ) )
|
||||
in_array( $this->container()->_id, $member->modPermission( $container::$modPerm ) )
|
||||
)
|
||||
)
|
||||
)
|
||||
@@ -271,17 +286,16 @@ trait Solvable
|
||||
/**
|
||||
* Get the solution
|
||||
*
|
||||
* @return \IPS\Content\Comment|NULL
|
||||
* @return Comment|NULL
|
||||
*/
|
||||
public function getSolution()
|
||||
public function getSolution(): Comment|NULL
|
||||
{
|
||||
try
|
||||
{
|
||||
$commentClass = static::$commentClass;
|
||||
|
||||
return $commentClass::load( $this->mapped('solved_comment_id') );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user