Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -12,7 +12,7 @@
|
||||
namespace IPS\blog;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -68,16 +68,31 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
* @brief [Node] Description suffix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}_{$descriptionLangSuffix}" as the key
|
||||
*/
|
||||
public static $descriptionLangSuffix = '_desc';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node ID Database Column
|
||||
*/
|
||||
public static $parentNodeColumnId = 'category_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Moderator Permission
|
||||
*/
|
||||
public static $modPerm = 'blogs';
|
||||
|
||||
/**
|
||||
* @brief [Node] Maximum results to display at a time in any node helper form elements. Useful for user-submitted node types when there may be a lot. NULL for no limit.
|
||||
*/
|
||||
public static $maxFormHelperResults = 2000;
|
||||
|
||||
/**
|
||||
* @brief Content Item Class
|
||||
*/
|
||||
public static $contentItemClass = 'IPS\blog\Entry';
|
||||
|
||||
/**
|
||||
* @brief Category
|
||||
*/
|
||||
protected $category;
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
@@ -152,16 +167,55 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permissions on any node
|
||||
*
|
||||
* For example - can be used to check if the user has
|
||||
* permission to create content in any node to determine
|
||||
* if there should be a "Submit" button
|
||||
*
|
||||
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
|
||||
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
|
||||
* @param array $where Additional WHERE clause
|
||||
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will return TRUE if "Post Before Registering" feature is enabled
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
*/
|
||||
public static function canOnAny( $permission, $member=NULL, $where = array(), $considerPostBeforeRegistering = TRUE )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
/* Posts per day - we need to do this independently here, because Blogs do not implement the Permissions interface */
|
||||
if ( \in_array( $permission, array( 'add', 'reply' ) ) )
|
||||
{
|
||||
$checkPostsPerDay = TRUE;
|
||||
if ( isset( static::$contentItemClass ) )
|
||||
{
|
||||
$contentClass = static::$contentItemClass;
|
||||
$checkPostsPerDay = $contentClass::$checkPostsPerDay;
|
||||
}
|
||||
|
||||
if ( $checkPostsPerDay === TRUE AND $member->checkPostsPerDay() === FALSE )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* This will always return true, but we always want to bubble up anyway */
|
||||
return parent::canOnAny( $permission, $member, $where, $considerPostBeforeRegistering );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permissions
|
||||
*
|
||||
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
|
||||
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
|
||||
* @param mixed $permission A key which has a value in static::$permissionMap['view'] matching a column ID in core_permission_index
|
||||
* @param \IPS\Member|\IPS\Member\Group|NULL $member The member or group to check (NULL for currently logged in member)
|
||||
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will return TRUE if "Post Before Registering" feature is enabled
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
*/
|
||||
public function can( $permission, $member=NULL )
|
||||
public function can( $permission, $member=NULL, $considerPostBeforeRegistering = TRUE )
|
||||
{
|
||||
/* Load member */
|
||||
if ( $member === NULL )
|
||||
@@ -169,6 +223,18 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
$member = \IPS\Member::loggedIn();
|
||||
}
|
||||
|
||||
/* If the member has hit their posting limits, then just stop here. */
|
||||
switch( $permission )
|
||||
{
|
||||
case 'add':
|
||||
case 'reply':
|
||||
if ( $member->checkPostsPerDay() === FALSE )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( $club = $this->club() )
|
||||
{
|
||||
switch ( $permission )
|
||||
@@ -227,7 +293,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
}
|
||||
}
|
||||
|
||||
return parent::can( $permission, $member );
|
||||
return parent::can( $permission, $member, $considerPostBeforeRegistering );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -314,7 +380,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
foreach ( \IPS\Db::i()->select( 'data', 'core_queue', array( 'app=? AND `key`=?', 'core', 'DeleteOrMoveContent' ) ) as $row )
|
||||
{
|
||||
$data = json_decode( $row, TRUE );
|
||||
if ( $data['class'] === get_class( $this ) and $data['id'] == $this->_id )
|
||||
if ( $data['class'] === \get_class( $this ) and $data['id'] == $this->_id )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -327,12 +393,23 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @param bool $public Whether this is a public form or not
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form, $public=FALSE )
|
||||
{
|
||||
if( $public )
|
||||
{
|
||||
$form->addTab( 'blog_settings' );
|
||||
|
||||
if ( !$this->id OR \IPS\Member::loggedIn()->modPermission('can_mod_blogs') )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'blog_category_id', $this->id ? $this->category_id : NULL, TRUE, array(
|
||||
'class' => '\IPS\blog\Category',
|
||||
'subnodes' => FALSE,
|
||||
), NULL, NULL, NULL, 'blog_category_id' ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'blog_name', $this->id ? $this->_title : NULL, TRUE, array(), NULL, NULL, NULL, 'blog_name' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Editor( 'blog_desc', $this->id ? $this->description : NULL, FALSE, array( 'app' => 'blog', 'key' => 'Blogs', 'autoSaveKey' => ( $this->id ? "blogs-blog-{$this->id}" : "blogs-new-blog" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL, 'minimize' => 'blog_desc_placeholder' ), NULL, NULL, NULL, 'blog_desc_wrap' ) );
|
||||
|
||||
@@ -345,7 +422,13 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
}
|
||||
else
|
||||
{
|
||||
$form->addHeader( 'blog_settings' );
|
||||
if( $this->id )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'blog_category_id', $this->category_id, TRUE, array(
|
||||
'class' => '\IPS\blog\Category',
|
||||
'subnodes' => FALSE,
|
||||
), NULL, NULL, NULL, 'blog_category_id' ) );
|
||||
}
|
||||
|
||||
$groups = array();
|
||||
foreach ( \IPS\Member\Group::groups() as $k => $v )
|
||||
@@ -370,14 +453,14 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
{
|
||||
if ( \IPS\Request::i()->blog_type === 'member' )
|
||||
{
|
||||
if( !is_object( $member ) or !$member->member_id )
|
||||
if( !\is_object( $member ) or !$member->member_id )
|
||||
{
|
||||
throw new \InvalidArgumentException( 'no_blog_author_selected' );
|
||||
}
|
||||
}
|
||||
},
|
||||
NULL, NULL, 'blog_member_id' ) );
|
||||
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'blog_groupblog_ids', $this->id ? explode( ',', $this->groupblog_ids ) : array(), FALSE, array( 'options' => $groups, 'multiple' => TRUE ), NULL, NULL, NULL, 'blog_groupblog_ids' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'blog_groupblog_name', NULL, FALSE, array( 'app' => 'blog', 'key' => ( $this->id ? "blogs_groupblog_name_{$this->id}" : NULL ) ), function( $value ) {
|
||||
if ( \IPS\Request::i()->blog_type === 'group' )
|
||||
@@ -458,6 +541,13 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'blog_enable_rss', $this->id ? $this->settings['allowrss'] : TRUE ) );
|
||||
}
|
||||
|
||||
/* Categories */
|
||||
if ( $public and $this->id )
|
||||
{
|
||||
$form->addTab( 'blog_entry_categories' );
|
||||
$form->addHtml( \IPS\Theme::i()->getTemplate( 'view', 'blog', 'front' )->manageCategories( $this ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -468,7 +558,13 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
if( isset( $values['blog_type'] ) and $values['blog_type'] == 'member' and isset( $values['blog_member_id'] ) and is_object( $values['blog_member_id'] ) )
|
||||
|
||||
if ( isset( $values['blog_category_id'] ) and $values[ 'blog_category_id' ] )
|
||||
{
|
||||
$values[ 'blog_category_id' ] = \intval( $values[ 'blog_category_id' ]->id );
|
||||
}
|
||||
|
||||
if( isset( $values['blog_type'] ) and $values['blog_type'] == 'member' and isset( $values['blog_member_id'] ) and \is_object( $values['blog_member_id'] ) )
|
||||
{
|
||||
$values['blog_member_id']->create_menu = NULL;
|
||||
$values['blog_member_id']->save();
|
||||
@@ -521,6 +617,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->category_id = $values[ 'blog_category_id' ];
|
||||
$this->save();
|
||||
|
||||
if( $values['blog_member_id'] )
|
||||
@@ -544,7 +641,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
|
||||
if ( $fieldKey === 'blog_name' )
|
||||
{
|
||||
$values['seo_name'] = \IPS\Http\Url\Friendly::seoTitle( ( is_array( $values[ $fieldKey ] ) ) ? $values[ $fieldKey ][ \IPS\Lang::defaultLanguage() ] : $values[ $fieldKey ] );
|
||||
$values['seo_name'] = \IPS\Http\Url\Friendly::seoTitle( ( \is_array( $values[ $fieldKey ] ) ) ? $values[ $fieldKey ][ \IPS\Lang::defaultLanguage() ] : $values[ $fieldKey ] );
|
||||
}
|
||||
|
||||
unset( $values[ $fieldKey ] );
|
||||
@@ -563,7 +660,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
{
|
||||
try
|
||||
{
|
||||
$feed = \IPS\blog\Blog\Feed::constructFromData( \IPS\Db::i()->select( '*', 'blog_rss_import', array( 'rss_blog_id=?', $this->id ) )->first() );
|
||||
$feed = \IPS\core\Rss\Import::constructFromData( \IPS\Db::i()->select( '*', 'core_rss_import', array( 'rss_import_class=? AND rss_import_node_id=?', 'IPS\\blog\\Entry', $this->id ) )->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
@@ -684,7 +781,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
public function get_seo_name()
|
||||
{
|
||||
/* If we have the seo_name, just return it - don't query the language string */
|
||||
if( $this->_data['seo_name'] )
|
||||
if( isset( $this->_data['seo_name'] ) and $this->_data['seo_name'] )
|
||||
{
|
||||
return $this->_data['seo_name'];
|
||||
}
|
||||
@@ -796,7 +893,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
$memberIds[] = $member;
|
||||
}
|
||||
|
||||
if( count( $memberIds ) )
|
||||
if( \count( $memberIds ) )
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_members', 'member_id IN(' . implode( ',', $memberIds ) . ')' ) as $member )
|
||||
{
|
||||
@@ -1000,6 +1097,23 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'blog' ), 'rows' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save Changed Columns
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save()
|
||||
{
|
||||
$new = $this->_new;
|
||||
|
||||
parent::save();
|
||||
|
||||
if ( $new )
|
||||
{
|
||||
\IPS\Api\Webhook::fire( 'blogBlog_create', $this, $this->webhookFilters() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Delete Record
|
||||
*
|
||||
@@ -1008,7 +1122,12 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
public function delete()
|
||||
{
|
||||
/* Delete RSS Imports */
|
||||
\IPS\Db::i()->delete( 'blog_rss_import', array( "rss_blog_id=?", $this->_id ) );
|
||||
try
|
||||
{
|
||||
$import = \IPS\core\Rss\Import::constructFromData( \IPS\Db::i()->select( '*', 'core_rss_import', array( "rss_import_class=? AND rss_import_node_id=?", 'IPS\\blog\\Entry', $this->_id ) )->first() );
|
||||
$import->delete();
|
||||
}
|
||||
catch( \UnderflowException $e ) { }
|
||||
|
||||
/* Delete Language Strings */
|
||||
foreach ( array( 'blog_groupblog_name' => "blogs_groupblog_name_{$this->id}" ) as $fieldKey => $langKey )
|
||||
@@ -1088,15 +1207,16 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
*
|
||||
* @param \IPS\Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
|
||||
* @return array
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Name
|
||||
* @apiresponse string description Description
|
||||
* @apiresponse \IPS\Member owner If the blog is owned by a single member, the member
|
||||
* @apiresponse [\IPS\Member\Group] groups If the blog is owned by groups, an array of the groups
|
||||
* @apiresponse bool pinned If the blog is pinned
|
||||
* @apiresponse int entries Number of entries
|
||||
* @apiresponse int comments Number of comments
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse int id ID number
|
||||
* @apiresponse string name Name
|
||||
* @apiresponse string description Description
|
||||
* @apiresponse \IPS\Member owner If the blog is owned by a single member, the member
|
||||
* @apiresponse [\IPS\Member\Group] groups If the blog is owned by groups, an array of the groups
|
||||
* @apiresponse bool pinned If the blog is pinned
|
||||
* @apiresponse int entries Number of entries
|
||||
* @apiresponse int comments Number of comments
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse \IPS\blog\Category|NULL category Category, or NULL for club blogs
|
||||
*/
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
{
|
||||
@@ -1113,17 +1233,26 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
}
|
||||
}
|
||||
|
||||
return array(
|
||||
$return = array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->_title,
|
||||
'description' => \IPS\Member::loggedIn()->language()->addToStack("blogs_blog_{$this->id}_desc"),
|
||||
'description' => $this->member_id ? \IPS\Text\Parser::removeLazyLoad( $this->desc ) : \IPS\Member::loggedIn()->language()->addToStack( static::$titleLangPrefix . $this->_id . static::$descriptionLangSuffix , NULL, array( 'removeLazyLoad' => TRUE ) ),
|
||||
'owner' => $this->member_id ? $this->owner()->apiOutput( $authorizedMember ) : null,
|
||||
'groups' => $groups,
|
||||
'pinned' => (bool) $this->pinned,
|
||||
'entries' => $this->count_entries,
|
||||
'comments' => $this->count_comments,
|
||||
'url' => (string) $this->url()
|
||||
'url' => (string) $this->url(),
|
||||
'category' => NULL
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$return['category'] = $this->category()->apiOutput();
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1234,7 +1363,39 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
}
|
||||
$where[] = array( \IPS\Db::i()->in( 'status', $statuses ) );
|
||||
|
||||
return new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'blog_blogs', $where )->join( 'core_clubs_memberships', array( 'club_id=blog_club_id AND member_id=?', $member->member_id ) ), get_called_class() );
|
||||
return iterator_to_array( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'blog_blogs', $where )->join( 'core_clubs_memberships', array( 'club_id=blog_club_id AND member_id=?', $member->member_id ) ), \get_called_class() ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category
|
||||
*
|
||||
* @return \IPS\Node\Model
|
||||
* @throws \OutOfRangeException|\BadMethodCallException
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
if( !$this->category_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if ( $this->category === NULL )
|
||||
{
|
||||
$this->category = \IPS\blog\Category::load( $this->category_id );
|
||||
}
|
||||
|
||||
return $this->category;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last comment time
|
||||
*
|
||||
* @note This should return the last comment time for this node only, not for children nodes
|
||||
* @return \IPS\DateTime|NULL
|
||||
*/
|
||||
public function getLastCommentTime()
|
||||
{
|
||||
return $this->last_edate ? \IPS\DateTime::ts( $this->last_edate ) : NULL;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user