Version 4.0.13.1
This commit is contained in:
1 parent
f9e857d255
commit
c6a86f0d9b
7517 files changed
+597400
-668041
No files matched your search
@@ -0,0 +1,989 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Album Node
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Gallery
|
||||
* @since 04 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\gallery;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Album Node
|
||||
*/
|
||||
class _Album extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\Embeddable
|
||||
{
|
||||
/**
|
||||
* @brief Define access levels
|
||||
*/
|
||||
const AUTH_TYPE_PUBLIC = 1;
|
||||
const AUTH_TYPE_PRIVATE = 2;
|
||||
const AUTH_TYPE_RESTRICTED = 3;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'gallery_albums';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'album_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent Node ID Database Column
|
||||
*/
|
||||
public static $parentNodeColumnId = 'category_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'albums';
|
||||
|
||||
/**
|
||||
* @brief [Node] Sortable?
|
||||
*/
|
||||
public static $nodeSortable = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Content Item Class
|
||||
*/
|
||||
public static $contentItemClass = 'IPS\gallery\Image';
|
||||
|
||||
/**
|
||||
* @brief [Node] If the node can be "owned", the owner "type" (typically "member" or "group") and the associated database column
|
||||
*/
|
||||
public static $ownerTypes = array( 'member' => 'owner_id' );
|
||||
|
||||
/**
|
||||
* @brief [Node] By mapping appropriate columns (rating_average and/or rating_total + rating_hits) allows to cache rating values
|
||||
*/
|
||||
public static $ratingColumnMap = array(
|
||||
'rating_average' => 'rating_aggregate',
|
||||
'rating_total' => 'rating_total',
|
||||
'rating_hits' => 'rating_count',
|
||||
);
|
||||
|
||||
/**
|
||||
* [Node] Return the owner if this node can be owned
|
||||
*
|
||||
* @throws \RuntimeException
|
||||
* @return \IPS\Member|null
|
||||
*/
|
||||
public function owner()
|
||||
{
|
||||
$owner = parent::owner();
|
||||
|
||||
/* Gallery albums have to be owned by a user, so return a guest user if the owner is invalid */
|
||||
if( $owner === NULL OR $owner->member_id === null )
|
||||
{
|
||||
return new \IPS\Member;
|
||||
}
|
||||
|
||||
return $owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Load and check permissions
|
||||
*
|
||||
* @param mixed $id ID
|
||||
* @param string $perm Permission Key
|
||||
* @return static
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function loadAndCheckPerms( $id, $perm='view' )
|
||||
{
|
||||
$obj = static::load( $id );
|
||||
|
||||
if ( !$obj->category()->can( $perm ) )
|
||||
{
|
||||
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() ) )
|
||||
{
|
||||
/* 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() )
|
||||
{
|
||||
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() )
|
||||
{
|
||||
/* 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();
|
||||
}
|
||||
}
|
||||
|
||||
return $obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached approved members
|
||||
*/
|
||||
protected $_approvedMembers = FALSE;
|
||||
|
||||
/**
|
||||
* Get members with access to restricted album
|
||||
*
|
||||
* @return array|null
|
||||
* @note This list will NOT include the album owner, who also inherently has access
|
||||
*/
|
||||
protected function get_approvedMembers()
|
||||
{
|
||||
if( $this->_approvedMembers !== FALSE )
|
||||
{
|
||||
return $this->_approvedMembers;
|
||||
}
|
||||
|
||||
if( $this->type === static::AUTH_TYPE_RESTRICTED )
|
||||
{
|
||||
$members = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'core_sys_social_group_members', array( 'group_id=?', $this->allowed_access ) ) as $member )
|
||||
{
|
||||
$members[] = \IPS\Member::load( $member['member_id'] );
|
||||
}
|
||||
|
||||
$this->_approvedMembers = $members;
|
||||
|
||||
return $this->_approvedMembers;
|
||||
}
|
||||
|
||||
$this->_approvedMembers = NULL;
|
||||
|
||||
return $this->_approvedMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get title
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get__title()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get SEO name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name_seo()
|
||||
{
|
||||
if( !$this->_data['name_seo'] )
|
||||
{
|
||||
$this->name_seo = \IPS\Http\Url::seoTitle( $this->name );
|
||||
|
||||
if( $this->_data['name_seo'] )
|
||||
{
|
||||
$this->save();
|
||||
}
|
||||
}
|
||||
|
||||
return $this->_data['name_seo'] ?: \IPS\Http\Url::seoTitle( $this->name );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get whether or not this node is enabled
|
||||
*
|
||||
* @note Return value NULL indicates the node cannot be enabled/disabled
|
||||
* @return bool|null
|
||||
*/
|
||||
protected function get__enabled()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sort order
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get__sortBy()
|
||||
{
|
||||
return $this->sort_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of content items
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__items()
|
||||
{
|
||||
return $this->count_imgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of content comments
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__comments()
|
||||
{
|
||||
return $this->count_comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content items
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__unnapprovedItems()
|
||||
{
|
||||
return $this->count_imgs_hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content comments
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__unapprovedComments()
|
||||
{
|
||||
return $this->count_comments_hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get content table description
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_description()
|
||||
{
|
||||
return $this->_data['description'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of items
|
||||
*
|
||||
* @param int $val Items
|
||||
* @return void
|
||||
*/
|
||||
protected function set__items( $val )
|
||||
{
|
||||
$this->count_imgs = (int) $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of items
|
||||
*
|
||||
* @param int $val Comments
|
||||
* @return void
|
||||
*/
|
||||
protected function set__comments( $val )
|
||||
{
|
||||
$this->count_comments = (int) $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content items
|
||||
*
|
||||
* @param int $val Unapproved Items
|
||||
* @return void
|
||||
*/
|
||||
protected function set__unapprovedItems( $val )
|
||||
{
|
||||
$this->count_imgs_hidden = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content comments
|
||||
*
|
||||
* @param int $val Unapproved Comments
|
||||
* @return void
|
||||
*/
|
||||
protected function set__unapprovedComments( $val )
|
||||
{
|
||||
$this->count_comments_hidden = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
foreach ( static::formFields( $this->_id ? $this : NULL ) as $field )
|
||||
{
|
||||
$form->add( $field );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get fields
|
||||
*
|
||||
* @param \IPS\gallery\Album|NULL $album The album
|
||||
* @param bool $forOther Is this specifically not for the current member (e.g. on a move form)?
|
||||
* @param bool $required If TRUE, required elements (like name are actually required) otherwise they just appear so (e.g. on move form)
|
||||
* @return array
|
||||
*/
|
||||
public static function formFields( \IPS\gallery\Album $album = NULL, $forOther = FALSE, $required = TRUE )
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$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\Node( 'album_category', ( $album and $album->category_id ) ? \IPS\gallery\Category::load( $album->category_id ) : NULL, $required ?: NULL, array(
|
||||
'class' => 'IPS\gallery\Category',
|
||||
'disabled' => false,
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
if ( ! $node->allow_albums )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
) );
|
||||
|
||||
if( $forOther or \IPS\gallery\Image::modPermission( 'edit', NULL, ( $album ? $album->category() : NULL ) ) )
|
||||
{
|
||||
if ( !$forOther )
|
||||
{
|
||||
$return[] = new \IPS\Helpers\Form\Radio( 'set_album_owner', ( $album AND $album->owner_id !== \IPS\Member::loggedIn()->member_id ) ? 'other' : 'me', $required ?: NULL, array( 'options' => array( 'me' => 'set_album_owner_me', 'other' => 'set_album_owner_other' ), 'toggles' => array( 'other' => array( 'album_owner' ) ) ), NULL, NULL, NULL, 'set_album_owner' );
|
||||
}
|
||||
$return[] = new \IPS\Helpers\Form\Member( 'album_owner', $album ? \IPS\Member::load( $album->owner_id )->name : NULL, NULL, array(), function( $val ) use ( $required, $forOther )
|
||||
{
|
||||
if ( !$val and $required and ( $forOther or \IPS\Request::i()->set_album_owner == 'other' ) )
|
||||
{
|
||||
throw new \DomainException('form_required');
|
||||
}
|
||||
}, NULL, NULL, 'album_owner' );
|
||||
}
|
||||
|
||||
$types = array( static::AUTH_TYPE_PUBLIC => 'album_public' );
|
||||
$toggles = array();
|
||||
|
||||
if( \IPS\Member::loggedIn()->group['g_create_albums_private'] )
|
||||
{
|
||||
$types[ static::AUTH_TYPE_PRIVATE ] = ( \IPS\gallery\Image::modPermission( 'edit', NULL, ( $album ? $album->category() : NULL ) ) ) ? 'album_private_mod' : 'album_private';
|
||||
}
|
||||
|
||||
if( \IPS\Member::loggedIn()->group['g_create_albums_fo'] )
|
||||
{
|
||||
$types[ static::AUTH_TYPE_RESTRICTED ] = 'album_friend_only';
|
||||
$toggles[ static::AUTH_TYPE_RESTRICTED ] = array( 'album_allowed_access' );
|
||||
}
|
||||
$return[] = new \IPS\Helpers\Form\Radio( 'album_type', ( $album and $album->type ) ? $album->type : static::AUTH_TYPE_PUBLIC, FALSE, array( 'options' => $types, 'toggles' => $toggles ), NULL, NULL, NULL, 'album_type' );
|
||||
|
||||
if( \IPS\Member::loggedIn()->group['g_create_albums_fo'] )
|
||||
{
|
||||
$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' );
|
||||
}
|
||||
|
||||
$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', 'rating' => 'sort_rating', 'num_comments' => 'sort_num_comments' ) ), NULL, NULL, NULL, 'album_sort_options' );
|
||||
|
||||
$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 $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
$this->postSaveIsEdit = FALSE;
|
||||
|
||||
/* Claim attachments */
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
\IPS\File::claimAttachments( 'gallery-new-album', $this->id, NULL, 'description', TRUE );
|
||||
|
||||
/* Update public/non-public album count */
|
||||
if( isset( $values['album_type'] ) AND isset( $values['album_category'] ) )
|
||||
{
|
||||
if( $values['album_type'] == static::AUTH_TYPE_PUBLIC )
|
||||
{
|
||||
$values['album_category']->public_albums = $values['album_category']->public_albums + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
$values['album_category']->nonpublic_albums = $values['album_category']->nonpublic_albums + 1;
|
||||
}
|
||||
|
||||
$values['album_category']->save();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->postSaveIsEdit = TRUE;
|
||||
}
|
||||
|
||||
/* 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'] );
|
||||
}
|
||||
|
||||
if( isset( $values['album_description'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_album_{$this->id}_desc", $values['album_description'] );
|
||||
}
|
||||
|
||||
/* Related ID */
|
||||
if( isset( $values['album_category'] ) )
|
||||
{
|
||||
$this->postSaveCategory = $this->category_id;
|
||||
$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'] );
|
||||
|
||||
if( !$values['owner_id'] )
|
||||
{
|
||||
$values['owner_id'] = \IPS\Member::loggedIn()->member_id;
|
||||
}
|
||||
unset( $values['set_album_owner'] );
|
||||
|
||||
if( isset( $values['album_owner'] ) )
|
||||
{
|
||||
unset( $values['album_owner'] );
|
||||
}
|
||||
}
|
||||
else if( isset( $values['album_owner'] ) )
|
||||
{
|
||||
$values['owner_id'] = ( $values['album_owner'] instanceof \IPS\Member ) ? $values['album_owner']->member_id : $values['album_owner'];
|
||||
unset( $values['album_owner'] );
|
||||
}
|
||||
|
||||
/* Send to parent */
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Remember if we are editing or adding
|
||||
*/
|
||||
protected $postSaveIsEdit = FALSE;
|
||||
|
||||
/**
|
||||
* @brief Remember previous category when editing
|
||||
*/
|
||||
protected $postSaveCategory = 0;
|
||||
|
||||
/**
|
||||
* [Node] Perform actions after saving the form
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return void
|
||||
*/
|
||||
public function postSaveForm( $values )
|
||||
{
|
||||
/* Update counts in categories if we move the album */
|
||||
if( $this->postSaveIsEdit and $this->postSaveCategory != $values['category_id'] )
|
||||
{
|
||||
$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() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get category album belongs to
|
||||
*
|
||||
* @return \IPS\gallery\Category
|
||||
*/
|
||||
public function category()
|
||||
{
|
||||
return \IPS\gallery\Category::load( $this->category_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Move to a different category
|
||||
*
|
||||
* @param \IPS\gallery\Category $newCategory New category
|
||||
* @pram \IPS\gallery\Category|NULL $existingCategory Old category
|
||||
* @return void
|
||||
*/
|
||||
public function moveTo( \IPS\gallery\Category $newCategory, \IPS\gallery\Category $existingCategory = NULL )
|
||||
{
|
||||
if ( $existingCategory === NULL )
|
||||
{
|
||||
$existingCategory = $this->category();
|
||||
}
|
||||
$this->category_id = $newCategory->id;
|
||||
$this->save();
|
||||
|
||||
/* Update images */
|
||||
\IPS\Db::i()->update( 'gallery_images', array( 'image_category_id' => $newCategory->id ), array( 'image_album_id=?', $this->id ) );
|
||||
|
||||
/* 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->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();
|
||||
}
|
||||
|
||||
/* Tags */
|
||||
\IPS\Db::i()->update( 'core_tags', array(
|
||||
'tag_aap_lookup' => md5( 'gallery;category;' . $newCategory->_id ),
|
||||
'tag_meta_parent_id' => $newCategory->_id
|
||||
), array( 'tag_meta_app=? and tag_meta_area=? and tag_meta_parent_id=?', 'gallery', 'images', $existingCategory->_id ) );
|
||||
|
||||
\IPS\Db::i()->update( 'core_tags_perms', array(
|
||||
'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 ) ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached URL
|
||||
*/
|
||||
protected $_url = NULL;
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$this->_url = \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=browse&album={$this->_id}", 'front', 'gallery_album', $this->name_seo );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest image information
|
||||
*
|
||||
* @return \IPS\gallery\Image|NULL
|
||||
*/
|
||||
public function lastImage()
|
||||
{
|
||||
if( !$this->last_img_id )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return \IPS\gallery\Image::load( $this->last_img_id );
|
||||
}
|
||||
catch ( \Exception $e ) /* Catch both Underflow and OutOfRange */
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last comment
|
||||
*
|
||||
* @param \IPS\Content\Comment|NULL $comment The latest comment or NULL to work it out
|
||||
* @return int
|
||||
* @note We actually want to set the last image info, not the last comment, so we ignore $comment
|
||||
*/
|
||||
public function setLastComment( \IPS\Content\Comment $comment=NULL )
|
||||
{
|
||||
$this->setLastImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last image data
|
||||
*
|
||||
* @param \IPS\gallery\Image|NULL $image The latest image or NULL to work it out
|
||||
* @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 )
|
||||
{
|
||||
/* Figure out our latest images in this album */
|
||||
$_latestImages = array();
|
||||
|
||||
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 )
|
||||
{
|
||||
if( $image['image_date'] > $this->last_img_date )
|
||||
{
|
||||
$this->last_img_date = $image['image_date'];
|
||||
$this->last_img_id = $image['image_id'];
|
||||
}
|
||||
|
||||
$_latestImages[] = $image['image_id'];
|
||||
}
|
||||
|
||||
$this->last_x_images = json_encode( $_latestImages );
|
||||
|
||||
/* Now get the counts and set them */
|
||||
$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->_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->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the latest images
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get__latestImages()
|
||||
{
|
||||
$_latestImages = json_decode( $this->last_x_images, TRUE );
|
||||
|
||||
if( !count( $_latestImages ) )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
|
||||
return \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_id IN(' . implode( ',', $_latestImages ) . ')' ) ), NULL, 20 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached calendar events
|
||||
*/
|
||||
protected $_events = NULL;
|
||||
|
||||
/**
|
||||
* Get any associated calendar events
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get__event()
|
||||
{
|
||||
if( $this->_events !== NULL )
|
||||
{
|
||||
return $this->_events;
|
||||
}
|
||||
|
||||
if( \IPS\Application::appIsEnabled( 'calendar' ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$events = iterator_to_array( \IPS\calendar\Event::getItemsWithPermission( array( array( 'event_album=?', $this->id ) ) ) );
|
||||
|
||||
if( !count( $events ) )
|
||||
{
|
||||
$this->_events = array();
|
||||
return $this->_events;
|
||||
}
|
||||
|
||||
\IPS\calendar\Calendar::addCss();
|
||||
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'calendar.css', 'calendar', 'front' ) );
|
||||
|
||||
$this->_events = $events;
|
||||
return $this->_events;
|
||||
}
|
||||
catch( \OutOfRangeException $e ){}
|
||||
}
|
||||
|
||||
$this->_events = array();
|
||||
return $this->_events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'gallery_Albums', $this->id );
|
||||
parent::delete();
|
||||
|
||||
\IPS\Lang::deleteCustom( 'gallery', "gallery_album_{$this->id}" );
|
||||
\IPS\Lang::deleteCustom( 'gallery', "gallery_album_{$this->id}_desc" );
|
||||
|
||||
/* If there was a social group saved, delete it */
|
||||
if( $this->allowed_access )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'core_sys_social_groups', array( 'group_id=?', $this->allowed_access ) );
|
||||
\IPS\Db::i()->delete( 'core_sys_social_group_members', array( 'group_id=?', $this->allowed_access ) );
|
||||
}
|
||||
|
||||
/* If any calendar events are associated, unassociate */
|
||||
if( \IPS\Application::appIsEnabled( 'calendar' ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'calendar_events', array( 'event_album' => 0 ), array( 'event_album=?', $this->id ) );
|
||||
}
|
||||
|
||||
/* Update category information */
|
||||
if( $this->type == static::AUTH_TYPE_PUBLIC )
|
||||
{
|
||||
$this->category()->public_albums = $this->category()->public_albums - 1;
|
||||
}
|
||||
else if( $this->type == static::AUTH_TYPE_PRIVATE or $this->type == static::AUTH_TYPE_PRIVATE )
|
||||
{
|
||||
$this->category()->nonpublic_albums = $this->category()->nonpublic_albums - 1;
|
||||
}
|
||||
|
||||
$this->category()->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the content item count
|
||||
*
|
||||
* @return null|int
|
||||
*/
|
||||
public function getContentItemCount()
|
||||
{
|
||||
$contentItemClass = static::$contentItemClass;
|
||||
return (int) \IPS\Db::i()->select( 'COUNT(*)', $contentItemClass::$databaseTable, array( $contentItemClass::$databasePrefix . 'album_id=?', $this->id ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function getContentItems( $limit, $offset, $additionalWhere = array() )
|
||||
{
|
||||
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 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Text for use with data-ipsTruncate
|
||||
* Returns the post with paragraphs turned into line breaks
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function truncated()
|
||||
{
|
||||
$text = \IPS\Text\Parser::removeElements( $this->description, array( 'blockquote' ) );
|
||||
$text = str_replace( array( '</p>', '</h1>', '</h2>', '</h3>', '</h4>', '</h5>', '</h6>' ), '<br>', $text );
|
||||
$text = strip_tags( str_replace( ">", "> ", $text ), '<br>' );
|
||||
|
||||
return $text;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached cover photo
|
||||
*/
|
||||
protected $coverPhoto = NULL;
|
||||
|
||||
/**
|
||||
* Retrieve a cover photo
|
||||
*
|
||||
* @param string $size One of full, medium, small or thumb
|
||||
* @return string|null
|
||||
*/
|
||||
public function coverPhoto( $size='thumb' )
|
||||
{
|
||||
$property = $size . "_file_name";
|
||||
|
||||
if( !$this->cover_img_id )
|
||||
{
|
||||
if( $lastImage = $this->lastImage() )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( !in_array( $size, array( 'full', 'medium', 'small', 'thumb' ) ) )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
if( $size == 'full' )
|
||||
{
|
||||
$size = 'masked';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load record based on a URL
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to load from
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function loadFromUrl( \IPS\Http\Url $url )
|
||||
{
|
||||
$qs = array_merge( $url->queryString, $url->getFriendlyUrlData() );
|
||||
|
||||
if ( isset( $qs['album'] ) )
|
||||
{
|
||||
if ( method_exists( get_called_class(), 'loadAndCheckPerms' ) )
|
||||
{
|
||||
return static::loadAndCheckPerms( $qs['album'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static::load( $qs['album'] );
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Does the currently logged in user have permission to delete this node?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function canDelete()
|
||||
{
|
||||
if( static::restrictionCheck( 'delete' ) )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if( $this->owner_id == \IPS\Member::loggedIn()->member_id AND \IPS\Member::loggedIn()->group['g_delete_own_albums'] )
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check 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)
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
* @note Albums don't have permissions, but instead check against the category they are in
|
||||
*/
|
||||
public function can( $permission, $member=NULL )
|
||||
{
|
||||
return $this->category()->can( $permission, $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* Search Index Permissions
|
||||
*
|
||||
* @return string Comma-delimited values or '*'
|
||||
* @li Number indicates a group
|
||||
* @li Number prepended by "m" indicates a member
|
||||
* @li Number prepended by "s" indicates a social group
|
||||
*/
|
||||
public function searchIndexPermissions()
|
||||
{
|
||||
$return = parent::searchIndexPermissions();
|
||||
|
||||
if ( $this->type != static::AUTH_TYPE_PUBLIC )
|
||||
{
|
||||
$return = ( $return === '*' ) ? array() : explode( ',', $return );
|
||||
|
||||
if ( $this->owner_id )
|
||||
{
|
||||
$return[] = "m{$this->owner_id}";
|
||||
}
|
||||
|
||||
if ( $this->type == static::AUTH_TYPE_RESTRICTED )
|
||||
{
|
||||
$return[] = "s{$this->allowed_access}";
|
||||
}
|
||||
|
||||
$return = implode( ',', array_unique( $return ) );
|
||||
}
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can Rate?
|
||||
*
|
||||
* @param \IPS\Member|NULL $member The member to check for (NULL for currently logged in member)
|
||||
* @return bool
|
||||
* @throws \BadMethodCallException
|
||||
*/
|
||||
public function canRate( \IPS\Member $member = NULL )
|
||||
{
|
||||
if( parent::canRate( $member ) )
|
||||
{
|
||||
if( $this->category()->allow_rating )
|
||||
{
|
||||
return $this->category()->can( 'rate', $member );
|
||||
}
|
||||
else
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for node tables
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
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' ) );
|
||||
}
|
||||
|
||||
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 ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,186 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Table Builder for IP.Gallery albums
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Gallery
|
||||
* @since 17 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\gallery\Album;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Table Builder for IP.Gallery albums
|
||||
*/
|
||||
class _Table extends \IPS\Helpers\Table\Table
|
||||
{
|
||||
/**
|
||||
* @brief Container
|
||||
*/
|
||||
protected $container;
|
||||
|
||||
/**
|
||||
* @brief Additional CSS classes to apply to columns
|
||||
*/
|
||||
public $classes = array( 'cGalleryAlbums' );
|
||||
|
||||
/**
|
||||
* @brief Pagination parameter
|
||||
*/
|
||||
protected $paginationKey = 'albumPage';
|
||||
|
||||
/**
|
||||
* @brief Table resort parameter
|
||||
*/
|
||||
public $resortKey = 'albumResort';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param \IPS\Http\Url|NULL $url Base URL (defaults to container URL)
|
||||
* @param \IPS\Node\Model|NULL $container The container
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( \IPS\Http\Url $url=NULL, \IPS\Node\Model $container=NULL )
|
||||
{
|
||||
/* Init */
|
||||
$this->container = $container;
|
||||
|
||||
/* Init */
|
||||
parent::__construct( ( $url !== NULL ) ? $url : $container->url() );
|
||||
|
||||
$this->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
|
||||
|
||||
/* Set container */
|
||||
if ( $container !== NULL )
|
||||
{
|
||||
$this->where[] = array( 'album_category_id=?', $container->_id );
|
||||
|
||||
if ( $this->sortBy === 'album_name' )
|
||||
{
|
||||
$this->sortDirection = 'asc';
|
||||
}
|
||||
|
||||
if ( !$this->sortBy and $container->_sortBy !== NULL )
|
||||
{
|
||||
$this->sortBy = $container->_sortBy;
|
||||
$this->sortDirection = $container->_sortOrder;
|
||||
}
|
||||
if ( !$this->filter )
|
||||
{
|
||||
$this->filter = $container->_filter;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we can't moderate in this category, restrict results */
|
||||
if( $container === NULL OR !\IPS\gallery\Image::modPermission( 'edit', NULL, $container ) )
|
||||
{
|
||||
if( count( \IPS\Member::loggedIn()->socialGroups() ) )
|
||||
{
|
||||
$this->where[] = array( '( album_type=1 OR ( album_type=2 AND album_owner_id=? ) OR ( album_type=3 AND ( album_owner_id=? OR ( album_allowed_access IS NOT NULL AND album_allowed_access IN(' . implode( ',', \IPS\Member::loggedIn()->socialGroups() ) . ') ) ) ) )', \IPS\Member::loggedIn()->member_id, \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->where[] = array( '( album_type=1 OR ( album_type IN (2,3) AND album_owner_id=? ) )', \IPS\Member::loggedIn()->member_id );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->where[] = array( 'album_type<>4' );
|
||||
}
|
||||
|
||||
|
||||
/* Set available sort options */
|
||||
foreach ( array( 'last_img_date', 'count_comments', 'rating_aggregate', 'name', 'count_imgs' ) as $k )
|
||||
{
|
||||
if( $k == 'count_comments' AND ( $container === NULL OR !$this->container->allow_comments ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if( $k == 'rating_aggregate' AND ( $container === NULL OR !$this->container->allow_rating ) )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->sortOptions[ $k ] = 'album_' . $k;
|
||||
}
|
||||
|
||||
if ( !$this->sortBy )
|
||||
{
|
||||
$this->sortBy = 'album_last_img_date';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set owner
|
||||
*
|
||||
* @param \IPS\Member $member The member to filter by
|
||||
* @return void
|
||||
*/
|
||||
public function setOwner( \IPS\Member $member )
|
||||
{
|
||||
$this->where[] = array( 'album_owner_id=?', $member->member_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get rows
|
||||
*
|
||||
* @param array $advancedSearchValues Values from the advanced search form
|
||||
* @return array
|
||||
*/
|
||||
public function getRows( $advancedSearchValues )
|
||||
{
|
||||
/* Init */
|
||||
$class = "IPS\\gallery\\Album";
|
||||
$subquery = NULL;
|
||||
|
||||
/* Check sortBy */
|
||||
$this->sortBy = in_array( $this->sortBy, $this->sortOptions ) ? $this->sortBy : 'album_last_img_date';
|
||||
|
||||
/* What are we sorting by? */
|
||||
$sortBy = $this->sortBy . ' ' . ( mb_strtolower( $this->sortDirection ) == 'asc' ? 'asc' : 'desc' );
|
||||
|
||||
/* Specify filter in where clause */
|
||||
$where = $this->where ? is_array( $this->where ) ? $this->where : array( $this->where ) : array();
|
||||
if ( $this->filter and isset( $this->filters[ $this->filter ] ) )
|
||||
{
|
||||
$where[] = is_array( $this->filters[ $this->filter ] ) ? $this->filters[ $this->filter ] : array( $this->filters[ $this->filter ] );
|
||||
}
|
||||
|
||||
/* Get results */
|
||||
$it = \IPS\Db::i()->select( '*', 'gallery_albums', $where, $sortBy, array( ( $this->limit * ( $this->page - 1 ) ), $this->limit ), NULL, NULL, \IPS\DB::SELECT_SQL_CALC_FOUND_ROWS );
|
||||
$this->pages = ceil( $it->count( TRUE ) / $this->limit );
|
||||
|
||||
$rows = iterator_to_array( $it );
|
||||
|
||||
foreach( $rows as $index => $row )
|
||||
{
|
||||
$rows[ $index ] = \IPS\gallery\Album::constructFromData( $row );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the table headers
|
||||
*
|
||||
* @param array|NULL $advancedSearchValues Advanced search values
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders( $advancedSearchValues )
|
||||
{
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,762 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Category Node
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Gallery
|
||||
* @since 04 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\gallery;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Category Node
|
||||
*/
|
||||
class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'gallery_categories';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'category_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Order Database Column
|
||||
*/
|
||||
public static $databaseColumnOrder = 'position';
|
||||
|
||||
/**
|
||||
* @brief [Node] Parent ID Database Column
|
||||
*/
|
||||
public static $databaseColumnParent = 'parent_id';
|
||||
|
||||
/**
|
||||
* @brief [Node] Node Title
|
||||
*/
|
||||
public static $nodeTitle = 'categories';
|
||||
|
||||
/**
|
||||
* @brief [Node] ACP Restrictions
|
||||
* @code
|
||||
array(
|
||||
'app' => 'core', // The application key which holds the restrictrions
|
||||
'module' => 'foo', // The module key which holds the restrictions
|
||||
'map' => array( // [Optional] The key for each restriction - can alternatively use "prefix"
|
||||
'add' => 'foo_add',
|
||||
'edit' => 'foo_edit',
|
||||
'permissions' => 'foo_perms',
|
||||
'delete' => 'foo_delete'
|
||||
),
|
||||
'all' => 'foo_manage', // [Optional] The key to use for any restriction not provided in the map (only needed if not providing all 4)
|
||||
'prefix' => 'foo_', // [Optional] Rather than specifying each key in the map, you can specify a prefix, and it will automatically look for restrictions with the key "[prefix]_add/edit/permissions/delete"
|
||||
* @endcode
|
||||
*/
|
||||
protected static $restrictions = array(
|
||||
'app' => 'gallery',
|
||||
'module' => 'gallery',
|
||||
'prefix' => 'categories_'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] App for permission index
|
||||
*/
|
||||
public static $permApp = 'gallery';
|
||||
|
||||
/**
|
||||
* @brief [Node] Type for permission index
|
||||
*/
|
||||
public static $permType = 'category';
|
||||
|
||||
/**
|
||||
* @brief The map of permission columns
|
||||
*/
|
||||
public static $permissionMap = array(
|
||||
'view' => 'view',
|
||||
'read' => 2,
|
||||
'add' => 3,
|
||||
'reply' => 4,
|
||||
'rate' => 5
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief [Node] Title prefix. If specified, will look for a language key with "{$key}_title" as the key
|
||||
*/
|
||||
public static $titleLangPrefix = 'gallery_category_';
|
||||
|
||||
/**
|
||||
* @brief [Node] Description suffix. If specified, will look for a language key with "{$titleLangPrefix}_{$id}_{$descriptionLangSuffix}" as the key
|
||||
*/
|
||||
public static $descriptionLangSuffix = '_desc';
|
||||
|
||||
/**
|
||||
* @brief [Node] Moderator Permission
|
||||
*/
|
||||
public static $modPerm = 'gallery_categories';
|
||||
|
||||
/**
|
||||
* @brief Content Item Class
|
||||
*/
|
||||
public static $contentItemClass = 'IPS\gallery\Image';
|
||||
|
||||
/**
|
||||
* Get SEO name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name_seo()
|
||||
{
|
||||
if( !$this->_data['name_seo'] )
|
||||
{
|
||||
$this->name_seo = \IPS\Http\Url::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'gallery_category_' . $this->id ) );
|
||||
$this->save();
|
||||
}
|
||||
|
||||
return $this->_data['name_seo'] ?: \IPS\Http\Url::seoTitle( \IPS\Lang::load( \IPS\Lang::defaultLanguage() )->get( 'gallery_category_' . $this->id ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get whether or not this node is enabled
|
||||
*
|
||||
* @note Return value NULL indicates the node cannot be enabled/disabled
|
||||
* @return bool|null
|
||||
*/
|
||||
protected function get__enabled()
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get sort order
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get__sortBy()
|
||||
{
|
||||
return $this->sort_options;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of content items
|
||||
*
|
||||
* @return int
|
||||
* @note We return null if there are non-public albums so that we can count what you can see properly
|
||||
*/
|
||||
protected function get__items()
|
||||
{
|
||||
return $this->nonpublic_albums ? NULL : $this->count_imgs;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of content comments
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__comments()
|
||||
{
|
||||
return $this->count_comments;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content items
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__unnapprovedItems()
|
||||
{
|
||||
return $this->count_imgs_hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content comments
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
protected function get__unapprovedComments()
|
||||
{
|
||||
return $this->count_comments_hidden;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of items
|
||||
*
|
||||
* @param int $val Items
|
||||
* @return void
|
||||
*/
|
||||
protected function set__items( $val )
|
||||
{
|
||||
$this->count_imgs = (int) $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set number of items
|
||||
*
|
||||
* @param int $val Comments
|
||||
* @return void
|
||||
*/
|
||||
protected function set__comments( $val )
|
||||
{
|
||||
$this->count_comments = (int) $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content items
|
||||
*
|
||||
* @param int $val Unapproved Items
|
||||
* @return void
|
||||
*/
|
||||
protected function set__unapprovedItems( $val )
|
||||
{
|
||||
$this->count_imgs_hidden = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Get number of unapproved content comments
|
||||
*
|
||||
* @param int $val Unapproved Comments
|
||||
* @return void
|
||||
*/
|
||||
protected function set__unapprovedComments( $val )
|
||||
{
|
||||
$this->count_comments_hidden = $val;
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Add/Edit Form
|
||||
*
|
||||
* @param \IPS\Helpers\Form $form The form
|
||||
* @return void
|
||||
*/
|
||||
public function form( &$form )
|
||||
{
|
||||
$form->addTab( 'category_settings' );
|
||||
$form->addHeader( 'category_settings' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_name', NULL, TRUE, array( 'app' => 'gallery', 'key' => ( $this->id ? "gallery_category_{$this->id}" : NULL ) ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_description', NULL, FALSE, array(
|
||||
'app' => 'gallery',
|
||||
'key' => ( $this->id ? "gallery_category_{$this->id}_desc" : NULL ),
|
||||
'editor' => array(
|
||||
'app' => 'gallery',
|
||||
'key' => 'Categories',
|
||||
'autoSaveKey' => ( $this->id ? "gallery-cat-{$this->id}" : "gallery-new-cat" ),
|
||||
'attachIds' => $this->id ? array( $this->id, NULL, 'description' ) : NULL,
|
||||
'minimize' => 'cdesc_placeholder'
|
||||
)
|
||||
) ) );
|
||||
|
||||
$class = get_called_class();
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Node( 'gcategory_parent_id', $this->id ? $this->parent_id : ( \IPS\Request::i()->parent ?: 0 ), FALSE, array(
|
||||
'class' => '\IPS\gallery\Category',
|
||||
'disabled' => false,
|
||||
'zeroVal' => 'node_no_parentg',
|
||||
'permissionCheck' => function( $node ) use ( $class )
|
||||
{
|
||||
if( isset( $class::$subnodeClass ) AND $class::$subnodeClass AND $node instanceof $class::$subnodeClass )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return !isset( \IPS\Request::i()->id ) or ( $node->id != \IPS\Request::i()->id and !$node->isChildOf( $node::load( \IPS\Request::i()->id ) ) );
|
||||
}
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Select( 'category_sort_options', $this->sort_options ?: 'updated', FALSE, array( 'options' => array( 'updated' => 'sort_updated', 'rating' => 'sort_rating', 'num_comments' => 'sort_num_comments' ) ), 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\YesNo( 'category_approve_img', $this->approve_img, FALSE ) );
|
||||
|
||||
if( \IPS\Settings::i()->gallery_watermark_path )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_watermark', $this->id ? $this->watermark : TRUE, FALSE ) );
|
||||
}
|
||||
|
||||
$form->addHeader( 'category_comments_and_ratings' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_allow_comments', $this->id ? $this->allow_comments : TRUE, FALSE, array( 'togglesOn' => array( 'category_approve_com' ) ), NULL, NULL, NULL, 'category_allow_comments' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_approve_com', $this->approve_com, FALSE, array(), NULL, NULL, NULL, 'category_approve_com' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'gcategory_allow_rating', $this->id ? $this->allow_rating : TRUE, FALSE ) );
|
||||
|
||||
if ( \IPS\Settings::i()->tags_enabled )
|
||||
{
|
||||
$form->addHeader( 'category_tags' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_can_tag', $this->id ? $this->can_tag : TRUE, FALSE, array( 'togglesOn' => array( 'category_tag_prefixes', 'category_preset_tags' ) ), NULL, NULL, NULL, 'category_can_tag' ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'category_tag_prefixes', $this->id ? $this->tag_prefixes : TRUE, FALSE, array(), NULL, NULL, NULL, 'category_tag_prefixes' ) );
|
||||
|
||||
if ( !\IPS\Settings::i()->tags_open_system )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Text( 'category_preset_tags', $this->preset_tags, FALSE, array( 'autocomplete' => array( 'unique' => 'true' ), 'nullLang' => 'ctags_predefined_unlimited' ), NULL, NULL, NULL, 'category_preset_tags' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$form->addTab( 'category_rules' );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'category_show_rules', $this->id ? $this->show_rules : 0, FALSE, array(
|
||||
'options' => array(
|
||||
0 => 'category_show_rules_none',
|
||||
1 => 'category_show_rules_link',
|
||||
2 => 'category_show_rules_full'
|
||||
),
|
||||
'toggles' => array(
|
||||
1 => array(
|
||||
'category_rules_title',
|
||||
'category_rules_text'
|
||||
),
|
||||
2 => array(
|
||||
'category_rules_title',
|
||||
'category_rules_text'
|
||||
),
|
||||
)
|
||||
) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_rules_title', NULL, FALSE, array( 'app' => 'gallery', 'key' => ( $this->id ? "gallery_category_{$this->id}_rulestitle" : NULL ) ), NULL, NULL, NULL, 'category_rules_title' ) );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_rules_text', NULL, FALSE, array( 'app' => 'gallery', 'key' => ( $this->id ? "gallery_category_{$this->id}_rules" : NULL ), 'editor' => array( 'app' => 'gallery', 'key' => 'Categories', 'autoSaveKey' => ( $this->id ? "gallery-rules-{$this->id}" : "gallery-new-rules" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'rules' ) : NULL ) ), NULL, NULL, NULL, 'category_rules_text' ) );
|
||||
//$form->add( new \IPS\Helpers\Form\Url( 'category_rules_link', $this->rules_link, FALSE, array(), NULL, NULL, NULL, 'category_rules_link' ) );
|
||||
|
||||
$form->addTab( 'error_messages' );
|
||||
$form->add( new \IPS\Helpers\Form\Translatable( 'category_permission_custom_error', NULL, FALSE, array( 'app' => 'gallery', 'key' => ( $this->id ? "gallery_category_{$this->id}_permerror" : NULL ), 'editor' => array( 'app' => 'gallery', 'key' => 'Categories', 'autoSaveKey' => ( $this->id ? "gallery-permerror-{$this->id}" : "gallery-new-permerror" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'permerror' ) : NULL, 'minimize' => 'gallery_permerror_placeholder' ) ), NULL, NULL, NULL, 'gallery_permission_custom_error' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* [Node] Format form values from add/edit form for save
|
||||
*
|
||||
* @param array $values Values from the form
|
||||
* @return array
|
||||
*/
|
||||
public function formatFormValues( $values )
|
||||
{
|
||||
/* Fix field (lang conflict) */
|
||||
if( isset( $values['gcategory_allow_rating'] ) )
|
||||
{
|
||||
$values['category_allow_rating'] = $values['gcategory_allow_rating'];
|
||||
unset( $values['gcategory_allow_rating'] );
|
||||
}
|
||||
if( isset( $values['gcategory_parent_id'] ) )
|
||||
{
|
||||
$values['category_parent_id'] = $values['gcategory_parent_id'];
|
||||
unset( $values['gcategory_parent_id'] );
|
||||
}
|
||||
|
||||
/* Claim attachments */
|
||||
if ( !$this->id )
|
||||
{
|
||||
$this->save();
|
||||
\IPS\File::claimAttachments( 'gallery-new-cat', $this->id, NULL, 'description', TRUE );
|
||||
\IPS\File::claimAttachments( 'gallery-new-rules', $this->id, NULL, 'rules', TRUE );
|
||||
\IPS\File::claimAttachments( 'gallery-new-permerror', $this->id, NULL, 'permerror', TRUE );
|
||||
}
|
||||
|
||||
/* Custom language fields */
|
||||
if( isset( $values['category_name'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_category_{$this->id}", $values['category_name'] );
|
||||
$values['name_seo'] = \IPS\Http\Url::seoTitle( $values['category_name'][ \IPS\Lang::defaultLanguage() ] );
|
||||
unset( $values['category_name'] );
|
||||
}
|
||||
|
||||
if( isset( $values['category_description'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_category_{$this->id}_desc", $values['category_description'] );
|
||||
unset( $values['category_description'] );
|
||||
}
|
||||
|
||||
if( isset( $values['category_rules_title'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_category_{$this->id}_rulestitle", $values['category_rules_title'] );
|
||||
unset( $values['category_rules_title'] );
|
||||
}
|
||||
|
||||
if( isset( $values['category_rules_text'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_category_{$this->id}_rules", $values['category_rules_text'] );
|
||||
unset( $values['category_rules_text'] );
|
||||
}
|
||||
|
||||
if( isset( $values['category_permission_custom_error'] ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'gallery', "gallery_category_{$this->id}_permerror", $values['category_permission_custom_error'] );
|
||||
unset( $values['category_permission_custom_error'] );
|
||||
}
|
||||
|
||||
/* Parent ID */
|
||||
if ( isset( $values['category_parent_id'] ) )
|
||||
{
|
||||
$values['category_parent_id'] = $values['category_parent_id'] ? intval( $values['category_parent_id']->id ) : 0;
|
||||
}
|
||||
|
||||
/* Send to parent */
|
||||
return $values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached URL
|
||||
*/
|
||||
protected $_url = NULL;
|
||||
|
||||
/**
|
||||
* Get URL
|
||||
*
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url()
|
||||
{
|
||||
if( $this->_url === NULL )
|
||||
{
|
||||
$this->_url = \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=browse&category={$this->_id}", 'front', 'gallery_category', $this->name_seo );
|
||||
}
|
||||
|
||||
return $this->_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "No Permission" error message
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function errorMessage()
|
||||
{
|
||||
if ( \IPS\Member::loggedIn()->language()->checkKeyExists( "gallery_category_{$this->id}_permerror" ) )
|
||||
{
|
||||
$message = \IPS\Member::loggedIn()->language()->addToStack( "gallery_category_{$this->id}_permerror" );
|
||||
if ( $message and $message != '<p></p>' )
|
||||
{
|
||||
return $message;
|
||||
}
|
||||
}
|
||||
|
||||
return 'node_error_no_perm';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest image information
|
||||
*
|
||||
* @return \IPS\gallery\Image|NULL
|
||||
*/
|
||||
public function lastImage()
|
||||
{
|
||||
$latestImage = NULL;
|
||||
|
||||
if( $this->last_img_id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$latestImage = \IPS\gallery\Image::load( $this->last_img_id );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
$latestImage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
foreach( $this->children() as $child )
|
||||
{
|
||||
$childLatest = $child->lastImage();
|
||||
|
||||
if( $childLatest !== NULL AND ( $latestImage === NULL OR $childLatest->date > $latestImage->date ) )
|
||||
{
|
||||
$latestImage = $childLatest;
|
||||
}
|
||||
}
|
||||
|
||||
return $latestImage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete Record
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'gallery_Categories', $this->id );
|
||||
parent::delete();
|
||||
|
||||
\IPS\Lang::deleteCustom( 'gallery', "gallery_category_{$this->id}_rulestitle" );
|
||||
\IPS\Lang::deleteCustom( 'gallery', "gallery_category_{$this->id}_rules" );
|
||||
\IPS\Lang::deleteCustom( 'gallery', "gallery_category_{$this->id}_permerror" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last comment
|
||||
*
|
||||
* @param \IPS\Content\Comment|NULL $comment The latest comment or NULL to work it out
|
||||
* @return int
|
||||
* @note We actually want to set the last image info, not the last comment, so we ignore $comment
|
||||
*/
|
||||
public function setLastComment( \IPS\Content\Comment $comment=NULL )
|
||||
{
|
||||
$this->setLastImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set last image data
|
||||
*
|
||||
* @param \IPS\gallery\Image|NULL $image The latest image or NULL to work it out
|
||||
* @return void
|
||||
*/
|
||||
public function setLastImage( \IPS\gallery\Image $image=NULL )
|
||||
{
|
||||
if( $image === NULL )
|
||||
{
|
||||
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(
|
||||
'gallery_albums',
|
||||
"image_album_id=album_id"
|
||||
)->first() );
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
$this->last_img_id = 0;
|
||||
$this->last_img_date = 0;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$this->last_img_id = $image->id;
|
||||
$this->last_img_date = $image->date;
|
||||
|
||||
if( $image->album_id )
|
||||
{
|
||||
$album = \IPS\gallery\Album::load( $image->album_id );
|
||||
$album->setLastImage( $image );
|
||||
$album->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get last comment time
|
||||
*
|
||||
* @note This should return the last comment time for this node only, not for children nodes
|
||||
* @return \IPS\DateTime|NULL
|
||||
*/
|
||||
public function getLastCommentTime()
|
||||
{
|
||||
return $this->last_img_date ? \IPS\DateTime::ts( $this->last_img_date ) : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Cached cover photo
|
||||
*/
|
||||
protected $coverPhoto = NULL;
|
||||
|
||||
/**
|
||||
* Retrieve a cover photo
|
||||
*
|
||||
* @param string $size One of full, medium, small or thumb
|
||||
* @return string|null
|
||||
*/
|
||||
public function coverPhoto( $size='thumb' )
|
||||
{
|
||||
$property = $size . "_file_name";
|
||||
|
||||
if( !$this->cover_img_id )
|
||||
{
|
||||
if( $lastImage = $this->lastImage() )
|
||||
{
|
||||
return (string) \IPS\File::get( 'gallery_Images', $lastImage->$property )->url;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if( !in_array( $size, array( 'full', 'medium', 'small', 'thumb' ) ) )
|
||||
{
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
if( $size == 'full' )
|
||||
{
|
||||
$size = 'masked';
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load record based on a URL
|
||||
*
|
||||
* @param \IPS\Http\Url $url URL to load from
|
||||
* @return static
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \OutOfRangeException
|
||||
*/
|
||||
public static function loadFromUrl( \IPS\Http\Url $url )
|
||||
{
|
||||
$qs = array_merge( $url->queryString, $url->getFriendlyUrlData() );
|
||||
|
||||
if ( isset( $qs['category'] ) )
|
||||
{
|
||||
if ( method_exists( get_called_class(), 'loadAndCheckPerms' ) )
|
||||
{
|
||||
return static::loadAndCheckPerms( $qs['category'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static::load( $qs['category'] );
|
||||
}
|
||||
}
|
||||
|
||||
throw new \InvalidArgumentException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if any albums are located in this category
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAlbums()
|
||||
{
|
||||
return (bool) \IPS\Db::i()->select( 'COUNT(*) as total', 'gallery_albums', array( 'album_category_id=?', $this->id ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Form to delete or move content
|
||||
*
|
||||
* @param bool $showMoveToChildren If TRUE, will show "move to children" even if there are no children
|
||||
* @return \IPS\Helpers\Form
|
||||
*/
|
||||
public function deleteOrMoveForm( $showMoveToChildren=FALSE )
|
||||
{
|
||||
if ( $this->hasChildren( NULL ) OR $this->hasAlbums() )
|
||||
{
|
||||
$showMoveToChildren = TRUE;
|
||||
if( $this->hasChildren( NULL ) AND $this->hasAlbums() )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['node_move_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_move_catsalbums', FALSE );
|
||||
\IPS\Member::loggedIn()->language()->words['node_delete_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_delete_children_catsalbums', FALSE );
|
||||
}
|
||||
else if( $this->hasChildren( NULL ) )
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['node_move_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_move_children', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( static::$nodeTitle ) ) ) );
|
||||
\IPS\Member::loggedIn()->language()->words['node_delete_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_delete_children_cats', FALSE );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['node_move_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_move_subalbums', FALSE );
|
||||
\IPS\Member::loggedIn()->language()->words['node_delete_children'] = \IPS\Member::loggedIn()->language()->addToStack( 'node_delete_children_albums', FALSE );
|
||||
}
|
||||
}
|
||||
return parent::deleteOrMoveForm( $showMoveToChildren );
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle submissions of form to delete or move content
|
||||
*
|
||||
* @param array $values Values from form
|
||||
* @param bool $deleteWhenDone Delete the node when done?
|
||||
* @return void
|
||||
*/
|
||||
public function deleteOrMoveFormSubmit( $values, $deleteWhenDone=TRUE )
|
||||
{
|
||||
if ( $this->hasAlbums() )
|
||||
{
|
||||
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'gallery_albums', array( 'album_category_id=?', $this->id ) ), 'IPS\gallery\Album' ) as $album )
|
||||
{
|
||||
if ( $values['node_move_children'] )
|
||||
{
|
||||
$album->moveTo( $values['node_move_children'] );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->_id, 'deleteWhenDone' => $deleteWhenDone ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::deleteOrMoveFormSubmit( $values );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get template for node tables
|
||||
*
|
||||
* @return callable
|
||||
*/
|
||||
public static function nodeTableTemplate()
|
||||
{
|
||||
return array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'categoryRow' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check permissions on any node
|
||||
*
|
||||
* For example - can be used to check if the user has
|
||||
* permission to create content in any node to determine
|
||||
* if there should be a "Submit" button
|
||||
*
|
||||
* @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)
|
||||
* @return bool
|
||||
* @throws \OutOfBoundsException If $permission does not exist in static::$permissionMap
|
||||
*/
|
||||
public static function canOnAny( $permission, $member = NULL )
|
||||
{
|
||||
/* Load member */
|
||||
if ( $member === NULL )
|
||||
{
|
||||
$member = \IPS\Member::loggedIn();
|
||||
}
|
||||
|
||||
if ( $member->members_bitoptions['remove_gallery_access'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return parent::canOnAny( $permission, $member );
|
||||
}
|
||||
|
||||
/**
|
||||
* [ActiveRecord] Duplicate
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __clone()
|
||||
{
|
||||
if ( $this->skipCloneDuplication === TRUE )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
$this->public_albums = 0;
|
||||
$this->nonpublic_albums = 0;
|
||||
|
||||
$oldId = $this->id;
|
||||
|
||||
parent::__clone();
|
||||
|
||||
foreach ( array( 'rules_title' => "gallery_category_{$this->id}_rulestitle", 'rules_text' => "gallery_category_{$this->id}_rules" ) as $fieldKey => $langKey )
|
||||
{
|
||||
$oldLangKey = str_replace( $this->id, $oldId, $langKey );
|
||||
\IPS\Lang::saveCustom( 'gallery', $langKey, iterator_to_array( \IPS\Db::i()->select( 'word_custom, lang_id', 'core_sys_lang_words', array( 'word_key=?', $oldLangKey ) )->setKeyField( 'lang_id' )->setValueField('word_custom') ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get content for embed
|
||||
*
|
||||
* @param array $params Additional parameters to add to URL
|
||||
* @return string
|
||||
*/
|
||||
public function embedContent( $params )
|
||||
{
|
||||
return 'x';
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -0,0 +1,137 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Image Comment Model
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Gallery
|
||||
* @since 04 Mar 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\gallery\Image;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Image Comment Model
|
||||
*/
|
||||
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\ReportCenter, \IPS\Content\Hideable, \IPS\Content\Reputation, \IPS\Content\Searchable, \IPS\Content\Embeddable
|
||||
{
|
||||
/**
|
||||
* @brief [ActiveRecord] Multiton Store
|
||||
*/
|
||||
protected static $multitons;
|
||||
|
||||
/**
|
||||
* @brief [Content\Comment] Item Class
|
||||
*/
|
||||
public static $itemClass = 'IPS\gallery\Image';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Table
|
||||
*/
|
||||
public static $databaseTable = 'gallery_comments';
|
||||
|
||||
/**
|
||||
* @brief [ActiveRecord] Database Prefix
|
||||
*/
|
||||
public static $databasePrefix = 'comment_';
|
||||
|
||||
/**
|
||||
* @brief Database Column Map
|
||||
*/
|
||||
public static $databaseColumnMap = array(
|
||||
'item' => 'img_id',
|
||||
'author' => 'author_id',
|
||||
'author_name' => 'author_name',
|
||||
'content' => 'text',
|
||||
'date' => 'post_date',
|
||||
'ip_address' => 'ip_address',
|
||||
'edit_time' => 'edit_time',
|
||||
'edit_member_name' => 'edit_name',
|
||||
'edit_show' => 'append_edit',
|
||||
'approved' => 'approved'
|
||||
);
|
||||
|
||||
/**
|
||||
* @brief Application
|
||||
*/
|
||||
public static $application = 'gallery';
|
||||
|
||||
/**
|
||||
* @brief Title
|
||||
*/
|
||||
public static $title = 'gallery_image_comment';
|
||||
|
||||
/**
|
||||
* @brief Icon
|
||||
*/
|
||||
public static $icon = 'camera';
|
||||
|
||||
/**
|
||||
* @brief Reputation Type
|
||||
*/
|
||||
public static $reputationType = 'comment_id';
|
||||
|
||||
/**
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'gallery-images';
|
||||
|
||||
/**
|
||||
* Get items with permisison check
|
||||
*
|
||||
* @note We override in order to provide checking against album restrictions
|
||||
* @param array $where Where clause
|
||||
* @param string $order MySQL ORDER BY clause (NULL to order by date)
|
||||
* @param int|array $limit Limit clause
|
||||
* @param string $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index
|
||||
* @param bool|NULL $includeHiddenItems Include hidden files? Boolean or NULL to detect if currently logged member has permission
|
||||
* @param int $queryFlags Select bitwise flags
|
||||
* @param \IPS\Member $member The member (NULL to use currently logged in member)
|
||||
* @param bool $joinContainer If true, will join container data (set to TRUE if your $where clause depends on this data)
|
||||
* @param bool $joinComments If true, will join comment data (set to TRUE if your $where clause depends on this data)
|
||||
* @param bool $joinReviews If true, will join review data (set to TRUE if your $where clause depends on this data)
|
||||
* @return \IPS\Patterns\ActiveRecordIterator|int
|
||||
*/
|
||||
public static function getItemsWithPermission( $where=array(), $order=NULL, $limit=10, $permissionKey='read', $includeHiddenItems=NULL, $queryFlags=0, \IPS\Member $member=NULL, $joinContainer=FALSE, $joinComments=FALSE, $joinReviews=FALSE, $countOnly=FALSE, $joins=NULL )
|
||||
{
|
||||
$where[] = \IPS\gallery\Image::getItemsWithPermissionWhere( $where, $member, $joins );
|
||||
return parent::getItemsWithPermission( $where, $order, $limit, $permissionKey, $includeHiddenItems, $queryFlags, $member, $joinContainer, $joinComments, $joinReviews, $countOnly, $joins );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get URL for doing stuff
|
||||
*
|
||||
* @param string|NULL $action Action
|
||||
* @return \IPS\Http\Url
|
||||
*/
|
||||
public function url( $action=NULL )
|
||||
{
|
||||
return parent::url( $action )->setQueryString( 'tab', 'comments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Do stuff after creating (abstracted as comments and reviews need to do different things)
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function postCreate()
|
||||
{
|
||||
parent::postCreate();
|
||||
|
||||
$item = $this->item();
|
||||
|
||||
if( $item->album_id )
|
||||
{
|
||||
\IPS\gallery\Album::load( $item->album_id )->setLastComment();
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,122 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Custom table helper for gallery images to override move menu
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Social Suite
|
||||
* @subpackage Gallery
|
||||
* @since 04 Apr 2014
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\gallery\Image;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom table helper for gallery images to override move menu
|
||||
*/
|
||||
class _Table extends \IPS\Helpers\Table\Content
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param array $class Database table
|
||||
* @param \IPS\Http\Url $baseUrl Base URL
|
||||
* @param array|null $where WHERE clause (To restrict to a node, use $container instead)
|
||||
* @param \IPS\Node\Model|NULL $container The container
|
||||
* @param bool|null $includeHidden Flag to pass to getItemsWithPermission() method for $includeHiddenContent, defaults to NULL
|
||||
* @param string|NULL $permCheck Permission key to check
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $class, \IPS\Http\Url $baseUrl, $where=NULL, \IPS\Node\Model $container=NULL, $includeHidden=NULL, $permCheck='view', $honorPinned=TRUE )
|
||||
{
|
||||
/* Are we changing the thumbnail viewing size? */
|
||||
if( isset( \IPS\Request::i()->thumbnailSize ) )
|
||||
{
|
||||
\IPS\Session::i()->csrfCheck();
|
||||
|
||||
\IPS\Request::i()->setCookie( 'thumbnailSize', \IPS\Request::i()->thumbnailSize, \IPS\DateTime::ts( time() )->add( new \DateInterval( 'P1Y' ) ) );
|
||||
}
|
||||
|
||||
return parent::__construct( $class, $baseUrl, $where, $container, $includeHidden, $permCheck, $honorPinned );
|
||||
}
|
||||
|
||||
/**
|
||||
* Multimod
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function multimod()
|
||||
{
|
||||
$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( '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',
|
||||
'url' => \IPS\Request::i()->url()->setQueryString( 'modaction', 'move' ),
|
||||
'permissionCheck' => function( $node )
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
) ) );
|
||||
|
||||
if ( $values = $form->values() )
|
||||
{
|
||||
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');
|
||||
|
||||
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );
|
||||
return;
|
||||
}
|
||||
|
||||
$params[] = ( isset( $values['move_to_category'] ) AND $values['move_to_category'] ) ? $values['move_to_category'] : $values['move_to_album'];
|
||||
$params[] = FALSE;
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( array_keys( \IPS\Request::i()->moderate ) as $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$object = $class::loadAndCheckPerms( $id );
|
||||
$object->modAction( \IPS\Request::i()->modaction, \IPS\Member::loggedIn(), $params );
|
||||
}
|
||||
catch ( \Exception $e ) {}
|
||||
}
|
||||
|
||||
\IPS\Output::i()->redirect( $this->baseUrl );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
Whitespace-only changes.
Reference in new issue
Block a user