<?php
/**
* @brief Entry Model
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Blog
* @since 3 Mar 2014
*/
namespace IPS\blog;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Entry Model
*/
class _Entry extends \IPS\Content\Item implements
\IPS\Content\Pinnable, \IPS\Content\Lockable, \IPS\Content\Hideable, \IPS\Content\Featurable,
\IPS\Content\Tags,
\IPS\Content\Followable,
\IPS\Content\Shareable,
\IPS\Content\ReadMarkers,
\IPS\Content\Views,
\IPS\Content\Polls,
\IPS\Content\Ratings,
\IPS\Content\EditHistory,
\IPS\Content\Searchable,
\IPS\Content\Embeddable,
\IPS\Content\FuturePublishing,
\IPS\Content\MetaData
{
use \IPS\Content\Reactable, \IPS\Content\Reportable;
/**
* @brief Multiton Store
*/
protected static $multitons;
/**
* @brief Application
*/
public static $application = 'blog';
/**
* @brief Module
*/
public static $module = 'blogs';
/**
* @brief Database Table
*/
public static $databaseTable = 'blog_entries';
/**
* @brief Database Prefix
*/
public static $databasePrefix = 'entry_';
/**
* @brief Database Column Map
*/
public static $databaseColumnMap = array(
'author' => 'author_id',
'author_name' => 'author_name',
'content' => 'content',
'container' => 'blog_id',
'date' => 'date',
'updated' => 'last_update',
'title' => 'name',
'num_comments' => 'num_comments',
'unapproved_comments' => 'queued_comments',
'hidden_comments' => 'hidden_comments',
'last_comment_by' => 'last_comment_mid',
'last_comment' => 'last_update', // Same as updated above
'views' => 'views',
'approved' => 'hidden',
'pinned' => 'pinned',
'poll' => 'poll_state',
'featured' => 'featured',
'ip_address' => 'ip_address',
'locked' => 'locked',
'cover_photo' => 'cover_photo',
'cover_photo_offset' => 'cover_offset',
'is_future_entry' => 'is_future_entry',
'future_date' => 'publish_date',
'status' => 'status',
'meta_data' => 'meta_data',
);
/**
* @brief Title
*/
public static $title = 'blog_entry';
/**
* @brief Node Class
*/
public static $containerNodeClass = 'IPS\blog\Blog';
/**
* @brief [Content\Item] Comment Class
*/
public static $commentClass = 'IPS\blog\Entry\Comment';
/**
* @brief [Content\Item] First "comment" is part of the item?
*/
public static $firstCommentRequired = FALSE;
/**
* @brief [Content\Comment] Language prefix for forms
*/
public static $formLangPrefix = 'blog_entry_';
/**
* @brief Icon
*/
public static $icon = 'file-text';
/**
* @brief The map of permission columns
*/
public static $permissionMap = array(
'view' => 'view',
'read' => 2,
'add' => 3,
'reply' => 4,
);
/**
* @brief [Content] Key for hide reasons
*/
public static $hideLogKey = 'blog-entry';
/**
* @brief [CoverPhoto] Storage extension
*/
public static $coverPhotoStorageExtension = 'blog_Entries';
/**
* @brief Use a default cover photo
*/
public static $coverPhotoDefault = true;
/**
* Set the title
*
* @param string $title Title
* @return void
*/
public function set_name( $name )
{
$this->_data['name'] = $name;
$this->_data['name_seo'] = \IPS\Http\Url\Friendly::seoTitle( $name );
}
/**
* Get SEO name
*
* @return string
*/
public function get_name_seo()
{
if( !$this->_data['name_seo'] )
{
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( $this->name );
$this->save();
}
return $this->_data['name_seo'] ?: \IPS\Http\Url\Friendly::seoTitle( $this->name );
}
/**
* Get the album HTML, if there is one associated
*
* @return string
*/
public function get__album()
{
if( \IPS\Application::appIsEnabled( 'gallery' ) AND $this->gallery_album )
{
try
{
$album = \IPS\gallery\Album::loadAndCheckPerms( $this->gallery_album );
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'gallery.css', 'gallery', 'front' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'gallery_responsive.css', 'gallery', 'front' ) );
}
return \IPS\Theme::i()->getTemplate( 'browse', 'gallery', 'front' )->miniAlbum( $album );
}
catch( \OutOfRangeException $e ){}
catch( \UnderflowException $e ){}
}
return '';
}
/**
* @brief Cached URLs
*/
protected $_url = array();
/**
* @brief URL Base
*/
public static $urlBase = 'app=blog&module=blogs&controller=entry&id=';
/**
* @brief URL Base
*/
public static $urlTemplate = 'blog_entry';
/**
* @brief SEO Title Column
*/
public static $seoTitleColumn = 'name_seo';
/**
* Can view this entry
*
* @param \IPS\Member|NULL $member The member or NULL for currently logged in member.
* @return bool
*/
public function canView( $member = NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
$return = parent::canView( $member );
if ( $this->status == 'draft' AND !static::canViewHiddenItems( $member, $this->container() ) AND !in_array( $this->container()->id, array_keys( \IPS\blog\Blog::loadByOwner( $member ) ) ) )
{
$return = FALSE;
}
/* Is this a future publish entry and we are the owner of the blog? */
if ( $this->status == 'draft' AND $this->is_future_entry == 1 AND in_array( $this->container()->id, array_keys( \IPS\blog\Blog::loadByOwner( $member ) ) ) )
{
$return = TRUE;
}
/* Club blog */
if ( $club = $this->container()->club() )
{
if ( !$club->canRead( $member ) )
{
return FALSE;
}
}
/* Private blog */
if( $this->container()->social_group != 0 AND $this->container()->owner() != $member )
{
/* This will throw an exception of the row does not exist */
try
{
if( !$member->member_id )
{
return FALSE;
}
$member = \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=? AND member_id=?', $this->container()->social_group, $member->member_id ) )->first();
}
catch( \UnderflowException $e )
{
return FALSE;
}
}
return $return;
}
/**
* Get items with permisison check
*
* @param array $where Where clause
* @param string $order MySQL ORDER BY clause (NULL to order by date)
* @param int|array $limit Limit clause
* @param string|NULL $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index or NULL to ignore permissions
* @param mixed $includeHiddenItems Include hidden items? NULL to detect if currently logged in member has permission, -1 to return public content only, TRUE to return unapproved content and FALSE to only return unapproved content the viewing member submitted
* @param int $queryFlags Select bitwise flags
* @param \IPS\Member $member The member (NULL to use currently logged in member)
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
* @param bool $countOnly If true will return the count
* @param array|null $joins Additional arbitrary joins for the query
* @param mixed $skipPermission If you are getting records from a specific container, pass the container to reduce the number of permission checks necessary or pass TRUE to skip conatiner-based permission. You must still specify this in the $where clause
* @param bool $joinTags If true, will join the tags table
* @param bool $joinAuthor If true, will join the members table for the author
* @param bool $joinLastCommenter If true, will join the members table for the last commenter
* @param bool $showMovedLinks If true, moved item links are included in the results
* @return \IPS\Patterns\ActiveRecordIterator|int
*/
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=\IPS\Content\Hideable::FILTER_AUTOMATIC, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL, $skipPermission=FALSE, $joinTags=TRUE, $joinAuthor=TRUE, $joinLastCommenter=TRUE, $showMovedLinks=FALSE )
{
if ( in_array( $permissionKey, array( 'view', 'read' ) ) )
{
$joinContainer = TRUE;
$member = $member ?: \IPS\Member::loggedIn();
if ( $member->member_id )
{
$where[] = array( '( blog_blogs.blog_member_id=' . $member->member_id . ' OR ( ' . \IPS\Content::socialGroupGetItemsWithPermissionWhere( 'blog_blogs.blog_social_group', $member ) . ' ) OR blog_blogs.blog_social_group IS NULL )' );
}
else
{
$where[] = array( "(" . \IPS\Content::socialGroupGetItemsWithPermissionWhere( 'blog_blogs.blog_social_group', $member ) . " OR blog_blogs.blog_social_group IS NULL )" );
}
if ( \IPS\Settings::i()->clubs )
{
$joins[] = array( 'from' => 'core_clubs', 'where' => 'core_clubs.id=blog_blogs.blog_club_id' );
if ( $member->member_id )
{
$where[] = array( '( blog_blogs.blog_club_id IS NULL OR ' . \IPS\Db::i()->in( 'blog_blogs.blog_club_id', $member->clubs() ) . ' OR core_clubs.type=? OR core_clubs.type=? OR core_clubs.type=?)', \IPS\Member\Club::TYPE_PUBLIC, \IPS\Member\Club::TYPE_READONLY, \IPS\Member\Club::TYPE_OPEN, );
}
else
{
$where[] = array( '( blog_blogs.blog_club_id IS NULL OR core_clubs.type=? OR core_clubs.type=? OR core_clubs.type=? )', \IPS\Member\Club::TYPE_PUBLIC, \IPS\Member\Club::TYPE_READONLY, \IPS\Member\Club::TYPE_OPEN, );
}
}
}
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
}
/**
* Additional WHERE clauses for Follow view
*
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
* @param array $joins Other joins
* @return array
*/
public static function followWhere( &$joinContainer, &$joins )
{
$joinContainer = TRUE;
if ( \IPS\Member::loggedIn()->member_id )
{
$where = array( array( '( blog_blogs.blog_social_group IS NULL OR blog_blogs.blog_member_id=' . \IPS\Member::loggedIn()->member_id . ' OR ( ' . \IPS\Content::socialGroupGetItemsWithPermissionWhere( 'blog_blogs.blog_social_group', \IPS\Member::loggedIn() ) . ' ) )' ) );
}
else
{
$where = array( \IPS\Content::socialGroupGetItemsWithPermissionWhere( 'blog_blogs.blog_social_group', \IPS\Member::loggedIn() ) );
}
if ( \IPS\Settings::i()->clubs )
{
$joins[] = array( 'from' => 'core_clubs', 'where' => 'core_clubs.id=blog_blogs.blog_club_id' );
if ( \IPS\Member::loggedIn()->member_id )
{
$where[] = array( '( blog_blogs.blog_club_id IS NULL OR ' . \IPS\Db::i()->in( 'blog_blogs.blog_club_id', \IPS\Member::loggedIn()->clubs() ) . ' OR core_clubs.type=? OR core_clubs.type=? )', \IPS\Member\Club::TYPE_PUBLIC, \IPS\Member\Club::TYPE_READONLY );
}
else
{
$where[] = array( '( blog_blogs.blog_club_id IS NULL OR core_clubs.type=? OR core_clubs.type=? )', \IPS\Member\Club::TYPE_PUBLIC, \IPS\Member\Club::TYPE_READONLY );
}
}
return array_merge( parent::followWhere( $joinContainer, $joins ), $where );
}
/**
* Get elements for add/edit form
*
* @param \IPS\Content\Item|NULL $item The current item if editing or NULL if creating
* @param int $container Container (e.g. forum) ID, if appropriate
* @return array
*/
public static function formElements( $item=NULL, \IPS\Node\Model $container=NULL )
{
$return = parent::formElements( $item, $container );
$return['entry'] = new \IPS\Helpers\Form\Editor( 'blog_entry_content', $item ? $item->content : NULL, TRUE, array( 'app' => 'blog', 'key' => 'Entries', 'autoSaveKey' => ( $item === NULL ) ? 'blog-entry-' . $container->id : 'blog-edit-' . $item->id, 'attachIds' => ( $item === NULL ? NULL : array( $item->id ) ) ) );
/* Gallery album association */
if( \IPS\Application::appIsEnabled( 'gallery' ) )
{
$return['album'] = new \IPS\Helpers\Form\Node( 'entry_gallery_album', ( $item AND $item->gallery_album ) ? $item->gallery_album : NULL, FALSE, array(
'url' => \IPS\Http\Url::internal( 'app=blog&module=blogs&controller=submit', 'front', 'blog_submit' ),
'class' => 'IPS\gallery\Album',
'permissionCheck' => 'add',
) );
}
$return['image'] = new \IPS\Helpers\Form\Upload( 'blog_entry_cover_photo', ( ( $item AND $item->cover_photo ) ? \IPS\File::get( 'blog_Entries', $item->cover_photo ) : NULL ), FALSE, array( 'storageExtension' => 'blog_Entries', 'image' => array( 'maxWidth' => 4800, 'maxHeight' => 4800 ) ) );
$return['publish'] = new \IPS\Helpers\Form\YesNo( 'blog_entry_publish', $item ? $item->status : TRUE, FALSE, array( 'togglesOn' => array( 'blog_entry_date' ) ) );
/* Publish date needs to go near the bottom */
$date = NULL;
if ( isset( $return['date'] ) )
{
$date = $return['date'];
unset( $return['date'] );
$return['date'] = $date;
}
/* Poll always needs to go on the end */
$poll = NULL;
if ( isset( $return['poll'] ) )
{
$poll = $return['poll'];
unset( $return['poll'] );
$return['poll'] = $poll;
}
return $return;
}
/**
* Process create/edit form
*
* @param array $values Values from form
* @return void
*/
public function processForm( $values )
{
parent::processForm( $values );
if ( !$this->_new )
{
$oldContent = $this->content;
}
$this->content = $values['blog_entry_content'];
if ( !$this->_new )
{
$this->sendAfterEditNotifications( $oldContent );
}
$this->status = $values['blog_entry_publish'] ? 'published' : 'draft';
if ( isset( $values['blog_entry_date'] ) )
{
$this->date = ( $values['blog_entry_date'] AND $values['blog_entry_publish'] ) ? $values['blog_entry_date']->getTimestamp() : time();
}
$this->cover_photo = (string) $values['blog_entry_cover_photo'];
/* Gallery album association */
if( \IPS\Application::appIsEnabled( 'gallery' ) AND $values['entry_gallery_album'] instanceof \IPS\gallery\Album )
{
$this->gallery_album = $values['entry_gallery_album']->_id;
}
else
{
$this->gallery_album = NULL;
}
if ( $this->date > time() )
{
$this->status = 'draft';
}
/* Ping */
$this->container()->ping();
}
/**
* Can a given member create this type of content?
*
* @param \IPS\Member $member The member
* @param \IPS\Node\Model|NULL $container Container (e.g. forum), if appropriate
* @param bool $showError If TRUE, rather than returning a boolean value, will display an error
* @return bool
*/
public static function canCreate( \IPS\Member $member, \IPS\Node\Model $container=NULL, $showError=FALSE )
{
parent::canCreate( $member, $container, $showError );
$return = TRUE;
$blogs = \IPS\blog\Blog::loadByOwner( $member );
if ( $container )
{
if ( $club = $container->club() )
{
$return = $club->isModerator( $member );
$error = 'no_module_permission';
}
elseif ( !in_array( $container->id, array_keys( $blogs ) ) )
{
$return = FALSE;
$error = 'no_module_permission';
}
if ( $container->disabled )
{
$return = FALSE;
$error = 'no_module_permission';
}
}
else
{
if( !count( $blogs ) )
{
$return = FALSE;
$error = 'no_module_permission';
}
}
/* Return */
if ( $showError and !$return )
{
\IPS\Output::i()->error( $error, '1B203/1', 403, '' );
}
return $return;
}
/**
* Process created object AFTER the object has been created
*
* @param \IPS\Content\Comment|NULL $comment The first comment
* @param array $values Values from form
* @return void
*/
protected function processAfterCreate( $comment, $values )
{
parent::processAfterCreate( $comment, $values );
\IPS\File::claimAttachments( 'blog-entry-' . $this->container()->id, $this->id );
if ( $this->status == 'published' )
{
$blog = $this->container();
$lastUpdateColumn = $blog::$databaseColumnMap['date'];
$blog->$lastUpdateColumn = time();
$blog->save();
}
}
/**
* Syncing to run when publishing something previously pending publishing
*
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
* @return void
*/
public function onPublish( $member )
{
$this->status = 'published';
$this->save();
parent::onPublish( $member );
/* The blog system is slightly different from the \Content future entry stuff. Future entries are treated as drafts,
so do count towards entries but parent::onPublish will try and increment item count again after publish */
$this->container()->resetCommentCounts();
$this->container()->save();
}
/**
* Syncing to run when unpublishing an item (making it a future dated entry when it was already published)
*
* @param \IPS\Member|NULL|FALSE $member The member doing the action (NULL for currently logged in member, FALSE for no member)
* @return void
*/
public function onUnpublish( $member )
{
$this->status = 'draft';
$this->save();
parent::onUnpublish( $member );
/* The blog system is slightly different from the \Content future entry stuff. Future entries are treated as drafts,
so do count towards entries but parent::onUnpublish will try and decrement item count after unpublish */
$this->container()->resetCommentCounts();
$this->container()->save();
}
/**
* Can comment?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @return bool
*/
public function canComment( $member=NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
return parent::canComment( $member ) and $member->group['g_blog_allowcomment'];
}
/**
* Can set items to be published in the future?
*
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
* @param \IPS\Node\Model|null $container Container
* @return bool
*/
public static function canFuturePublish( $member=NULL, \IPS\Node\Model $container = NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
return (boolean) $member->member_id > 0;
}
/**
* Check Moderator Permission
*
* @param string $type 'edit', 'hide', 'unhide', 'delete', etc.
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
* @param \IPS\Node\Model|NULL $container The container
* @return bool
*/
public static function modPermission( $type, \IPS\Member $member = NULL, \IPS\Node\Model $container = NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
$result = parent::modPermission( $type, $member, $container );
if ( $result !== TRUE )
{
if ( in_array( $type, array( 'edit', 'delete', 'lock', 'unlock' ) ) and $container and $container->member_id === $member->member_id )
{
$result = $member->group['g_blog_allowownmod'];
}
}
return $result;
}
/**
* Get template for content tables
*
* @return callable
*/
public static function contentTableTemplate()
{
return array( \IPS\Theme::i()->getTemplate( 'global', 'blog', 'front' ), 'rows' );
}
/**
* Search Index Permissions
*
* @return string Comma-delimited values or '*'
* @li Number indicates a group
* @li Number prepended by "m" indicates a member
* @li Number prepended by "s" indicates a social group
*/
public function searchIndexPermissions()
{
if ( $this->status == 'draft' )
{
return '0';
}
return parent::searchIndexPermissions();
}
/**
* WHERE clause for getting items for sitemap (permissions are already accounted for)
*
* @return array
*/
public static function sitemapWhere()
{
return array( array( 'blog_entries.entry_is_future_entry=0 AND blog_entries.entry_status!=?', 'draft' ) );
}
/**
* Get output for API
*
* @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 title Title
* @apiresponse \IPS\blog\Blog blog Blog
* @apiresponse \IPS\Member author The member that created the entry
* @apiresponse bool draft If this entry is a draft
* @apiresponse datetime date Date
* @apiresponse string entry Entry content
* @apiresponse int comments Number of comments
* @apiresponse int views Number of posts
* @apiresponse string prefix The prefix tag, if there is one
* @apiresponse [string] tags The tags
* @apiresponse bool locked Entry is locked
* @apiresponse bool hidden Entry is hidden
* @apiresponse bool future Will be published at a future date?
* @apiresponse bool pinned Entry is pinned
* @apiresponse bool featured Entry is featured
* @apiresponse \IPS\Poll poll Poll data, if there is one
* @apiresponse string url URL
* @apiresponse float rating Average Rating
*/
public function apiOutput( \IPS\Member $authorizedMember = NULL )
{
return array(
'id' => $this->id,
'title' => $this->name,
'blog' => $this->container()->apiOutput( $authorizedMember ),
'author' => $this->author()->apiOutput( $authorizedMember ),
'draft' => $this->status == 'draft',
'date' => \IPS\DateTime::ts( $this->date )->rfc3339(),
'entry' => $this->content(),
'comments' => $this->num_comments,
'views' => $this->views,
'prefix' => $this->prefix(),
'tags' => $this->tags(),
'locked' => (bool) $this->locked(),
'hidden' => (bool) $this->hidden(),
'future' => $this->isFutureDate(),
'pinned' => (bool) $this->mapped('pinned'),
'featured' => (bool) $this->mapped('featured'),
'poll' => $this->poll_state ? \IPS\Poll::load( $this->poll_state )->apiOutput( $authorizedMember ) : null,
'url' => (string) $this->url(),
'rating' => $this->averageRating(),
);
}
/**
* Reaction Type
*
* @return string
*/
public static function reactionType()
{
return 'entry_id';
}
/**
* Supported Meta Data Types
*
* @return array
*/
public static function supportedMetaDataTypes()
{
return array( 'core_FeaturedComments', 'core_ContentMessages' );
}
/**
* Can perform an action on a message
*
* @param string The action
* @param \IPS\Member|NULL The member, or NULL for currently logged in
* @return bool
*/
public function canOnMessage( $action, \IPS\Member $member = NULL )
{
$return = parent::canOnMessage( $action, $member );
if ( $return === FALSE )
{
$member = $member ?: \IPS\Member::loggedIn();
if ( $member->member_id AND $member->member_id === $this->author()->member_id AND $member->group['g_blog_allowownmod'] )
{
$return = TRUE;
}
}
return $return;
}
/**
* Can Feature a Comment
*
* @param \IPS\Member|NULL The member, or NULL for currently logged in
* @return bool
*/
public function canFeatureComment( \IPS\Member $member = NULL )
{
$return = parent::canFeatureComment( $member );
if ( $return === FALSE )
{
$member = $member ?: \IPS\Member::loggedIn();
if ( $member->member_id AND $member->member_id === $this->author()->member_id AND $member->group['g_blog_allowownmod'] )
{
$return = TRUE;
}
}
return $return;
}
/**
* Can Unfeature a Comment
*
* @param \IPS\Member|NULL The member, or NULL for currently logged in
* @return bool
*/
public function canUnfeatureComment( \IPS\Member $member = NULL )
{
$return = parent::canUnfeatureComment( $member );
if ( $return === FALSE )
{
$member = $member ?: \IPS\Member::loggedIn();
if ( $member->member_id AND $member->member_id === $this->author()->member_id AND $member->group['g_blog_allowownmod'] )
{
$return = TRUE;
}
}
return $return;
}
/**
* Returns the content images
*
* @param int|null $limit Number of attachments to fetch, or NULL for all
*
* @return array|NULL
* @throws \BadMethodCallException
*/
public function contentImages( $limit = NULL )
{
$idColumn = static::$databaseColumnId;
$internal = NULL;
$attachments = array();
if ( isset( static::$databaseColumnMap['content'] ) )
{
$internal = \IPS\Db::i()->select( 'attachment_id', 'core_attachments_map', array( 'location_key=? and id1=?', 'blog_Entries', $this->$idColumn ) );
}
if ( $internal )
{
foreach( \IPS\Db::i()->select( '*', 'core_attachments', array( array( 'attach_id IN(?)', $internal ), array( 'attach_is_image=1' ) ), 'attach_id ASC', $limit ) as $row )
{
$attachments[] = array( 'core_Attachment' => $row['attach_location'] );
}
}
return count( $attachments ) ? $attachments : NULL;
}
/**
* Get content for embed
*
* @param array $params Additional parameters to add to URL
* @return string
*/
public function embedContent( $params )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'blog', 'front' ) );
return \IPS\Theme::i()->getTemplate( 'global', 'blog' )->embedEntry( $this, $this->container(), $this->url()->setQueryString( $params ) );
}
}