Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

+229 -118
View File
@@ -12,7 +12,7 @@
namespace IPS\gallery;
/* 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;
@@ -166,7 +166,7 @@ class _Image extends \IPS\Content\Item implements
}
}
if ( count( $albumIds ) )
if ( \count( $albumIds ) )
{
$return = array();
$albumData = iterator_to_array( \IPS\Db::i()->select( array( 'album_id', 'album_name', 'album_name_seo' ), 'gallery_albums', \IPS\Db::i()->in( 'album_id', $albumIds ) )->setKeyField( 'album_id' ) );
@@ -189,7 +189,13 @@ class _Image extends \IPS\Content\Item implements
*/
public function get_metadata()
{
return is_array( $this->_data['metadata'] ) ? $this->_data['metadata'] : ( $this->_data['metadata'] ? json_decode( $this->_data['metadata'], TRUE ) : array() );
/* Videos don't have EXIF data */
if( !isset( $this->_data['metadata'] ) )
{
return array();
}
return \is_array( $this->_data['metadata'] ) ? $this->_data['metadata'] : ( $this->_data['metadata'] ? json_decode( $this->_data['metadata'], TRUE ) : array() );
}
/**
@@ -199,7 +205,7 @@ class _Image extends \IPS\Content\Item implements
*/
public function get__dimensions()
{
return is_array( $this->_data['data'] ) ? $this->_data['data'] : ( $this->_data['data'] ? json_decode( $this->_data['data'], TRUE ) : array() );
return \is_array( $this->_data['data'] ) ? $this->_data['data'] : ( $this->_data['data'] ? json_decode( $this->_data['data'], TRUE ) : array() );
}
/**
@@ -220,7 +226,7 @@ class _Image extends \IPS\Content\Item implements
*/
public function get__notes()
{
return is_array( $this->_data['notes'] ) ? $this->_data['notes'] : ( $this->_data['notes'] ? json_decode( $this->_data['notes'], TRUE ) : array() );
return \is_array( $this->_data['notes'] ) ? $this->_data['notes'] : ( $this->_data['notes'] ? json_decode( $this->_data['notes'], TRUE ) : array() );
}
/**
@@ -231,7 +237,7 @@ class _Image extends \IPS\Content\Item implements
public function get__notes_json()
{
/* We want to essentially double encode the entities so that when javascript decodes the JSON it is safe */
if( $this->_notes and is_array( $this->_notes ) )
if( $this->_notes and \is_array( $this->_notes ) )
{
$notes = $this->_notes;
array_walk( $notes, function( &$v, $k )
@@ -322,7 +328,14 @@ class _Image extends \IPS\Content\Item implements
*/
public function get_small_file_name()
{
return $this->_data['small_file_name'] ?: $this->_data['masked_file_name'];
if( isset( $this->_data['small_file_name'] ) AND $this->_data['small_file_name'] )
{
return $this->_data['small_file_name'];
}
else
{
return $this->masked_file_name;
}
}
/**
@@ -464,18 +477,18 @@ class _Image extends \IPS\Content\Item implements
$modStates[] = 'read';
}
$modActions = implode( $modActions, ' ' );
$modStates = implode( $modStates, ' ' );
$modActions = implode( ' ', $modActions );
$modStates = implode( ' ', $modStates );
return json_encode( array(
'filenames' => array(
'small' => array( $this->_data['small_file_name'] ? (string) \IPS\File::get( 'gallery_Images', $this->_data['small_file_name'] )->url : null, $imageSizes['small'][0], $imageSizes['small'][1] ),
'large' => array( $this->_data['masked_file_name'] ? (string) \IPS\File::get( 'gallery_Images', $this->_data['masked_file_name'] )->url : null, $imageSizes['large'][0], $imageSizes['large'][1] )
'small' => array( $this->_data['small_file_name'] ? (string) \IPS\File::get( 'gallery_Images', $this->_data['small_file_name'] )->url : null, $this->_data['small_file_name'] ? $imageSizes['small'][0] : null, $this->_data['small_file_name'] ? $imageSizes['small'][1] : null ),
'large' => array( $this->_data['masked_file_name'] ? (string) \IPS\File::get( 'gallery_Images', $this->_data['masked_file_name'] )->url : null, $this->_data['masked_file_name'] ? $imageSizes['large'][0] : null, $this->_data['masked_file_name'] ? $imageSizes['large'][1] : null )
),
/* We do not use ENT_QUOTES as this replaces " to " which browsers turn back into " again which breaks the JSON string as it needs to be \", single quotes break the data-attribute='' boundaries */
'caption' => $this->_data['caption'],
'date' => \IPS\DateTime::ts( $this->mapped('date') )->relative(),
'hasState' => count( $state ) ? TRUE : FALSE,
'hasState' => \count( $state ) ? TRUE : FALSE,
'state' => $state,
'container' => ( $this->directContainer() instanceof \IPS\gallery\Category ) ? \IPS\Member::loggedIn()->language()->addToStack( "gallery_category_{$this->directContainer()->_id}", false, array( 'json' => true, 'jsonEscape' => true ) ) : $this->directContainer()->_title,
'id' => $this->_data['id'],
@@ -623,7 +636,7 @@ class _Image extends \IPS\Content\Item implements
/* Loop through and see if we are also including albums */
$includingAlbums = FALSE;
if( !count( $filters ) )
if( !\count( $filters ) )
{
$includingAlbums = TRUE;
}
@@ -640,14 +653,15 @@ class _Image extends \IPS\Content\Item implements
if( $includingAlbums === TRUE )
{
if( count( $filters ) )
if( \count( $filters ) )
{
foreach( $filters as $k => $filter )
{
if( $filter->itemClass == 'IPS\\gallery\\Image' )
{
/* container class can be category or album */
$filter->containerClasses = array( 'IPS\\gallery\\Category', 'IPS\\gallery\\Album' );
$filter->containerClasses = array( 'IPS\\gallery\\Category' );
$filter->containerClassExclusions = array( 'IPS\\gallery\\Image\\Comment', 'IPS\\gallery\\Image\\Review' );
}
}
}
@@ -668,31 +682,35 @@ class _Image extends \IPS\Content\Item implements
*/
public function notificationRecipients( $limit=array( 0, 25 ), $extra=NULL, $countOnly=FALSE )
{
$unions = array( static::containerFollowers( $this->container(), 3, array( 'immediate' ), $this->mapped('date'), NULL, NULL, 0 ) );
if( get_class( $this->container() ) != get_class( $this->directContainer() ) )
/* Do we only want the count? */
if( $countOnly )
{
$unions[] = static::containerFollowers( $this->directContainer(), 3, array( 'immediate' ), $this->mapped('date'), NULL, NULL, 0 );
$count = 0;
$count += $this->author()->followersCount( 3, array( 'immediate' ), $this->mapped('date') );
$count += static::containerFollowerCount( $this->container(), 3, array( 'immediate' ), $this->mapped('date') );
if( \get_class( $this->container() ) != \get_class( $this->directContainer() ) )
{
$count += static::containerFollowerCount( $this->directContainer(), 3, array( 'immediate' ), $this->mapped('date') );
}
return $count;
}
/* Create a union query to return the followers */
$unions = array( static::containerFollowers( $this->container(), 3, array( 'immediate' ), $this->mapped('date'), NULL ) );
if( \get_class( $this->container() ) != \get_class( $this->directContainer() ) )
{
$unions[] = static::containerFollowers( $this->directContainer(), 3, array( 'immediate' ), $this->mapped('date'), NULL );
}
if ( $followersQuery = $this->author()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL, NULL, 0 ) )
if ( $followersQuery = $this->author()->followers( 3, array( 'immediate' ), $this->mapped('date'), NULL ) )
{
$unions[] = $followersQuery;
}
if ( $countOnly )
{
$return = 0;
foreach ( $unions as $query )
{
$return += $query->count();
}
return $return;
}
else
{
return \IPS\Db::i()->union( $unions, 'follow_added', $limit, NULL, FALSE, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
}
return \IPS\Db::i()->union( $unions, 'follow_added', $limit );
}
/**
@@ -702,25 +720,41 @@ class _Image extends \IPS\Content\Item implements
* @param \IPS\gallery\Album|NULL $album The album the images were posted in, or NULL for no album.
* @param \IPS\Member|NULL $member The member posting the images or NULL for currently logged in member.
* @param int|array $limit LIMIT clause
* @param bool $countOnly Only return the count
* @return \IPS\Db\Select
*/
public static function _notificationRecipients( $category, $album=NULL, $member=NULL, $limit=array( 0, 25 ) )
public static function _notificationRecipients( $category, $album=NULL, $member=NULL, $limit=array( 0, 25 ), $countOnly=FALSE )
{
$member = $member ?: \IPS\Member::loggedIn();
$unions = array( static::containerFollowers( $category, 3, array( 'immediate' ), NULL, $limit, 'follow_added', TRUE, NULL ) );
if ( !is_null( $album ) )
/* Do we only want the count? */
if( $countOnly )
{
$unions[] = static::containerFollowers( $album, 3, array( 'immediate' ), NULL, $limit, 'follow_added', TRUE, NULL );
$count = 0;
$count += $member->followersCount( 3, array( 'immediate' ) );
$count += static::containerFollowerCount( $category, 3, array( 'immediate' ) );
if( $album )
{
$count += static::containerFollowerCount( $album, 3, array( 'immediate' ) );
}
return $count;
}
$unions = array( static::containerFollowers( $category, 3, array( 'immediate' ), NULL, NULL, 'follow_added' ) );
if ( !\is_null( $album ) )
{
$unions[] = static::containerFollowers( $album, 3, array( 'immediate' ), NULL, NULL, 'follow_added' );
}
if ( $followersQuery = $member->followers( 3, array( 'immediate' ), NULL, NULL, NULL, NULL ) )
if ( $followersQuery = $member->followers( 3, array( 'immediate' ), NULL, NULL ) )
{
$unions[] = $followersQuery;
}
return \IPS\Db::i()->union( $unions, NULL, NULL, NULL, FALSE, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
return \IPS\Db::i()->union( $unions, 'follow_added', $limit );
}
/**
@@ -736,7 +770,7 @@ class _Image extends \IPS\Content\Item implements
$member = $member ?: \IPS\Member::loggedIn();
try
{
$count = static::_notificationRecipients( $category, $album, $member )->count( TRUE );
$count = static::_notificationRecipients( $category, $album, $member, NULL, TRUE );
}
catch( \BadMethodCallException $e )
{
@@ -748,16 +782,13 @@ class _Image extends \IPS\Content\Item implements
if ( $count > static::NOTIFICATIONS_PER_BATCH )
{
$queueData = array();
$queueData['category_id'] = $category->$categoryIdColumn;
$queueData['member_id'] = $member->member_id;
$queueData['album_id'] = NULL;
if ( !is_null( $album ) )
{
$queueData['album_id'] = $album->$albumIdColumn;
}
$queueData = array(
'followerCount' => $count,
'category_id' => $category->$categoryIdColumn,
'member_id' => $member->member_id,
'album_id' => $album ? $album->$albumIdColumn : NULL
);
\IPS\Task::queue( 'gallery', 'Follow', $queueData, 2 );
}
else
@@ -808,7 +839,7 @@ class _Image extends \IPS\Content\Item implements
}
$notification = new \IPS\Notification( \IPS\Application::load('core'), 'unapproved_content_bulk', $directContainer, array( $directContainer, $member, $directContainer::$contentItemClass ), array( $member->member_id ) );
foreach ( \IPS\Db::i()->select( '*', 'core_members', ( count( $moderators['m'] ) ? \IPS\Db::i()->in( 'member_id', $moderators['m'] ) . ' OR ' : '' ) . \IPS\Db::i()->in( 'member_group_id', $moderators['g'] ) . ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $moderators['g'] ) ) as $moderator )
foreach ( \IPS\Db::i()->select( '*', 'core_members', ( \count( $moderators['m'] ) ? \IPS\Db::i()->in( 'member_id', $moderators['m'] ) . ' OR ' : '' ) . \IPS\Db::i()->in( 'member_group_id', $moderators['g'] ) . ' OR ' . \IPS\Db::i()->findInSet( 'mgroup_others', $moderators['g'] ) ) as $moderator )
{
$notification->recipients->attach( \IPS\Member::constructFromData( $moderator ) );
}
@@ -826,11 +857,23 @@ class _Image extends \IPS\Content\Item implements
*/
public static function _sendNotificationsBatch( $category, $album=NULL, $member=NULL, $offset=0 )
{
/* Check notification initiator spam status */
if( ( $member instanceof \IPS\Member ) AND $member->members_bitoptions['bw_is_spammer'] )
{
/* Initiator is flagged as spammer, don't send notifications */
return NULL;
}
$member = $member ?: \IPS\Member::loggedIn();
$directContainer = $album ?: $category;
$followIds = array();
$followers = static::_notificationRecipients( $category, $album, $member, array( $offset, static::NOTIFICATIONS_PER_BATCH ) );
$followers = iterator_to_array( static::_notificationRecipients( $category, $album, $member, array( $offset, static::NOTIFICATIONS_PER_BATCH ) ) );
if( !\count( $followers ) )
{
return NULL;
}
$notification = new \IPS\Notification( \IPS\Application::load( 'core' ), 'new_content_bulk', $directContainer, array( $directContainer, $member, $directContainer::$contentItemClass ), array( $member->member_id ) );
@@ -840,19 +883,14 @@ class _Image extends \IPS\Content\Item implements
if ( $followMember != $member and $directContainer->can( 'view', $followMember ) )
{
$followIds[] = $follower['follow_id'];
$notification->recipients->attach( $followMember );
$notification->recipients->attach( $followMember, $follower );
}
}
\IPS\Db::i()->update( 'core_follow', array( 'follow_notify_sent' => time() ), \IPS\Db::i()->in( 'follow_id', $followIds ) );
$notification->send();
$newOffset = $offset + static::NOTIFICATIONS_PER_BATCH;
if ( $newOffset > $followers->count( TRUE ) )
{
return NULL;
}
return $newOffset;
return $offset + static::NOTIFICATIONS_PER_BATCH;
}
/**
@@ -924,16 +962,16 @@ class _Image extends \IPS\Content\Item implements
$results[] = $image;
if( count( $results ) == $count )
if( \count( $results ) == $count )
{
break;
}
}
if( count( $results ) < $count )
if( \count( $results ) < $count )
{
$where['date'] = array( static::$databasePrefix . $sortBy . " {$dir} ?", $this->$sortBy );
$results = array_merge( $results, iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $sortBy . ' ' . $direction, $count - count( $results ) ) ) );
$results = array_merge( $results, iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $sortBy . ' ' . $direction, $count - \count( $results ) ) ) );
}
return $results;
@@ -984,7 +1022,7 @@ class _Image extends \IPS\Content\Item implements
$result = $this->fetchNextOrPreviousImages( 1, 'DESC' );
if( is_array( $result ) )
if( \is_array( $result ) )
{
return array_pop( $result );
}
@@ -1031,7 +1069,7 @@ class _Image extends \IPS\Content\Item implements
$result = $this->fetchNextOrPreviousImages( 1, 'ASC' );
if( is_array( $result ) )
if( \is_array( $result ) )
{
return array_pop( $result );
}
@@ -1040,30 +1078,32 @@ class _Image extends \IPS\Content\Item implements
/**
* Should new items be moderated?
*
* @param \IPS\Member $member The member posting
* @param \IPS\Node\Model $container The container
* @param \IPS\Member $member The member posting
* @param \IPS\Node\Model $container The container
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will check if a newly registered member would be moderated
* @return bool
*/
public static function moderateNewItems( \IPS\Member $member, \IPS\Node\Model $container = NULL )
public static function moderateNewItems( \IPS\Member $member, \IPS\Node\Model $container = NULL, $considerPostBeforeRegistering = FALSE )
{
if ( $container and $container->approve_img and !$member->group['g_avoid_q'] )
{
return !static::modPermission( 'approve', $member, $container );
}
return parent::moderateNewItems( $member, $container );
return parent::moderateNewItems( $member, $container, $considerPostBeforeRegistering );
}
/**
* Should new comments be moderated?
*
* @param \IPS\Member $member The member posting
* @param \IPS\Member $member The member posting
* @param bool $considerPostBeforeRegistering If TRUE, and $member is a guest, will check if a newly registered member would be moderated
* @return bool
*/
public function moderateNewComments( \IPS\Member $member )
public function moderateNewComments( \IPS\Member $member, $considerPostBeforeRegistering = FALSE )
{
$commentClass = static::$commentClass;
return ( $this->container()->approve_com and !$member->group['g_avoid_q'] ) or parent::moderateNewComments( $member );
return ( $this->container()->approve_com and !$member->group['g_avoid_q'] ) or parent::moderateNewComments( $member, $considerPostBeforeRegistering );
}
/**
@@ -1108,9 +1148,8 @@ class _Image extends \IPS\Content\Item implements
$return['description'] = new \IPS\Helpers\Form\Editor( 'image_description', $item ? $item->description : NULL, FALSE, array(
'app' => 'gallery',
'key' => 'Images',
'autoSaveKey' => ( $item === NULL ? ( 'newContentItem-' . static::$application . '/' . static::$module . '-' . ( $tempId ?: 0 ) . '-' . ( $container ? $container->_id : 0 ) ) : ( 'contentEdit-' . static::$application . '/' . static::$module . '-' . $item->id ) ),
'attachIds' => ( $item === NULL ? NULL : array( $item->id ) ),
'editorId' => "filedata_{$currentlyEditing}_image_description"
'autoSaveKey' => ( $item === NULL ? NULL : ( 'contentEdit-' . static::$application . '/' . static::$module . '-' . $item->id ) ),
'editorId' => ( $item === NULL ) ? "filedata_{$currentlyEditing}_image_description" : 'image_description'
) );
$return['credit_info'] = new \IPS\Helpers\Form\TextArea( 'image_credit_info', $item ? $item->credit_info : NULL, FALSE );
$return['copyright'] = new \IPS\Helpers\Form\Text( 'image_copyright', $item ? $item->copyright : NULL, FALSE, array( 'maxLength' => 255 ) );
@@ -1158,6 +1197,19 @@ class _Image extends \IPS\Content\Item implements
return $return;
}
/**
* Process after the object has been edited on the front-end
*
* @param array $values Values from form
* @return void
*/
public function processAfterEdit( $values )
{
parent::processAfterEdit( $values );
\IPS\Request::i()->setClearAutosaveCookie( 'contentEdit-' . static::$application . '/' . static::$module . '-' . $this->id );
}
/**
* Process create/edit form
*
@@ -1176,7 +1228,8 @@ class _Image extends \IPS\Content\Item implements
$oldContent = $this->description;
}
$this->description = $values['image_description'];
if ( !$this->_new )
$sendFilterNotifications = $this->checkProfanityFilters( FALSE, $this->_new );
if ( !$this->_new AND $sendFilterNotifications === FALSE )
{
$this->sendAfterEditNotifications( $oldContent );
}
@@ -1213,10 +1266,10 @@ class _Image extends \IPS\Content\Item implements
/* Extract EXIF data if possible */
if( \IPS\Image::exifSupported() )
{
$this->metadata = \IPS\Image::create( $file->contents() )->parseExif();
$this->metadata = ( isset( $values['_exif'] ) ) ? $values['_exif'] : \IPS\Image::create( $file->contents() )->parseExif();
/* And then parse geolocation data */
if( count( $this->metadata ) )
if( \count( $this->metadata ) )
{
$this->parseGeolocation();
@@ -1415,12 +1468,12 @@ class _Image extends \IPS\Content\Item implements
$watermarks = explode( ',', \IPS\Settings::i()->gallery_watermark_images );
/* Create the various thumbnails */
$largeImage = \IPS\File::create( 'gallery_Images', 'large.' . $file->originalFilename, $this->_createImage( $file, explode( 'x', \IPS\Settings::i()->gallery_large_dims ), FALSE, in_array( 'large', $watermarks ) ) );
$largeImage = \IPS\File::create( 'gallery_Images', 'large.' . $file->originalFilename, $this->createImageFile( $file, explode( 'x', \IPS\Settings::i()->gallery_large_dims ), FALSE, \in_array( 'large', $watermarks ) ), $file->container );
$this->masked_file_name = (string) $largeImage;
$thumbnailDimensions['large'] = $largeImage->getImageDimensions();
$smallImage = \IPS\File::create( 'gallery_Images', 'small.' . $file->originalFilename, $this->_createImage( $file, explode( 'x', \IPS\Settings::i()->gallery_small_dims ), \IPS\Settings::i()->gallery_use_square_thumbnails, in_array( 'small', $watermarks ) ) );
$smallImage = \IPS\File::create( 'gallery_Images', 'small.' . $file->originalFilename, $this->createImageFile( $file, explode( 'x', \IPS\Settings::i()->gallery_small_dims ), \IPS\Settings::i()->gallery_use_square_thumbnails, \in_array( 'small', $watermarks ) ), $file->container );
$this->small_file_name = (string) $smallImage;
$thumbnailDimensions['small'] = $smallImage->getImageDimensions();
@@ -1432,23 +1485,26 @@ class _Image extends \IPS\Content\Item implements
* Create image object and apply watermark, if appropriate
*
* @param \IPS\File $file Base file to create from
* @param array $dimensions Dimensions to resize to
* @param array|NULL $dimensions Dimensions to resize to, or NULL to not resize
* @param bool $crop Whether to crop (true) or resize (false)
* @param bool $watermark Watermark the created image
* @return \IPS\Image
*/
protected function _createImage( $file, $dimensions, $crop=FALSE, $watermark=TRUE )
public function createImageFile( $file, $dimensions, $crop=FALSE, $watermark=TRUE )
{
$image = \IPS\Image::create( $file->contents() );
if( $crop )
if( $dimensions !== NULL )
{
//$image->crop( $dimensions[0], $dimensions[1] );
$image->resizeToMax( $dimensions[0], $dimensions[0] );
}
else
{
$image->resizeToMax( $dimensions[0], $dimensions[1] );
if( $crop )
{
//$image->crop( $dimensions[0], $dimensions[1] );
$image->resizeToMax( $dimensions[0], $dimensions[0] );
}
else
{
$image->resizeToMax( $dimensions[0], $dimensions[1] );
}
}
if( $watermark and \IPS\Settings::i()->gallery_use_watermarks and \IPS\Settings::i()->gallery_watermark_path AND $this->container()->watermark )
@@ -1491,19 +1547,23 @@ class _Image extends \IPS\Content\Item implements
/**
* Return the form to enable the map
*
* @param bool $lightbox Is this for the lightbox?
* @return string
*/
public function enableMapForm()
public function enableMapForm( $lightbox = FALSE )
{
if( $this->canEdit() )
{
/* We do this to prevent a javascript error from having two elements on the same page with the same name/id */
$setting = $lightbox ? "map_enabled_lightbox" : "map_enabled";
$form = new \IPS\Helpers\Form;
$form->class = 'ipsForm_vertical';
$form->add( new \IPS\Helpers\Form\YesNo( 'map_enabled', $this->gps_show, FALSE ) );
$form->add( new \IPS\Helpers\Form\YesNo( $setting, $this->gps_show, FALSE ) );
if( $values = $form->values() )
{
$this->gps_show = $values['map_enabled'];
$this->gps_show = $values[ $setting ];
$this->save();
\IPS\Output::i()->redirect( $this->url() );
}
@@ -1528,7 +1588,7 @@ class _Image extends \IPS\Content\Item implements
{
foreach ( $data as $k => $v )
{
if ( !in_array( $v, $return ) )
if ( !\in_array( $v, $return ) )
{
$return[ $k ] = $v;
}
@@ -1541,7 +1601,7 @@ class _Image extends \IPS\Content\Item implements
/**
* Log for deletion later
*
* \IPS\Member|NULL $member The member or NULL for currently logged in
* @param \IPS\Member|NULL $member The member, NULL for currently logged in, or FALSE for no member
* @return void
*/
public function logDelete( $member = NULL )
@@ -1690,7 +1750,7 @@ class _Image extends \IPS\Content\Item implements
return array(
'id' => $this->id,
'caption' => $this->caption,
'description' => $this->description,
'description' => \IPS\Text\Parser::removeLazyLoad( $this->description ),
'filename' => $this->file_name,
'filesize' => $this->file_size,
'images' => array(
@@ -1837,21 +1897,22 @@ class _Image extends \IPS\Content\Item implements
/**
* Check permissions
*
* @param mixed $permission 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
* @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 the permission map (either of the container or of this class) 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 map
*/
public function can( $permission, $member=NULL )
public function can( $permission, $member=NULL, $considerPostBeforeRegistering=TRUE )
{
if ( !parent::can( $permission, $member ) )
if ( !parent::can( $permission, $member, $considerPostBeforeRegistering ) )
{
return FALSE;
}
try
{
if ( !$this->directContainer()->can( $permission, $member ) )
if ( !$this->directContainer()->can( $permission, $member, $considerPostBeforeRegistering ) )
{
return FALSE;
}
@@ -1886,13 +1947,13 @@ class _Image extends \IPS\Content\Item implements
$member = $member ?: \IPS\Member::loggedIn();
/* Is this a private album we can't access? */
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_PRIVATE AND $this->directContainer()->owner() != $member )
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_PRIVATE AND $this->directContainer()->owner()->member_id != $member->member_id )
{
return FALSE;
}
/* Is this a restricted album we can't access? */
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_RESTRICTED AND $this->directContainer()->owner() != $member )
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_RESTRICTED AND $this->directContainer()->owner()->member_id != $member->member_id )
{
/* This will throw an exception of the row does not exist */
try
@@ -2012,7 +2073,7 @@ class _Image extends \IPS\Content\Item implements
if( $hiddenContainers !== TRUE )
{
if( is_array( $hiddenContainers ) AND count( $hiddenContainers ) )
if( \is_array( $hiddenContainers ) AND \count( $hiddenContainers ) )
{
$result[0] .= " AND ( gallery_albums.album_id IS NULL OR gallery_albums.album_hidden=0 OR gallery_albums.album_category_id IN(" . implode( ',', $hiddenContainers ) . ") )";
}
@@ -2062,7 +2123,7 @@ class _Image extends \IPS\Content\Item implements
{
$_check = explode( ' ', trim( $_order ) );
if( count( $_check ) == 2 )
if( \count( $_check ) == 2 )
{
if( $_check[0] == 'image_updated' OR $_check[0] == 'image_date' )
{
@@ -2092,7 +2153,7 @@ class _Image extends \IPS\Content\Item implements
}
/**
* Total item count (including children)
* Total item \count(including children)
*
* @param \IPS\Node\Model $container The container
* @param bool $includeItems If TRUE, items will be included (this should usually be true)
@@ -2110,7 +2171,7 @@ class _Image extends \IPS\Content\Item implements
return parent::contentCount( $container, $includeItems, $includeComments, $includeReviews, $depth );
}
$_key = md5( get_class( $container ) . $container->_id );
$_key = md5( \get_class( $container ) . $container->_id );
if( !isset( static::$itemCounts[ $_key ][ $container->_id ] ) )
{
@@ -2161,6 +2222,10 @@ class _Image extends \IPS\Content\Item implements
{
$return = "m{$this->member_id}";
}
else
{
$return = '';
}
}
else
{
@@ -2212,25 +2277,27 @@ class _Image extends \IPS\Content\Item implements
/**
* Can comment?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @param \IPS\Member\NULL $member The member (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
*/
public function canComment( $member=NULL )
public function canComment( $member=NULL, $considerPostBeforeRegistering = TRUE )
{
$member = $member ?: \IPS\Member::loggedIn();
return parent::canComment( $member ) and $this->container()->allow_comments and $this->directContainer()->allow_comments;
return parent::canComment( $member, $considerPostBeforeRegistering ) and $this->container()->allow_comments and $this->directContainer()->allow_comments;
}
/**
* Can review?
*
* @param \IPS\Member\NULL $member The member (NULL for currently logged in member)
* @param \IPS\Member\NULL $member The member (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
*/
public function canReview( $member = NULL )
public function canReview( $member=NULL, $considerPostBeforeRegistering = TRUE )
{
$member = $member ?: \IPS\Member::loggedIn();
return parent::canReview( $member ) and $this->container()->allow_reviews and $this->directContainer()->allow_reviews;
return parent::canReview( $member, $considerPostBeforeRegistering ) and $this->container()->allow_reviews and $this->directContainer()->allow_reviews;
}
/**
@@ -2270,14 +2337,14 @@ class _Image extends \IPS\Content\Item implements
/**
* Returns the content images
*
* @param int|null $limit Number of attachments to fetch, or NULL for all
*
* @return array|NULL If array, then array( 'core_Attachment' => 'month_x/foo.gif', ... );
* @param int|null $limit Number of attachments to fetch, or NULL for all
* @param bool $ignorePermissions If set to TRUE, permission to view the images will not be checked
* @return array|NULL
* @throws \BadMethodCallException
*/
public function contentImages( $limit = NULL )
public function contentImages( $limit = NULL, $ignorePermissions = FALSE )
{
$result = parent::contentImages( $limit );
$result = parent::contentImages( $limit, $ignorePermissions );
if( $result === NULL )
{
@@ -2288,4 +2355,48 @@ class _Image extends \IPS\Content\Item implements
return $result;
}
/**
* Get content for an email
*
* @param \IPS\Email $email The email
* @param string $type 'html' or 'plaintext'
* @return string
*/
public function emailContent( \IPS\Email $email, $type, $includeLinks=TRUE, $includeAuthor=TRUE )
{
if ( $type === 'html' )
{
return \IPS\Email::template( 'gallery', '_imageContent', $type, array( $this, $includeLinks, $includeAuthor, $email ) );
}
else
{
return parent::emailContent( $email, $type, $includeLinks, $includeAuthor );
}
}
/**
* @brief Some constants to define the ability to download original images
*/
const DOWNLOAD_ORIGINAL_NONE = 0;
const DOWNLOAD_ORIGINAL_RAW = 1;
const DOWNLOAD_ORIGINAL_WATERMARKED = 2;
/**
* Can the member download the original image?
*
* @note Returns one of the defined constants
* @li DOWNLOAD_ORIGINAL_NONE
* @li DOWNLOAD_ORIGINAL_RAW
* @li DOWNLOAD_ORIGINAL_WATERMARKED
* @param \IPS\Member|NULL $member The member to test, or NULL for currently logged in member
* @return int
*/
public function canDownloadOriginal( $member=NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
return $member->group['g_download_original'];
}
}