Version 4.2.0

This commit is contained in:
Neo committed 2025-12-19 05:44:59 -08:00
1 parent 0dc2aee5ed
commit 96997ddd8e
2074 files changed
+125454 -55780

No files matched your search

+182 -40
View File
@@ -1,13 +1,12 @@
<?php
/**
* @brief Album Node
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Community Suite
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 04 Mar 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\gallery;
@@ -30,7 +29,8 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
const AUTH_TYPE_PUBLIC = 1;
const AUTH_TYPE_PRIVATE = 2;
const AUTH_TYPE_RESTRICTED = 3;
const AUTH_TYPE_DELETED = 4;
/**
* @brief [ActiveRecord] Multiton Store
*/
@@ -56,6 +56,11 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public static $nodeTitle = 'albums';
/**
* @brief [Node] Node Database Order Column
*/
public static $databaseColumnOrder = 'name';
/**
* @brief [Node] Sortable?
*/
@@ -80,6 +85,23 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
'rating_hits' => 'rating_count',
);
/**
* Return this album as a content item instead of a node
*
* @return \IPS\gallery\Album\Item
*/
public function asItem()
{
$data = $this->_data;
foreach( $this->_data as $k => $v )
{
$data['album_' . $k ] = $v;
}
return \IPS\gallery\Album\Item::constructFromData( $data );
}
/**
* [Node] Return the owner if this node can be owned
*
@@ -109,13 +131,18 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public static function loadAndCheckPerms( $id, $perm='view' )
{
$obj = static::load( $id );
$obj = parent::loadAndCheckPerms( $id );
if ( !$obj->category()->can( $perm ) )
{
throw new \OutOfRangeException;
}
if ( $obj->type == static::AUTH_TYPE_DELETED )
{
throw new \OutOfRangeException;
}
/* If we don't have edit permission in the category, check album restrictions */
if( !\IPS\gallery\Image::modPermission( 'edit', NULL, $obj->category() ) )
{
@@ -147,6 +174,21 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
return $obj;
}
/**
* Fetch all nodes owned by a given user
*
* @param \IPS\Member|NULL $member The member whose nodes to load
* @param array $where Initial where clause
* @return array
* @throws \RuntimeException
*/
public static function loadByOwner( $member=NULL, $where=array() )
{
$where[] = array( 'album_type !=?', static::AUTH_TYPE_DELETED );
return parent::loadByOwner( $member, $where );
}
/**
* @brief Cached approved members
@@ -458,15 +500,25 @@ 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_rating', $album ? $album->allow_rating : 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 );
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);
}
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_use_comments', $album ? $album->use_comments : 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_use_reviews', $album ? $album->use_reviews : TRUE, FALSE );
}
return $return;
}
@@ -631,7 +683,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
* Move to a different category
*
* @param \IPS\gallery\Category $newCategory New category
* @pram \IPS\gallery\Category|NULL $existingCategory Old category
* @param \IPS\gallery\Category|NULL $existingCategory Old category
* @return void
*/
public function moveTo( \IPS\gallery\Category $newCategory, \IPS\gallery\Category $existingCategory = NULL )
@@ -665,6 +717,21 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
'tag_perm_aap_lookup' => md5( 'gallery;category;' . $newCategory->_id ),
'tag_perm_text' => \IPS\Db::i()->select( 'perm_2', 'core_permission_index', array( 'app=? AND perm_type=? AND perm_type_id=?', 'gallery', 'category', $newCategory->_id ) )->first()
), array( 'tag_perm_aap_lookup=?', md5( 'gallery;category;' . $existingCategory->_id ) ) );
/* Load the item */
$asItem = $this->asItem();
/* Add to search index */
\IPS\Content\Search\Index::i()->index( $asItem );
foreach ( array( 'commentClass', 'reviewClass' ) as $class )
{
$className = \IPS\gallery\Album\Item::$$class;
\IPS\Content\Search\Index::i()->massUpdate( $className, NULL, $this->id, $this->searchIndexPermissions(), NULL, $newCategory->_id );
}
/* Update caches */
$asItem->expireWidgetCaches();
}
/**
@@ -761,7 +828,7 @@ 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 */
/* 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();
@@ -770,8 +837,40 @@ 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();
}
/* 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->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();
/* Save and then make sure search index is updated */
\IPS\Content\Search\Index::i()->index( $this->asItem() );
}
/**
* 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->medium_file_name );
}
return count( $images ) ? $images : NULL;
}
/**
* Retrieve the latest images
*
@@ -857,6 +956,9 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
\IPS\Db::i()->update( 'calendar_events', array( 'event_album' => 0 ), array( 'event_album=?', $this->id ) );
}
/* Delete as an item to remove comments, meta data, search index, reviews, etc. */
$this->asItem()->delete();
/* Update category information */
if( $this->type == static::AUTH_TYPE_PUBLIC )
{
@@ -884,22 +986,42 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
/**
* Retrieve content items (if applicable) for a node.
*
* @param int $limit The limit
* @param int $offset The offset
* @param array $additionalWhere Additional where clauses
* @return \IPS\Patterns\ActiveRecordIterator
* @param int $limit The limit
* @param int $offset The offset
* @param array $additional Where Additional where clauses
* @param int $countOnly If TRUE, will get the number of results
* @return \IPS\Patterns\ActiveRecordIterator|int
* @throws \BadMethodCallException
*/
public function getContentItems( $limit, $offset, $additionalWhere = array() )
public function getContentItems( $limit, $offset, $additionalWhere = array(), $countOnly=FALSE )
{
if ( !isset( static::$contentItemClass ) )
{
throw new \BadMethodCallException;
}
$contentItemClass = static::$contentItemClass;
$limit = ( $offset !== NULL ) ? array( $offset, $limit ) : NULL;
return new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', $contentItemClass::$databaseTable, array( $contentItemClass::$databasePrefix . 'album_id=?', $this->_id ), $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId, $limit ), $contentItemClass );
$where = array();
$where[] = array( $contentItemClass::$databasePrefix . 'album_id=?', $this->_id );
if ( count( $additionalWhere ) )
{
foreach( $additionalWhere AS $clause )
{
$where[] = $clause;
}
}
if ( $countOnly )
{
return \IPS\Db::i()->select( 'COUNT(*)', $contentItemClass::$databaseTable, $where )->first();
}
else
{
$limit = ( $offset !== NULL ) ? array( $offset, $limit ) : NULL;
return new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', $contentItemClass::$databaseTable, $where, $contentItemClass::$databasePrefix . $contentItemClass::$databaseColumnId, $limit ), $contentItemClass );
}
}
/**
@@ -938,7 +1060,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
if( $size == 'full' )
{
$size = 'masked';
$size = 'masked';
}
$property = $size . "_file_name";
@@ -953,7 +1075,7 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
return NULL;
}
if( !in_array( $size, array( 'full', 'medium', 'small', 'thumb' ) ) )
if( !in_array( $size, array( 'masked', 'medium', 'small', 'thumb' ) ) )
{
throw new \InvalidArgumentException;
}
@@ -1024,6 +1146,30 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public function can( $permission, $member=NULL )
{
/* Load the item */
$asItem = $this->asItem();
/* Albums can be hidden, so make sure to test permissions */
if( $asItem->hidden() )
{
if( !$asItem->canView( $member ) )
{
return FALSE;
}
$methodToCheck = "can" . \ucwords( $permission );
if( method_exists( $asItem, $methodToCheck ) )
{
return $asItem->$methodToCheck( $member );
}
else
{
return $asItem->can( $permission, $member );
}
}
/* We'll just rely on category permissions if the album isn't hidden */
try
{
return $this->category()->can( $permission, $member );
@@ -1096,27 +1242,11 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
*/
public static function nodeTableTemplate()
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'gallery.css', 'gallery', 'front' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'gallery_responsive.css', 'gallery', 'front' ) );
}
\IPS\gallery\Application::outputCss();
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
}
/**
* Get content for embed
*
* @param array $params Additional parameters to add to URL
* @return string
*/
public function embedContent( $params )
{
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->embedAlbums( $this, $this->url()->setQueryString( $params ) );
}
/**
* Get output for API
*
@@ -1143,8 +1273,20 @@ class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\
'approvedMembers' => $this->approvedMembers ? array_map( function( $val ) {
return $val->apiOutput();
}, $this->approvedMembers ) : null,
'images' => $this->count_images,
'images' => $this->count_imgs,
'url' => (string) $this->url()
);
}
/**
* Get template for managing this nodes follows
*
* @return callable
*/
public static function manageFollowNodeRow()
{
\IPS\gallery\Application::outputCss();
return array( \IPS\Theme::i()->getTemplate( 'global', 'gallery' ), 'manageFollowNodeRow' );
}
}