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
+132
-123
@@ -11,9 +11,23 @@
|
||||
namespace IPS\Content;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use Exception;
|
||||
use IPS\Application;
|
||||
use IPS\Content\Search\Index;
|
||||
use IPS\DateTime;
|
||||
use IPS\forums\Forum;
|
||||
use IPS\forums\Topic;
|
||||
use IPS\forums\Topic\Post;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -28,41 +42,38 @@ trait ItemTopic
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract function getTopicTitle();
|
||||
abstract function getTopicTitle(): string;
|
||||
|
||||
/**
|
||||
* Get the topic content
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
abstract function getTopicContent();
|
||||
abstract function getTopicContent(): mixed;
|
||||
|
||||
/**
|
||||
* Get the database column which stores the topic ID
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public static function topicIdColumn()
|
||||
public static function topicIdColumn(): string
|
||||
{
|
||||
return 'topicid';
|
||||
return static::$databaseColumnMap['item_topicid'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the database column which stores the forum ID
|
||||
* Return the Forum ID
|
||||
*
|
||||
* @return string
|
||||
* @return int
|
||||
*/
|
||||
public static function containerForumIdColumn()
|
||||
{
|
||||
return 'forum_id';
|
||||
}
|
||||
abstract function getForumId() : int;
|
||||
|
||||
/**
|
||||
* Create/Update Topic
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function syncTopic()
|
||||
public function syncTopic(): void
|
||||
{
|
||||
/* If this item is pending deletion, do nothing */
|
||||
if( $this->hidden() == -2 )
|
||||
@@ -71,7 +82,6 @@ trait ItemTopic
|
||||
}
|
||||
|
||||
$column = static::topicIdColumn();
|
||||
$containercolumn = static::containerForumIdColumn();
|
||||
|
||||
/* Existing topic */
|
||||
if ( $this->$column )
|
||||
@@ -79,15 +89,11 @@ trait ItemTopic
|
||||
/* Get */
|
||||
try
|
||||
{
|
||||
$topic = \IPS\forums\Topic::load( $this->$column );
|
||||
if ( !$topic )
|
||||
{
|
||||
return;
|
||||
}
|
||||
$topic = Topic::load( $this->$column );
|
||||
$title = $this->getTopicTitle();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $title );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $title );
|
||||
$topic->title = $title;
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
if ( Settings::i()->tags_enabled )
|
||||
{
|
||||
$topic->setTags( $this->prefix() ? array_merge( $this->tags(), array( 'prefix' => $this->prefix() ) ) : $this->tags() );
|
||||
}
|
||||
@@ -97,64 +103,72 @@ trait ItemTopic
|
||||
/* If the first post of the topic is missing, NULL will be returned */
|
||||
if( $firstPost === NULL )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$content = $this->getTopicContent();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $content );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $content );
|
||||
$firstPost->post = $content;
|
||||
$firstPost->save();
|
||||
\IPS\Content\Search\Index::i()->index( $firstPost );
|
||||
Index::i()->index( $firstPost );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* New topic */
|
||||
else
|
||||
elseif( !isset( static::$skipTopicCreation ) or !static::$skipTopicCreation )
|
||||
{
|
||||
/* Create topic */
|
||||
try
|
||||
{
|
||||
$forum = \IPS\forums\Forum::load( $this->container()->$containercolumn );
|
||||
$forum = Forum::load( $this->getForumId() );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
catch( OutOfRangeException )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$topic = \IPS\forums\Topic::createItem( $this->author(), $this->mapped('ip_address'), \IPS\DateTime::ts( $this->mapped('date') ), $forum, $this->hidden() );
|
||||
$topic = Topic::createItem( $this->author(), $this->mapped('ip_address'), DateTime::ts( $this->mapped('date') ), $forum, $this->hidden() );
|
||||
$title = $this->getTopicTitle();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $title );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $title );
|
||||
$topic->title = $title;
|
||||
$topic->topic_archive_status = \IPS\forums\Topic::ARCHIVE_EXCLUDE;
|
||||
$topic->topic_archive_status = Topic::ARCHIVE_EXCLUDE;
|
||||
$topic->save();
|
||||
|
||||
if( $this->isAnonymous() )
|
||||
if( IPS::classUsesTrait( $this, 'IPS\Content\Anonymous' ) AND $this->isAnonymous() )
|
||||
{
|
||||
$topic->setAnonymous( TRUE, $this->author );
|
||||
try
|
||||
{
|
||||
$topic->setAnonymous( TRUE, $this->author );
|
||||
}
|
||||
catch( \BadMethodCallException ){}
|
||||
}
|
||||
|
||||
$topic->markRead( $this->author() );
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
if ( Settings::i()->tags_enabled )
|
||||
{
|
||||
$topic->setTags( $this->prefix() ? array_merge( $this->tags(), array( 'prefix' => $this->prefix() ) ) : $this->tags() );
|
||||
}
|
||||
|
||||
/* Create post */
|
||||
$content = $this->getTopicContent();
|
||||
\IPS\Member::loggedIn()->language()->parseOutputForDisplay( $content );
|
||||
$post = \IPS\forums\Topic\Post::create( $topic, $content, TRUE, NULL, NULL, $this->author() );
|
||||
Member::loggedIn()->language()->parseOutputForDisplay( $content );
|
||||
$post = Post::create( $topic, $content, true, null, null, $this->author(), DateTime::ts( $topic->start_date ) );
|
||||
|
||||
if( $this->isAnonymous() )
|
||||
if( IPS::classUsesTrait( $this, 'IPS\Content\Anonymous' ) AND $this->isAnonymous() )
|
||||
{
|
||||
$post->setAnonymous( TRUE, $this->author );
|
||||
try
|
||||
{
|
||||
$post->setAnonymous( TRUE, $this->author );
|
||||
}
|
||||
catch( \BadMethodCallException ){}
|
||||
}
|
||||
|
||||
$topic->topic_firstpost = $post->pid;
|
||||
$topic->save();
|
||||
\IPS\Content\Search\Index::i()->index( $post );
|
||||
Index::i()->index( $post );
|
||||
|
||||
/* Send notifications */
|
||||
if ( !$topic->isFutureDate() AND !$topic->hidden() )
|
||||
@@ -172,19 +186,19 @@ trait ItemTopic
|
||||
* Get Topic (checks member's permissions)
|
||||
*
|
||||
* @param bool $checkPerms Should check if the member can read the topic?
|
||||
* @return \IPS\forums\Topic|NULL
|
||||
* @return Topic|NULL
|
||||
*/
|
||||
public function topic( $checkPerms=TRUE )
|
||||
public function topic( bool $checkPerms=TRUE ): Topic|NULL
|
||||
{
|
||||
$column = static::topicIdColumn();
|
||||
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $this->$column )
|
||||
if ( Application::appIsEnabled('forums') and $this->$column )
|
||||
{
|
||||
try
|
||||
{
|
||||
return $checkPerms ? \IPS\forums\Topic::loadAndCheckPerms( $this->$column ) : \IPS\forums\Topic::load( $this->$column );
|
||||
return $checkPerms ? Topic::loadAndCheckPerms( $this->$column ) : Topic::load( $this->$column );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -196,37 +210,32 @@ trait ItemTopic
|
||||
/**
|
||||
* Change Author
|
||||
*
|
||||
* @param \IPS\Member $newAuthor The new author
|
||||
* @param bool $log If TRUE, action will be logged to moderator log
|
||||
* @param Member $newAuthor The new author
|
||||
* @param bool $log If TRUE, action will be logged to moderator log
|
||||
* @return void
|
||||
*/
|
||||
public function changeAuthor( \IPS\Member $newAuthor, $log=TRUE )
|
||||
public function itemAuthorChanged( Member $newAuthor, bool $log=TRUE ): void
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled( 'forums' ) )
|
||||
if ( Application::appIsEnabled( 'forums' ) )
|
||||
{
|
||||
if ( $topic = $this->topic() )
|
||||
{
|
||||
$topic->changeAuthor( $newAuthor, $log );
|
||||
}
|
||||
}
|
||||
|
||||
return parent::changeAuthor( $newAuthor, $log );
|
||||
}
|
||||
|
||||
/**
|
||||
* Process after the object has been edited on the front-end
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @return void
|
||||
*/
|
||||
public function processAfterEdit( $values )
|
||||
public function itemEdited(): void
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $this->topic() )
|
||||
if ( Application::appIsEnabled('forums') and $this->topic() )
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
|
||||
parent::processAfterEdit( $values );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -234,11 +243,9 @@ trait ItemTopic
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function processAfterTagUpdate()
|
||||
protected function itemTagsUpdated(): void
|
||||
{
|
||||
parent::processAfterTagUpdate();
|
||||
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $this->topic() )
|
||||
if ( Application::appIsEnabled('forums') and $this->topic() )
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
@@ -247,13 +254,12 @@ trait ItemTopic
|
||||
/**
|
||||
* Syncing to run when hiding
|
||||
*
|
||||
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
|
||||
* @param Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
|
||||
* @return void
|
||||
*/
|
||||
public function onHide( $member )
|
||||
public function itemHidden( Member|null|bool $member ): void
|
||||
{
|
||||
parent::onHide( $member );
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $topic = $this->topic() )
|
||||
if ( Application::appIsEnabled('forums') and $topic = $this->topic() )
|
||||
{
|
||||
$topic->hide( $member );
|
||||
}
|
||||
@@ -263,21 +269,18 @@ trait ItemTopic
|
||||
* Syncing to run when unhiding
|
||||
*
|
||||
* @param bool $approving If true, is being approved for the first time
|
||||
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
|
||||
* @param Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
|
||||
* @return void
|
||||
*/
|
||||
public function onUnhide( $approving, $member )
|
||||
public function itemUnhidden( bool $approving, Member|null|bool $member ): void
|
||||
{
|
||||
$containercolumn = static::containerForumIdColumn();
|
||||
|
||||
parent::onUnhide( $approving, $member );
|
||||
if ( \IPS\Application::appIsEnabled('forums') )
|
||||
if ( Application::appIsEnabled('forums') )
|
||||
{
|
||||
if ( $topic = $this->topic() )
|
||||
{
|
||||
$topic->unhide( $member );
|
||||
}
|
||||
elseif ( $approving and $this->container()->$containercolumn )
|
||||
elseif ( $approving and $this->getForumId() )
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
@@ -285,34 +288,71 @@ trait ItemTopic
|
||||
}
|
||||
|
||||
/**
|
||||
* Move
|
||||
* Run when an item is published
|
||||
*
|
||||
* @param \IPS\Node\Model $container Container to move to
|
||||
* @param bool $keepLink If TRUE, will keep a link in the source
|
||||
* @return void
|
||||
* @param Member|null $member
|
||||
* @return void
|
||||
*/
|
||||
public function move( \IPS\Node\Model $container, $keepLink=FALSE )
|
||||
public function itemPublished( ?Member $member=null ) : void
|
||||
{
|
||||
$containercolumn = static::containerForumIdColumn();
|
||||
$oldCategory = $this->container();
|
||||
|
||||
parent::move( $container, $keepLink );
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $topic = $this->topic() )
|
||||
if ( Application::appIsEnabled('forums') )
|
||||
{
|
||||
/* If the old category didn't sync, but the new one does, create the topic */
|
||||
if ( !$oldCategory->$containercolumn and $this->container()->$containercolumn )
|
||||
if ( $topic = $this->topic() )
|
||||
{
|
||||
$this->syncTopic();
|
||||
if ( $topic->hidden() )
|
||||
{
|
||||
$topic->unhide( $member );
|
||||
}
|
||||
}
|
||||
|
||||
/* If both the old and the new categories sync, but to different forums, move the topic, unless it's been moved manually */
|
||||
elseif ( $oldCategory->$containercolumn and $this->container()->$containercolumn and $oldCategory->$containercolumn != $this->container()->$containercolumn and $topic->forum_id == $oldCategory->$containercolumn )
|
||||
elseif ( $this->getForumId() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$topic->move( \IPS\forums\Forum::load( $this->container()->$containercolumn ), $keepLink );
|
||||
$this->syncTopic();
|
||||
}
|
||||
catch( Exception ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run when an item is unpublished
|
||||
*
|
||||
* @param Member|null $member
|
||||
* @return void
|
||||
*/
|
||||
public function itemUnpublished( ?Member $member=null ) : void
|
||||
{
|
||||
if ( Application::appIsEnabled('forums') AND $topic = $this->topic() )
|
||||
{
|
||||
$topic->hide( $member );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Move
|
||||
*
|
||||
* @param bool $keepLink If TRUE, will keep a link in the source
|
||||
* @return void
|
||||
*/
|
||||
public function itemMoved( bool $keepLink=FALSE ): void
|
||||
{
|
||||
if ( Application::appIsEnabled('forums') and $topic = $this->topic() )
|
||||
{
|
||||
if( $forumId = $this->getForumId() )
|
||||
{
|
||||
if( $topic->forum_id != $forumId )
|
||||
{
|
||||
try
|
||||
{
|
||||
$topic->move( Forum::load( $forumId ), $keepLink );
|
||||
}
|
||||
catch ( Exception ) { }
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->syncTopic();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -320,44 +360,13 @@ trait ItemTopic
|
||||
/**
|
||||
* Create from form
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param \IPS\Node\Model|NULL $container Container (e.g. forum), if appropriate
|
||||
* @param bool $sendNotification TRUE to automatically send new content notifications (useful for items that may be uploaded in bulk)
|
||||
* @return \IPS\Content\Item
|
||||
* @return void
|
||||
*/
|
||||
public static function createFromForm( $values, \IPS\Node\Model $container = NULL, $sendNotification = TRUE )
|
||||
public function itemCreatedFromForm(): void
|
||||
{
|
||||
$containercolumn = static::containerForumIdColumn();
|
||||
|
||||
$item = parent::createFromForm( $values, $container, $sendNotification );
|
||||
if ( \IPS\Application::appIsEnabled('forums') and $item->container()->$containercolumn and !$item->hidden() )
|
||||
if ( Application::appIsEnabled('forums') and $this->getForumId() and !$this->hidden() )
|
||||
{
|
||||
$item->syncTopic();
|
||||
$this->syncTopic();
|
||||
}
|
||||
return $item;
|
||||
}
|
||||
|
||||
/**
|
||||
* If, when making a post, we should merge with an existing comment, this method returns the comment to merge with
|
||||
*
|
||||
* @return \IPS\Content\Comment|NULL
|
||||
*/
|
||||
public function mergeConcurrentComment()
|
||||
{
|
||||
$column = static::topicIdColumn();
|
||||
$lastComment = parent::mergeConcurrentComment();
|
||||
|
||||
/* If we sync to the forums, make sure that the "last comment" is not actually the first post */
|
||||
if( $this->$column AND $lastComment !== NULL )
|
||||
{
|
||||
$firstComment = \IPS\forums\Topic::load( $this->$column )->comments( 1, 0, 'date', 'asc' );
|
||||
|
||||
if( $firstComment->pid == $lastComment->pid )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return $lastComment;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user