Version 4.1.19

This commit is contained in:
Neo committed 2025-12-19 05:38:56 -08:00
1 parent 28bd025b35
commit 2bd5025018
2674 files changed
+233518 -77766

No files matched your search

+127 -32
View File
@@ -2,9 +2,9 @@
/**
* @brief Album Node
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @package IPS Community Suite
* @subpackage Gallery
* @since 04 Mar 2014
* @version SVN_VERSION_NUMBER
@@ -128,8 +128,20 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
/* 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() )
{
/* This will throw an exception of the row does not exist */
$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();
/* 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 )
{
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();
}
catch( \UnderflowException $e )
{
throw new \OutOfRangeException;
}
}
}
@@ -192,7 +204,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
{
if( !$this->_data['name_seo'] )
{
$this->name_seo = \IPS\Http\Url::seoTitle( $this->name );
$this->name_seo = \IPS\Http\Url\Friendly::seoTitle( $this->name );
if( $this->_data['name_seo'] )
{
@@ -200,7 +212,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
}
}
return $this->_data['name_seo'] ?: \IPS\Http\Url::seoTitle( $this->name );
return $this->_data['name_seo'] ?: \IPS\Http\Url\Friendly::seoTitle( $this->name );
}
/**
@@ -400,6 +412,11 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
return false;
}
if ( ! $node->can( 'add' ) )
{
return false;
}
return true;
}
) );
@@ -441,9 +458,15 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
$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\YesNo( 'album_allow_comments', $album ? $album->allow_comments : TRUE, FALSE );
if( ( ( $album and $album->category_id ) and ( \IPS\gallery\Category::load( $album->category_id )->allow_comments ) ) or ( ( isset( \IPS\Request::i()->chosenCategory ) or isset( \IPS\Request::i()->category ) ) and \IPS\gallery\Category::load( (int) \IPS\Request::i()->chosenCategory ?: \IPS\Request::i()->category )->allow_comments ) )
{
$return[] = new \IPS\Helpers\Form\YesNo('album_allow_comments', $album ? $album->allow_comments : TRUE, FALSE);
}
$return[] = new \IPS\Helpers\Form\YesNo( 'album_allow_rating', $album ? $album->allow_rating : TRUE, FALSE );
$return[] = new \IPS\Helpers\Form\YesNo( 'album_allow_reviews', $album ? $album->allow_reviews : TRUE, FALSE );
if( ( ( $album and $album->category_id ) and ( \IPS\gallery\Category::load( $album->category_id )->allow_reviews ) ) or ( ( isset( \IPS\Request::i()->chosenCategory ) or isset( \IPS\Request::i()->category ) ) and \IPS\gallery\Category::load( (int) \IPS\Request::i()->chosenCategory ?: \IPS\Request::i()->category )->allow_reviews ) )
{
$return[] = new \IPS\Helpers\Form\YesNo('album_allow_reviews', $album ? $album->allow_reviews : TRUE, FALSE);
}
return $return;
}
@@ -462,7 +485,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
if ( !$this->id )
{
$this->save();
\IPS\File::claimAttachments( 'gallery-new-album', $this->id, NULL, 'description', TRUE );
\IPS\File::claimAttachments( 'gallery-new-album', $this->id, NULL, 'description' );
/* Update public/non-public album count */
if( isset( $values['album_type'] ) AND isset( $values['album_category'] ) )
@@ -482,13 +505,38 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
else
{
$this->postSaveIsEdit = TRUE;
/* Are we changing from a private / friends only album to a public one? */
if ( $values['album_type'] != $this->type )
{
/* Remember the current type */
$this->postSaveType = $this->type;
/* Private to Public */
if ( $values['album_type'] == static::AUTH_TYPE_PUBLIC )
{
$values['album_category']->public_albums = $values['album_category']->public_albums + 1;
$values['album_category']->nonpublic_albums = $values['album_category']->nonpublic_albums - 1;
$values['album_category']->save();
}
else
{
/* Public to Private... but only if was really public previously (we don't want to do this for private to friends-only) */
if ( $this->type == static::AUTH_TYPE_PUBLIC )
{
$values['album_category']->public_albums = $values['album_category']->public_albums - 1;
$values['album_category']->nonpublic_albums = $values['album_category']->nonpublic_albums + 1;
$values['album_category']->save();
}
}
}
}
/* Custom language fields */
if( isset( $values['album_name'] ) )
{
\IPS\Lang::saveCustom( 'gallery', "gallery_album_{$this->id}", $values['album_name'] );
$values['name_seo'] = \IPS\Http\Url::seoTitle( is_array( $values['album_name'] ) ? $values['album_name'][ \IPS\Lang::defaultLanguage() ] : $values['album_name'] );
$values['name_seo'] = \IPS\Http\Url\Friendly::seoTitle( is_array( $values['album_name'] ) ? $values['album_name'][ \IPS\Lang::defaultLanguage() ] : $values['album_name'] );
}
if( isset( $values['album_description'] ) )
@@ -503,7 +551,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
$values['category_id'] = $values['album_category']->id;
unset( $values['album_category'] );
}
if( isset( $values['set_album_owner'] ) )
{
$values['owner_id'] = ( isset( $values['set_album_owner'] ) and $values['set_album_owner'] == 'me' ) ? \IPS\Member::loggedIn()->member_id : ( ( $values['album_owner'] instanceof \IPS\Member ) ? $values['album_owner']->member_id : $values['album_owner'] );
@@ -514,12 +562,12 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
}
unset( $values['set_album_owner'] );
if( isset( $values['album_owner'] ) )
if( array_key_exists( 'album_owner', $values ) )
{
unset( $values['album_owner'] );
}
}
else if( isset( $values['album_owner'] ) )
else if( array_key_exists( 'album_owner', $values ) )
{
$values['owner_id'] = ( $values['album_owner'] instanceof \IPS\Member ) ? $values['album_owner']->member_id : $values['album_owner'];
unset( $values['album_owner'] );
@@ -543,6 +591,11 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
protected $postSaveCategory = 0;
/**
* @brief Remember previous album status when editing
*/
protected $postSaveType = NULL;
/**
* [Node] Perform actions after saving the form
*
@@ -557,8 +610,11 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
$this->moveTo( \IPS\gallery\Category::load( $values['category_id'] ), \IPS\gallery\Category::load( $this->postSaveCategory ) );
}
/* Update index */
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\gallery\Image', $this->id, NULL, $this->searchIndexPermissions() );
/* Update search index */
if( $this->postSaveIsEdit and ( $this->postSaveType != $values['album_type'] OR $this->postSaveCategory != $values['category_id'] ) )
{
\IPS\Content\Search\Index::i()->massUpdate( 'IPS\gallery\Image', $this->id, NULL, $this->searchIndexPermissions() );
}
}
/**
@@ -593,13 +649,9 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
/* Update categories */
foreach ( array( $newCategory, $existingCategory ) as $category )
{
$category->count_imgs = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_category_id=? and image_approved=1', $category->_id ) )->first();
$category->count_imgs_hidden = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_category_id=? and image_approved=0', $category->_id ) )->first();
$category->count_comments = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_comments', array( 'image_category_id=? and image_approved=1 and comment_approved=1', $category->_id ) )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
$category->count_comments_hidden = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_comments', array( 'image_category_id=? and image_approved=1 and comment_approved=0', $category->_id ) )->join( 'gallery_images', 'image_id=comment_img_id' )->first();
$category->setLastComment();
$category->public_albums = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_category_id=? and album_type=1', $category->_id ) )->first();
$category->nonpublic_albums = (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_category_id=? and album_type>1', $category->_id ) )->first();
$category->setLastComment();
$category->save();
}
@@ -684,18 +736,19 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
/**
* Set last image data
*
* @param \IPS\gallery\Image|NULL $image The latest image or NULL to work it out
* @param \IPS\gallery\Image|NULL $image The latest image or NULL to work it out
* @param string $sortBy The column to sort by for last X images (defaults to image_date DESC; third parties can override)
* @return void
* @note This is called from the category, so we don't need to update our parent (the category)
*/
public function setLastImage( \IPS\gallery\Image $image=NULL )
public function setLastImage( \IPS\gallery\Image $image=NULL, $sortBy='image_date DESC' )
{
/* Figure out our latest images in this album */
$_latestImages = array();
$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 ), 'image_date DESC', 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 ) ) as $image )
{
if( $image['image_date'] > $this->last_img_date )
{
@@ -717,8 +770,6 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
$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->save();
}
/**
@@ -879,6 +930,17 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public function coverPhoto( $size='thumb' )
{
/* Can we view the images in this album? */
if ( !$this->can( 'read' ) )
{
return NULL;
}
if( $size == 'full' )
{
$size = 'masked';
}
$property = $size . "_file_name";
if( !$this->cover_img_id )
@@ -896,11 +958,6 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
throw new \InvalidArgumentException;
}
if( $size == 'full' )
{
$size = 'masked';
}
if( $this->coverPhoto === NULL )
{
$this->coverPhoto = \IPS\gallery\Image::load( $this->cover_img_id );
@@ -919,7 +976,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public static function loadFromUrl( \IPS\Http\Url $url )
{
$qs = array_merge( $url->queryString, $url->getFriendlyUrlData() );
$qs = array_merge( $url->queryString, $url->hiddenQueryString );
if ( isset( $qs['album'] ) )
{
@@ -967,7 +1024,14 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public function can( $permission, $member=NULL )
{
return $this->category()->can( $permission, $member );
try
{
return $this->category()->can( $permission, $member );
}
catch( \OutOfRangeException $e )
{
return FALSE;
}
}
/**
@@ -1052,4 +1116,35 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
{
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->embedAlbums( $this, $this->url()->setQueryString( $params ) );
}
/**
* Get output for API
*
* @return array
* @apiresponse int id ID number
* @apiresponse string name Name
* @apiresponse string description Description
* @apiresponse \IPS\gallery\Category category The category
* @apiresponse \IPS\Member owner The owner
* @apiresponse string privacy 'public', 'private' (can only be viewed by owner) or 'restricted' (can only be viewed by owner or approved members)
* @apiresponse [\IPS\Member] approvedMembers If the album is restricted, the members who can view it, in addition to the owner and moderators with appropriate permission
* @apiresponse int images Number of images
* @apiresponse string url URL
*/
public function apiOutput()
{
return array(
'id' => $this->id,
'name' => $this->name,
'description' => $this->description,
'category' => $this->category()->apiOutput(),
'owner' => $this->owner()->apiOutput(),
'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();
}, $this->approvedMembers ) : null,
'images' => $this->count_images,
'url' => (string) $this->url()
);
}
}