Version 4.3.0
This commit is contained in:
1 parent
96997ddd8e
commit
fe1acf984a
1349 files changed
+116159
-67711
No files matched your search
@@ -24,12 +24,21 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\Embeddable
|
||||
{
|
||||
/**
|
||||
* @brief Define access levels
|
||||
* @brief Define view access levels
|
||||
*/
|
||||
const AUTH_TYPE_PUBLIC = 1;
|
||||
const AUTH_TYPE_PRIVATE = 2;
|
||||
const AUTH_TYPE_RESTRICTED = 3;
|
||||
const AUTH_TYPE_DELETED = 4;
|
||||
|
||||
/**
|
||||
* @brief Define submit access levels
|
||||
*/
|
||||
const AUTH_SUBMIT_OWNER = 0;
|
||||
const AUTH_SUBMIT_PUBLIC = 1;
|
||||
const AUTH_SUBMIT_GROUPS = 2;
|
||||
const AUTH_SUBMIT_MEMBERS = 3;
|
||||
const AUTH_SUBMIT_CLUB = 4;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
@@ -124,16 +133,19 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
/**
|
||||
* [Node] Load and check permissions
|
||||
*
|
||||
* @param mixed $id ID
|
||||
* @param string $perm Permission Key
|
||||
* @param mixed $id ID
|
||||
* @param string $perm Permission Key
|
||||
* @param \IPS\Member|NULL $member Member, or NULL for logged in member
|
||||
* @return static
|
||||
* @throws \OutOfRangeException
|
||||
* @note Album 'add' permissions are properly checked via the can() method
|
||||
*/
|
||||
public static function loadAndCheckPerms( $id, $perm='view' )
|
||||
public static function loadAndCheckPerms( $id, $perm='view', \IPS\Member $member = NULL )
|
||||
{
|
||||
$obj = parent::loadAndCheckPerms( $id );
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if ( !$obj->category()->can( $perm ) )
|
||||
if ( !$obj->can( $perm ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
@@ -147,23 +159,23 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
if( !\IPS\gallery\Image::modPermission( 'edit', NULL, $obj->category() ) )
|
||||
{
|
||||
/* Throw exception if this is a private album we can't access */
|
||||
if( $obj->type == static::AUTH_TYPE_PRIVATE AND $obj->owner() != \IPS\Member::loggedIn() )
|
||||
if( $obj->type == static::AUTH_TYPE_PRIVATE AND $obj->owner() != $member )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
/* Throw exception if this is a restricted album we can't access */
|
||||
if( $obj->type == static::AUTH_TYPE_RESTRICTED AND $obj->owner() != \IPS\Member::loggedIn() )
|
||||
if( $obj->type == static::AUTH_TYPE_RESTRICTED AND $obj->owner() != $member )
|
||||
{
|
||||
/* This will throw an exception if the row does not exist... but we need it to throw an OutOfRangeException */
|
||||
try
|
||||
{
|
||||
if( !\IPS\Member::loggedIn()->member_id )
|
||||
if( !$member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$member = \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=? AND member_id=?', $obj->allowed_access, \IPS\Member::loggedIn()->member_id ) )->first();
|
||||
$member = \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=? AND member_id=?', $obj->allowed_access, $member->member_id ) )->first();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
@@ -174,6 +186,27 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all albums we can submit to
|
||||
*
|
||||
* @param \IPS\gallery\Category $category Category we are submitting in
|
||||
* @return array
|
||||
* @throws \RuntimeException
|
||||
*/
|
||||
public static function loadForSubmit( $category )
|
||||
{
|
||||
$ownedAlbums = static::loadByOwner( NULL, array( array( 'album_category_id=?', $category->id ) ) );
|
||||
$permittedAlbums = \IPS\gallery\Album\Item::getItemsWithPermission( array( array( 'album_category_id=?', $category->id ) ), NULL, NULL, 'add' );
|
||||
$finalAlbums = $ownedAlbums;
|
||||
|
||||
foreach( $permittedAlbums as $album )
|
||||
{
|
||||
$finalAlbums[ $album->id ] = $album->asNode();
|
||||
}
|
||||
|
||||
return $finalAlbums;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch all nodes owned by a given user
|
||||
@@ -196,7 +229,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
protected $_approvedMembers = FALSE;
|
||||
|
||||
/**
|
||||
* Get members with access to restricted album
|
||||
* Get members with access to view restricted album
|
||||
*
|
||||
* @return array|null
|
||||
* @note This list will NOT include the album owner, who also inherently has access
|
||||
@@ -288,6 +321,17 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
return $this->count_imgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items count language string
|
||||
*
|
||||
* @return string
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function get__countLanguageString()
|
||||
{
|
||||
return 'num_images';
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of content comments
|
||||
*
|
||||
@@ -442,7 +486,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\Text( 'album_name', $album ? $album->name : '', $required ?: NULL );
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\Editor( 'album_description', $album ? $album->description : '', FALSE, array( 'app' => 'gallery', 'key' => 'Albums', 'autoSaveKey' => ( $album ? "gallery_album_{$album->id}_desc" : "gallery-new-album" ), 'attachIds' => $album ? array( $album->id, NULL, 'description' ) : NULL, 'minimize' => 'cdesc_placeholder' ) );
|
||||
$return[] = new \IPS\Helpers\Form\Editor( 'album_description', $album ? $album->description : '', FALSE, array( 'app' => 'gallery', 'key' => 'Albums', 'autoSaveKey' => ( $album ? "gallery_album_{$album->id}_desc" : "gallery-new-album" ), 'attachIds' => $album ? array( $album->id, NULL, 'description' ) : NULL ) );
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\Node( 'album_category', ( $album and $album->category_id ) ? \IPS\gallery\Category::load( $album->category_id ) : NULL, $required ?: NULL, array(
|
||||
'class' => 'IPS\gallery\Category',
|
||||
@@ -463,7 +507,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
}
|
||||
) );
|
||||
|
||||
if( $forOther or \IPS\gallery\Image::modPermission( 'edit', NULL, ( $album ? $album->category() : NULL ) ) )
|
||||
if( $forOther or \IPS\gallery\Album\Item::modPermission( 'edit', NULL, ( $album ? $album->category() : NULL ) ) )
|
||||
{
|
||||
if ( !$forOther )
|
||||
{
|
||||
@@ -497,8 +541,37 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
{
|
||||
$return[] = new \IPS\Helpers\Form\SocialGroup( 'album_allowed_access', $album ? $album->allowed_access : NULL, FALSE, array( 'owner' => $album ? \IPS\Member::load( $album->owner_id ) : ( \IPS\Request::i()->album_owner ? \IPS\Member::load( \IPS\Request::i()->album_owner, 'name' ) : \IPS\Member::loggedIn() ) ), NULL, NULL, NULL, 'album_allowed_access' );
|
||||
}
|
||||
|
||||
$submitTypes = array(
|
||||
static::AUTH_SUBMIT_OWNER => 'album_submittype_owner',
|
||||
static::AUTH_SUBMIT_PUBLIC => 'album_submittype_public',
|
||||
static::AUTH_SUBMIT_GROUPS => 'album_submittype_groups',
|
||||
static::AUTH_SUBMIT_MEMBERS => 'album_submittype_members'
|
||||
);
|
||||
|
||||
/* Is the category in a club */
|
||||
if( $album AND $album->category_id )
|
||||
{
|
||||
if( $album->category()->club() )
|
||||
{
|
||||
$submitTypes[ static::AUTH_SUBMIT_CLUB ] = 'album_submittype_club';
|
||||
}
|
||||
}
|
||||
elseif( !$album AND ( isset( \IPS\Request::i()->chosenCategory ) or isset( \IPS\Request::i()->category ) ) )
|
||||
{
|
||||
if( \IPS\gallery\Category::load( (int) \IPS\Request::i()->chosenCategory ?: \IPS\Request::i()->category )->club() )
|
||||
{
|
||||
$submitTypes[ static::AUTH_SUBMIT_CLUB ] = 'album_submittype_club';
|
||||
}
|
||||
}
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\Radio( 'album_submit_type', ( $album and $album->submit_type ) ? $album->submit_type : static::AUTH_SUBMIT_OWNER, FALSE, array( 'options' => $submitTypes, 'toggles' => array( static::AUTH_SUBMIT_MEMBERS => array( 'album_submit_access_members' ), static::AUTH_SUBMIT_GROUPS => array( 'album_submit_access_groups' ) ) ), NULL, NULL, NULL, 'album_submit_type' );
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\SocialGroup( 'album_submit_access_members', ( $album AND $album->submit_type == static::AUTH_SUBMIT_MEMBERS ) ? $album->submit_access : NULL, FALSE, array( 'owner' => $album ? \IPS\Member::load( $album->owner_id ) : ( \IPS\Request::i()->album_owner ? \IPS\Member::load( \IPS\Request::i()->album_owner, 'name' ) : \IPS\Member::loggedIn() ) ), NULL, NULL, NULL, 'album_submit_access_members' );
|
||||
$groups = array_combine( array_keys( \IPS\Member\Group::groups( TRUE, FALSE ) ), array_map( function( $_group ) { return (string) $_group; }, \IPS\Member\Group::groups( TRUE, FALSE ) ) );
|
||||
$return[] = new \IPS\Helpers\Form\Select( 'album_submit_access_groups', ( $album and $album->submit_type == static::AUTH_SUBMIT_GROUPS ) ? explode( ',', $album->submit_access ) : NULL, FALSE, array( 'options' => $groups, 'multiple' => true ), NULL, NULL, NULL, 'album_submit_access_groups' );
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\Select( 'album_sort_options', ( $album and $album->sort_options ) ? $album->sort_options : 'updated', FALSE, array( 'options' => array( 'updated' => 'sort_updated', 'last_comment' => 'sort_last_comment', 'title' => 'sort_title', 'rating' => 'sort_rating', 'date' => 'sort_date', 'num_comments' => 'sort_num_comments', 'num_reviews' => 'sort_num_reviews', 'views' => 'sort_views' ) ), NULL, NULL, NULL, 'album_sort_options' );
|
||||
$return[] = new \IPS\Helpers\Form\Select( 'album_sort_options', ( $album and $album->sort_options ) ? $album->sort_options : 'updated', FALSE, array( 'options' => array( 'updated' => 'sort_updated', 'last_comment' => 'sort_last_comment', 'title' => 'album_sort_caption', 'rating' => 'sort_rating', 'date' => 'sort_date', 'num_comments' => 'sort_num_comments', 'num_reviews' => 'sort_num_reviews', 'views' => 'sort_views' ) ), NULL, NULL, NULL, 'album_sort_options' );
|
||||
|
||||
$return[] = new \IPS\Helpers\Form\YesNo( 'album_allow_rating', $album ? $album->allow_rating : TRUE, FALSE );
|
||||
|
||||
@@ -624,11 +697,25 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
$values['owner_id'] = ( $values['album_owner'] instanceof \IPS\Member ) ? $values['album_owner']->member_id : $values['album_owner'];
|
||||
unset( $values['album_owner'] );
|
||||
}
|
||||
else
|
||||
else if ( !$this->postSaveIsEdit )
|
||||
{
|
||||
$values['owner_id'] = \IPS\Member::loggedIn()->member_id;
|
||||
}
|
||||
|
||||
switch( $values['album_submit_type'] )
|
||||
{
|
||||
case static::AUTH_SUBMIT_GROUPS:
|
||||
$values['submit_access'] = implode( ',', $values['album_submit_access_groups'] );
|
||||
break;
|
||||
|
||||
case static::AUTH_SUBMIT_MEMBERS:
|
||||
$values['submit_access'] = $values['album_submit_access_members'];
|
||||
break;
|
||||
}
|
||||
|
||||
unset( $values['album_submit_access_members'] );
|
||||
unset( $values['album_submit_access_groups'] );
|
||||
|
||||
/* Send to parent */
|
||||
return $values;
|
||||
}
|
||||
@@ -656,6 +743,8 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
*/
|
||||
public function postSaveForm( $values )
|
||||
{
|
||||
\IPS\File::claimAttachments( 'gallery-new-album', $this->id );
|
||||
|
||||
/* Update counts in categories if we move the album */
|
||||
if( $this->postSaveIsEdit and $this->postSaveCategory != $values['category_id'] )
|
||||
{
|
||||
@@ -732,6 +821,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
|
||||
/* Update caches */
|
||||
$asItem->expireWidgetCaches();
|
||||
$asItem->adjustSessions();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -815,7 +905,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
|
||||
$this->last_img_date = 0;
|
||||
$this->last_img_id = 0;
|
||||
foreach( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_album_id=? AND image_approved=1', $this->id ), $sortBy, array( 0, 20 ) ) as $image )
|
||||
foreach( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_album_id=? AND image_approved=1', $this->id ), $sortBy, array( 0, 20 ), NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER ) as $image )
|
||||
{
|
||||
if( $image['image_date'] > $this->last_img_date )
|
||||
{
|
||||
@@ -829,23 +919,23 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
$this->last_x_images = json_encode( $_latestImages );
|
||||
|
||||
/* Now get the counts and set them for our images */
|
||||
$this->_items = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_images', array( 'image_album_id=? AND image_approved=1', $this->id ) )->first();
|
||||
$this->_unapprovedItems = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_images', array( 'image_album_id=? AND image_approved=0', $this->id ) )->first();
|
||||
$this->_items = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_images', array( 'image_album_id=? AND image_approved=1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$this->_unapprovedItems = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_images', array( 'image_album_id=? AND image_approved=0', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
$this->_comments = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_comments', array( 'gallery_images.image_album_id=? AND comment_approved=1', $this->id ) )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
|
||||
$this->_unapprovedComments = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_comments', array( 'gallery_images.image_album_id=? AND comment_approved=0', $this->id ) )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
|
||||
$this->_comments = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_comments', array( 'gallery_images.image_album_id=? AND comment_approved=1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
|
||||
$this->_unapprovedComments = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_comments', array( 'gallery_images.image_album_id=? AND comment_approved=0', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
|
||||
|
||||
$this->_reviews = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_reviews', array( 'gallery_images.image_album_id=? AND review_approved=1', $this->id ) )->join( 'gallery_images', 'image_id=review_image_id' )->first();
|
||||
$this->_unapprovedReviews = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_reviews', array( 'gallery_images.image_album_id=? AND review_approved=0', $this->id ) )->join( 'gallery_images', 'image_id=review_image_id' )->first();
|
||||
$this->_reviews = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_reviews', array( 'gallery_images.image_album_id=? AND review_approved=1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->join( 'gallery_images', 'image_id=review_image_id' )->first();
|
||||
$this->_unapprovedReviews = \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_reviews', array( 'gallery_images.image_album_id=? AND review_approved=0', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->join( 'gallery_images', 'image_id=review_image_id' )->first();
|
||||
|
||||
/* And then get counts/latest data for the direct comments/reviews */
|
||||
$this->comments = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=1', $this->id ) )->first();
|
||||
$this->comments_unapproved = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=0', $this->id ) )->first();
|
||||
$this->comments_hidden = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=-1', $this->id ) )->first();
|
||||
$this->comments = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$this->comments_unapproved = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=0', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$this->comments_hidden = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_comments', array( 'comment_album_id=? AND comment_approved=-1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
$this->reviews = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=1', $this->id ) )->first();
|
||||
$this->reviews_unapproved = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=0', $this->id ) )->first();
|
||||
$this->reviews_hidden = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=-1', $this->id ) )->first();
|
||||
$this->reviews = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$this->reviews_unapproved = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=0', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
$this->reviews_hidden = (int) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_album_reviews', array( 'review_album_id=? AND review_approved=-1', $this->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
/* Save and then make sure search index is updated */
|
||||
\IPS\Content\Search\Index::i()->index( $this->asItem() );
|
||||
@@ -861,14 +951,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
*/
|
||||
public function contentImages( $limit = NULL )
|
||||
{
|
||||
$images = array();
|
||||
|
||||
foreach( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_album_id=?', $this->id ) ), NULL, $limit ? $limit : 10 ) as $image )
|
||||
{
|
||||
$images[] = array( 'gallery_Images' => $image->medium_file_name );
|
||||
}
|
||||
|
||||
return count( $images ) ? $images : NULL;
|
||||
$this->asItem()->contentImages( $limit );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1047,45 +1130,53 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
/**
|
||||
* Retrieve a cover photo
|
||||
*
|
||||
* @param string $size One of full, medium, small or thumb
|
||||
* @param string $size Masked or small
|
||||
* @return string|null
|
||||
*/
|
||||
public function coverPhoto( $size='thumb' )
|
||||
public function coverPhoto( $size='small' )
|
||||
{
|
||||
/* Can we view the images in this album? */
|
||||
if ( !$this->can( 'read' ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( $size == 'full' )
|
||||
/* Make sure it's a valid size */
|
||||
if( !in_array( $size, array( 'masked', 'small' ) ) )
|
||||
{
|
||||
$size = 'masked';
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
$property = $size . "_file_name";
|
||||
|
||||
if( !$this->cover_img_id )
|
||||
/* If we have an explicit cover photo set, make sure it's valid and load/cache it */
|
||||
if( $this->cover_img_id )
|
||||
{
|
||||
if( $lastImage = $this->lastImage() )
|
||||
if( $this->coverPhoto === NULL )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
try
|
||||
{
|
||||
$this->coverPhoto = \IPS\gallery\Image::load( $this->cover_img_id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* Cover photo isn't valid, reset album automatically */
|
||||
$this->cover_img_id = 0;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if( $this->coverPhoto !== NULL )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $this->coverPhoto->$property )->url;
|
||||
}
|
||||
}
|
||||
|
||||
if( !in_array( $size, array( 'masked', 'medium', 'small', 'thumb' ) ) )
|
||||
if( $lastImage = $this->lastImage() AND !$lastImage->media )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
}
|
||||
|
||||
if( $this->coverPhoto === NULL )
|
||||
{
|
||||
$this->coverPhoto = \IPS\gallery\Image::load( $this->cover_img_id );
|
||||
}
|
||||
|
||||
return (string) \IPS\File::get( 'gallery_Images', $this->coverPhoto->$property )->url;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1132,7 +1223,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
return $this->asItem()->canDelete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1149,6 +1240,55 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
/* Load the item */
|
||||
$asItem = $this->asItem();
|
||||
|
||||
/* Figure out member */
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
/* If we are checking 'add' permission, verify if we can add */
|
||||
if( $permission == 'add' )
|
||||
{
|
||||
/* First check we can submit to this album based on the "Submissions" setting */
|
||||
switch ( $this->submit_type )
|
||||
{
|
||||
/* Owner */
|
||||
case static::AUTH_SUBMIT_OWNER:
|
||||
if ( $this->owner_id != $member->member_id )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Chosen groups */
|
||||
case static::AUTH_SUBMIT_GROUPS:
|
||||
if ( !$member->inGroup( explode( ',', $this->submit_access ) ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Chosen members */
|
||||
case static::AUTH_SUBMIT_MEMBERS:
|
||||
if ( !in_array( $this->submit_access, $member->socialGroups() ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
/* Club */
|
||||
case static::AUTH_SUBMIT_CLUB:
|
||||
if ( $club = $this->category()->club() and !in_array( $club->id, $member->clubs() ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
/* Verify if we can add any more files to this album */
|
||||
if( \IPS\Member::loggedIn()->group['g_img_album_limit'] AND \IPS\Member::loggedIn()->group['g_img_album_limit'] - ( $this->count_imgs + $this->count_imgs_hidden ) < 1 )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Albums can be hidden, so make sure to test permissions */
|
||||
if( $asItem->hidden() )
|
||||
{
|
||||
@@ -1190,7 +1330,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
*/
|
||||
public function searchIndexPermissions()
|
||||
{
|
||||
$return = parent::searchIndexPermissions();
|
||||
$return = $this->category()->searchIndexPermissions();
|
||||
|
||||
if ( $this->type != static::AUTH_TYPE_PUBLIC )
|
||||
{
|
||||
@@ -1250,6 +1390,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
/**
|
||||
* 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 name Name
|
||||
@@ -1261,17 +1402,17 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
|
||||
* @apiresponse int images Number of images
|
||||
* @apiresponse string url URL
|
||||
*/
|
||||
public function apiOutput()
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
{
|
||||
return array(
|
||||
'id' => $this->id,
|
||||
'name' => $this->name,
|
||||
'description' => $this->description,
|
||||
'category' => $this->category()->apiOutput(),
|
||||
'owner' => $this->owner()->apiOutput(),
|
||||
'category' => $this->category()->apiOutput( $authorizedMember ),
|
||||
'owner' => $this->owner()->apiOutput( $authorizedMember ),
|
||||
'privacy' => ( $this->type == static::AUTH_TYPE_PUBLIC ) ? 'public' : ( $this->type == static::AUTH_TYPE_PRIVATE ? 'private' : ( $this->type == static::AUTH_TYPE_RESTRICTED ? 'restricted' : null ) ),
|
||||
'approvedMembers' => $this->approvedMembers ? array_map( function( $val ) {
|
||||
return $val->apiOutput();
|
||||
'approvedMembers' => $this->approvedMembers ? array_map( function( $val ) use ( $authorizedMember ) {
|
||||
return $val->apiOutput( $authorizedMember );
|
||||
}, $this->approvedMembers ) : null,
|
||||
'images' => $this->count_imgs,
|
||||
'url' => (string) $this->url()
|
||||
|
||||
@@ -21,9 +21,9 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Album Comment Model
|
||||
*/
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
@@ -123,7 +123,7 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
|
||||
{
|
||||
parent::postCreate();
|
||||
|
||||
$this->item()->asNode()->setLastComment();
|
||||
$this->item()->asNode()->setLastComment( $this );
|
||||
$this->item()->asNode()->save();
|
||||
}
|
||||
|
||||
@@ -173,4 +173,16 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'gallery', 'front' ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->embedAlbumComment( $this, $this->item(), $this->url()->setQueryString( $params ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container item class to use for mod permission checks
|
||||
*
|
||||
* @return string|NULL
|
||||
* @note By default we will return NULL and the container check will execute against Node::$contentItemClass, however
|
||||
* in some situations we may need to override this (i.e. for Gallery Albums)
|
||||
*/
|
||||
protected static function getContainerModPermissionClass()
|
||||
{
|
||||
return 'IPS\gallery\Album\Item';
|
||||
}
|
||||
}
|
||||
@@ -31,10 +31,9 @@ class _Item extends \IPS\Content\Item implements
|
||||
\IPS\Content\Hideable,
|
||||
\IPS\Content\Featurable,
|
||||
\IPS\Content\Lockable,
|
||||
\IPS\Content\ReportCenter,
|
||||
\IPS\Content\MetaData
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
@@ -230,7 +229,7 @@ class _Item extends \IPS\Content\Item implements
|
||||
{
|
||||
if( $this->cover_img_id OR $this->last_img_id )
|
||||
{
|
||||
return \IPS\File::get( 'gallery_Images', \IPS\gallery\Image::load( $this->cover_img_id ?: $this->last_img_id )->thumb_file_name );
|
||||
return \IPS\File::get( 'gallery_Images', \IPS\gallery\Image::load( $this->cover_img_id ?: $this->last_img_id )->small_file_name );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -279,10 +278,48 @@ class _Item extends \IPS\Content\Item implements
|
||||
*/
|
||||
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( $permissionKey == 'add' )
|
||||
{
|
||||
$where[] = static::submitRestrictionWhere( $member, \IPS\gallery\Category::load( $where[0][1] ) );
|
||||
}
|
||||
|
||||
$where[] = static::getItemsWithPermissionWhere( $where, $member, $joins );
|
||||
|
||||
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional WHERE clauses for finding albums the user can submit to
|
||||
*
|
||||
* @param \IPS\Member|NULL $member Member to check
|
||||
* @param \IPS\gallery\Category $category Category we are submitted in
|
||||
* @return string
|
||||
*/
|
||||
public static function submitRestrictionWhere( $member, $category )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
/* For starters, allow us to submit to public albums and our own albums */
|
||||
$wheres = array(
|
||||
'(album_submit_type=' . \IPS\gallery\Album::AUTH_SUBMIT_OWNER . ' and album_owner_id=' . $member->member_id . ')',
|
||||
'(album_submit_type=' . \IPS\gallery\Album::AUTH_SUBMIT_PUBLIC . ')'
|
||||
);
|
||||
|
||||
/* Now allow us to submit to albums that allow group submissions */
|
||||
$wheres[] = '(album_submit_type=' . \IPS\gallery\Album::AUTH_SUBMIT_GROUPS . ' AND ' . \IPS\Db::i()->findInSet( 'album_submit_access', $member->groups ) . ')';
|
||||
|
||||
/* And where we as an individual member are allowed to submit */
|
||||
$wheres[] = '(album_submit_type=' . \IPS\gallery\Album::AUTH_SUBMIT_MEMBERS . ' AND ' . \IPS\Db::i()->findInSet( 'album_submit_access', $member->socialGroups() ) . ')';
|
||||
|
||||
/* And finally, if we're in a club and we allow anyone in the club to submit, handle that */
|
||||
if( $category->club() AND in_array( $category->club()->id, $member->clubs() ) )
|
||||
{
|
||||
$wheres[] = '(album_submit_type=' . \IPS\gallery\Album::AUTH_SUBMIT_CLUB . ')';
|
||||
}
|
||||
|
||||
return '(album_owner_id=' . $member->member_id . ' OR ' . implode( ' OR ', $wheres ) . ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached groups the member can access
|
||||
*/
|
||||
@@ -368,24 +405,6 @@ class _Item extends \IPS\Content\Item implements
|
||||
return $this->asNode()->searchIndexPermissions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Can edit?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
|
||||
* @return bool
|
||||
*/
|
||||
public function canEdit( $member=NULL )
|
||||
{
|
||||
$member = $member ?: \IPS\Member::loggedIn();
|
||||
|
||||
if( $member->member_id == $this->mapped('author') )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return parent::canEdit( $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns needed to query for search result / stream view
|
||||
*
|
||||
@@ -433,8 +452,13 @@ class _Item extends \IPS\Content\Item implements
|
||||
|
||||
$return = array();
|
||||
|
||||
foreach ( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_id IN(' . implode( ',', $imageIds ) . ')' ) ), NULL, 20 ) as $image )
|
||||
foreach ( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_id IN(' . implode( ',', $imageIds ) . ')' ) ), NULL, NULL ) as $image )
|
||||
{
|
||||
if( isset( $return[ $image->album_id] ) AND count( $return[ $image->album_id ] ) > 19 )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$return[ $image->album_id ][] = $image;
|
||||
}
|
||||
|
||||
@@ -464,6 +488,29 @@ class _Item extends \IPS\Content\Item implements
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultAlbumSnippet( $indexData, $itemData, $images, $url, $view == 'condensed' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the language string key to use in search results
|
||||
*
|
||||
* @note Normally we show "(user) posted a (thing) in (area)" but sometimes this may not be accurate, so this is abstracted to allow
|
||||
* content classes the ability to override
|
||||
* @param array $authorData Author data
|
||||
* @param array $articles Articles language strings
|
||||
* @param array $indexData Search index data
|
||||
* @param array $itemData Data about the item
|
||||
* @return string
|
||||
*/
|
||||
public static function searchResultSummaryLanguage( $authorData, $articles, $indexData, $itemData )
|
||||
{
|
||||
if( !in_array( 'IPS\Content\Comment', class_parents( $indexData['index_class'] ) ) )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( "album_user_own_activity_item", FALSE, array( 'sprintf' => array( $authorData['name'], $articles['indefinite'] ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return parent::searchResultSummaryLanguage( $authorData, $articles, $indexData, $itemData );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief A classname applied to the search result block
|
||||
*/
|
||||
@@ -516,7 +563,7 @@ class _Item extends \IPS\Content\Item implements
|
||||
{
|
||||
\IPS\gallery\Application::outputCss();
|
||||
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery', 'front' ), 'albums' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -581,4 +628,36 @@ class _Item extends \IPS\Content\Item implements
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'gallery', 'front' ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->embedAlbums( $this, $this->asNode(), $this->url()->setQueryString( $params ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container item class to use for mod permission checks
|
||||
*
|
||||
* @return string|NULL
|
||||
* @note By default we will return NULL and the container check will execute against Node::$contentItemClass, however
|
||||
* in some situations we may need to override this (i.e. for Gallery Albums)
|
||||
*/
|
||||
protected static function getContainerModPermissionClass()
|
||||
{
|
||||
return 'IPS\gallery\Album\Item';
|
||||
}
|
||||
|
||||
/**
|
||||
* 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', ... );
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function contentImages( $limit = NULL )
|
||||
{
|
||||
$images = array();
|
||||
|
||||
foreach( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_album_id=?', $this->id ) ), NULL, $limit ? $limit : 10 ) as $image )
|
||||
{
|
||||
$images[] = array( 'gallery_Images' => $image->masked_file_name );
|
||||
}
|
||||
|
||||
return count( $images ) ? $images : NULL;
|
||||
}
|
||||
}
|
||||
@@ -21,9 +21,9 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Album Review Model
|
||||
*/
|
||||
class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
@@ -63,6 +63,7 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
|
||||
'votes_helpful' => 'votes_helpful',
|
||||
'votes_data' => 'votes_data',
|
||||
'approved' => 'approved',
|
||||
'author_response' => 'author_response',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -105,7 +106,7 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
|
||||
{
|
||||
parent::postCreate();
|
||||
|
||||
$this->item()->asNode()->setLastComment();
|
||||
$this->item()->asNode()->setLastReview( $this );
|
||||
$this->item()->asNode()->save();
|
||||
}
|
||||
|
||||
@@ -152,4 +153,16 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'embed.css', 'gallery', 'front' ) );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->embedAlbumReview( $this, $this->item(), $this->url()->setQueryString( $params ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the container item class to use for mod permission checks
|
||||
*
|
||||
* @return string|NULL
|
||||
* @note By default we will return NULL and the container check will execute against Node::$contentItemClass, however
|
||||
* in some situations we may need to override this (i.e. for Gallery Albums)
|
||||
*/
|
||||
protected static function getContainerModPermissionClass()
|
||||
{
|
||||
return 'IPS\gallery\Album\Item';
|
||||
}
|
||||
}
|
||||
@@ -62,7 +62,7 @@ class _Table extends \IPS\Helpers\Table\Content
|
||||
{
|
||||
if ( !$this->sortBy and $container->_sortBy )
|
||||
{
|
||||
$this->sortBy = '`' . \IPS\gallery\Album::$databaseTable . '`.`' . \IPS\gallery\Album::$databasePrefix . $container->_sortBy . '`';
|
||||
$this->sortBy = \IPS\gallery\Album::$databasePrefix . $container->_sortBy;
|
||||
$this->sortDirection = $container->_sortOrder;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ class _Table extends \IPS\Helpers\Table\Content
|
||||
$this->filter = $container->_filter;
|
||||
}
|
||||
|
||||
if ( $this->sortBy === 'name' )
|
||||
if ( $this->sortBy === 'album_name' )
|
||||
{
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
@@ -107,7 +107,7 @@ class _Table extends \IPS\Helpers\Table\Content
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->sortOptions[ 'album_' . $k ] = $k;
|
||||
$this->sortOptions[ 'album_' . $k ] = 'album_' . $k;
|
||||
}
|
||||
|
||||
unset( $this->sortOptions['date'] );
|
||||
@@ -151,4 +151,21 @@ class _Table extends \IPS\Helpers\Table\Content
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sort direction to use for links
|
||||
*
|
||||
* @note Abstracted so other table helper instances can adjust as needed
|
||||
* @param string $column Sort by string
|
||||
* @return string [asc|desc]
|
||||
*/
|
||||
public function getSortDirection( $column )
|
||||
{
|
||||
if( $column == 'album_name' )
|
||||
{
|
||||
return 'asc';
|
||||
}
|
||||
|
||||
return 'desc';
|
||||
}
|
||||
}
|
||||
@@ -287,6 +287,7 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return !isset( \IPS\Request::i()->id ) or ( $node->id != \IPS\Request::i()->id and !$node->isChildOf( $node::load( \IPS\Request::i()->id ) ) );
|
||||
}
|
||||
) ) );
|
||||
|
||||
$sortoptions = array(
|
||||
'album_last_img_date' => 'sort_updated',
|
||||
'album_last_comment' => 'sort_last_comment',
|
||||
@@ -298,7 +299,10 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
'album_count_imgs' => 'sort_album_count_imgs'
|
||||
);
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'category_sort_options', $this->sort_options ?: 'updated', FALSE, array( 'options' => $sortoptions ), NULL, NULL, NULL, 'category_sort_options' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_allow_albums', $this->id ? $this->allow_albums : TRUE, FALSE ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'category_sort_options_img', $this->sort_options_img ?: 'updated', FALSE, array( 'options' => array( 'updated' => 'sort_updated', 'last_comment' => 'sort_last_comment', 'title' => 'album_sort_caption', 'rating' => 'sort_rating', 'date' => 'sort_date', 'num_comments' => 'sort_num_comments', 'num_reviews' => 'sort_num_reviews', 'views' => 'sort_views' ) ), NULL, NULL, NULL, 'category_sort_options_img' ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'category_allow_albums', $this->id ? $this->allow_albums : 1, TRUE, array( 'options' => array( 0 => 'cat_no_allow_albums', 1 => 'cat_allow_albums', 2 => 'cat_require_albums' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_approve_img', $this->approve_img, FALSE ) );
|
||||
|
||||
if( \IPS\Settings::i()->gallery_watermark_path )
|
||||
@@ -374,7 +378,7 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/* If watermarks are disabled, enable them at the category level so that if you later enable watermarks they work in your existing categories */
|
||||
if( !\IPS\Settings::i()->gallery_watermark_path )
|
||||
{
|
||||
$values['category_watermark']= 1;
|
||||
$values['category_watermark'] = 1;
|
||||
}
|
||||
|
||||
/* Claim attachments */
|
||||
@@ -565,7 +569,7 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
try
|
||||
{
|
||||
$image = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_category_id=? AND image_approved=1 AND ( image_album_id = 0 OR album_type NOT IN ( 2, 3 ) )', $this->id ), 'image_date DESC', 1 )->join(
|
||||
$image = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_category_id=? AND image_approved=1 AND ( image_album_id = 0 OR album_type NOT IN ( 2, 3 ) )', $this->id ), 'image_date DESC', 1, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->join(
|
||||
'gallery_albums',
|
||||
"image_album_id=album_id"
|
||||
)->first() );
|
||||
@@ -590,6 +594,29 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$album->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the comment/approved/hidden counts
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function resetCommentCounts()
|
||||
{
|
||||
parent::resetCommentCounts();
|
||||
|
||||
/* If we allow albums, add album comment/review counts too */
|
||||
if( $this->allow_albums )
|
||||
{
|
||||
try
|
||||
{
|
||||
$consolidated = \IPS\Db::i()->select( 'SUM(album_comments) as comments, SUM(album_comments_unapproved) as unapproved_comments', 'gallery_albums', array( 'album_category_id=?', $this->_id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
|
||||
|
||||
$this->_comments = $this->count_comments + $consolidated['comments'];
|
||||
$this->_unapprovedComments = $this->count_comments_hidden + $consolidated['unapproved_comments'];
|
||||
}
|
||||
catch( \UnderflowException $e ){}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last comment time
|
||||
@@ -610,44 +637,54 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
/**
|
||||
* Retrieve a cover photo
|
||||
*
|
||||
* @param string $size One of full, medium, small or thumb
|
||||
* @param string $size Masked or small
|
||||
* @return string|null
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function coverPhoto( $size='thumb' )
|
||||
public function coverPhoto( $size='small' )
|
||||
{
|
||||
if ( !$this->can( 'read' ) )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( $size == 'full' )
|
||||
/* Make sure it's a valid size */
|
||||
if( !in_array( $size, array( 'masked', 'small' ) ) )
|
||||
{
|
||||
$size = 'masked';
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
$property = $size . "_file_name";
|
||||
|
||||
if( !$this->cover_img_id )
|
||||
/* If we have an explicit cover photo set, make sure it's valid and load/cache it */
|
||||
if( $this->cover_img_id )
|
||||
{
|
||||
if( $lastImage = $this->lastImage() )
|
||||
if( $this->coverPhoto === NULL )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
try
|
||||
{
|
||||
$this->coverPhoto = \IPS\gallery\Image::load( $this->cover_img_id );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* Cover photo isn't valid, reset category automatically */
|
||||
$this->cover_img_id = 0;
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
if( $this->coverPhoto !== NULL )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $this->coverPhoto->$property )->url;
|
||||
}
|
||||
}
|
||||
|
||||
if( !in_array( $size, array( 'masked', 'medium', 'small', 'thumb' ) ) )
|
||||
if( $lastImage = $this->lastImage() )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
}
|
||||
|
||||
if( $this->coverPhoto === NULL )
|
||||
{
|
||||
$this->coverPhoto = \IPS\gallery\Image::load( $this->cover_img_id );
|
||||
}
|
||||
|
||||
return (string) \IPS\File::get( 'gallery_Images', $this->coverPhoto->$property )->url;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -778,10 +815,11 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\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 array $where Additional WHERE clause
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
*/
|
||||
public static function canOnAny( $permission, $member = NULL )
|
||||
public static function canOnAny( $permission, $member=NULL, $where = array() )
|
||||
{
|
||||
/* Load member */
|
||||
if ( $member === NULL )
|
||||
@@ -794,7 +832,7 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return parent::canOnAny( $permission, $member );
|
||||
return parent::canOnAny( $permission, $member, $where );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -835,7 +873,6 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
return 'x';
|
||||
}
|
||||
|
||||
|
||||
/* !Clubs */
|
||||
|
||||
/**
|
||||
@@ -884,5 +921,11 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( $values['club_node_name'] );
|
||||
}
|
||||
|
||||
if ( !$this->_id )
|
||||
{
|
||||
$this->save();
|
||||
\IPS\File::claimAttachments( 'gallery-new-cat', $this->id, NULL, 'description' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,20 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Image Comment Model
|
||||
*/
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Form Template
|
||||
*/
|
||||
public static $formTemplate = array( array( 'forms', 'gallery', 'front' ), 'commentTemplate' );
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Comment Template
|
||||
*/
|
||||
public static $commentTemplate = array( array( 'global', 'gallery', 'front' ), 'commentContainer' );
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
@@ -146,10 +156,9 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
|
||||
*/
|
||||
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
|
||||
{
|
||||
$image = $itemData['image_medium_file_name'] ?: $itemData['image_masked_file_name'];
|
||||
$url = \IPS\Http\Url::internal( \IPS\gallery\Image::$urlBase . $indexData['index_item_id'], 'front', \IPS\gallery\Image::$urlTemplate, \IPS\Http\Url\Friendly::seoTitle( $indexData['index_title'] ?: $itemData[ \IPS\gallery\Image::$databasePrefix . \IPS\gallery\Image::$databaseColumnMap['title'] ] ) );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultCommentSnippet( $indexData, $itemData, $image, $url, $reviewRating, $view == 'condensed' );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultCommentSnippet( $indexData, $itemData, $itemData['image_small_file_name'], $url, $reviewRating, $view == 'condensed' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,6 @@ class _Image extends \IPS\Content\Item implements
|
||||
\IPS\Content\Permissions,
|
||||
\IPS\Content\Tags,
|
||||
\IPS\Content\Followable,
|
||||
\IPS\Content\ReportCenter,
|
||||
\IPS\Content\ReadMarkers,
|
||||
\IPS\Content\Views,
|
||||
\IPS\Content\Hideable, \IPS\Content\Featurable, \IPS\Content\Pinnable, \IPS\Content\Lockable,
|
||||
@@ -35,7 +34,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
\IPS\Content\Embeddable,
|
||||
\IPS\Content\MetaData
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
@@ -142,9 +141,9 @@ class _Image extends \IPS\Content\Item implements
|
||||
public static function basicDataColumns()
|
||||
{
|
||||
$return = parent::basicDataColumns();
|
||||
$return[] = 'image_medium_file_name';
|
||||
$return[] = 'image_masked_file_name';
|
||||
$return[] = 'image_original_file_name';
|
||||
$return[] = 'image_small_file_name';
|
||||
$return[] = 'image_album_id';
|
||||
$return[] = 'image_copyright';
|
||||
return $return;
|
||||
@@ -239,7 +238,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
{
|
||||
if ( ! empty( $v['NOTE'] ) )
|
||||
{
|
||||
$v['NOTE'] = htmlspecialchars( $v['NOTE'], \IPS\HTMLENTITIES, 'UTF-8', TRUE );
|
||||
$v['NOTE'] = htmlspecialchars( $v['NOTE'], ENT_DISALLOWED, 'UTF-8', TRUE );
|
||||
}
|
||||
} );
|
||||
}
|
||||
@@ -315,17 +314,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
return $this->_data['caption_seo'] ?: \IPS\Http\Url\Friendly::seoTitle( $this->caption );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Medium File Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_medium_file_name()
|
||||
{
|
||||
return $this->_data['medium_file_name'] ?: $this->_data['masked_file_name'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get Small File Name
|
||||
*
|
||||
@@ -333,17 +322,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function get_small_file_name()
|
||||
{
|
||||
return $this->_data['small_file_name'] ?: $this->_data['medium_file_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Thumbnail File Name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_thumb_file_name()
|
||||
{
|
||||
return $this->_data['thumb_file_name'] ?: $this->_data['small_file_name'];
|
||||
return $this->_data['small_file_name'] ?: $this->_data['masked_file_name'];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -369,9 +348,10 @@ class _Image extends \IPS\Content\Item implements
|
||||
/**
|
||||
* Return selection of image data as a JSON-encoded string (used for patchwork)
|
||||
*
|
||||
* @param array $parameters Optional key => value array of additional query string parameters to use with the image URL
|
||||
* @return string
|
||||
*/
|
||||
public function json()
|
||||
public function json( $parameters=array() )
|
||||
{
|
||||
$imageSizes = json_decode( $this->_data['data'], true );
|
||||
$state = array();
|
||||
@@ -453,6 +433,11 @@ class _Image extends \IPS\Content\Item implements
|
||||
{
|
||||
$modActions[] = 'approve';
|
||||
}
|
||||
|
||||
if( $this->canHide() )
|
||||
{
|
||||
$modActions[] = 'hide';
|
||||
}
|
||||
|
||||
$state['pending'] = TRUE;
|
||||
$modStates[] = 'unapproved';
|
||||
@@ -485,26 +470,26 @@ class _Image extends \IPS\Content\Item implements
|
||||
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] ),
|
||||
'medium' => array( $this->_data['medium_file_name'] ? (string) \IPS\File::get( 'gallery_Images', $this->_data['medium_file_name'] )->url : null, $imageSizes['medium'][0], $imageSizes['medium'][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] )
|
||||
),
|
||||
/* 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' => str_replace( "'", "'", htmlspecialchars( $this->_data['caption'], \IPS\HTMLENTITIES, 'UTF-8', FALSE ) ),
|
||||
'caption' => $this->_data['caption'],
|
||||
'date' => \IPS\DateTime::ts( $this->mapped('date') )->relative(),
|
||||
'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, 'escape' => TRUE ) ) : mb_substr( json_encode( str_replace( "'", "'", htmlspecialchars( str_replace( '"', '"', $this->directContainer()->_title ), \IPS\HTMLENTITIES, 'UTF-8', FALSE ) ), JSON_UNESCAPED_UNICODE ), 1, -1 ),
|
||||
'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'],
|
||||
'url' => (string) $this->url(),
|
||||
'url' => (string) $this->url()->setQueryString( $parameters ),
|
||||
'author' => array(
|
||||
'photo' => str_replace( "'", "'", htmlspecialchars( (string) $this->author()->photo, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) ),
|
||||
'name' => str_replace( "'", "'", htmlspecialchars( $this->author()->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) )
|
||||
'photo' => (string) $this->author()->photo,
|
||||
'name' => $this->author()->name
|
||||
),
|
||||
'modActions' => $modActions,
|
||||
'modStates' => $modStates,
|
||||
'allowComments' => (boolean) $this->directContainer()->allow_comments,
|
||||
'comments' => ( $this->directContainer()->allow_comments ) ? $this->_data['comments'] : 0,
|
||||
'views' => $this->_data['views']
|
||||
) );
|
||||
), JSON_UNESCAPED_SLASHES | JSON_HEX_TAG | JSON_HEX_AMP | JSON_HEX_APOS );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -541,7 +526,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
{
|
||||
\IPS\gallery\Application::outputCss();
|
||||
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsRows' );
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery', 'front' ), 'tableRowsRows' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -578,18 +563,19 @@ class _Image extends \IPS\Content\Item implements
|
||||
/**
|
||||
* Get comment/review output
|
||||
*
|
||||
* @param string $tab Active tab
|
||||
* @param string $tab Active tab
|
||||
* @param bool $condensed Use condensed style
|
||||
* @return string
|
||||
*/
|
||||
public function commentReviews( $tab )
|
||||
public function commentReviews( $tab, $condensed=FALSE )
|
||||
{
|
||||
if ( $tab === 'reviews' AND $this->container()->allow_reviews AND $this->directContainer()->allow_reviews )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('view')->reviews( $this );
|
||||
return \IPS\Theme::i()->getTemplate('view')->reviews( $this, $condensed );
|
||||
}
|
||||
elseif( $tab === 'comments' AND $this->container()->allow_comments AND $this->directContainer()->allow_comments )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate('view')->comments( $this );
|
||||
return \IPS\Theme::i()->getTemplate('view')->comments( $this, $condensed );
|
||||
}
|
||||
|
||||
return '';
|
||||
@@ -771,7 +757,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
$queueData['album_id'] = $album->$albumIdColumn;
|
||||
}
|
||||
|
||||
\IPS\Task::queue( 'gallery', 'Follow', $queueData );
|
||||
\IPS\Task::queue( 'gallery', 'Follow', $queueData, 2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -874,14 +860,16 @@ class _Image extends \IPS\Content\Item implements
|
||||
protected $imagesSameDate = NULL;
|
||||
|
||||
/**
|
||||
* Get the next 5 images in the container
|
||||
* Get the next or previous 5 images in the container
|
||||
*
|
||||
* @param int $count (Maximum) number of images to return
|
||||
* @param int $count (Maximum) number of images to return
|
||||
* @param string $direction DESC or ASC
|
||||
* @return array
|
||||
*/
|
||||
public function nextImages( $count )
|
||||
public function fetchNextOrPreviousImages( $count, $direction = 'DESC' )
|
||||
{
|
||||
$where = array();
|
||||
$dir = $direction == 'DESC' ? '<' : '>';
|
||||
|
||||
if( $this->album_id )
|
||||
{
|
||||
@@ -905,8 +893,8 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
if( !$this->imagesSameDate )
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . ' >= ?', $this->$column );
|
||||
return iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ASC', $count ) );
|
||||
$where['date'] = array( static::$databasePrefix . $column . " {$dir}= ?", $this->$column );
|
||||
return iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ' . $direction, $count ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -916,7 +904,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
$results = array();
|
||||
$seen = FALSE;
|
||||
|
||||
foreach( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ASC', NULL ) as $image )
|
||||
foreach( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ' . $direction, NULL ) as $image )
|
||||
{
|
||||
if( !$seen )
|
||||
{
|
||||
@@ -938,81 +926,8 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
if( count( $results ) < $count )
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . ' > ?', $this->$column );
|
||||
$results = array_merge( $results, iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ASC', $count - count( $results ) ) ) );
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the previous 5 images in the container
|
||||
*
|
||||
* @param int $count (Maximum) number of images to return
|
||||
* @return array
|
||||
*/
|
||||
public function previousImages( $count )
|
||||
{
|
||||
$where = array();
|
||||
|
||||
if( $this->album_id )
|
||||
{
|
||||
$where[] = array( 'image_album_id=?', $this->album_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where[] = array( 'image_category_id=?', $this->category_id );
|
||||
$where[] = array( 'image_album_id=?', 0 );
|
||||
}
|
||||
|
||||
$where['id'] = array( 'image_id<>?', $this->id );
|
||||
|
||||
$column = $this->getDateColumn();
|
||||
|
||||
if( $this->imagesSameDate === NULL )
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . '= ?', $this->$column );
|
||||
$this->imagesSameDate = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', $where )->first();
|
||||
}
|
||||
|
||||
if( !$this->imagesSameDate )
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . ' <= ?', $this->$column );
|
||||
return iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' DESC', $count ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . '= ?', $this->$column );
|
||||
unset( $where['id'] );
|
||||
|
||||
$results = array();
|
||||
$seen = FALSE;
|
||||
|
||||
foreach( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' DESC', NULL ) as $image )
|
||||
{
|
||||
if( !$seen )
|
||||
{
|
||||
if( $image->id == $this->id )
|
||||
{
|
||||
$seen = TRUE;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$results[] = $image;
|
||||
|
||||
if( count( $results ) == $count )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( count( $results ) < $count )
|
||||
{
|
||||
$where['date'] = array( static::$databasePrefix . $column . ' < ?', $this->$column );
|
||||
$results = array_merge( $results, iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' DESC', $count - count( $results ) ) ) );
|
||||
$where['date'] = array( static::$databasePrefix . $column . " {$dir} ?", $this->$column );
|
||||
$results = array_merge( $results, iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( $where, static::$databasePrefix . $column . ' ' . $direction, $count - count( $results ) ) ) );
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -1022,11 +937,46 @@ class _Image extends \IPS\Content\Item implements
|
||||
/**
|
||||
* Get Next Item
|
||||
*
|
||||
* @param string|NULL $context Context to consider next/previous from
|
||||
* @return \IPS\Content\Item|NULL
|
||||
*/
|
||||
public function nextItem()
|
||||
public function nextItem( $context=NULL )
|
||||
{
|
||||
$result = $this->nextImages( 1 );
|
||||
if( $context !== NULL )
|
||||
{
|
||||
$results = NULL;
|
||||
switch( $context )
|
||||
{
|
||||
case 'featured':
|
||||
$results = iterator_to_array( static::featured( 20, NULL ) );
|
||||
break;
|
||||
|
||||
case 'new':
|
||||
$results = iterator_to_array( static::getItemsWithPermission( ( \IPS\Settings::i()->club_nodes_in_apps ? array() : array( array( 'category_club_id IS NULL' ) ) ), NULL, 30, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, !\IPS\Settings::i()->club_nodes_in_apps ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if( $results !== NULL )
|
||||
{
|
||||
$returnNext = FALSE;
|
||||
foreach( $results as $imageResult )
|
||||
{
|
||||
if( $returnNext === TRUE )
|
||||
{
|
||||
return $imageResult;
|
||||
}
|
||||
|
||||
if( $imageResult->id == $this->id )
|
||||
{
|
||||
$returnNext = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$result = $this->fetchNextOrPreviousImages( 1, 'DESC' );
|
||||
|
||||
if( is_array( $result ) )
|
||||
{
|
||||
@@ -1037,11 +987,43 @@ class _Image extends \IPS\Content\Item implements
|
||||
/**
|
||||
* Get Previous Item
|
||||
*
|
||||
* @param string|NULL $context Context to consider next/previous from
|
||||
* @return \IPS\Content\Item|NULL
|
||||
*/
|
||||
public function prevItem()
|
||||
public function prevItem( $context=NULL )
|
||||
{
|
||||
$result = $this->previousImages( 1 );
|
||||
if( $context !== NULL )
|
||||
{
|
||||
$results = NULL;
|
||||
switch( $context )
|
||||
{
|
||||
case 'featured':
|
||||
$results = iterator_to_array( static::featured( 20, NULL ) );
|
||||
break;
|
||||
|
||||
case 'new':
|
||||
$results = iterator_to_array( static::getItemsWithPermission( ( \IPS\Settings::i()->club_nodes_in_apps ? array() : array( array( 'category_club_id IS NULL' ) ) ), NULL, 30, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, !\IPS\Settings::i()->club_nodes_in_apps ) );
|
||||
break;
|
||||
}
|
||||
|
||||
if( $results !== NULL )
|
||||
{
|
||||
$previousResult = NULL;
|
||||
foreach( $results as $imageResult )
|
||||
{
|
||||
if( $imageResult->id == $this->id )
|
||||
{
|
||||
return $previousResult;
|
||||
}
|
||||
|
||||
$previousResult = $imageResult;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
$result = $this->fetchNextOrPreviousImages( 1, 'ASC' );
|
||||
|
||||
if( is_array( $result ) )
|
||||
{
|
||||
@@ -1060,7 +1042,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
{
|
||||
if ( $container and $container->approve_img and !$member->group['g_avoid_q'] )
|
||||
{
|
||||
return TRUE;
|
||||
return !static::modPermission( 'approve', $member, $container );
|
||||
}
|
||||
|
||||
return parent::moderateNewItems( $member, $container );
|
||||
@@ -1124,7 +1106,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
'attachIds' => ( $item === NULL ? NULL : array( $item->id ) ),
|
||||
'editorId' => "filedata_{$currentlyEditing}_image_description"
|
||||
) );
|
||||
$return['credit'] = new \IPS\Helpers\Form\TextArea( 'image_credit_info', $item ? $item->credit_info : NULL, FALSE );
|
||||
$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 ) );
|
||||
|
||||
/* If we are editing, return the appropriate fields */
|
||||
@@ -1177,7 +1159,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
* @return void
|
||||
*/
|
||||
public function processForm( $values )
|
||||
{
|
||||
{
|
||||
parent::processForm( $values );
|
||||
|
||||
/* Set a few details */
|
||||
@@ -1242,7 +1224,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
{
|
||||
$val = utf8_encode( $val );
|
||||
} );
|
||||
//$this->metadata = array_map( 'utf8_encode', $this->metadata );
|
||||
|
||||
$this->metadata = json_encode( $metadata );
|
||||
}
|
||||
|
||||
@@ -1266,12 +1248,11 @@ class _Image extends \IPS\Content\Item implements
|
||||
/* Or was the thumbnail removed? */
|
||||
elseif( !$this->_new AND $this->masked_file_name )
|
||||
{
|
||||
foreach( array( 'masked_file_name', 'medium_file_name', 'small_file_name', 'thumb_file_name' ) as $key )
|
||||
foreach( array( 'masked_file_name', 'small_file_name' ) as $key )
|
||||
{
|
||||
if( $this->$key )
|
||||
{
|
||||
$file = \IPS\File::get( 'gallery_Images', $this->$key );
|
||||
$file->delete();
|
||||
\IPS\File::get( 'gallery_Images', $this->$key )->delete();
|
||||
|
||||
$this->$key = NULL;
|
||||
}
|
||||
@@ -1390,27 +1371,13 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function deleteThumbnails()
|
||||
{
|
||||
$possibleImagesToDelete = array( 'masked_file_name', 'medium_file_name', 'small_file_name', 'thumb_file_name' );
|
||||
$imagesToDelete = array();
|
||||
|
||||
/* Usually the masked_file_name and the original_file_name are different, however with many upgrades they are not, and if we delete
|
||||
the original file (which would be mapped in both original_file_name AND masked_file_name) then we cannot rebuild thumbnails after
|
||||
and the image will be broken */
|
||||
foreach( $possibleImagesToDelete as $image )
|
||||
foreach( array( 'masked_file_name', 'small_file_name' ) as $size )
|
||||
{
|
||||
if( $this->$image != $this->original_file_name )
|
||||
{
|
||||
$imagesToDelete[] = $image;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( $imagesToDelete as $k )
|
||||
{
|
||||
if ( $this->$k )
|
||||
if( isset( $this->_data[ $size ] ) AND $this->$size AND $this->$size != $this->original_file_name )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'gallery_Images', $this->$k )->delete();
|
||||
\IPS\File::get( 'gallery_Images', $this->$size )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
}
|
||||
@@ -1425,6 +1392,8 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function buildThumbnails( $file=NULL )
|
||||
{
|
||||
$this->deleteThumbnails();
|
||||
|
||||
if( $file === NULL )
|
||||
{
|
||||
$file = \IPS\File::get( 'gallery_Images', $this->original_file_name );
|
||||
@@ -1439,21 +1408,11 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
$thumbnailDimensions['large'] = $largeImage->getImageDimensions();
|
||||
|
||||
$mediumImage = \IPS\File::create( 'gallery_Images', 'medium.' . $file->originalFilename, $this->_createImage( $file, explode( 'x', \IPS\Settings::i()->gallery_medium_dims ), FALSE, in_array( 'medium', $watermarks ) ) );
|
||||
$this->medium_file_name = (string) $mediumImage;
|
||||
|
||||
$thumbnailDimensions['medium'] = $mediumImage->getImageDimensions();
|
||||
|
||||
$smallImage = \IPS\File::create( 'gallery_Images', 'small.' . $file->originalFilename, $this->_createImage( $file, explode( 'x', \IPS\Settings::i()->gallery_small_dims ), FALSE, in_array( 'small', $watermarks ) ) );
|
||||
$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 ) ) );
|
||||
$this->small_file_name = (string) $smallImage;
|
||||
|
||||
$thumbnailDimensions['small'] = $smallImage->getImageDimensions();
|
||||
|
||||
$thumbImage = \IPS\File::create( 'gallery_Images', 'thumb.' . $file->originalFilename, $this->_createImage( $file, explode( 'x', \IPS\Settings::i()->gallery_thumb_dims ), \IPS\Settings::i()->gallery_use_square_thumbnails, in_array( 'thumbnail', $watermarks ) ) );
|
||||
$this->thumb_file_name = (string) $thumbImage;
|
||||
|
||||
$thumbnailDimensions['thumb'] = $thumbImage->getImageDimensions();
|
||||
|
||||
$this->_dimensions = $thumbnailDimensions;
|
||||
}
|
||||
|
||||
@@ -1472,7 +1431,8 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
if( $crop )
|
||||
{
|
||||
$image->crop( $dimensions[0], $dimensions[1] );
|
||||
//$image->crop( $dimensions[0], $dimensions[1] );
|
||||
$image->resizeToMax( $dimensions[0], $dimensions[0] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1549,8 +1509,9 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function sizes()
|
||||
{
|
||||
$return = array();
|
||||
$data = json_decode( $this->data, TRUE );
|
||||
$return = array();
|
||||
$data = json_decode( $this->data, TRUE );
|
||||
|
||||
if( !empty( $data ) )
|
||||
{
|
||||
foreach ( $data as $k => $v )
|
||||
@@ -1561,15 +1522,29 @@ class _Image extends \IPS\Content\Item implements
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( isset( $return['large'] ) and isset( $return['thumb'] ) and $return['large'][0] < $return['thumb'][0] and $return['large'][1] < $return['thumb'][1] )
|
||||
{
|
||||
unset( $return['thumb'] );
|
||||
}
|
||||
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log for deletion later
|
||||
*
|
||||
* \IPS\Member|NULL $member The member or NULL for currently logged in
|
||||
* @return void
|
||||
*/
|
||||
public function logDelete( $member = NULL )
|
||||
{
|
||||
parent::logDelete( $member );
|
||||
|
||||
/* Now we need to update "last image" info */
|
||||
if( $this->album_id )
|
||||
{
|
||||
$album = \IPS\gallery\Album::load( $this->album_id );
|
||||
$album->setLastImage();
|
||||
$album->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Record
|
||||
*
|
||||
@@ -1624,12 +1599,9 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
|
||||
{
|
||||
$image = $itemData['image_medium_file_name'] ?: $itemData['image_masked_file_name'];
|
||||
$url = \IPS\Http\Url::internal( static::$urlBase . $indexData['index_item_id'], 'front', static::$urlTemplate, \IPS\Http\Url\Friendly::seoTitle( $indexData['index_title'] ?: $itemData[ static::$databasePrefix . static::$databaseColumnMap['title'] ] ) );
|
||||
|
||||
$albumData = isset( $itemData['extra'] ) ? $itemData['extra'] : NULL;
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultImageSnippet( $indexData, $itemData, $albumData, $image, $url, $view == 'condensed' );
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultImageSnippet( $indexData, $itemData, ( isset( $itemData['extra'] ) ? $itemData['extra'] : NULL ), $itemData['image_small_file_name'], $url, $view == 'condensed' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1673,13 +1645,14 @@ class _Image extends \IPS\Content\Item implements
|
||||
/**
|
||||
* 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 caption Caption
|
||||
* @apiresponse string description Description
|
||||
* @apiresponse string filename Original file name (e.g. 'image.png')
|
||||
* @apiresponse int filesize Original file size, in bytes
|
||||
* @apiresponse object images URLs to where the images are stored. Keys are 'original', 'large', 'medium', 'small' and 'thumb' and values are URLs to the corresponding images
|
||||
* @apiresponse object images URLs to where the images are stored. Keys are 'original', 'large', and 'small', and values are URLs to the corresponding images
|
||||
* @apiresponse \IPS\gallery\Album album The album, if in one
|
||||
* @apiresponse \IPS\gallery\Category category The category (if in an album, this will be the category that the album is in)
|
||||
* @apiresponse \IPS\Member author The author
|
||||
@@ -1700,7 +1673,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
* @apiresponse string url URL
|
||||
* @apiresponse float rating Average Rating
|
||||
*/
|
||||
public function apiOutput()
|
||||
public function apiOutput( \IPS\Member $authorizedMember = NULL )
|
||||
{
|
||||
return array(
|
||||
'id' => $this->id,
|
||||
@@ -1711,9 +1684,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
'images' => array(
|
||||
'original' => (string) \IPS\File::get( 'gallery_Images', $this->original_file_name )->url,
|
||||
'large' => (string) \IPS\File::get( 'gallery_Images', $this->masked_file_name )->url,
|
||||
'medium' => (string) \IPS\File::get( 'gallery_Images', $this->medium_file_name )->url,
|
||||
'small' => (string) \IPS\File::get( 'gallery_Images', $this->small_file_name )->url,
|
||||
'thumb' => (string) \IPS\File::get( 'gallery_Images', $this->thumb_file_name )->url,
|
||||
),
|
||||
'album' => $this->album_id ? $this->directContainer()->apiOutput() : null,
|
||||
'category' => $this->container()->apiOutput(),
|
||||
@@ -1850,6 +1821,38 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in map
|
||||
*/
|
||||
public function can( $permission, $member=NULL )
|
||||
{
|
||||
if ( !parent::can( $permission, $member ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if ( !$this->directContainer()->can( $permission, $member ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
/* If the direct container is lost, assume we can do nothing. @see \IPS\Content\Item::can() */
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Still here? It must be okay */
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can view?
|
||||
@@ -1871,13 +1874,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 == 2 AND $this->directContainer()->owner() != $member )
|
||||
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_PRIVATE AND $this->directContainer()->owner() != $member )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Is this a restricted album we can't access? */
|
||||
if( $this->directContainer()->type == 3 AND $this->directContainer()->owner() != $member )
|
||||
if( $this->directContainer()->type == \IPS\gallery\Album::AUTH_TYPE_RESTRICTED AND $this->directContainer()->owner() != $member )
|
||||
{
|
||||
/* This will throw an exception of the row does not exist */
|
||||
try
|
||||
@@ -1887,7 +1890,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
$member = \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=? AND member_id=?', $this->directContainer()->allowed_access, $member->member_id ) )->first();
|
||||
$member = \IPS\Member::constructFromData( \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=? AND member_id=?', $this->directContainer()->allowed_access, $member->member_id ) )->first() );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
@@ -1913,6 +1916,36 @@ class _Image extends \IPS\Content\Item implements
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can set as album coverphoto?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canSetAsAlbumCover( $member=NULL )
|
||||
{
|
||||
if( ( $this->album_id AND $this->canEdit() ) OR static::modPermission( 'edit', $member, $this->container() ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can set as category coverphoto?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for or NULL for the currently logged in member
|
||||
* @return bool
|
||||
*/
|
||||
public function canSetAsCategoryCover( $member=NULL )
|
||||
{
|
||||
if( static::modPermission( 'edit', $member, $this->container() ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached groups the member can access
|
||||
*/
|
||||
@@ -1955,7 +1988,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
/* If you can edit images in a category you can see images in private albums in that category. We can only really check globally at this stage, however. */
|
||||
if( \IPS\gallery\Image::modPermission( 'edit', $member ) )
|
||||
{
|
||||
$result = array( "( gallery_albums.album_id IS NULL OR gallery_albums.album_type IN(1,2) OR ( gallery_albums.album_type=3 AND ( gallery_albums.album_owner_id=? OR gallery_albums.album_allowed_access IN (" . implode( ',', $restricted ) . ") ) ) )", $member->member_id );
|
||||
$result = array( "( gallery_albums.album_id IS NULL OR gallery_albums.album_type IN(1,2,3) )" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2011,7 +2044,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
/* We have to fix order by for images */
|
||||
$orders = explode( ',', $order );
|
||||
$newOrder = array();
|
||||
$newOrders = array();
|
||||
|
||||
foreach( $orders as $_order )
|
||||
{
|
||||
@@ -2030,7 +2063,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
$order = implode( ', ', $newOrders );
|
||||
|
||||
$where[] = static::getItemsWithPermissionWhere( $where, $member, $joins );
|
||||
$where[] = static::getItemsWithPermissionWhere( $where, $member, $joins );
|
||||
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins, $skipPermission, $joinTags, $joinAuthor, $joinLastCommenter, $showMovedLinks );
|
||||
}
|
||||
|
||||
@@ -2065,10 +2098,12 @@ class _Image extends \IPS\Content\Item implements
|
||||
return parent::contentCount( $container, $includeItems, $includeComments, $includeReviews, $depth );
|
||||
}
|
||||
|
||||
$count = static::getItemsWithPermission( array( array( 'gallery_images.image_category_id=?', $container->_id ) ), NULL, 1, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
|
||||
|
||||
$_key = md5( get_class( $container ) . $container->_id );
|
||||
static::$itemCounts[ $_key ][ $container->_id ] = $count;
|
||||
|
||||
if( !isset( static::$itemCounts[ $_key ][ $container->_id ] ) )
|
||||
{
|
||||
static::$itemCounts[ $_key ][ $container->_id ] = static::getItemsWithPermission( array( array( 'gallery_images.image_category_id=?', $container->_id ) ), NULL, 1, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
|
||||
}
|
||||
|
||||
return parent::contentCount( $container, $includeItems, $includeComments, $includeReviews, $depth );
|
||||
}
|
||||
@@ -2082,7 +2117,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
*/
|
||||
public function embedImage()
|
||||
{
|
||||
return \IPS\File::get( 'gallery_Images', $this->thumb_file_name );
|
||||
return \IPS\File::get( 'gallery_Images', $this->small_file_name );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2108,7 +2143,7 @@ class _Image extends \IPS\Content\Item implements
|
||||
public function searchIndexPermissions()
|
||||
{
|
||||
/* If this is a private album, only the author can view in search */
|
||||
if ( $this->directContainer() instanceof \IPS\gallery\Album and $this->directContainer()->type != 1 )
|
||||
if ( $this->directContainer() instanceof \IPS\gallery\Album and $this->directContainer()->type != \IPS\gallery\Album::AUTH_TYPE_PUBLIC )
|
||||
{
|
||||
if ( $this->member_id )
|
||||
{
|
||||
@@ -2219,4 +2254,26 @@ class _Image extends \IPS\Content\Item implements
|
||||
|
||||
return $sortOptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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', ... );
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function contentImages( $limit = NULL )
|
||||
{
|
||||
$result = parent::contentImages( $limit );
|
||||
|
||||
if( $result === NULL )
|
||||
{
|
||||
$result = array();
|
||||
}
|
||||
|
||||
$result[] = array( 'gallery_Images' => $this->masked_file_name );
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -21,10 +21,20 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
/**
|
||||
* Image Review Model
|
||||
*/
|
||||
class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
use \IPS\Content\Reactable;
|
||||
|
||||
use \IPS\Content\Reactable, \IPS\Content\Reportable;
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Form Template
|
||||
*/
|
||||
public static $formTemplate = array( array( 'forms', 'gallery', 'front' ), 'reviewTemplate' );
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Comment Template
|
||||
*/
|
||||
public static $commentTemplate = array( array( 'global', 'gallery', 'front' ), 'reviewContainer' );
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
@@ -63,6 +73,7 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
|
||||
'votes_helpful' => 'votes_helpful',
|
||||
'votes_data' => 'votes_data',
|
||||
'approved' => 'approved',
|
||||
'author_response' => 'author_response',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -51,83 +51,195 @@ class _Table extends \IPS\Helpers\Table\Content
|
||||
}
|
||||
|
||||
/**
|
||||
* Multimod
|
||||
* Build the form to move images
|
||||
*
|
||||
* @return void
|
||||
* @param \IPS\Node\Model $currentContainer Current image container
|
||||
* @param string $class Class to use
|
||||
* @param array $extraAlbumOptions Additional options to use for the album helper (e.g. to force owner)
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
protected function multimod()
|
||||
static public function buildMoveForm( $currentContainer, $class, $extraAlbumOptions=array() )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
$form = new \IPS\Helpers\Form( 'form', 'move' );
|
||||
$form->class = 'ipsForm_vertical';
|
||||
if ( \IPS\gallery\Category::canOnAny('add') and \IPS\gallery\Album::canOnAny('add') )
|
||||
{
|
||||
$options = array( 'category' => 'image_category', 'album' => 'image_album' );
|
||||
$toggles = array( 'category' => array( 'move_to_category' ), 'album' => array( 'move_to_album' ) );
|
||||
$extraFields = array();
|
||||
|
||||
if ( \IPS\gallery\Image::modPermission( 'edit', NULL, NULL ) and \IPS\Db::i()->select( 'COUNT(*)', 'gallery_categories', array( array( 'category_allow_albums>0' ), array( '(' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_' . \IPS\gallery\Category::$permissionMap['add'], \IPS\Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_' . \IPS\gallery\Category::$permissionMap['add'] . '=? )', '*' ) ) )->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . \IPS\gallery\Category::$databaseTable . "." . \IPS\gallery\Category::$databasePrefix . \IPS\gallery\Category::$databaseColumnId, \IPS\gallery\Category::$permApp, \IPS\gallery\Category::$permType ) )->first() )
|
||||
{
|
||||
$options['new_album'] = 'move_to_new_album';
|
||||
|
||||
/* Basic check that we selected something */
|
||||
if( !isset( \IPS\Request::i()->moderate ) OR empty( \IPS\Request::i()->moderate ) )
|
||||
{
|
||||
\IPS\Output::i()->error( 'nothing_mm_selected', '1G329/1', 403, '' );
|
||||
}
|
||||
|
||||
$class = $this->class;
|
||||
$params = array();
|
||||
|
||||
if ( \IPS\Request::i()->modaction == 'move' )
|
||||
{
|
||||
$form = new \IPS\Helpers\Form( 'form', 'move' );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_to_category', NULL, FALSE, array( 'clubs' => true, 'class' => 'IPS\\gallery\\Category', 'url' => \IPS\Request::i()->url()->setQueryString( 'modaction', 'move' ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_to_album', NULL, FALSE, array(
|
||||
'class' => 'IPS\\gallery\\Album',
|
||||
'forceOwner' => FALSE,
|
||||
'url' => \IPS\Request::i()->url()->setQueryString( 'modaction', 'move' ),
|
||||
'permissionCheck' => function( $node )
|
||||
foreach ( \IPS\gallery\Album::formFields( NULL, TRUE, \IPS\Request::i()->move_to === 'new_album' ) as $field )
|
||||
{
|
||||
/* Have we hit an images per album limit? */
|
||||
if( $node->owner()->group['g_img_album_limit'] AND ( $node->count_imgs + $node->count_imgs_hidden ) >= $node->owner()->group['g_img_album_limit'] )
|
||||
if ( !$field->htmlId )
|
||||
{
|
||||
return false;
|
||||
$field->htmlId = $field->name . '_id';
|
||||
}
|
||||
$toggles['new_album'][] = $field->htmlId;
|
||||
|
||||
$extraFields[] = $field;
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'move_to', NULL, TRUE, array( 'options' => $options, 'toggles' => $toggles ) ) );
|
||||
foreach ( $extraFields as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_to_category', NULL, NULL, array(
|
||||
'clubs' => true,
|
||||
'class' => 'IPS\\gallery\\Category',
|
||||
'permissionCheck' => function( $node ) use ( $currentContainer, $class )
|
||||
{
|
||||
/* If the image is in the same category already, we can't move it there */
|
||||
if( $currentContainer instanceof \IPS\gallery\Category and $currentContainer->id == $node->id )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the category requires albums, we cannot move images directly to it */
|
||||
if( $node->allow_albums == 2 )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If the category is a club, check mod permissions appropriately */
|
||||
try
|
||||
{
|
||||
/* If the item is in a club, only allow moving to other clubs that you moderate */
|
||||
if ( $currentContainer and \IPS\IPS::classUsesTrait( $currentContainer, 'IPS\Content\ClubContainer' ) and $currentContainer->club() )
|
||||
{
|
||||
return $class::modPermission( 'move', \IPS\Member::loggedIn(), $node ) and $node->can( 'add' ) ;
|
||||
}
|
||||
}
|
||||
catch( \OutOfBoundsException $e ) { }
|
||||
|
||||
/* Can we add in this category? */
|
||||
if ( $node->can( 'add' ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
|
||||
return false;
|
||||
}
|
||||
), function( $val ) {
|
||||
if ( !$val and isset( \IPS\Request::i()->move_to ) and \IPS\Request::i()->move_to == 'category' )
|
||||
{
|
||||
if( ( !isset( $values['move_to_category'] ) OR !( $values['move_to_category'] instanceof \IPS\Node\Model ) ) AND
|
||||
( !isset( $values['move_to_album'] ) OR !( $values['move_to_album'] instanceof \IPS\Node\Model ) ) )
|
||||
{
|
||||
$form->error = \IPS\Member::loggedIn()->language()->addToStack('gallery_cat_or_album');
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'move_to_category' ) );
|
||||
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
return;
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'move_to_album', NULL, NULL, array_merge( array(
|
||||
'class' => 'IPS\\gallery\\Album',
|
||||
'permissionCheck' => function( $node ) use ( $currentContainer )
|
||||
{
|
||||
/* If the image is in the same album already, we can't move it there */
|
||||
if( $currentContainer instanceof \IPS\gallery\Album and $currentContainer->id == $node->id )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$params[] = ( isset( $values['move_to_category'] ) AND $values['move_to_category'] ) ? $values['move_to_category'] : $values['move_to_album'];
|
||||
$params[] = FALSE;
|
||||
/* Do we have permission to add? */
|
||||
if( !$node->can( 'add' ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Have we hit an images per album limit? */
|
||||
if( $node->owner()->group['g_img_album_limit'] AND ( $node->count_imgs + $node->count_imgs_hidden ) >= $node->owner()->group['g_img_album_limit'] )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
), $extraAlbumOptions ), function( $val ) {
|
||||
if ( !$val and isset( \IPS\Request::i()->move_to ) and \IPS\Request::i()->move_to == 'album' )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'move_to_album' ) );
|
||||
|
||||
return $form;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the form to move items
|
||||
*
|
||||
* @return string|array
|
||||
*/
|
||||
protected function getMoveForm()
|
||||
{
|
||||
$class = $this->class;
|
||||
$params = array();
|
||||
|
||||
$currentContainer = $this->container;
|
||||
|
||||
$form = static::buildMoveForm( $currentContainer, $class );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
if ( isset( $values['move_to'] ) )
|
||||
{
|
||||
if ( $values['move_to'] == 'new_album' )
|
||||
{
|
||||
$albumValues = $values;
|
||||
unset( $albumValues['move_to'] );
|
||||
unset( $albumValues['move_to_category'] );
|
||||
unset( $albumValues['move_to_album'] );
|
||||
|
||||
$target = new \IPS\gallery\Album;
|
||||
$target->saveForm( $target->formatFormValues( $albumValues ) );
|
||||
$target->save();
|
||||
}
|
||||
else
|
||||
{
|
||||
$target = ( \IPS\Request::i()->move_to == 'category' ) ? $values['move_to_category'] : $values['move_to_album'];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Output::i()->output );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
return;
|
||||
$target = isset( $values['move_to_category'] ) ? $values['move_to_category'] : $values['move_to_album'];
|
||||
}
|
||||
|
||||
$params[] = $target;
|
||||
$params[] = FALSE;
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
|
||||
foreach ( array_keys( \IPS\Request::i()->moderate ) as $id )
|
||||
if ( \IPS\Request::i()->isAjax() )
|
||||
{
|
||||
try
|
||||
{
|
||||
$object = $class::loadAndCheckPerms( $id );
|
||||
$object->modAction( \IPS\Request::i()->modaction, \IPS\Member::loggedIn(), $params );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
\IPS\Output::i()->sendOutput( \IPS\Output::i()->output );
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $this->baseUrl );
|
||||
else
|
||||
{
|
||||
\IPS\Output::i()->sendOutput( \IPS\Theme::i()->getTemplate( 'global', 'core' )->globalTemplate( \IPS\Output::i()->title, \IPS\Output::i()->output, array( 'app' => \IPS\Dispatcher::i()->application->directory, 'module' => \IPS\Dispatcher::i()->module->key, 'controller' => \IPS\Dispatcher::i()->controller ) ), 200, 'text/html', \IPS\Output::i()->httpHeaders );
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sort direction to use for links
|
||||
*
|
||||
* @note Abstracted so other table helper instances can adjust as needed
|
||||
* @param string $column Sort by string
|
||||
* @return string [asc|desc]
|
||||
*/
|
||||
public function getSortDirection( $column )
|
||||
{
|
||||
if( $column == 'image_caption' )
|
||||
{
|
||||
return 'asc';
|
||||
}
|
||||
|
||||
return 'desc';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user