Version 5.0.0 beta 1

This commit is contained in:
Neo committed 2025-12-19 16:27:35 -08:00
1 parent 25ddeb65d6
commit 15c7beabc5
6736 files changed
+627902 -497943

No files matched your search

+67 -56
View File
@@ -11,116 +11,131 @@
namespace IPS\gallery;
use Exception;
use IPS\Application as SystemApplication;
use IPS\Content\Filter;
use IPS\DateTime;
use IPS\File;
use IPS\Http\Url;
use IPS\Login;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Settings;
use IPS\Theme;
use IPS\Xml\Rss;
use OutOfRangeException;
/**
* Gallery Application Class
*/
class _Application extends \IPS\Application
class Application extends SystemApplication
{
/**
* Init
*
* @return void
*/
public function init()
public function init(): void
{
/* Handle RSS requests */
if ( \IPS\Request::i()->module == 'gallery' and \IPS\Request::i()->controller == 'browse' and \IPS\Request::i()->do == 'rss' )
if ( Request::i()->module == 'gallery' and Request::i()->controller == 'browse' and Request::i()->do == 'rss' )
{
$member = NULL;
if( \IPS\Request::i()->member AND \IPS\Request::i()->key )
if( Request::i()->member AND Request::i()->key )
{
$member = \IPS\Member::load( \IPS\Request::i()->member );
if( !\IPS\Login::compareHashes( $member->getUniqueMemberHash(), (string) \IPS\Request::i()->key ) )
$member = Member::load( Request::i()->member );
if( !Login::compareHashes( $member->getUniqueMemberHash(), (string) Request::i()->key ) )
{
$member = NULL;
}
}
$this->sendGalleryRss( $member ?? new \IPS\Member );
$this->sendGalleryRss( $member ?? new Member );
if( !\IPS\Member::loggedIn()->group['g_view_board'] )
if( !Member::loggedIn()->group['g_view_board'] )
{
\IPS\Output::i()->error( 'node_error', '2G218/1', 404, '' );
Output::i()->error( 'node_error', '2G218/1', 404, '' );
}
}
if( \IPS\Member::loggedIn()->members_bitoptions['remove_gallery_access'] )
if( Member::loggedIn()->members_bitoptions['remove_gallery_access'] )
{
\IPS\Output::i()->error( 'node_error', '2G218/1', 404, '' );
Output::i()->error( 'node_error', '2G218/1', 404, '' );
}
}
/**
* Send the gallery RSS feed for the indicated member
*
* @param \IPS\Member $member Member
* @param Member $member Member
* @return void
* @note We use a template so that we can embed image directly into feed while still allowing it to be customized
*/
protected function sendGalleryRss( $member )
protected function sendGalleryRss( Member $member ) : void
{
if( !\IPS\Settings::i()->gallery_rss_enabled )
if( !Settings::i()->gallery_rss_enabled )
{
\IPS\Output::i()->error( 'gallery_rss_offline', '2G189/3', 403, 'gallery_rss_offline_admin' );
Output::i()->error( 'gallery_rss_offline', '2G189/3', 403, 'gallery_rss_offline_admin' );
}
$where = array();
if( isset( \IPS\Request::i()->category ) )
if( isset( Request::i()->category ) )
{
try
{
$category = \IPS\gallery\Category::load( \IPS\Request::i()->category );
$category = Category::load( Request::i()->category );
if( !$category->can( 'read', $member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$where[] = array( 'image_category_id=?', $category->id );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/8', 404, '' );
Output::i()->error( 'node_error', '2G189/8', 404, '' );
}
}
else if ( isset( \IPS\Request::i()->album ) )
else if ( isset( Request::i()->album ) )
{
try
{
$album = \IPS\gallery\Album::load( \IPS\Request::i()->album );
$album = Album::load( Request::i()->album );
if( !$album->can( 'read', $member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$where[] = array( 'image_album_id=?', $album->id );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/9', 404, '' );
Output::i()->error( 'node_error', '2G189/9', 404, '' );
}
}
$document = \IPS\Xml\Rss::newDocument( isset( $category ) ? $category->url() : ( isset( $album ) ? $album->url() : \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ) ), $member->language()->get('gallery_rss_title'), $member->language()->get('gallery_rss_title') );
$document = Rss::newDocument( isset( $category ) ? $category->url() : ( isset( $album ) ? $album->url() : Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ) ), $member->language()->get('gallery_rss_title'), $member->language()->get('gallery_rss_title') );
foreach ( \IPS\gallery\Image::getItemsWithPermission( $where, NULL, 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, $member ) as $image )
foreach (Image::getItemsWithPermission( $where, NULL, 10, 'read', Filter::FILTER_AUTOMATIC, 0, $member ) as $image )
{
$document->addItem( $image->caption, $image->url(), \IPS\Theme::i()->getTemplate( 'view' )->rssContent( $image ), \IPS\DateTime::ts( $image->updated ), $image->id );
$document->addItem( $image->caption, $image->url(), Theme::i()->getTemplate( 'view' )->rssContent( $image ), DateTime::ts( $image->updated ), $image->id );
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
Output::i()->sendOutput( $document->asXML(), 200, 'text/xml', array(), TRUE );
}
/**
* [Node] Get Icon for tree
*
* @note Return the class for the icon (e.g. 'globe')
* @return string|null
* @note Return the class for the icon (e.g. 'globe')
* @return string
*/
protected function get__icon()
protected function get__icon(): string
{
return 'camera';
}
@@ -148,7 +163,7 @@ class _Application extends \IPS\Application
* @endcode
* @return array
*/
public function defaultFrontNavigation()
public function defaultFrontNavigation(): array
{
return array(
'rootTabs' => array(),
@@ -163,50 +178,50 @@ class _Application extends \IPS\Application
*
* @return void
*/
public function convertLegacyParameters()
public function convertLegacyParameters() : void
{
/* convert ?module=images&section=img_ctrl&img=100&file=medium */
/* convert ?module=images&section=img_ctrl&id=100&file=medium */
if( isset( \IPS\Request::i()->section ) AND \IPS\Request::i()->section == 'img_ctrl' )
if( isset( Request::i()->section ) AND Request::i()->section == 'img_ctrl' )
{
$id = ( isset( \IPS\Request::i()->img ) ) ? \IPS\Request::i()->img : \IPS\Request::i()->id;
$id = ( isset( Request::i()->img ) ) ? Request::i()->img : Request::i()->id;
if( $id )
{
if( \IPS\Request::i()->file == 'med' )
if( Request::i()->file == 'med' )
{
\IPS\Request::i()->file = 'medium';
Request::i()->file = 'medium';
}
$imageSize = ( ( \IPS\Request::i()->file == 'small' ) ? 'small' : 'masked' ) . '_file_name';
$imageSize = ( ( Request::i()->file == 'small' ) ? 'small' : 'masked' ) . '_file_name';
try
{
\IPS\Output::i()->redirect( (string) \IPS\File::get( 'gallery_Images', \IPS\gallery\Image::load( $id )->$imageSize )->url );
Output::i()->redirect( (string) File::get( 'gallery_Images', Image::load( $id )->$imageSize )->url );
}
catch ( \Exception $e ){}
catch ( Exception ){}
}
}
/* convert ?app=gallery&module=images&section=viewimage&img=14586 */
if( isset( \IPS\Request::i()->section ) AND \IPS\Request::i()->section == 'viewimage' )
if( isset( Request::i()->section ) AND Request::i()->section == 'viewimage' )
{
$id = ( isset( \IPS\Request::i()->img ) ) ? \IPS\Request::i()->img : \IPS\Request::i()->id;
$id = ( isset( Request::i()->img ) ) ? Request::i()->img : Request::i()->id;
if( $id )
{
if( \IPS\Request::i()->file == 'med' )
if( Request::i()->file == 'med' )
{
\IPS\Request::i()->file = 'medium';
Request::i()->file = 'medium';
}
$imageSize = ( ( \IPS\Request::i()->file == 'small' ) ? 'small' : 'masked' ) . '_file_name';
$imageSize = ( ( Request::i()->file == 'small' ) ? 'small' : 'masked' ) . '_file_name';
try
{
\IPS\Output::i()->redirect( \IPS\gallery\Image::load( $id )->url() );
Output::i()->redirect( Image::load( $id )->url() );
}
catch ( \Exception $e ){}
catch ( Exception ){}
}
}
}
@@ -216,13 +231,9 @@ class _Application extends \IPS\Application
*
* @return void
*/
public static function outputCss()
public static function outputCss() : void
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'gallery.css', 'gallery' ), \IPS\Theme::i()->css( 'global.css', 'gallery' ) );
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' ) );
}
Output::i()->cssFiles = array_merge( Output::i()->cssFiles, Theme::i()->css( 'gallery.css', 'gallery' ) );
}
/**
@@ -230,7 +241,7 @@ class _Application extends \IPS\Application
*
* @return array
*/
public function uploadSettings()
public function uploadSettings(): array
{
/* Apps can overload this */
return array( 'gallery_watermark_path' );
@@ -244,7 +255,7 @@ class _Application extends \IPS\Application
public function getWebhooks() : array
{
return array_merge( [
'galleryAlbum_create' => \IPS\gallery\Album::class
'galleryAlbum_create' => Album::class
],parent::getWebhooks());
}
@@ -10,20 +10,19 @@
*/
namespace IPS\gallery\api\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\Types;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Gallery mutations GraphQL API
*/
abstract class _Mutation
abstract class Mutation
{
/**
* Get the supported query types in this app
@@ -10,25 +10,29 @@
*/
namespace IPS\gallery\api\GraphQL\Queries;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\SafeException;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\gallery\api\GraphQL\Types\ImageType;
use IPS\gallery\Image as ImageClass;
use OutOfRangeException;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Image query for GraphQL API
*/
class _Image
class Image
{
/*
* @brief Query description
*/
public static $description = "Returns a gallery image";
public static string $description = "Returns a gallery image";
/*
* Query arguments
@@ -43,7 +47,7 @@ class _Image
/**
* Return the query return type
*/
public function type()
public function type() : ImageType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::image();
}
@@ -51,25 +55,26 @@ class _Image
/**
* Resolves this query
*
* @param mixed Value passed into this resolver
* @param array Arguments
* @param array Context values
* @return \IPS\gallery\Image
* @param mixed $val
* @param array $args
* @param array $context
* @param array $info
* @return ImageClass
*/
public function resolve($val, $args, $context, $info)
public function resolve( mixed $val, array $args, array $context, array $info ) : ImageClass
{
try
{
$image = \IPS\gallery\Image::loadAndCheckPerms( $args['id'] );
$image = ImageClass::loadAndCheckPerms( $args['id'] );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
throw new \IPS\Api\GraphQL\SafeException( 'NO_IMAGE', '1F294/2', 400 );
throw new SafeException( 'NO_IMAGE', '1F294/2', 400 );
}
if( !$image->can('read') )
{
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_ID', '2F294/9', 403 );
throw new SafeException( 'INVALID_ID', '2F294/9', 403 );
}
return $image;
+7 -7
View File
@@ -10,30 +10,30 @@
*/
namespace IPS\gallery\api\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\Types;
use IPS\gallery\api\GraphQL\Queries\Image;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Forums queries for GraphQL API
*/
abstract class _Query
abstract class Query
{
/**
* Get the supported query types in this app
*
* @return array
*/
public static function queries()
public static function queries() : array
{
return [
'image' => new \IPS\gallery\api\GraphQL\Queries\Image(),
'image' => new Image(),
];
}
}
@@ -10,13 +10,17 @@
*/
namespace IPS\gallery\api\GraphQL;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\Types;
use IPS\gallery\api\GraphQL\Types\AlbumCommentType;
use IPS\gallery\api\GraphQL\Types\AlbumItemType;
use IPS\gallery\api\GraphQL\Types\AlbumType;
use IPS\gallery\api\GraphQL\Types\ImageCommentType;
use IPS\gallery\api\GraphQL\Types\ImageType;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
@@ -25,42 +29,42 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
* so we'll generate singletons here.
* @todo automate this somehow?
*/
class _TypeRegistry
class TypeRegistry
{
/**
* Returns the album instance
*
* @var \IPS\gallery\api\GraphQL\Types\AlbumType
* @var AlbumType|null
*/
protected static $album;
protected static ?AlbumType $album = null;
/**
* Returns the album comment instance
*
* @var \IPS\gallery\api\GraphQL\Types\AlbumCommentType
* @var AlbumCommentType|null
*/
protected static $albumComment;
protected static ?AlbumCommentType $albumComment = null;
/**
* Returns the album item instance
*
* @var \IPS\gallery\api\GraphQL\Types\AlbumItemType
* @var AlbumItemType|null
*/
protected static $albumItem;
protected static ?AlbumItemType $albumItem = null;
/**
* Returns the image instance
*
* @var \IPS\gallery\api\GraphQL\Types\ImageType
* @var ImageType|null
*/
protected static $image;
protected static ?ImageType $image = null;
/**
* Returns the Image comment instance
*
* @var \IPS\gallery\api\GraphQL\Types\ImageCommentType
* @var ImageCommentType|null
*/
protected static $imageComment;
protected static ?ImageCommentType $imageComment = null;
/**
* Constructor
@@ -71,42 +75,42 @@ class _TypeRegistry
}
/**
* @return ImageType
* @return AlbumType
*/
public static function album() : \IPS\gallery\api\GraphQL\Types\AlbumType
public static function album() : AlbumType
{
return self::$album ?: (self::$album = new \IPS\gallery\api\GraphQL\Types\AlbumType());
return self::$album ?: (self::$album = new AlbumType());
}
/**
* @return AlbumCommentType
*/
public static function albumComment() : \IPS\gallery\api\GraphQL\Types\AlbumCommentType
public static function albumComment() : AlbumCommentType
{
return self::$albumComment ?: (self::$albumComment = new \IPS\gallery\api\GraphQL\Types\AlbumCommentType());
return self::$albumComment ?: (self::$albumComment = new AlbumCommentType());
}
/**
* @return AlbumCommentType
* @return AlbumItemType
*/
public static function albumItem() : \IPS\gallery\api\GraphQL\Types\AlbumItemType
public static function albumItem() : AlbumItemType
{
return self::$albumItem ?: (self::$albumItem = new \IPS\gallery\api\GraphQL\Types\AlbumItemType());
return self::$albumItem ?: (self::$albumItem = new AlbumItemType());
}
/**
* @return ImageType
*/
public static function image() : \IPS\gallery\api\GraphQL\Types\ImageType
public static function image() : ImageType
{
return self::$image ?: (self::$image = new \IPS\gallery\api\GraphQL\Types\ImageType());
return self::$image ?: (self::$image = new ImageType());
}
/**
* @return ImageCommentType
*/
public static function imageComment() : \IPS\gallery\api\GraphQL\Types\ImageCommentType
public static function imageComment() : ImageCommentType
{
return self::$imageComment ?: (self::$imageComment = new \IPS\gallery\api\GraphQL\Types\ImageCommentType());
return self::$imageComment ?: (self::$imageComment = new ImageCommentType());
}
}
@@ -11,53 +11,44 @@
namespace IPS\gallery\api\GraphQL\Types;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\Content\Api\GraphQL\CommentType;
use IPS\gallery\api\GraphQL\TypeRegistry;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AlbumCommentType for GraphQL API
*/
class _AlbumCommentType extends \IPS\Content\Api\GraphQL\CommentType
class AlbumCommentType extends CommentType
{
/*
* @brief The item classname we use for this type
*/
protected static $commentClass = '\IPS\gallery\Album\Comment';
protected static string $commentClass = '\IPS\gallery\Album\Comment';
/*
* @brief GraphQL type name
*/
protected static $typeName = 'gallery_AlbumComment';
protected static string $typeName = 'gallery_AlbumComment';
/*
* @brief GraphQL type description
*/
protected static $typeDescription = 'An album comment';
protected static string $typeDescription = 'An album comment';
/**
* Get the item type that goes with this item type
*
* @return ObjectType
*/
public static function getItemType()
public static function getItemType(): ObjectType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::album();
}
/**
* Return the fields available in this type
*
* @return array
*/
public function fields()
{
$defaultFields = parent::fields();
return $defaultFields;
return TypeRegistry::album();
}
}
@@ -11,46 +11,48 @@
namespace IPS\gallery\api\GraphQL\Types;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\Content\Api\GraphQL\ItemType;
use IPS\gallery\api\GraphQL\TypeRegistry;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AlbumItemType for GraphQL API
*/
class _AlbumItemType extends \IPS\Content\Api\GraphQL\ItemType
class AlbumItemType extends ItemType
{
/*
* @brief The item classname we use for this type
*/
protected static $itemClass = '\IPS\gallery\Album\Item';
protected static string $itemClass = '\IPS\gallery\Album\Item';
/*
* @brief GraphQL type name
*/
protected static $typeName = 'gallery_AlbumItem';
protected static string $typeName = 'gallery_AlbumItem';
/*
* @brief GraphQL type description
*/
protected static $typeDescription = 'An album';
protected static string $typeDescription = 'An album';
/*
* @brief Follow data passed in to FollowType resolver
*/
protected static $followData = array('app' => 'gallery', 'area' => 'album');
protected static array $followData = array('app' => 'gallery', 'area' => 'album');
/**
* Return the fields available in this type
*
* @return array
*/
public function fields()
public function fields(): array
{
// Extend our fields with image-specific stuff
$defaultFields = parent::fields();
@@ -68,8 +70,8 @@ class _AlbumItemType extends \IPS\Content\Api\GraphQL\ItemType
*
* @return ObjectType
*/
protected static function getCommentType()
protected static function getCommentType(): ObjectType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::albumComment();
return TypeRegistry::albumComment();
}
}
@@ -12,45 +12,47 @@
namespace IPS\gallery\api\GraphQL\Types;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\Node\Api\GraphQL\NodeType;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* AlbumType for GraphQL API
*/
class _AlbumType extends \IPS\Node\Api\GraphQL\NodeType
class AlbumType extends NodeType
{
/*
* @brief The item classname we use for this type
*/
protected static $nodeClass = '\IPS\gallery\Album';
protected static string $nodeClass = '\IPS\gallery\Album';
/*
* @brief GraphQL type name
*/
protected static $typeName = 'gallery_Album';
protected static string $typeName = 'gallery_Album';
/*
* @brief GraphQL type description
*/
protected static $typeDescription = 'An album';
protected static string $typeDescription = 'An album';
/*
* @brief Follow data passed in to FollowType resolver
*/
protected static $followData = array('app' => 'gallery', 'area' => 'album');
protected static array $followData = array('app' => 'gallery', 'area' => 'album');
/**
* Return the fields available in this type
*
* @return array
*/
public function fields()
public function fields(): array
{
$defaultFields = parent::fields();
$albumFields = array(
@@ -91,7 +93,7 @@ class _AlbumType extends \IPS\Node\Api\GraphQL\NodeType
*
* @return ObjectType
*/
public static function getItemType()
public static function getItemType(): ObjectType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::image();
}
@@ -11,53 +11,44 @@
namespace IPS\gallery\api\GraphQL\Types;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\Content\Api\GraphQL\CommentType;
use IPS\gallery\api\GraphQL\TypeRegistry;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* ImageCommentType for GraphQL API
*/
class _ImageCommentType extends \IPS\Content\Api\GraphQL\CommentType
class ImageCommentType extends CommentType
{
/*
* @brief The item classname we use for this type
*/
protected static $commentClass = '\IPS\gallery\Image\Comment';
protected static string $commentClass = '\IPS\gallery\Image\Comment';
/*
* @brief GraphQL type name
*/
protected static $typeName = 'gallery_ImageComment';
protected static string $typeName = 'gallery_ImageComment';
/*
* @brief GraphQL type description
*/
protected static $typeDescription = 'An image comment';
protected static string $typeDescription = 'An image comment';
/**
* Get the item type that goes with this item type
*
* @return ObjectType
*/
public static function getItemType()
public static function getItemType(): ObjectType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::image();
}
/**
* Return the fields available in this type
*
* @return array
*/
public function fields()
{
$defaultFields = parent::fields();
return $defaultFields;
return TypeRegistry::image();
}
}
@@ -12,45 +12,50 @@
namespace IPS\gallery\api\GraphQL\Types;
use GraphQL\Type\Definition\ObjectType;
use IPS\Api\GraphQL\TypeRegistry;
use IPS\Content\Api\GraphQL\ItemType;
use IPS\File;
use IPS\gallery\Album;
use IPS\GeoLocation;
use function defined;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* ImageType for GraphQL API
*/
class _ImageType extends \IPS\Content\Api\GraphQL\ItemType
class ImageType extends ItemType
{
/*
* @brief The item classname we use for this type
*/
protected static $itemClass = '\IPS\gallery\Image';
protected static string $itemClass = '\IPS\gallery\Image';
/*
* @brief GraphQL type name
*/
protected static $typeName = 'gallery_Image';
protected static string $typeName = 'gallery_Image';
/*
* @brief GraphQL type description
*/
protected static $typeDescription = 'An image';
protected static string $typeDescription = 'An image';
/*
* @brief Follow data passed in to FollowType resolver
*/
protected static $followData = array('app' => 'gallery', 'area' => 'image');
protected static array $followData = array('app' => 'gallery', 'area' => 'image');
/**
* Return the fields available in this type
*
* @return array
*/
public function fields()
public function fields(): array
{
// Extend our fields with image-specific stuff
$defaultFields = parent::fields();
@@ -72,7 +77,7 @@ class _ImageType extends \IPS\Content\Api\GraphQL\ItemType
'resolve' => function ($image) {
if( $image->album_id )
{
return \IPS\gallery\Album::load( $image->album_id );
return Album::load( $image->album_id );
}
return NULL;
@@ -111,19 +116,19 @@ class _ImageType extends \IPS\Content\Api\GraphQL\ItemType
'maskedFileName' => [
'type' => TypeRegistry::string(),
'resolve' => function ($image) {
return (string) \IPS\File::get( 'gallery_Images', $image->masked_file_name )->url;
return (string) File::get( 'gallery_Images', $image->masked_file_name )->url;
}
],
'originalFileName' => [
'type' => TypeRegistry::string(),
'resolve' => function ($image) {
return (string) \IPS\File::get( 'gallery_Images', $image->original_file_name )->url;
return (string) File::get( 'gallery_Images', $image->original_file_name )->url;
}
],
'smallFileName' => [
'type' => TypeRegistry::string(),
'resolve' => function ($image) {
return (string) \IPS\File::get( 'gallery_Images', $image->small_file_name )->url;
return (string) File::get( 'gallery_Images', $image->small_file_name )->url;
}
],
'fileSize' => [
@@ -133,11 +138,11 @@ class _ImageType extends \IPS\Content\Api\GraphQL\ItemType
}
],
'location' => [
'type' => \IPS\GeoLocation\Api\GraphQL\TypeRegistry::geolocation(),
'type' => GeoLocation\Api\GraphQL\TypeRegistry::geolocation(),
'resolve' => function ($image) {
if( $image->gps_raw )
{
return \IPS\GeoLocation::buildFromJson( $image->gps_raw );
return GeoLocation::buildFromJson( $image->gps_raw );
}
return NULL;
@@ -197,7 +202,7 @@ class _ImageType extends \IPS\Content\Api\GraphQL\ItemType
*
* @return ObjectType
*/
protected static function getCommentType()
protected static function getCommentType(): ObjectType
{
return \IPS\gallery\api\GraphQL\TypeRegistry::imageComment();
}
+45 -30
View File
@@ -12,16 +12,29 @@
namespace IPS\gallery\api;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Api\Controller;
use IPS\Api\Exception;
use IPS\Api\PaginatedResponse;
use IPS\Api\Response;
use IPS\Db;
use IPS\gallery\Album;
use IPS\gallery\Album\Item;
use IPS\Request;
use OutOfRangeException;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Gallery Albums API
*/
class _albums extends \IPS\Api\Controller
class albums extends Controller
{
/**
* GET /gallery/albums
@@ -34,75 +47,76 @@ class _albums extends \IPS\Api\Controller
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Album>
* @apireturn PaginatedResponse<IPS\gallery\Album>
* @return PaginatedResponse<Album>
*/
public function GETindex()
public function GETindex(): PaginatedResponse
{
/* Where clause */
$where = array();
/* Categories */
if ( isset( \IPS\Request::i()->categories ) )
if ( isset( Request::i()->categories ) )
{
$where[] = array( \IPS\Db::i()->in( 'album_category_id', array_filter( explode( ',', \IPS\Request::i()->categories ) ) ) );
$where[] = array( Db::i()->in( 'album_category_id', array_filter( explode( ',', Request::i()->categories ) ) ) );
}
/* Owners */
if ( isset( \IPS\Request::i()->owners ) )
if ( isset( Request::i()->owners ) )
{
$where[] = array( \IPS\Db::i()->in( 'album_owner_id', array_filter( explode( ',', \IPS\Request::i()->owners ) ) ) );
$where[] = array( Db::i()->in( 'album_owner_id', array_filter( explode( ',', Request::i()->owners ) ) ) );
}
/* Privacy */
if ( isset( \IPS\Request::i()->privacy ) )
if ( isset( Request::i()->privacy ) )
{
$privacy = array();
foreach ( array_filter( explode( ',', \IPS\Request::i()->privacy ) ) as $type )
foreach ( array_filter( explode( ',', Request::i()->privacy ) ) as $type )
{
switch ( $type )
{
case 'public':
$privacy[] = \IPS\gallery\Album::AUTH_TYPE_PUBLIC;
$privacy[] = Album::AUTH_TYPE_PUBLIC;
break;
case 'private':
$privacy[] = \IPS\gallery\Album::AUTH_TYPE_PRIVATE;
$privacy[] = Album::AUTH_TYPE_PRIVATE;
break;
case 'restricted':
$privacy[] = \IPS\gallery\Album::AUTH_TYPE_RESTRICTED;
$privacy[] = Album::AUTH_TYPE_RESTRICTED;
break;
}
}
$where[] = array( \IPS\Db::i()->in( 'album_type', $privacy ) );
$where[] = array( Db::i()->in( 'album_type', $privacy ) );
}
/* Sort */
if ( isset( \IPS\Request::i()->sortBy ) and \in_array( \IPS\Request::i()->sortBy, array( 'name', 'count_images' ) ) )
if ( isset( Request::i()->sortBy ) and in_array( Request::i()->sortBy, array( 'name', 'count_images' ) ) )
{
$sortBy = 'album_' . \IPS\Request::i()->sortBy;
$sortBy = 'album_' . Request::i()->sortBy;
}
else
{
$sortBy = 'album_id';
}
$sortDir = ( isset( \IPS\Request::i()->sortDir ) and \in_array( mb_strtolower( \IPS\Request::i()->sortDir ), array( 'asc', 'desc' ) ) ) ? \IPS\Request::i()->sortDir : 'asc';
$sortDir = ( isset( Request::i()->sortDir ) and in_array( mb_strtolower( Request::i()->sortDir ), array( 'asc', 'desc' ) ) ) ? Request::i()->sortDir : 'asc';
/* Get results */
if ( $this->member )
{
$joins = array();
$where[] = \IPS\gallery\Album\Item::getItemsWithPermissionWhere( $where, $this->member, $joins );
$where[] = Item::getItemsWithPermissionWhere( $where, $this->member, $joins );
}
/* Return */
return new \IPS\Api\PaginatedResponse(
return new PaginatedResponse(
200,
\IPS\Db::i()->select( '*', 'gallery_albums', $where, "{$sortBy} {$sortDir}" ),
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
Db::i()->select( '*', 'gallery_albums', $where, "{$sortBy} {$sortDir}" ),
isset( Request::i()->page ) ? Request::i()->page : 1,
'IPS\gallery\Album',
\IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', $where )->first(),
Db::i()->select( 'COUNT(*)', 'gallery_albums', $where )->first(),
$this->member,
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
isset( Request::i()->perPage ) ? Request::i()->perPage : NULL
);
}
@@ -112,18 +126,19 @@ class _albums extends \IPS\Api\Controller
*
* @param int $id ID Number
* @throws 2G315/1 INVALID_ID The album ID does not exist or the authorized user does not have permisison to view it
* @return \IPS\gallery\Album
* @apireturn \IPS\gallery\Album
* @return Response
*/
public function GETitem( $id )
public function GETitem( int $id ): Response
{
try
{
$album = $this->member ? \IPS\gallery\Album::loadAndCheckPerms( $id, 'view', $this->member ) : \IPS\gallery\Album::load( $id );
return new \IPS\Api\Response( 200, $album->apiOutput( $this->member ) );
$album = $this->member ? Album::loadAndCheckPerms( $id, 'view', $this->member ) : Album::load( $id );
return new Response( 200, $album->apiOutput( $this->member ) );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G315/1', 404 );
throw new Exception( 'INVALID_ID', '2G315/1', 404 );
}
}
}
+28 -16
View File
@@ -12,22 +12,32 @@
namespace IPS\gallery\api;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Api\PaginatedResponse;
use IPS\Api\Response;
use IPS\Db;
use IPS\gallery\Category;
use IPS\Node\Api\NodeController;
use IPS\Request;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Gallery Categories API
*/
class _categories extends \IPS\Node\Api\NodeController
class categories extends NodeController
{
/**
* Class
*/
protected $class = 'IPS\gallery\Category';
protected string $class = 'IPS\gallery\Category';
/**
* GET /gallery/categories
@@ -37,33 +47,34 @@ class _categories extends \IPS\Node\Api\NodeController
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @return \IPS\Api\PaginatedResponse<IPS\blog\Entry>
* @apireturn PaginatedResponse<IPS\gallery\Category>
* @return PaginatedResponse<Category>
*/
public function GETindex()
public function GETindex(): PaginatedResponse
{
/* Where clause */
$where = array();
/* Sort */
if ( isset( \IPS\Request::i()->sortBy ) and \in_array( \IPS\Request::i()->sortBy, array( 'count_imgs', 'last_img_date' ) ) )
if ( isset( Request::i()->sortBy ) and in_array( Request::i()->sortBy, array( 'count_imgs', 'last_img_date' ) ) )
{
$sortBy = 'category_' . \IPS\Request::i()->sortBy;
$sortBy = 'category_' . Request::i()->sortBy;
}
else
{
$sortBy = 'category_id';
}
$sortDir = ( isset( \IPS\Request::i()->sortDir ) and \in_array( mb_strtolower( \IPS\Request::i()->sortDir ), array( 'asc', 'desc' ) ) ) ? \IPS\Request::i()->sortDir : 'asc';
$sortDir = ( isset( Request::i()->sortDir ) and in_array( mb_strtolower( Request::i()->sortDir ), array( 'asc', 'desc' ) ) ) ? Request::i()->sortDir : 'asc';
/* Return */
return new \IPS\Api\PaginatedResponse(
return new PaginatedResponse(
200,
\IPS\Db::i()->select( '*', 'gallery_categories', $where, "{$sortBy} {$sortDir}" ),
isset( \IPS\Request::i()->page ) ? \IPS\Request::i()->page : 1,
Db::i()->select( '*', 'gallery_categories', $where, "{$sortBy} {$sortDir}" ),
isset( Request::i()->page ) ? Request::i()->page : 1,
'IPS\gallery\Category',
\IPS\Db::i()->select( 'COUNT(*)', 'gallery_categories', $where )->first(),
Db::i()->select( 'COUNT(*)', 'gallery_categories', $where )->first(),
$this->member,
isset( \IPS\Request::i()->perPage ) ? \IPS\Request::i()->perPage : NULL
isset( Request::i()->perPage ) ? Request::i()->perPage : NULL
);
}
@@ -72,9 +83,10 @@ class _categories extends \IPS\Node\Api\NodeController
* Get information about a specific gallery category
*
* @param int $id ID Number
* @return \IPS\blog\Blog
* @apireturn \IPS\gallery\Category
* @return Response
*/
public function GETitem( $id )
public function GETitem( int $id ): Response
{
return $this->_view( $id );
}
+75 -51
View File
@@ -12,21 +12,35 @@
namespace IPS\gallery\api;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Api\Exception;
use IPS\Api\PaginatedResponse;
use IPS\Api\Response;
use IPS\Content\Api\CommentController;
use IPS\Db;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\Member;
use IPS\Request;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Gallery Comments API
*/
class _comments extends \IPS\Content\Api\CommentController
class comments extends CommentController
{
/**
* Class
*/
protected $class = 'IPS\gallery\Image\Comment';
protected string $class = 'IPS\gallery\Image\Comment';
/**
* GET /gallery/comments
@@ -43,20 +57,21 @@ class _comments extends \IPS\Content\Api\CommentController
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Image\Comment>
* @apireturn PaginatedResponse<IPS\gallery\Image\Comment>
* @return PaginatedResponse<Comment>
*/
public function GETindex()
public function GETindex(): PaginatedResponse
{
/* Where clause */
$where = array();
/* Albums */
if ( isset( \IPS\Request::i()->albums ) )
if ( isset( Request::i()->albums ) )
{
$where[] = array( \IPS\Db::i()->in( 'image_album_id', array_filter( explode( ',', \IPS\Request::i()->albums ) ) ) );
$where[] = array( Db::i()->in( 'image_album_id', array_filter( explode( ',', Request::i()->albums ) ) ) );
}
return $this->_list( $where, 'categories' );
return $this->_list( $where );
}
/**
@@ -65,12 +80,14 @@ class _comments extends \IPS\Content\Api\CommentController
*
* @param int $id ID Number
* @throws 2L297/1 INVALID_ID The comment ID does not exist or the authorized user does not have permission to view it
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @return Response
*/
public function GETitem( $id )
public function GETitem( int $id ): Response
{
try
{
/* @var Comment $class */
$class = $this->class;
if ( $this->member )
{
@@ -81,11 +98,11 @@ class _comments extends \IPS\Content\Api\CommentController
$object = $class::load( $id );
}
return new \IPS\Api\Response( 200, $object->apiOutput( $this->member ) );
return new Response( 200, $object->apiOutput( $this->member ) );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G317/1', 404 );
throw new Exception( 'INVALID_ID', '2G317/1', 404 );
}
}
@@ -106,18 +123,19 @@ class _comments extends \IPS\Content\Api\CommentController
* @throws 1G317/4 NO_AUTHOR The author ID does not exist
* @throws 1G317/5 NO_CONTENT No content was supplied
* @throws 2G317/9 NO_PERMISSION The authorized user does not have permission to comment on that image
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @return Response
*/
public function POSTindex()
public function POSTindex(): Response
{
/* Get image */
try
{
$image = \IPS\gallery\Image::load( \IPS\Request::i()->image );
$image = Image::load( Request::i()->image );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2L297/3', 403 );
throw new Exception( 'INVALID_ID', '2L297/3', 403 );
}
/* Get author */
@@ -125,38 +143,38 @@ class _comments extends \IPS\Content\Api\CommentController
{
if ( !$image->canComment( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G317/9', 403 );
throw new Exception( 'NO_PERMISSION', '2G317/9', 403 );
}
$author = $this->member;
}
else
{
if ( \IPS\Request::i()->author )
if ( Request::i()->author )
{
$author = \IPS\Member::load( \IPS\Request::i()->author );
$author = Member::load( Request::i()->author );
if ( !$author->member_id )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G317/4', 404 );
throw new Exception( 'NO_AUTHOR', '1G317/4', 404 );
}
}
else
{
if ( \IPS\Request::i()->author === 0 )
if ( Request::i()->author === 0 )
{
$author = new \IPS\Member;
$author->name = \IPS\Request::i()->author_name;
$author = new Member;
$author->name = Request::i()->author_name;
}
else
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G317/4', 400 );
throw new Exception( 'NO_AUTHOR', '1G317/4', 400 );
}
}
}
/* Check we have a post */
if ( !\IPS\Request::i()->content )
if ( !Request::i()->content )
{
throw new \IPS\Api\Exception( 'NO_CONTENT', '1G317/5', 403 );
throw new Exception( 'NO_CONTENT', '1G317/5', 403 );
}
/* Do it */
@@ -177,21 +195,22 @@ class _comments extends \IPS\Content\Api\CommentController
* @throws 2G317/6 INVALID_ID The comment ID does not exist or the authorized user does not have permission to view it
* @throws 1G317/7 NO_AUTHOR The author ID does not exist
* @throws 2G317/A NO_PERMISSION The authorized user does not have permission to edit the comment
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @return Response
*/
public function POSTitem( $id )
public function POSTitem( int $id ):Response
{
try
{
/* Load */
$comment = \IPS\gallery\Image\Comment::load( $id );
$comment = Comment::load( $id );
if ( $this->member and !$comment->canView( $this->member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
if ( $this->member and !$comment->canEdit( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G317/A', 403 );
throw new Exception( 'NO_PERMISSION', '2G317/A', 403 );
}
/* Do it */
@@ -199,14 +218,14 @@ class _comments extends \IPS\Content\Api\CommentController
{
return $this->_edit( $comment );
}
catch ( \InvalidArgumentException $e )
catch ( InvalidArgumentException $e )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G317/7', 400 );
throw new Exception( 'NO_AUTHOR', '1G317/7', 400 );
}
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G317/6', 404 );
throw new Exception( 'INVALID_ID', '2G317/6', 404 );
}
}
@@ -217,25 +236,27 @@ class _comments extends \IPS\Content\Api\CommentController
* @param int $id ID Number
* @throws 2G317/8 INVALID_ID The comment ID does not exist
* @throws 2G317/B NO_PERMISSION The authorized user does not have permission to delete the comment
* @return void
* @apireturn void
* @return Response
*/
public function DELETEitem( $id )
public function DELETEitem( int $id ): Response
{
try
{
{
/* @var Comment $class */
$class = $this->class;
$object = $class::load( $id );
if ( $this->member and !$object->canDelete( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G317/B', 403 );
throw new Exception( 'NO_PERMISSION', '2G317/B', 403 );
}
$object->delete();
return new \IPS\Api\Response( 200, NULL );
return new Response( 200, NULL );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G317/8', 404 );
throw new Exception( 'INVALID_ID', '2G317/8', 404 );
}
}
@@ -246,14 +267,15 @@ class _comments extends \IPS\Content\Api\CommentController
* @param int $id ID Number
* @apiparam int id ID of the reaction to add
* @apiparam int author ID of the member reacting
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @throws 1S425/2 NO_REACTION The reaction ID does not exist
* @throws 1S425/3 NO_AUTHOR The author ID does not exist
* @throws 1S425/4 REACT_ERROR Error adding the reaction
* @throws 1S425/5 INVALID_ID Object ID does not exist
* @note If the author has already reacted to this content, any existing reaction will be removed first
* @return Response
*/
public function POSTitem_react( $id )
public function POSTitem_react( int $id ): Response
{
return $this->_reactAdd( $id );
}
@@ -264,13 +286,14 @@ class _comments extends \IPS\Content\Api\CommentController
*
* @param int $id ID Number
* @apiparam int author ID of the member who reacted
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @throws 1S425/6 NO_AUTHOR The author ID does not exist
* @throws 1S425/7 REACT_ERROR Error adding the reaction
* @throws 1S425/8 INVALID_ID Object ID does not exist
* @note If the author has already reacted to this content, any existing reaction will be removed first
* @return Response
*/
public function DELETEitem_react( $id )
public function DELETEitem_react( int $id ): Response
{
return $this->_reactRemove( $id );
}
@@ -285,9 +308,10 @@ class _comments extends \IPS\Content\Api\CommentController
* @apiparam string message Optional message
* @throws 1S425/B NO_AUTHOR The author ID does not exist
* @throws 1S425/C REPORTED_ALREADY The member has reported this item in the past 24 hours
* @return \IPS\gallery\Image\Comment
* @apireturn \IPS\gallery\Image\Comment
* @return Response
*/
public function POSTitem_report( $id )
public function POSTitem_report( int $id ): Response
{
return $this->_report( $id );
}
+125 -100
View File
@@ -12,21 +12,42 @@
namespace IPS\gallery\api;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Api\Exception;
use IPS\Api\PaginatedResponse;
use IPS\Api\Response;
use IPS\Content\Api\ItemController;
use IPS\Content\Item;
use IPS\Db;
use IPS\File;
use IPS\gallery\Album;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\gallery\Image\Review;
use IPS\Member;
use IPS\Request;
use IPS\Text\Parser;
use OutOfRangeException;
use function count;
use function defined;
use function strlen;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Gallery Images API
*/
class _images extends \IPS\Content\Api\ItemController
class images extends ItemController
{
/**
* Class
*/
protected $class = 'IPS\gallery\Image';
protected string $class = 'IPS\gallery\Image';
/**
* GET /gallery/images
@@ -44,21 +65,22 @@ class _images extends \IPS\Content\Api\ItemController
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Image>
* @apireturn PaginatedResponse<IPS\gallery\Image>
* @return PaginatedResponse<Image>
*/
public function GETindex()
public function GETindex(): PaginatedResponse
{
/* Where clause */
$where = array();
/* Albums */
if ( isset( \IPS\Request::i()->albums ) )
if ( isset( Request::i()->albums ) )
{
$where[] = array( \IPS\Db::i()->in( 'image_album_id', array_filter( explode( ',', \IPS\Request::i()->albums ) ) ) );
$where[] = array( Db::i()->in( 'image_album_id', array_filter( explode( ',', Request::i()->albums ) ) ) );
}
/* Return */
return $this->_list( $where, 'categories' );
return $this->_list( $where );
}
/**
@@ -67,17 +89,18 @@ class _images extends \IPS\Content\Api\ItemController
*
* @param int $id ID Number
* @throws 2G316/1 INVALID_ID The image ID does not exist or the authorized user does not have permission to view it
* @return \IPS\gallery\Image
* @apireturn \IPS\gallery\Image
* @return Response
*/
public function GETitem( $id )
public function GETitem( int $id ): Response
{
try
{
return $this->_view( $id );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G316/1', 404 );
throw new Exception( 'INVALID_ID', '2G316/1', 404 );
}
}
@@ -112,89 +135,90 @@ class _images extends \IPS\Content\Api\ItemController
* @throws 1G316/6 NO_IMAGE The image was invalid
* @throws 2G316/D NO_PERMISSION The authorized user does not have permission to create an image in that category/album
* @throws 1G316/E IMAGE_TOO_BIG The image exceeds the filesize the authorized user can upload
* @return \IPS\gallery\Image
* @apireturn \IPS\gallery\Image
* @return Response
*/
public function POSTindex()
public function POSTindex(): Response
{
/* Get category or album */
if ( isset( \IPS\Request::i()->album ) )
if ( isset( Request::i()->album ) )
{
try
{
$album = \IPS\gallery\Album::load( \IPS\Request::i()->album );
$album = Album::load( Request::i()->album );
$category = $album->category();
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/2', 400 );
throw new Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/2', 400 );
}
}
else
{
try
{
$category = \IPS\gallery\Category::load( \IPS\Request::i()->category );
$category = Category::load( Request::i()->category );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/2', 400 );
throw new Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/2', 400 );
}
}
/* Get author */
if ( $this->member )
{
if ( isset( \IPS\Request::i()->album ) )
if ( isset( Request::i()->album ) )
{
if ( !$album->can( 'add', $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G316/D', 403 );
throw new Exception( 'NO_PERMISSION', '2G316/D', 403 );
}
}
elseif ( !$category->can( 'add', $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G316/D', 403 );
throw new Exception( 'NO_PERMISSION', '2G316/D', 403 );
}
$author = $this->member;
}
else
{
if ( \IPS\Request::i()->author )
if ( Request::i()->author )
{
$author = \IPS\Member::load( \IPS\Request::i()->author );
$author = Member::load( Request::i()->author );
if ( !$author->member_id )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G316/3', 400 );
throw new Exception( 'NO_AUTHOR', '1G316/3', 400 );
}
}
else
{
if ( \IPS\Request::i()->author === 0 )
if ( Request::i()->author === 0 )
{
$author = new \IPS\Member;
$author = new Member;
}
else
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G316/3', 400 );
throw new Exception( 'NO_AUTHOR', '1G316/3', 400 );
}
}
}
/* Check we have a caption and a filename */
if ( !\IPS\Request::i()->caption )
if ( !Request::i()->caption )
{
throw new \IPS\Api\Exception( 'NO_CAPTION', '1G316/4', 400 );
throw new Exception( 'NO_CAPTION', '1G316/4', 400 );
}
if ( !\IPS\Request::i()->filename )
if ( !Request::i()->filename )
{
throw new \IPS\Api\Exception( 'NO_FILENAME', '1G316/5', 400 );
throw new Exception( 'NO_FILENAME', '1G316/5', 400 );
}
/* Check it's a valid image */
$imageContents = base64_decode( \IPS\Request::i()->image );
if ( $this->member and $this->member->group['g_max_upload'] and \strlen( $imageContents ) > $this->member->group['g_max_upload'] * 1024 )
$imageContents = base64_decode( Request::i()->image );
if ( $this->member and $this->member->group['g_max_upload'] and strlen( $imageContents ) > $this->member->group['g_max_upload'] * 1024 )
{
throw new \IPS\Api\Exception( 'IMAGE_TOO_BIG', '1G316/E', 400 );
throw new Exception( 'IMAGE_TOO_BIG', '1G316/E', 400 );
}
try
{
@@ -202,11 +226,11 @@ class _images extends \IPS\Content\Api\ItemController
}
catch ( \Exception $e )
{
throw new \IPS\Api\Exception( 'NO_IMAGE', '1G316/6', 400 );
throw new Exception( 'NO_IMAGE', '1G316/6', 400 );
}
/* Create the file */
$file = \IPS\File::create( 'gallery_Images', \IPS\Request::i()->filename, $imageContents );
$file = File::create( 'gallery_Images', Request::i()->filename, $imageContents );
/* Create the object */
$image = $this->_create( $category, $author );
@@ -215,33 +239,30 @@ class _images extends \IPS\Content\Api\ItemController
$image->original_file_name = (string) $file;
$image->file_size = $file->filesize();
$image->file_name = $file->originalFilename;
$image->file_type = \IPS\File::getMimeType( $file->filename );
$image->file_type = File::getMimeType( $file->filename );
if( \IPS\Image::exifSupported() )
{
$image->metadata = $imageObject->parseExif();
if( \count( $image->metadata ) )
if( count( $image->metadata ) )
{
$image->parseGeolocation();
$image->gps_show = isset( \IPS\Request::i()->gpsShow ) ? \IPS\Request::i()->gpsShow : 1;
$image->gps_show = isset( Request::i()->gpsShow ) ? Request::i()->gpsShow : 1;
}
$metadata = $image->metadata;
array_walk_recursive( $metadata, function( &$val, $key )
{
$val = utf8_encode( $val );
} );
$image->metadata = json_encode( $metadata );
}
$image->buildThumbnails( $file );
$image->save();
/* Output */
return new \IPS\Api\Response( 201, $image->apiOutput( $this->member ) );
return new Response( 201, $image->apiOutput( $this->member ) );
}
/**
* POST /gallery/images/{id}
* Edit an image
*
* @param int $id
* @note For requests using an OAuth Access Token for a particular member, any parameters the user doesn't have permission to use are ignored (for example, locked will only be honoured if the authenticated user has permission to lock topics).
* @apiparam int album The ID number of the album (only provide this or category to move image)
* @apiparam int category The ID number of the category (only provide this or category to move image)
@@ -263,20 +284,21 @@ class _images extends \IPS\Content\Api\ItemController
* @throws 1G316/8 NO_CATEGORY_OR_ALBUM The category or album does not exist or the authorized user does not have permission to post in it
* @throws 1G316/9 NO_AUTHOR The author ID does not exist
* @throws 2G316/F NO_PERMISSION The authorized user does not have permission to edit the image
* @return \IPS\gallery\Image
* @apireturn \IPS\gallery\Image
* @return Response
*/
public function POSTitem( $id )
public function POSTitem( int $id ): Response
{
try
{
$image = \IPS\gallery\Image::load( $id );
$image = Image::load( $id );
if ( $this->member and !$image->can( 'read', $this->member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
if ( $this->member and !$image->canEdit( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G316/FD', 403 );
throw new Exception( 'NO_PERMISSION', '2G316/FD', 403 );
}
/* New category or album */
@@ -284,49 +306,49 @@ class _images extends \IPS\Content\Api\ItemController
{
try
{
if ( isset( \IPS\Request::i()->album ) and \IPS\Request::i()->album != $image->album_id )
if ( isset( Request::i()->album ) and Request::i()->album != $image->album_id )
{
$newAlbum = \IPS\gallery\Album::load( \IPS\Request::i()->album );
$newAlbum = Album::load( Request::i()->album );
if ( $this->member and !$newAlbum->can( 'add', $this->member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$image->move( $newAlbum );
}
elseif ( isset( \IPS\Request::i()->category ) and \IPS\Request::i()->category != $image->category_id )
elseif ( isset( Request::i()->category ) and Request::i()->category != $image->category_id )
{
$newCategory = \IPS\gallery\Category::load( \IPS\Request::i()->category );
$newCategory = Category::load( Request::i()->category );
if ( $this->member and !$newCategory->can( 'add', $this->member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$image->move( $newCategory );
}
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/8', 400 );
throw new Exception( 'NO_CATEGORY_OR_ALBUM', '1G316/8', 400 );
}
}
/* New author */
if ( !$this->member and isset( \IPS\Request::i()->author ) )
if ( !$this->member and isset( Request::i()->author ) )
{
try
{
$member = \IPS\Member::load( \IPS\Request::i()->author );
$member = Member::load( Request::i()->author );
if ( !$member->member_id )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
$image->changeAuthor( $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G316/9', 400 );
throw new Exception( 'NO_AUTHOR', '1G316/9', 400 );
}
}
@@ -335,11 +357,11 @@ class _images extends \IPS\Content\Api\ItemController
/* Save and return */
$image->save();
return new \IPS\Api\Response( 200, $image->apiOutput( $this->member ) );
return new Response( 200, $image->apiOutput( $this->member ) );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G316/7', 404 );
throw new Exception( 'INVALID_ID', '2G316/7', 404 );
}
}
@@ -353,17 +375,18 @@ class _images extends \IPS\Content\Api\ItemController
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @throws 2G316/A INVALID_ID The image ID does not exist or the authorized user does not have permission to view it
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Image\Comment>
* @apireturn PaginatedResponse<IPS\gallery\Image\Comment>
* @return PaginatedResponse<Comment>
*/
public function GETitem_comments( $id )
public function GETitem_comments( int $id ): PaginatedResponse
{
try
{
return $this->_comments( $id, 'IPS\gallery\Image\Comment' );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G316/A', 404 );
throw new Exception( 'INVALID_ID', '2G316/A', 404 );
}
}
@@ -377,68 +400,69 @@ class _images extends \IPS\Content\Api\ItemController
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @throws 2G316/B INVALID_ID The image ID does not exist or the authorized user does not have permission to view it
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Image\Review>
* @apireturn PaginatedResponse<IPS\gallery\Image\Review>
* @return PaginatedResponse<Review>
*/
public function GETitem_reviews( $id )
public function GETitem_reviews( int $id ): PaginatedResponse
{
try
{
return $this->_comments( $id, 'IPS\gallery\Image\Review' );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G316/B', 404 );
throw new Exception( 'INVALID_ID', '2G316/B', 404 );
}
}
/**
* Create or update image
*
* @param \IPS\Content\Item $item The item
* @param Item $item The item
* @param string $type add or edit
* @return \IPS\Content\Item
* @return Item
*/
protected function _createOrUpdate( \IPS\Content\Item $item, $type='add' )
protected function _createOrUpdate( Item $item, string $type='add' ): Item
{
/* Album */
if ( isset( \IPS\Request::i()->album ) and !$item->id )
if ( isset( Request::i()->album ) and !$item->id )
{
$item->album_id = \IPS\Request::i()->album;
$item->album_id = Request::i()->album;
}
/* Caption */
if ( isset( \IPS\Request::i()->caption ) )
if ( isset( Request::i()->caption ) )
{
$item->caption = \IPS\Request::i()->caption;
$item->caption = Request::i()->caption;
}
/* Description */
if ( isset( \IPS\Request::i()->description ) )
if ( isset( Request::i()->description ) )
{
$descriptionContents = \IPS\Request::i()->description;
$descriptionContents = Request::i()->description;
if ( $this->member )
{
$descriptionContents = \IPS\Text\Parser::parseStatic( $descriptionContents, TRUE, NULL, $this->member, 'gallery_Images' );
$descriptionContents = Parser::parseStatic( $descriptionContents, NULL, $this->member, 'gallery_Images' );
}
$item->description = $descriptionContents;
}
/* Copyright */
if ( isset( \IPS\Request::i()->copyright ) )
if ( isset( Request::i()->copyright ) )
{
$item->copyright = \IPS\Request::i()->copyright;
$item->copyright = Request::i()->copyright;
}
/* Credit */
if ( isset( \IPS\Request::i()->credit ) )
if ( isset( Request::i()->credit ) )
{
$item->credit_info = \IPS\Request::i()->credit;
$item->credit_info = Request::i()->credit;
}
/* GPS Show */
if ( isset( \IPS\Request::i()->gpsShow ) )
if ( isset( Request::i()->gpsShow ) )
{
$item->gps_show = \IPS\Request::i()->gpsShow;
$item->gps_show = Request::i()->gpsShow;
}
/* Pass up */
@@ -452,25 +476,26 @@ class _images extends \IPS\Content\Api\ItemController
* @param int $id ID Number
* @throws 2G316/C INVALID_ID The image ID does not exist
* @throws 2G316/G NO_PERMISSION The authorized user does not have permission to delete the image
* @return void
* @apireturn void
* @return Response
*/
public function DELETEitem( $id )
public function DELETEitem( int $id ): Response
{
try
{
$item = \IPS\gallery\Image::load( $id );
$item = Image::load( $id );
if ( $this->member and !$item->canDelete( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G316/G', 404 );
throw new Exception( 'NO_PERMISSION', '2G316/G', 404 );
}
$item->delete();
return new \IPS\Api\Response( 200, NULL );
return new Response( 200, NULL );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G316/C', 404 );
throw new Exception( 'INVALID_ID', '2G316/C', 404 );
}
}
}
+81 -55
View File
@@ -12,21 +12,37 @@
namespace IPS\gallery\api;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Api\Exception;
use IPS\Api\PaginatedResponse;
use IPS\Api\Response;
use IPS\Content\Api\CommentController;
use IPS\Db;
use IPS\gallery\Image;
use IPS\gallery\Image\Review;
use IPS\Member;
use IPS\Request;
use IPS\Settings;
use OutOfRangeException;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Gallery Reviews API
*/
class _reviews extends \IPS\Content\Api\CommentController
class reviews extends CommentController
{
/**
* Class
*/
protected $class = 'IPS\gallery\Image\Review';
protected string $class = 'IPS\gallery\Image\Review';
/**
* GET /gallery/reviews
@@ -43,20 +59,21 @@ class _reviews extends \IPS\Content\Api\CommentController
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
* @return \IPS\Api\PaginatedResponse<IPS\gallery\Image\Review>
* @apireturn PaginatedResponse<IPS\gallery\Image\Review>
* @return PaginatedResponse<Review>
*/
public function GETindex()
public function GETindex(): PaginatedResponse
{
/* Where clause */
$where = array();
/* Albums */
if ( isset( \IPS\Request::i()->albums ) )
if ( isset( Request::i()->albums ) )
{
$where[] = array( \IPS\Db::i()->in( 'image_album_id', array_filter( explode( ',', \IPS\Request::i()->albums ) ) ) );
$where[] = array( Db::i()->in( 'image_album_id', array_filter( explode( ',', Request::i()->albums ) ) ) );
}
return $this->_list( $where, 'categories' );
return $this->_list( $where );
}
/**
@@ -65,12 +82,14 @@ class _reviews extends \IPS\Content\Api\CommentController
*
* @param int $id ID Number
* @throws 2G318/1 INVALID_ID The review ID does not exist or the authorized user does not have permission to view it
* @return \IPS\gallery\Image\Review
* @apireturn \IPS\gallery\Image\Review
* @return Response
*/
public function GETitem( $id )
public function GETitem( int $id ): Response
{
try
{
/* @var Review $class */
$class = $this->class;
if ( $this->member )
{
@@ -81,11 +100,11 @@ class _reviews extends \IPS\Content\Api\CommentController
$object = $class::load( $id );
}
return new \IPS\Api\Response( 200, $object->apiOutput( $this->member ) );
return new Response( 200, $object->apiOutput( $this->member ) );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G318/1', 404 );
throw new Exception( 'INVALID_ID', '2G318/1', 404 );
}
}
@@ -108,18 +127,19 @@ class _reviews extends \IPS\Content\Api\CommentController
* @throws 1L298/4 NO_CONTENT No content was supplied
* @throws 1G318/5 INVALID_RATING The rating is not a valid number up to the maximum rating
* @throws 2G318/D NO_PERMISSION The authorized user does not have permission to review that image
* @return \IPS\gallery\Image\Review
* @apireturn \IPS\gallery\Image\Review
* @return Response
*/
public function POSTindex()
public function POSTindex(): Response
{
/* Get image */
try
{
$image = \IPS\gallery\Image::load( \IPS\Request::i()->image );
$image = Image::load( Request::i()->image );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G318/2', 403 );
throw new Exception( 'INVALID_ID', '2G318/2', 403 );
}
/* Get author */
@@ -127,44 +147,44 @@ class _reviews extends \IPS\Content\Api\CommentController
{
if ( !$image->canReview( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G318/D', 403 );
throw new Exception( 'NO_PERMISSION', '2G318/D', 403 );
}
$author = $this->member;
}
else
{
if ( \IPS\Request::i()->author )
if ( Request::i()->author )
{
$author = \IPS\Member::load( \IPS\Request::i()->author );
$author = Member::load( Request::i()->author );
if ( !$author->member_id )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G318/3', 404 );
throw new Exception( 'NO_AUTHOR', '1G318/3', 404 );
}
}
else
{
if ( \IPS\Request::i()->author === 0 )
if ( Request::i()->author === 0 )
{
$author = new \IPS\Member;
$author->name = \IPS\Request::i()->author_name;
$author = new Member;
$author->name = Request::i()->author_name;
}
else
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G318/3', 400 );
throw new Exception( 'NO_AUTHOR', '1G318/3', 400 );
}
}
}
/* Check we have a post */
if ( !\IPS\Request::i()->content )
if ( !Request::i()->content )
{
throw new \IPS\Api\Exception( 'NO_CONTENT', '1G318/4', 403 );
throw new Exception( 'NO_CONTENT', '1G318/4', 403 );
}
/* Check we have a rating */
if ( !\IPS\Request::i()->rating or !\in_array( (int) \IPS\Request::i()->rating, range( 1, \IPS\Settings::i()->reviews_rating_out_of ) ) )
if ( !Request::i()->rating or !in_array( (int) Request::i()->rating, range( 1, Settings::i()->reviews_rating_out_of ) ) )
{
throw new \IPS\Api\Exception( 'INVALID_RATING', '2G318/8', 403 );
throw new Exception( 'INVALID_RATING', '2G318/8', 403 );
}
/* Do it */
@@ -187,41 +207,42 @@ class _reviews extends \IPS\Content\Api\CommentController
* @throws 1G318/B NO_AUTHOR The author ID does not exist
* @throws 1G318/A INVALID_RATING The rating is not a valid number up to the maximum rating
* @throws 2G318/E NO_PERMISSION The authorized user does not have permission to edit the review
* @return \IPS\gallery\Image\Review
* @apireturn \IPS\gallery\Image\Review
* @return Response
*/
public function POSTitem( $id )
public function POSTitem( int $id ): Response
{
try
{
/* Load */
$comment = \IPS\gallery\Image\Review::load( $id );
$comment = Review::load( $id );
if ( $this->member and !$comment->canView( $this->member ) )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
if ( $this->member and !$comment->canEdit( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G318/E', 403 );
throw new Exception( 'NO_PERMISSION', '2G318/E', 403 );
}
/* Check */
if ( isset( \IPS\Request::i()->rating ) and !\in_array( (int) \IPS\Request::i()->rating, range( 1, \IPS\Settings::i()->reviews_rating_out_of ) ) )
if ( isset( Request::i()->rating ) and !in_array( (int) Request::i()->rating, range( 1, Settings::i()->reviews_rating_out_of ) ) )
{
throw new \IPS\Api\Exception( 'INVALID_RATING', '1G318/A', 403 );
throw new Exception( 'INVALID_RATING', '1G318/A', 403 );
}
/* Do it */
try
{
return $this->_edit( $comment );
}
catch ( \InvalidArgumentException $e )
catch ( InvalidArgumentException $e )
{
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1G318/B', 400 );
throw new Exception( 'NO_AUTHOR', '1G318/B', 400 );
}
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G318/9', 404 );
throw new Exception( 'INVALID_ID', '2G318/9', 404 );
}
}
@@ -232,25 +253,27 @@ class _reviews extends \IPS\Content\Api\CommentController
* @param int $id ID Number
* @throws 2G318/C INVALID_ID The review ID does not exist
* @throws 2G318/F NO_PERMISSION The authorized user does not have permission to delete the review
* @return void
* @apireturn void
* @return Response
*/
public function DELETEitem( $id )
public function DELETEitem( int $id ): Response
{
try
{
{
/* @var Review $class */
$class = $this->class;
$object = $class::load( $id );
if ( $this->member and !$object->canDelete( $this->member ) )
{
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2G318/F', 403 );
throw new Exception( 'NO_PERMISSION', '2G318/F', 403 );
}
$object->delete();
return new \IPS\Api\Response( 200, NULL );
return new Response( 200, NULL );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException $e )
{
throw new \IPS\Api\Exception( 'INVALID_ID', '2G318/C', 404 );
throw new Exception( 'INVALID_ID', '2G318/C', 404 );
}
}
@@ -261,14 +284,15 @@ class _reviews extends \IPS\Content\Api\CommentController
* @param int $id ID Number
* @apiparam int id ID of the reaction to add
* @apiparam int author ID of the member reacting
* @return \IPS\gallery\Image\Review
* @apireturn \IPS\gallery\Image\Review
* @throws 1S425/2 NO_REACTION The reaction ID does not exist
* @throws 1S425/3 NO_AUTHOR The author ID does not exist
* @throws 1S425/4 REACT_ERROR Error adding the reaction
* @throws 1S425/5 INVALID_ID Object ID does not exist
* @note If the author has already reacted to this content, any existing reaction will be removed first
* @return Response
*/
public function POSTitem_react( $id )
public function POSTitem_react( int $id ): Response
{
return $this->_reactAdd( $id );
}
@@ -279,13 +303,14 @@ class _reviews extends \IPS\Content\Api\CommentController
*
* @param int $id ID Number
* @apiparam int author ID of the member who reacted
* @return \IPS\gallery\Image\Review
* @apireturn Review
* @throws 1S425/6 NO_AUTHOR The author ID does not exist
* @throws 1S425/7 REACT_ERROR Error adding the reaction
* @throws 1S425/8 INVALID_ID Object ID does not exist
* @note If the author has already reacted to this content, any existing reaction will be removed first
* @return Response
*/
public function DELETEitem_react( $id )
public function DELETEitem_react( int $id ): Response
{
return $this->_reactRemove( $id );
}
@@ -300,9 +325,10 @@ class _reviews extends \IPS\Content\Api\CommentController
* @apiparam string message Optional message
* @throws 1S425/B NO_AUTHOR The author ID does not exist
* @throws 1S425/C REPORTED_ALREADY The member has reported this item in the past 24 hours
* @return \IPS\gallery\Image\Review
* @apireturn \IPS\gallery\Image\Review
* @return Response
*/
public function POSTitem_report( $id )
public function POSTitem_report( int $id ): Response
{
return $this->_report( $id );
}
+8 -208
View File
@@ -7,13 +7,6 @@
"image categories"
]
},
"app=gallery&module=gallery&controller=categories&do=form": {
"lang_key": "menu__gallery_gallery_categories",
"restriction": "categories_manage",
"keywords": [
"add category"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=category_allow_comments": {
"lang_key": "category_allow_comments",
"restriction": "categories_manage",
@@ -27,71 +20,18 @@
"restriction": "categories_manage",
"keywords": [
"comments approved",
"must approved"
"must approved",
"comments must"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=category_can_tag": {
"lang_key": "category_can_tag",
"restriction": "categories_manage",
"keywords": [
"allow tags",
"tags"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=category_sort_options": {
"lang_key": "category_sort_options",
"restriction": "categories_manage",
"keywords": [
"default sort",
"sort order"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=category_tag_prefixes": {
"lang_key": "category_tag_prefixes",
"restriction": "categories_manage",
"keywords": [
"allow prefixes",
"prefixes"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_allow_albums": {
"lang_key": "category_allow_albums",
"restriction": "categories_manage",
"keywords": [
"allow albums"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_allow_reviews": {
"lang_key": "category_allow_reviews",
"restriction": "categories_manage",
"keywords": [
"allow reviews",
"reviews"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_approve_img": {
"lang_key": "category_approve_img",
"restriction": "categories_manage",
"keywords": [
"images must",
"must approved"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_description": {
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_description": {
"lang_key": "category_description",
"restriction": "categories_manage",
"keywords": [
"category description"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_name": {
"lang_key": "category_name",
"restriction": "categories_manage",
"keywords": [
"category name"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_category_show_rules": {
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_show_rules": {
"lang_key": "category_show_rules",
"restriction": "categories_manage",
"keywords": [
@@ -100,7 +40,7 @@
"show rules"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_gcategory_allow_rating": {
"app=gallery&module=gallery&controller=categories&searchResult=form_new_gcategory_allow_rating": {
"lang_key": "gcategory_allow_rating",
"restriction": "categories_manage",
"keywords": [
@@ -108,13 +48,6 @@
"ratings"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_1_gcategory_parent_id": {
"lang_key": "gcategory_parent_id",
"restriction": "categories_manage",
"keywords": [
"parent category"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_allow_albums": {
"lang_key": "category_allow_albums",
"restriction": "categories_manage",
@@ -131,44 +64,6 @@
"reviews"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_approve_img": {
"lang_key": "category_approve_img",
"restriction": "categories_manage",
"keywords": [
"items approved",
"must approved"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_description": {
"lang_key": "category_description",
"restriction": "categories_manage",
"keywords": [
"category description"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_name": {
"lang_key": "category_name",
"restriction": "categories_manage",
"keywords": [
"category name"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_show_rules": {
"lang_key": "category_show_rules",
"restriction": "categories_manage",
"keywords": [
"rules",
"show rules"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_gcategory_allow_rating": {
"lang_key": "gcategory_allow_rating",
"restriction": "categories_manage",
"keywords": [
"allow ratings",
"ratings"
]
},
"app=gallery&module=gallery&controller=categories&searchResult=form_new_gcategory_parent_id": {
"lang_key": "gcategory_parent_id",
"restriction": "categories_manage",
@@ -185,31 +80,7 @@
"permission denied"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=category_allow_comments": {
"lang_key": "category_allow_comments",
"restriction": "categories_manage",
"keywords": [
"allow comments",
"comments"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=category_approve_com": {
"lang_key": "category_approve_com",
"restriction": "categories_manage",
"keywords": [
"comments must",
"must approved"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=category_can_tag": {
"lang_key": "category_can_tag",
"restriction": "categories_manage",
"keywords": [
"allow tags",
"tags"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=category_sort_options": {
"app=gallery&module=gallery&controller=categories&searchResult=category_sort_options": {
"lang_key": "category_sort_options",
"restriction": "categories_manage",
"keywords": [
@@ -217,30 +88,7 @@
"sort order"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=category_tag_prefixes": {
"lang_key": "category_tag_prefixes",
"restriction": "categories_manage",
"keywords": [
"allow prefixes",
"prefixes"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_allow_albums": {
"lang_key": "category_allow_albums",
"restriction": "categories_manage",
"keywords": [
"allow albums"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_allow_reviews": {
"lang_key": "category_allow_reviews",
"restriction": "categories_manage",
"keywords": [
"allow reviews",
"reviews"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_approve_img": {
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_approve_img": {
"lang_key": "category_approve_img",
"restriction": "categories_manage",
"keywords": [
@@ -249,52 +97,13 @@
"must approved"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_description": {
"lang_key": "category_description",
"restriction": "categories_manage",
"keywords": [
"category description"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_name": {
"app=gallery&module=gallery&controller=categories&searchResult=form_new_category_name": {
"lang_key": "category_name",
"restriction": "categories_manage",
"keywords": [
"category name"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_category_show_rules": {
"lang_key": "category_show_rules",
"restriction": "categories_manage",
"keywords": [
"rules",
"show rules"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_gcategory_allow_rating": {
"lang_key": "gcategory_allow_rating",
"restriction": "categories_manage",
"keywords": [
"allow ratings",
"ratings"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=form_new_gcategory_parent_id": {
"lang_key": "gcategory_parent_id",
"restriction": "categories_manage",
"keywords": [
"parent",
"parent category"
]
},
"app=gallery&module=gallery&controller=categories&subnode=0&parent=1&searchResult=gallery_permission_custom_error": {
"lang_key": "category_permission_custom_error",
"restriction": "categories_manage",
"keywords": [
"custom error",
"custom permission denied"
]
},
"app=gallery&module=gallery&controller=settings": {
"lang_key": "menu__gallery_gallery_settings",
"restriction": "settings_manage",
@@ -423,15 +232,6 @@
"upload movies"
]
},
"app=core&module=members&controller=members&searchResult=remove_gallery_upload": {
"lang_key": "remove_gallery_upload",
"restriction": null,
"keywords": [
"Can Upload",
"Gallery Upload",
"Images"
]
},
"app=core&module=members&controller=groups&searchResult=4_g_create_albums": {
"lang_key": "g_create_albums",
"restriction": "groups_manage",
+7 -32
View File
@@ -31,43 +31,18 @@
<widget key="recentImageReviews"><![CDATA[{"class":"\\IPS\\Widget\\PermissionCache","restrict":["sidebar","cms"],"default_area":"","allow_reuse":false,"menu_style":"menu","embeddable":true}]]></widget>
<widget key="albums"><![CDATA[{"class":"\\IPS\\Widget\\PermissionCache","restrict":["sidebar","cms"],"default_area":"","allow_reuse":true,"menu_style":"menu","embeddable":true}]]></widget>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories"><![CDATA[{"lang_key":"menu__gallery_gallery_categories","restriction":"categories_manage","keywords":["gallery categories","image categories"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;do=form"><![CDATA[{"lang_key":"menu__gallery_gallery_categories","restriction":"categories_manage","keywords":["add category"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_allow_comments"><![CDATA[{"lang_key":"category_allow_comments","restriction":"categories_manage","keywords":["allow comments","comments"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_approve_com"><![CDATA[{"lang_key":"category_approve_com","restriction":"categories_manage","keywords":["comments approved","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_can_tag"><![CDATA[{"lang_key":"category_can_tag","restriction":"categories_manage","keywords":["allow tags","tags"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_sort_options"><![CDATA[{"lang_key":"category_sort_options","restriction":"categories_manage","keywords":["default sort","sort order"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_tag_prefixes"><![CDATA[{"lang_key":"category_tag_prefixes","restriction":"categories_manage","keywords":["allow prefixes","prefixes"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_allow_albums"><![CDATA[{"lang_key":"category_allow_albums","restriction":"categories_manage","keywords":["allow albums"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_allow_reviews"><![CDATA[{"lang_key":"category_allow_reviews","restriction":"categories_manage","keywords":["allow reviews","reviews"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_approve_img"><![CDATA[{"lang_key":"category_approve_img","restriction":"categories_manage","keywords":["images must","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_description"><![CDATA[{"lang_key":"category_description","restriction":"categories_manage","keywords":["category description"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_name"><![CDATA[{"lang_key":"category_name","restriction":"categories_manage","keywords":["category name"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_category_show_rules"><![CDATA[{"lang_key":"category_show_rules","restriction":"categories_manage","keywords":["gallery rules","rules","show rules"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_gcategory_allow_rating"><![CDATA[{"lang_key":"gcategory_allow_rating","restriction":"categories_manage","keywords":["allow ratings","ratings"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_1_gcategory_parent_id"><![CDATA[{"lang_key":"gcategory_parent_id","restriction":"categories_manage","keywords":["parent category"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_approve_com"><![CDATA[{"lang_key":"category_approve_com","restriction":"categories_manage","keywords":["comments approved","must approved","comments must"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_description"><![CDATA[{"lang_key":"category_description","restriction":"categories_manage","keywords":["category description"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_show_rules"><![CDATA[{"lang_key":"category_show_rules","restriction":"categories_manage","keywords":["gallery rules","rules","show rules"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_gcategory_allow_rating"><![CDATA[{"lang_key":"gcategory_allow_rating","restriction":"categories_manage","keywords":["allow ratings","ratings"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_allow_albums"><![CDATA[{"lang_key":"category_allow_albums","restriction":"categories_manage","keywords":["albums","allow albums"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_allow_reviews"><![CDATA[{"lang_key":"category_allow_reviews","restriction":"categories_manage","keywords":["allow reviews","reviews"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_approve_img"><![CDATA[{"lang_key":"category_approve_img","restriction":"categories_manage","keywords":["items approved","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_description"><![CDATA[{"lang_key":"category_description","restriction":"categories_manage","keywords":["category description"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_name"><![CDATA[{"lang_key":"category_name","restriction":"categories_manage","keywords":["category name"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_show_rules"><![CDATA[{"lang_key":"category_show_rules","restriction":"categories_manage","keywords":["rules","show rules"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_gcategory_allow_rating"><![CDATA[{"lang_key":"gcategory_allow_rating","restriction":"categories_manage","keywords":["allow ratings","ratings"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_gcategory_parent_id"><![CDATA[{"lang_key":"gcategory_parent_id","restriction":"categories_manage","keywords":["parent","parent category"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=gallery_permission_custom_error"><![CDATA[{"lang_key":"category_permission_custom_error","restriction":"categories_manage","keywords":["custom error","permission denied"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=category_allow_comments"><![CDATA[{"lang_key":"category_allow_comments","restriction":"categories_manage","keywords":["allow comments","comments"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=category_approve_com"><![CDATA[{"lang_key":"category_approve_com","restriction":"categories_manage","keywords":["comments must","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=category_can_tag"><![CDATA[{"lang_key":"category_can_tag","restriction":"categories_manage","keywords":["allow tags","tags"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=category_sort_options"><![CDATA[{"lang_key":"category_sort_options","restriction":"categories_manage","keywords":["default sort","sort order"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=category_tag_prefixes"><![CDATA[{"lang_key":"category_tag_prefixes","restriction":"categories_manage","keywords":["allow prefixes","prefixes"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_allow_albums"><![CDATA[{"lang_key":"category_allow_albums","restriction":"categories_manage","keywords":["allow albums"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_allow_reviews"><![CDATA[{"lang_key":"category_allow_reviews","restriction":"categories_manage","keywords":["allow reviews","reviews"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_approve_img"><![CDATA[{"lang_key":"category_approve_img","restriction":"categories_manage","keywords":["approved","images must","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_description"><![CDATA[{"lang_key":"category_description","restriction":"categories_manage","keywords":["category description"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_name"><![CDATA[{"lang_key":"category_name","restriction":"categories_manage","keywords":["category name"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_category_show_rules"><![CDATA[{"lang_key":"category_show_rules","restriction":"categories_manage","keywords":["rules","show rules"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_gcategory_allow_rating"><![CDATA[{"lang_key":"gcategory_allow_rating","restriction":"categories_manage","keywords":["allow ratings","ratings"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=form_new_gcategory_parent_id"><![CDATA[{"lang_key":"gcategory_parent_id","restriction":"categories_manage","keywords":["parent","parent category"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;subnode=0&amp;parent=1&amp;searchResult=gallery_permission_custom_error"><![CDATA[{"lang_key":"category_permission_custom_error","restriction":"categories_manage","keywords":["custom error","custom permission denied"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=category_sort_options"><![CDATA[{"lang_key":"category_sort_options","restriction":"categories_manage","keywords":["default sort","sort order"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_approve_img"><![CDATA[{"lang_key":"category_approve_img","restriction":"categories_manage","keywords":["approved","images must","must approved"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=categories&amp;searchResult=form_new_category_name"><![CDATA[{"lang_key":"category_name","restriction":"categories_manage","keywords":["category name"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=settings"><![CDATA[{"lang_key":"menu__gallery_gallery_settings","restriction":"settings_manage","keywords":["gallery settings"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=settings&amp;searchResult=form_gallery_bandwidth_period"><![CDATA[{"lang_key":"gallery_bandwidth_period","restriction":"settings_manage","keywords":["bandwidth log retention","bandwidth logs","number of hours"]}]]></acpsearch>
<acpsearch key="app=gallery&amp;module=gallery&amp;controller=settings&amp;searchResult=form_gallery_detailed_bandwidth"><![CDATA[{"lang_key":"gallery_detailed_bandwidth","restriction":"settings_manage","keywords":["bandwidth","bandwidth logs","store bandwidth logs"]}]]></acpsearch>
@@ -0,0 +1 @@
[]
+2 -2
View File
@@ -3,7 +3,7 @@
<table width='100%' cellpadding='0' cellspacing='0' border='0'>
<tr>
<td dir='{dir}' width='40' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
<img src='{$content->author()->get_photo( true, true )}' width='40' height='40' style='border: 1px solid #777777; vertical-align: middle;'>
<img src='{$content->author()->get_photo( true, true )}' width='40' height='40' style='border-radius: 6px; vertical-align: middle;'>
</td>
<td dir='{dir}' width='30' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
<br />
@@ -20,7 +20,7 @@
<table width='100%' cellpadding='5' cellspacing='0' border='0'>
{{if $container = $content->containerWrapper()}}
<tr>
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px; color: #8d8d8d">
<td dir='{dir}' style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px; color: #5e7a98">
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $container->getTitleForLanguage( $email->language ) ) ) )}
</td>
</tr>
+4 -7
View File
@@ -6,9 +6,6 @@
"ContentRouter": {
"gallery": "IPS\\gallery\\extensions\\core\\ContentRouter\\gallery"
},
"CreateMenu": {
"gallery": "IPS\\gallery\\extensions\\core\\CreateMenu\\gallery"
},
"Dashboard": {
"Overview": "IPS\\gallery\\extensions\\core\\Dashboard\\Overview"
},
@@ -45,9 +42,6 @@
"MemberRestrictions": {
"Gallery": "IPS\\gallery\\extensions\\core\\MemberRestrictions\\Gallery"
},
"MemberSync": {
"Gallery": "IPS\\gallery\\extensions\\core\\MemberSync\\Gallery"
},
"Permissions": {
"Permissions": "IPS\\gallery\\extensions\\core\\Permissions\\Permissions"
},
@@ -56,10 +50,13 @@
"galleryImages": "IPS\\gallery\\extensions\\core\\Profile\\galleryImages"
},
"Queue": {
"CleanUpGalleryImages": "IPS\\gallery\\extensions\\core\\Queue\\CleanUpGalleryImages",
"Follow": "IPS\\gallery\\extensions\\core\\Queue\\Follow",
"RebuildGalleryImages": "IPS\\gallery\\extensions\\core\\Queue\\RebuildGalleryImages"
},
"SearchContent": {
"Albums": "IPS\\gallery\\extensions\\core\\SearchContent\\Albums",
"Images": "IPS\\gallery\\extensions\\core\\SearchContent\\Images"
},
"Sitemap": {
"Images": "IPS\\gallery\\extensions\\core\\Sitemap\\Images",
"Videos": "IPS\\gallery\\extensions\\core\\Sitemap\\Videos"
-23
View File
@@ -1,26 +1,3 @@
/**
* Friendly URL Structure
*
* For each value in the $furl array:
* The key should be the "SEO Template" - an identifier which you'll use when displaying a URL.
* The value should be an associative array with two or three elements: 'friendly' and 'real', and optionally 'verify':
* 'friendly'
* The friendly URL to use - encase variables in {curly braces} containing a symbol, followed by the name of the parameter that matches in the "real" URL
* The symbol should be # for numbers or @ for strings
* For example, if the "real" URL contains id=XXX, where XXX is a number, you should include {#id} somewhere in the friendly URL.
* You can also use the tag {?} for the "SEO Title" (that is, any variables that shouldn't be part of the real URL, such as the name of the topipc being viewed).
* If you want to support more than one SEO Title, you can give them zero-indexed keys like so: {?0} {?1} {?2}
* 'real'
* This should be the base of the real URL. You should not include parameters which will be parsed out from the friendly URL.
* 'verify'
* This should be the name of a class that contains a loadFromUrl() and an url() method. The dynamic URL (i.e. app=core&...) will be passed to loadFromUrl(), and the url()
* method will subsequently be called to retrieve the correct URL, ideal with ActiveRecord pattern classes.
*
* IMPORTANT: Ensure values are listed with the most specific ones first. This is to ensure that non-FURL redirects are done correctly. For example, if you have these FURLs:
* /index.php?app=myapp&module=mymodule&controller=mycontroller&do=myaction -> /myfolder/myaction
* /index.php?app=myapp&module=mymodule&controller=mycontroller -> /myfolder
* They must be provided in that order, otherwise the former will redirec to /myfolder/?do=myaction rather than /myfolder/myaction
*/
{
"topLevel": "gallery",
"pages": {
+101 -233
View File
@@ -1,118 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="gallery">
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.carousel.js" javascript_type="controller" javascript_version="107827" javascript_position="1000200"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
* ips.browse.carousel.js - Controller for Gallery carousel
*
* Author: Ehren Harber
*/
;( function(){
"use strict";
ips.controller.register('gallery.front.browse.carousel', {
initialize () {
this.carouselControls = this.scope[0].closest('[data-carousel-controls]');
this.carousel = document.getElementById(this.carouselControls.dataset.carouselControls);
if(this.carouselControls && this.carousel.scrollWidth > this.carousel.clientWidth){
this.showArrows();
} else {
return;
}
this.buttons = this.scope[0].querySelectorAll('[data-carousel-arrow]');
this.buttons.forEach(button => {
button.addEventListener('click', this.scrollPanels);
});
},
showArrows: function(){
this.carouselControls.hidden = false;
},
scrollPanels: function(ev) {
let carouselControls = this.closest('[data-carousel-controls]'),
carousel = document.getElementById(carouselControls.dataset.carouselControls),
direction = this.dataset.carouselArrow,
currentScroll = carousel.scrollLeft,
scrollByVar = getComputedStyle(carousel).getPropertyValue('--carousel--scroll'),
carouselChildWidth = carousel.firstElementChild.offsetWidth,
scrollBy = scrollByVar * (carouselChildWidth);
if (direction == 'prev'){
scrollBy = -scrollBy;
}
if (currentScroll == '0' && direction == 'prev'){
carousel.scrollLeft = carousel.scrollWidth;
} else if ((currentScroll == carousel.scrollWidth - carousel.clientWidth) && (direction == 'next')){
carousel.scrollLeft = 0;
} else {
carousel.scrollLeft = currentScroll + scrollBy;
}
},
});
}());]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.list.js" javascript_type="controller" javascript_version="107827" javascript_position="1000200">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
* ips.browse.list.js - Gallery browse list controller
*
* Author: Rikki Tissier
*/
;( function($, _, undefined){
&quot;use strict&quot;;
ips.controller.register('gallery.front.browse.list', {
initialize: function () {
this.on( 'change', '[data-role=&quot;moderation&quot;]', this.selectImage );
},
/**
* Toggles classes when the moderation checkbox is checked
*
* @param {event} e Event object
* @returns {void}
*/
selectImage: function (e) {
var row = $( e.currentTarget ).closest('.cGalleryImageItem');
row.toggleClass( 'cGalleryImageItem_selected', $( e.currentTarget ).is(':checked') );
}
});
}(jQuery, _));</file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/global" javascript_name="ips.global.nsfw.js" javascript_type="controller" javascript_version="107827" javascript_position="1000250">;( function($, _, undefined){
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/global" javascript_name="ips.global.nsfw.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000200">;( function($, _, undefined){
&quot;use strict&quot;;
ips.controller.register('gallery.front.global.nsfw', {
initialize () {
this.on( 'click', '.ipsImageBlock__nsfw button', this.removeOverlays );
this.on( 'click', '.ipsNsfwOverlay button', this.removeOverlays );
},
removeOverlays( e ) {
e.preventDefault();
var expires = new Date();
let expires = new Date();
expires.setDate( expires.getDate() + 365 );
ips.utils.cookie.set( 'nsfwImageOptIn', true, expires.toUTCString() );
$('.ipsImageBlock__nsfw').fadeOut(500, function() { this.remove() });
$('.ipsNsfwOverlay').fadeOut(500, function() { this.remove() });
},
});
}(jQuery, _));</file>
<file javascript_app="gallery" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.settings.js" javascript_type="controller" javascript_version="107827" javascript_position="1000050">/**
<file javascript_app="gallery" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.settings.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000050">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -169,7 +77,7 @@
});
}(jQuery, _));</file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.chooseCategory.js" javascript_type="controller" javascript_version="107827" javascript_position="1000100"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.chooseCategory.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -246,41 +154,8 @@
* @returns {void}
*/
_resizeFormDiv: function (form) {
this.scope.find('[data-role="chooseAlbumType"]').hide();
var self = this;
var resize = function (animate) {
var height = form.innerHeight() + 130;
var submitHeight = form.find('.cGalleryDialog_submitBar').height();
if( animate ){
self.scope.closest('.cGalleryDialog').animate({
minHeight: ( height + submitHeight ) + 'px'
});
} else {
self.scope.closest('.cGalleryDialog').css({
minHeight: ( height + submitHeight ) + 'px'
});
}
}
form.show().css({
opacity: "0.001"
});
if( this.scope.closest('.ipsDialog').length ){
resize(true);
}
form.animate({
opacity: "1"
}, function () {
if( self.scope.closest('.ipsDialog').length ){
self._resizeTimer = setInterval( function () {
resize(false);
}, 500);
}
});
this.scope.find('[data-role="chooseAlbumType"]').attr("hidden", "");
form.removeAttr("hidden");
},
/**
@@ -369,7 +244,7 @@
});
}(jQuery, _));
]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.existingAlbums.js" javascript_type="controller" javascript_version="107827" javascript_position="1000100"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.existingAlbums.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -388,18 +263,7 @@
*/
initialize: function () {
this.on( 'click', '#elGallerySubmit_albumChooser > li', this.clickAlbum );
this._checkSelected();
},
/**
* Event handler for clicking an album entry
*
* @param {event} e Event object
* @returns {void}
*/
clickAlbum: function (e) {
$( e.currentTarget ).find('input[type="radio"]').prop( 'checked', true );
this._checkSelected();
this.clickAlbum();
},
/**
@@ -407,16 +271,16 @@
*
* @returns {void}
*/
_checkSelected: function () {
if( this.scope.find('input[name="existing_album"]:checked').length ){
this.scope.find('button[type="submit"]').prop( 'disabled', false );
clickAlbum: function (e) {
if( this.scope.find('[name="existing_album"]:checked').length ){
this.scope.find('[type="submit"]').prop( 'disabled', false );
} else {
this.scope.find('button[type="submit"]').prop( 'disabled', true );
this.scope.find('[type="submit"]').prop( 'disabled', true );
}
}
});
}(jQuery, _));]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.uploadImages.js" javascript_type="controller" javascript_version="107827" javascript_position="1000100"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.uploadImages.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -463,8 +327,8 @@
$('.cGallerySubmit_bottomBar').removeClass('ipsHide');
// We want to move the allowed types of files span
$('[data-role="allowedTypes"]').html( this.scope.find('span.ipsType_light.ipsType_small').html() );
this.scope.find('span.ipsType_light.ipsType_small').remove();
$('[data-role="allowedTypes"]').html( this.scope.find('span.i-color_soft.i-font-size_-2').html() );
this.scope.find('span.i-color_soft.i-font-size_-2').remove();
// And change the uploader message
this.scope.find('.ipsAttachment_supportDrag').html( ips.getString('uploader_add_images') );
@@ -547,7 +411,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.wrapper.js" javascript_type="controller" javascript_version="107827" javascript_position="1000100"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.wrapper.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -585,6 +449,7 @@
this.on( 'click', '[data-role="imageDescriptionUseEditor"]', this.setUpImageDescriptionRich );
this.on( 'click', '[data-role="imageDescriptionUseTextarea"]', this.setUpImageDescriptionPlain );
this.on( 'click', '[data-role="addCopyrightCredit"]', this.showCopyrightCredit );
this.on( 'click', '[data-role="saveDetails"]', this.saveDetails );
this.on( 'click', '[data-role="saveInfo"]', this.saveInfo );
// Handle events from uploader
@@ -607,8 +472,8 @@
* @returns {void}
*/
setup: function () {
// On initial load, destroy the ckeditor object as it will be recreated for each individual form
ips.ui.editor.destruct( this.scope.find('[data-ipseditor]') );
// On initial load, destroy the tiptap object as it will be recreated for each individual form
ips.ui.editorv5.destruct( this.scope.find('[data-ipseditorv5]') );
if( this.scope.find('.cGalleryDialog_imageForm').is(':visible') ){
this._enlargeUploadStep();
@@ -707,6 +572,38 @@
$(e.currentTarget).trigger('closeMenu');
},
/**
* Mobile-specific functionality for 'save' button
*
* @returns {void}
*/
saveDetails: function (e) {
if( e ){
e.preventDefault();
}
this._markActiveImageAsSaved();
// Show and then hide a 'saved' message
$(e.currentTarget).next('[data-role="savedMessage"]').fadeIn();
setTimeout( function () {
$(e.currentTarget).next('[data-role="savedMessage"]').fadeOut();
}, 2000 );
// Hide any error messages
if( e ){
$( e.currentTarget ).closest('.cGallerySubmit_details').find('[data-errorField]').hide();
}
// Mobile-only behavior
if( ips.utils.responsive.enabled() && ips.utils.responsive.currentIs('phone') ){
// Fade out details form
this._toggleDetailsPanelMobile(false);
// Remove active selection styles
this.scope.find('.cGallerySubmit_activeFile').removeClass('cGallerySubmit_activeFile');
}
},
/**
* Confirm the user wants to close the dialog
*
@@ -753,33 +650,22 @@
* @returns {void}
*/
setUpImageDetailsForm: function (e) {
// Remove selection from all other files
this.scope.find('.cGallerySubmit_activeFile').removeClass('cGallerySubmit_activeFile');
$( e.currentTarget ).addClass('cGallerySubmit_activeFile');
let imageId;
let tempId;
const detailsPanel = this.scope.find('[data-role="imageDetails"]');
// Get the image ID first
if ($(e.currentTarget).attr('data-uploading-temp-id')) {
// if the details pane was opened before the fileid was set, we use the existing temp id
imageId = $(e.currentTarget).attr('data-uploading-temp-id')
} else if( $( e.currentTarget ).attr('data-fileid').startsWith('o_') ) {
imageId = $('input[name="images_existing\\[' + $( e.currentTarget ).attr('data-fileid') + '\\]"').val();
if (!imageId) {
imageId = $(e.currentTarget).attr('data-fileid');
$(e.currentTarget).attr('data-uploading-temp-id', $(e.currentTarget).attr('data-fileid'))
}
} else if ( $(e.currentTarget).attr('data-fileid') && parseInt($(e.currentTarget).attr('data-fileid')) ) {
imageId = $( e.currentTarget ).attr('data-fileid');
} else {
// in this case, we assume it's still uploading
tempId = imageId = Math.round(Math.random() * Math.pow(2, 32)).toString(16)
$(e.currentTarget).attr('data-uploading-temp-id', imageId)
if( $( e.currentTarget ).attr('data-fileid').indexOf('o_') != -1 )
{
var imageId = $('input[name="images_existing\\[' + $( e.currentTarget ).attr('data-fileid') + '\\]"').val();
}
else
{
var imageId = $( e.currentTarget ).attr('data-fileid');
}
var imagePreview = $( e.currentTarget ).find('.ipsImage').attr('src');
var imagePreview = $( e.currentTarget ).find('[data-role="preview"] img').attr('src');
var detailsPanel = this.scope.find('[data-role="imageDetails"]');
// Hide our existing form, if any
detailsPanel.find('.cGallerySubmit_details, [data-role="submitHelp"]').hide();
@@ -793,7 +679,6 @@
}
} else {
// Otherwise, clone our existing form to use
$('[data-role="defaultImageDetailsForm"]').find('#cke_filedata__image_description_DEFAULT').remove();
var htmlToInsert = $('[data-role="defaultImageDetailsForm"]').html();
htmlToInsert = '<div id="image_details_' + imageId + '">' + htmlToInsert.replace( /name="image_tags_DEFAULT"/g, 'name="image_tags_DEFAULT" data-ipsAutocomplete ').replace( /_DEFAULT/g, '_' + imageId ) + "</div>";
@@ -807,25 +692,17 @@
var filenameWithoutExt = filename.replace(/\.[^/.]+$/, '');
$('#elInput_image_title_' + imageId ).val( filenameWithoutExt );
// Fix yes/no fields as they will reinitialize and break
detailsPanel.find('> form #image_details_' + imageId ).find('.ipsToggle').remove();
if( !_.isUndefined( imagePreview ) ){
imageForm
.find('.cGallerySubmit_preview')
.removeClass('ipsBox_transparent')
.removeClass('ipsNoThumb')
.removeClass('ipsNoThumb_video')
.html( $("<img class='ipsImage'/>").attr('src', imagePreview ) )
.html("<img src='" + imagePreview + "' alt='' />")
.show();
}
else {
imageForm
.find('.cGallerySubmit_preview')
.addClass('ipsBox_transparent')
.addClass('ipsNoThumb')
.addClass('ipsNoThumb_video')
.html("")
.html("<i></i>")
.show();
}
@@ -898,16 +775,16 @@
* @returns {void}
*/
setUpImageDescriptionRich: function(e) {
var currentDescription = $( e.currentTarget ).closest('[data-role="imageDescriptionTextarea"]')
.find( '> textarea' )
const currentDescription = $(e.currentTarget).closest('[data-role="imageDescriptionTextarea"]')
.find('> textarea')
.val()
.trim();
if( currentDescription.length ){
var editorObj = ips.ui.editor.getObj( $( e.currentTarget ).closest('[data-role="imageDescriptionTextarea"]')
const editorObj = ips.ui.editorv5.getObj($(e.currentTarget).closest('[data-role="imageDescriptionTextarea"]')
.prev('[data-role="imageDescriptionEditor"]')
.find('[data-ipseditor]') );
var editorInstance = editorObj.getInstance();
editorInstance.setData( currentDescription );
.find('[data-ipseditorv5]'));
const editorInstance = editorObj.getInstance();
editorInstance.commands.setContent( currentDescription );
$( e.currentTarget ).closest('[data-role="imageDescriptionTextarea"]')
.find( '> textarea' )
.val('');
@@ -927,9 +804,9 @@
* @returns {void}
*/
setUpImageDescriptionPlain: function (e) {
var editorObj = ips.ui.editor.getObj( $( e.currentTarget ).closest('[data-role="imageDescriptionEditor"]')
.find('[data-ipseditor]') );
var currentDescription = $( editorObj.getInstance().getData() ).text()
const editorObj = ips.ui.editorv5.getObj($(e.currentTarget).closest('[data-role="imageDescriptionEditor"]')
.find('[data-ipseditorv5]'));
const currentDescription = $(editorObj.getInstance().getHTML()).text()
.trim();
if( currentDescription.length ){
$( e.currentTarget ).closest('[data-role="imageDescriptionEditor"]')
@@ -980,12 +857,12 @@
// If we are submitting images, get the info we need
if( form.attr('id') == 'elGallerySubmit' ){
// Sync editor to its textarea
this.scope.find('[data-ipseditor]').each( function(){
this.scope.find('[data-ipseditorv5]').each( function(){
try {
var editorObj = ips.ui.editor.getObj( $( this ) );
var editorObj = ips.ui.editorv5.getObj( $( this ) );
var editorInstance = editorObj.getInstance();
$( this ).find('textarea[data-role="contentEditor"]').val( editorInstance.getData() );
$( this ).find('textarea[data-role="contentEditor"]').val( editorInstance.getHTML() );
} catch (err) {
Debug.error("Couldn't update textarea from editor");
}
@@ -1032,20 +909,7 @@
form.find('textarea[name="images_order"]').val( JSON.stringify( imageOrder ) );
// And get the individual image details and store in the submission
const tempIdMap = {}
form.find('[data-uploading-temp-id][data-fileid]').each(function() {
tempIdMap[$(this).attr('data-uploading-temp-id')] = $(this).attr('data-fileid');
})
form.find('textarea[name="images_info"]').val( JSON.stringify( $('#form_imageDetails').serializeArray().map(({name, value}) => {
for(const key in tempIdMap) {
if (name.includes(key)) {
name = name.replaceAll(key, tempIdMap[key])
break;
}
}
return {name, value}
}) ) );
form.find('textarea[name="images_info"]').val( JSON.stringify( $('#form_imageDetails').serializeArray() ) );
// Hide/disable some stuff
this.scope.find('[data-role="imageDetails"]').addClass('ipsHide');
@@ -1141,7 +1005,7 @@
if( response.imageTags && wrapper.find('.cGalleryTagsField').hasClass('ipsHide') ){
wrapper.find('.cGalleryTagsField').removeClass('ipsHide');
wrapper.find('.cGalleryTagsField .ipsFieldRow_content').append( response.imageTags );
wrapper.find('.cGalleryTagsField .ipsFieldRow__content').append( response.imageTags );
}
if( response.tagsField && wrapper.find('.cGalleryTagsButton').hasClass('ipsHide') ) {
@@ -1275,6 +1139,8 @@
wrapper.find('[data-role="images"]').animate({
opacity: "1"
});
dialogElem.find('.ipsDialog_close').hide();
$( document ).trigger( 'contentChange', [ wrapper ] );
});
@@ -1300,7 +1166,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.image.js" javascript_type="controller" javascript_version="107827" javascript_position="1000150">/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.image.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000150">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -1442,7 +1308,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.note.js" javascript_type="controller" javascript_version="107827" javascript_position="1000150"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.note.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000150"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -1835,6 +1701,7 @@
var self = this;
// If the note block is now out of view, flip it to the other side
/*
var parent = this.scope.closest('.cGalleryViewImage');
var notePos = this.scope.position();
@@ -1861,6 +1728,7 @@
}
}
}
*/
// If this is a new note, we don't want to update the position remotely yet.
// We'll only do that once the note text is saved for the first time.
@@ -1900,7 +1768,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.notes.js" javascript_type="controller" javascript_version="107827" javascript_position="1000150"><![CDATA[/**
<file javascript_app="gallery" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.notes.js" javascript_type="controller" javascript_version="5000026" javascript_position="1000150"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -1983,35 +1851,35 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.browse.js" javascript_type="template" javascript_version="107827" javascript_position="1000050">// Empty</file>
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.submit.js" javascript_type="template" javascript_version="107827" javascript_position="1000050"><![CDATA[ips.templates.set('gallery.submit.imageItem', " \
<div class='ipsAttach ipsImageAttach ipsPad_half ipsAreaBackground_light {{#done}}ipsAttach_done{{/done}}' id='{{id}}' data-role='file' data-fileid='{{id}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-isImage='1'>\
<ul class='ipsList_inline ipsImageAttach_controls'>\
<li data-role='insert' {{#insertable}}style='display: none'{{/insertable}}><a href='#' data-action='insertFile' class='ipsAttach_selection' data-ipsTooltip title='{{#lang}}insertIntoPost{{/lang}}'><i class='fa fa-plus'></i></a></li>\
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.browse.js" javascript_type="template" javascript_version="5000026" javascript_position="1000050">// Empty</file>
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.submit.js" javascript_type="template" javascript_version="5000026" javascript_position="1000050"><![CDATA[ips.templates.set('gallery.submit.imageItem', " \
<div class='ipsAttach ipsImageAttach {{#done}}ipsAttach_done{{/done}}' id='{{id}}' data-role='file' data-fileid='{{id}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-isImage='1'>\
<ul class='ipsImageAttach_controls'>\
<li data-role='insert' {{#insertable}}style='display: none'{{/insertable}}><a href='#' data-action='insertFile' class='ipsAttach_selection' data-ipsTooltip title='{{#lang}}insertIntoPost{{/lang}}'><i class='fa-solid fa-plus'></i></a></li>\
</li>\
<li class='ipsPos_right' {{#newUpload}}style='display: none'{{/newUpload}} data-role='deleteFileWrapper'>\
<li class='i-margin-start_auto' {{#newUpload}}style='display: none'{{/newUpload}} data-role='deleteFileWrapper'>\
<input type='hidden' name='{{field_name}}_keep[{{id}}]' value='1'>\
<a href='#' data-role='deleteFile' class='ipsButton ipsButton_verySmall ipsButton_light' data-ipsTooltip title='{{#lang}}attachRemove{{/lang}}'><i class='fa fa-trash-o'></i></a>\
<a href='#' data-role='deleteFile' class='ipsButton ipsButton--small ipsButton--soft' data-ipsTooltip title='{{#lang}}attachRemove{{/lang}}'><i class='fa-regular fa-trash-can'></i></a>\
</li>\
</ul>\
<div class='ipsImageAttach_thumb ipsType_center' data-role='preview' data-grid-ratio='65' data-action='insertFile' {{#thumb}}style='background-image: url( \"{{thumbnail}}\" )'{{/thumb}}>\
<div class='ipsImageAttach_thumb' data-role='preview' data-grid-ratio='65' data-action='insertFile' {{#thumb}}style='background-image: url( \"{{thumbnail}}\" )'{{/thumb}}>\
{{#status}}\
<span class='ipsImageAttach_status ipsType_light' data-role='status'>{{{status}}}</span>\
<span class='ipsAttachment_progress'><span data-role='progressbar'></span></span>\
<span class='ipsImageAttach_status i-color_soft' data-role='status'>{{{status}}}</span>\
<meter class='ipsMeter' data-role='progressbar' max='100'></meter>\
{{/status}}\
{{#thumb}}\
{{{thumb}}}\
{{/thumb}}\
</div>\
<h2 class='ipsType_reset ipsAttach_title ipsType_medium ipsTruncate ipsTruncate_line cGalleryImageAttach_info' data-role='title'>{{title}}</h2>\
<p class='ipsType_light cGalleryImageAttach_info'>{{size}} {{#statusText}}&middot; <span data-role='status'>{{statusText}}</span>{{/statusText}}</p>\
<h2 class='ipsAttach_title ipsTruncate_1 cGalleryImageAttach_info' data-role='title'>{{title}}</h2>\
<p class='cGalleryImageAttach_info'>{{size}} {{#statusText}}&middot; <span data-role='status'>{{statusText}}</span>{{/statusText}}</p>\
</div>\
");
ips.templates.set('gallery.submit.imageItemWrapper', " \
<div class='cGallerySubmit_fileList'>{{{content}}}</div>\
");]]></file>
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.view.js" javascript_type="template" javascript_version="107827" javascript_position="1000050"><![CDATA[ips.templates.set('gallery.notes.wrapper', " \
<file javascript_app="gallery" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.view.js" javascript_type="template" javascript_version="5000026" javascript_position="1000050"><![CDATA[ips.templates.set('gallery.notes.wrapper', " \
<div class='cGalleryNote' data-controller='gallery.front.view.note' data-noteID='{{id}}' data-note=\"{{note}}\" {{#editable}}data-editable{{/editable}} data-posLeft='{{left}}' data-posTop='{{top}}' data-dimWidth='{{width}}' data-dimHeight='{{height}}'>\
<div class='cGalleryNote_border'></div>\
<div class='cGalleryNote_note' style='display: none'>\
@@ -2026,9 +1894,9 @@ ips.templates.set('gallery.notes.delete', " \
ips.templates.set('gallery.notes.edit', " \
<textarea>{{note}}</textarea>\
<ul class='ipsList_inline'>\
<li><button data-action='save' class='ipsButton ipsButton_light ipsButton_verySmall'>{{#lang}}save_note{{/lang}}</button></li>\
<li><a href='#' data-action='cancel'>{{#lang}}cancel_note{{/lang}}</a></li>\
<ul class='ipsButtons i-justify-content_start i-margin-top_2'>\
<li><button data-action='save' class='ipsButton ipsButton--positive'>{{#lang}}save_note{{/lang}}</button></li>\
<li><a href='#' class='ipsButton ipsButton--inherit' data-action='cancel'>{{#lang}}cancel_note{{/lang}}</a></li>\
</ul>\
");]]></file>
<order app="global" path="/dev/js//framework/">templates
+10 -6
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="gallery" version="107827">
<app key="gallery" version="5000026">
<word key="__app_gallery" js="0">Gallery</word>
<word key="frontnavigation_gallery" js="0">Gallery</word>
<word key="gallery_title" js="0">Gallery</word>
@@ -39,7 +39,6 @@
<word key="filestorage__gallery_Images" js="0">Gallery Images</word>
<word key="acp_search_title_gallery_Categories" js="0">Gallery Categories</word>
<word key="acp_search_title_gallery_Albums" js="0">Gallery Albums</word>
<word key="gallery_images" js="0">Images</word>
<word key="gallery_media" js="0">Gallery Videos</word>
<word key="block_gallery_Overview" js="0">Gallery Overview</word>
<word key="total_images" js="0">Total Images</word>
@@ -195,6 +194,7 @@
<word key="can_unhide_gallery_image" js="0">Can unhide images?</word>
<word key="can_view_hidden_gallery_image" js="0">Can view hidden images?</word>
<word key="can_delete_gallery_image" js="0">Can delete images?</word>
<word key="can_view_reports_gallery_image" js="0">Can view reported images?</word>
<word key="can_edit_gallery_image_comment" js="0">Can edit comments?</word>
<word key="can_hide_gallery_image_comment" js="0">Can hide comments?</word>
<word key="can_unhide_gallery_image_comment" js="0">Can unhide comments?</word>
@@ -215,6 +215,7 @@
<word key="can_edit_item_message_gallery_album" js="0">Can edit messages on albums?</word>
<word key="can_delete_item_message_gallery_album" js="0">Can delete messages on albums?</word>
<word key="can_delete_gallery_album" js="0">Can delete albums?</word>
<word key="can_view_reports_gallery_album" js="0">Can view reported albums?</word>
<word key="can_edit_gallery_album_comment" js="0">Can edit album comments?</word>
<word key="can_hide_gallery_album_comment" js="0">Can hide album comments?</word>
<word key="can_unhide_gallery_album_comment" js="0">Can unhide album comments?</word>
@@ -225,6 +226,7 @@
<word key="can_unhide_gallery_album_review" js="0">Can unhide album reviews?</word>
<word key="can_view_hidden_gallery_album_review" js="0">Can view hidden album reviews?</word>
<word key="can_delete_gallery_album_review" js="0">Can delete album reviews?</word>
<word key="can_view_reports_gallery_album_review" js="0">Can view reported album reviews?</word>
<word key="can_edit_gallery_image_review" js="0">Can edit reviews?</word>
<word key="can_hide_gallery_image_review" js="0">Can hide reviews?</word>
<word key="can_unhide_gallery_image_review" js="0">Can unhide reviews?</word>
@@ -273,6 +275,7 @@
<word key="bdate" js="0">Date</word>
<word key="bsize" js="0">Image size</word>
<word key="bandwidth_stats" js="0">Bandwidth Usage</word>
<word key="gallery_images" js="0">Images</word>
<word key="images_submitted" js="0">Images Submitted</word>
<word key="gdiskspace_used" js="0">Diskspace Used</word>
<word key="gaverage_filesize" js="0">Average Filesize</word>
@@ -332,6 +335,7 @@
<word key="image_new_album" js="0">Create new album?</word>
<word key="image__comment_placeholder" js="0">Add a comment...</word>
<word key="image_submit_comment" js="0">Submit Comment</word>
<word key="filedata__image_description" js="0">Description</word>
<word key="map_enabled" js="0">Show map?</word>
<word key="map_enabled_lightbox" js="0">Show map?</word>
<word key="map_privacy" js="0">Map privacy</word>
@@ -523,12 +527,10 @@
<word key="gallery_category_id" js="0">Category</word>
<word key="profile_gallery_gallery" js="0">Albums</word>
<word key="profile_gallery_galleryImages" js="0">Images</word>
<word key="choose_album" js="0">Choose Album</word>
<word key="choose_category" js="0">Choose Category</word>
<word key="upload_images" js="0">Upload Images</word>
<word key="image_information" js="0">Add Information</word>
<word key="process" js="0">Finish</word>
<word key="create_new_album" js="0">Create new album</word>
<word key="choose_selected_album" js="0">Use Selected Album</word>
<word key="submit_breadcrumb" js="0">Submit Image</word>
<word key="submit_directly_to" js="0">Post directly to the category %s</word>
@@ -550,7 +552,6 @@
<word key="create_album" js="0">Create Album</word>
<word key="create_an_album" js="0">Create an album</word>
<word key="add_to_existing_album" js="0">Add to an existing album</word>
<word key="choose_existing_album" js="0">Use an existing album</word>
<word key="change_album" js="0">change</word>
<word key="set_tags" js="0">Set tags...</word>
<word key="set_copyright" js="0">Set copyright...</word>
@@ -572,6 +573,7 @@
<word key="add_gallery_image_limit" js="0"><![CDATA[Planning to add these to an album? Albums can contain up to <strong>{# [1:image or video][?:images or videos]}</strong>.]]></word>
<word key="add_gallery_album_limit" js="0"><![CDATA[You can upload up to <strong>{# [1:image or video][?:images or videos]}</strong> to this album]]></word>
<word key="album_full" js="0">Album full</word>
<word key="choose_album" js="0">Choose Album</word>
<word key="album_full_desc" js="0">You can't add any more images to this album</word>
<word key="x_more_images_album" js="0">You can add {# [1:more image][?:more images]} to this album</word>
<word key="saving_images" js="0">Saving Images</word>
@@ -579,11 +581,13 @@
<word key="adding_to_category_x" js="0"><![CDATA[Adding images to <strong>%s</strong>]]></word>
<word key="add_copyright_image" js="0">Add a copyright for this image</word>
<word key="add_credit_image" js="0">Add a credit for this image</word>
<word key="create_new_album" js="0">Create new album</word>
<word key="cannot_create_album" js="0">Sorry, you don't have permission to create a new album in this category.</word>
<word key="used_max_albums" js="0">You can't create any more albums (maximum of %d).</word>
<word key="no_existing_albums" js="0">You have no albums in this category to choose from</word>
<word key="use_no_album" js="0">Continue without using an album</word>
<word key="uploading_to_x" js="0">Uploading to %s</word>
<word key="choose_existing_album" js="0">Use an existing album</word>
<word key="files_had_errors" js="0">Some files had errors</word>
<word key="copyright" js="0">Copyright</word>
<word key="set_copyright_desc" js="0">Sets the copyright for each image you're uploading except ones you individually add a copyright for.</word>
@@ -868,7 +872,7 @@
<word key="gallery_new_images_count" js="0">Number of new images to show</word>
<word key="gallery_nsfw" js="0">Enable NSFW?</word>
<word key="gallery_nsfw_desc" js="0">Images can be set as not safe for work (NSFW) and will appear blurred unless the member opts in to viewing them.</word>
<word key="gallery_image_is_nsfw" js="0">This image is NSFW</word>
<word key="gallery_image_is_nsfw" js="0">This media is NSFW</word>
<word key="gallery_nsfw_view_anyway" js="0">View anyway</word>
<word key="nsfw_set_all" js="0">Set NSFW on all</word>
<word key="nsfw_enable_all" js="0">Mark all images as not safe for work</word>
+7
View File
@@ -0,0 +1,7 @@
{
"Gallery": {
"type": "MemberListenerType",
"classname": "IPS\\gallery\\listeners\\Gallery",
"extends": "IPS\\Member"
}
}
+10 -8
View File
@@ -1702,16 +1702,18 @@
"zerofill": false
},
"image_file_size": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 20,
"name": "image_file_size",
"type": "BIGINT",
"length": 20,
"decimals": null,
"values": [],
"allow_null": false,
"default": 0,
"comment": "",
"unsigned": false,
"auto_increment": false
"values": [],
"zerofill": false
},
"image_file_type": {
"allow_null": true,
@@ -2250,7 +2252,7 @@
"decimals": null,
"values": null,
"allow_null": false,
"default": 0,
"default": "",
"comment": "",
"unsigned": true,
"auto_increment": false
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
[]
+26 -393
View File
@@ -1,360 +1,4 @@
{
"31000": "3.1.0 Beta 1",
"31001": "3.1.0 RC 1",
"31002": "3.1.0 RC 2",
"31003": "3.1.0",
"32000": "3.2.0 Beta 1",
"32001": "3.2.0 Beta 2",
"32002": "3.2.0 Beta 3",
"32003": "3.2.0",
"32004": "3.2.1",
"32005": "3.2.2",
"40000": "4.0.0 Beta 1",
"40001": "4.0.0 Beta 2",
"40002": "4.0.0 Beta 3",
"40003": "4.0.0 Beta 4",
"40004": "4.0.0 Beta 4a",
"40005": "4.0.0 Beta 6",
"40006": "4.0.0",
"40007": "4.0.1",
"40008": "4.0.2",
"40009": "4.0.3",
"40010": "4.0.4",
"41000": "4.1.0 Beta 1",
"41001": "4.1.0 Beta 2",
"41002": "4.1.0",
"41003": "4.1.1",
"42000": "4.2.0 RC 1",
"42001": "4.2.0",
"42002": "4.2.1",
"42003": "4.2.2",
"50000": "5.0.0 Beta 1",
"50001": "5.0.0 Beta 2",
"50002": "5.0.0",
"50003": "5.0.1",
"50004": "5.0.2",
"50005": "5.0.3",
"50006": "5.0.4",
"50007": "5.0.5",
"50008": "5.0.6",
"60000": "4.0.0",
"100000": "4.0.0 Beta 0",
"100001": "4.0.0 Beta 1",
"100002": "4.0.0 Beta 2",
"100003": "4.0.0 Beta 3",
"100004": "4.0.0 Beta 3a",
"100005": "4.0.0 Beta 4",
"100006": "4.0.0 Beta 4a",
"100007": "4.0.0 Beta 4b",
"100008": "4.0.0 Beta 5",
"100009": "4.0.0 Beta 5a",
"100010": "4.0.0 Beta 6",
"100011": "4.0.0 Beta 7",
"100012": "4.0.0 Beta 7a",
"100013": "4.0.0 Beta 8",
"100014": "4.0.0 RC1",
"100015": "4.0.0 RC2",
"100016": "4.0.0 RC3",
"100017": "4.0.0 RC4",
"100018": "4.0.0 RC5",
"100019": "4.0.0 RC5a",
"100020": "4.0.0 RC6",
"100021": "4.0.0 RC7",
"100022": "4.0.0 RC7a",
"100023": "4.0.0",
"100024": "4.0.1",
"100025": "4.0.2",
"100026": "4.0.3",
"100027": "4.0.4",
"100028": "4.0.5",
"100029": "4.0.5.1",
"100030": "4.0.6",
"100031": "4.0.6.1",
"100032": "4.0.7",
"100033": "4.0.8",
"100034": "4.0.8.1",
"100035": "4.0.9",
"100036": "4.0.9.1",
"100037": "4.0.9.2",
"100038": "4.0.10",
"100039": "4.0.10.1",
"100040": "4.0.10.2",
"100041": "4.0.11",
"100042": "4.0.12",
"100043": "4.0.12.1",
"100044": "4.0.13",
"100045": "4.0.13.1",
"101000": "4.1.0 Beta 1",
"101001": "4.1.0 Beta 2",
"101002": "4.1.0 Beta 3",
"101003": "4.1.0 Beta 4",
"101004": "4.1.0 Beta 5",
"101005": "4.1.0 Beta 6",
"101006": "4.1.0 Beta 7",
"101007": "4.1.0 Beta 8",
"101008": "4.1.0 Beta 9",
"101009": "4.1.0 Beta 10",
"101010": "4.1.0",
"101011": "4.1.1",
"101012": "4.1.2",
"101013": "4.1.3",
"101014": "4.1.3.1",
"101015": "4.1.3.2",
"101016": "4.1.4",
"101017": "4.1.4.1",
"101018": "4.1.5",
"101019": "4.1.5.1",
"101020": "4.1.5.2",
"101021": "4.1.6",
"101022": "4.1.6.1",
"101023": "4.1.7",
"101024": "4.1.8",
"101025": "4.1.8.1",
"101026": "4.1.9",
"101027": "4.1.10",
"101028": "4.1.11",
"101029": "4.1.11.1",
"101030": "4.1.12",
"101031": "4.1.12.1",
"101032": "4.1.12.2",
"101033": "4.1.12.3",
"101034": "4.1.13 Beta 1",
"101035": "4.1.13 Beta 2",
"101036": "4.1.13",
"101037": "4.1.13",
"101038": "4.1.13.1",
"101040": "4.1.13.2",
"101041": "4.1.13.2",
"101042": "4.1.14 Beta 1",
"101043": "4.1.14 Beta 2",
"101044": "4.1.14 Beta 3",
"101045": "4.1.14 Beta 4",
"101046": "4.1.14 Beta 5",
"101049": "4.1.14 Beta 6",
"101050": "4.1.14 Beta 7",
"101051": "4.1.14 RC",
"101052": "4.1.14",
"101053": "4.1.14.1",
"101054": "4.1.14.2",
"101055": "4.1.14.3",
"101056": "4.1.15",
"101057": "4.1.15 Beta 1",
"101058": "4.1.15 Beta 2",
"101059": "4.1.15 Beta 2a",
"101060": "4.1.15 Beta 3",
"101061": "4.1.15",
"101062": "4.1.15",
"101063": "4.1.15",
"101064": "4.1.16 Beta 1",
"101065": "4.1.16 Beta 2",
"101066": "4.1.16 Beta 3",
"101067": "4.1.16 Beta 4",
"101068": "4.1.16 Beta 5",
"101069": "4.1.16",
"101070": "4.1.16.1",
"101071": "4.1.17 Beta 1",
"101072": "4.1.17 Beta 1a",
"101073": "4.1.17 Beta 1b",
"101074": "4.1.17 Beta 2",
"101075": "4.1.17 Beta 3",
"101076": "4.1.17 Beta 3",
"101077": "4.1.17",
"101078": "4.1.17.1",
"101079": "4.1.18 Beta 1",
"101082": "4.1.18 Beta 1b",
"101083": "4.1.18 Beta 2",
"101084": "4.1.18 Beta 3",
"101085": "4.1.18",
"101088": "4.1.18.1",
"101089": "4.1.18.2",
"101090": "4.1.19 Beta 1",
"101091": "4.1.19 Beta 2",
"101092": "4.1.19 Beta 3",
"101093": "4.1.19",
"101094": "4.1.19.1",
"101095": "4.1.19.2 Beta 1",
"101096": "4.1.19.2",
"101097": "4.1.19.2",
"101098": "4.1.19.3",
"101099": "4.1.19.4",
"101100": "4.2.0 Beta 1",
"101101": "4.2.0 Beta 1",
"101102": "4.2.0 Beta 1",
"101103": "4.2.0 Beta 1",
"101104": "4.2.0 Beta 2",
"101105": "4.2.0 Beta 3",
"101106": "4.2.0 Beta 3a",
"101107": "4.2.0 Beta 4",
"101108": "4.2.0 Beta 4",
"101109": "4.2.0 Beta 5",
"101110": "4.2.0 Beta 5a",
"101111": "4.2.0 Beta 6",
"101112": "4.2.0 Beta 6a",
"101113": "4.2.0 Beta 6a",
"101114": "4.2.0 Beta 7",
"101115": "4.2.0 Beta 7a",
"101116": "4.2.0 Beta 8",
"101117": "4.2.0 Beta 8",
"102000": "4.2.0",
"102001": "4.2.0",
"102002": "4.2.0",
"102003": "4.2.0",
"102004": "4.2.1",
"102005": "4.2.2 Beta 1",
"102006": "4.2.2 Beta 2",
"102007": "4.2.2",
"102008": "4.2.2",
"102009": "4.2.2",
"102010": "4.2.3 Beta 1",
"102011": "4.2.3",
"102012": "4.2.3",
"102013": "4.2.3",
"102014": "4.2.4 Beta 1",
"102015": "4.2.4 Beta 2",
"102016": "4.2.4",
"102017": "4.2.4",
"102018": "4.2.4",
"102019": "4.2.4",
"102020": "4.2.4",
"102021": "4.2.5 Beta 1",
"102022": "4.2.5 Beta 2",
"102023": "4.2.5 Beta 3",
"102024": "4.2.5",
"102025": "4.2.5",
"102026": "4.2.5",
"102027": "4.2.5",
"102028": "4.2.5",
"102029": "4.2.5",
"102030": "4.2.6 Beta 1",
"102031": "4.2.6 Beta 1",
"102032": "4.2.6 Beta 2",
"102033": "4.2.6 Beta 3",
"102034": "4.2.6",
"102035": "4.2.6",
"102036": "4.2.6",
"102037": "4.2.7 Beta 1",
"102038": "4.2.7 Beta 2",
"102039": "4.2.7 Beta 3",
"102040": "4.2.7 Beta 4",
"102041": "4.2.7 Beta 5",
"102042": "4.2.7",
"102043": "4.2.7",
"102044": "4.2.7",
"102045": "4.2.7",
"102046": "4.2.7",
"102047": "4.2.8",
"102048": "4.2.8",
"102049": "4.2.9",
"103000": "4.3.0 Beta 1",
"103002": "4.3.0 Beta 2",
"103003": "4.3.0 Beta 3",
"103004": "4.3.0 Beta 4",
"103005": "4.3.0",
"103006": "4.3.1",
"103007": "4.3.1",
"103008": "4.3.1",
"103009": "4.3.2",
"103010": "4.3.2",
"103011": "4.3.3",
"103012": "4.3.3",
"103013": "4.3.3",
"103014": "4.3.3",
"103015": "4.3.3",
"103016": "4.3.3",
"103017": "4.3.3",
"103018": "4.3.3",
"103019": "4.3.3",
"103020": "4.3.3",
"103021": "4.3.4",
"103022": "4.3.4",
"103023": "4.3.4",
"103024": "4.3.4",
"103025": "4.3.4",
"103026": "4.3.5 Beta 1",
"103027": "4.3.5 Beta 2",
"103028": "4.3.5",
"103029": "4.3.5",
"103030": "4.3.5",
"103031": "4.3.5",
"103032": "4.3.5",
"103033": "4.3.6 Beta 1",
"103034": "4.3.6 Beta 2",
"103035": "4.3.6",
"103036": "4.3.6",
"103037": "4.3.6",
"103038": "4.3.6",
"103039": "4.3.6",
"104000": "4.4.0 Beta 1",
"104001": "4.4.0 Beta 2",
"104002": "4.4.0 Beta 3",
"104004": "4.4.0 Beta 4",
"104003": "4.4.0 Beta 4",
"104005": "4.4.0",
"104006": "4.4.0",
"104007": "4.4.0",
"104008": "4.4.0",
"104009": "4.4.1",
"104010": "4.4.1 Beta 2",
"104011": "4.4.1",
"104012": "4.4.1",
"104013": "4.4.1",
"104014": "4.4.1",
"104015": "4.4.2 Beta 1",
"104016": "4.4.2",
"104017": "4.4.2",
"104018": "4.4.2",
"104019": "4.4.2",
"104020": "4.4.2",
"104021": "4.4.3 Beta 1",
"104022": "4.4.3 Beta 2",
"104023": "4.4.3",
"104024": "4.4.3",
"104025": "4.4.3",
"104026": "4.4.4 Beta 1",
"104027": "4.4.4",
"104028": "4.4.4",
"104029": "4.4.4",
"104030": "4.4.5 Beta 1",
"104031": "4.4.5 Beta 2",
"104032": "4.4.5 Beta 2",
"104033": "4.4.5",
"104034": "4.4.5",
"104035": "4.4.5",
"104036": "4.4.5",
"104037": "4.4.5",
"104038": "4.4.6",
"104039": "4.4.6",
"104040": "4.4.6",
"104041": "4.4.7 Beta 1",
"104042": "4.4.7 Beta 2",
"104043": "4.4.7 Beta 3",
"104044": "4.4.7",
"104045": "4.4.8 Beta 1",
"104046": "4.4.8 Beta 2",
"104047": "4.4.8",
"104048": "4.4.9 Beta 1",
"104049": "4.4.9",
"104050": "4.4.9",
"104051": "4.4.9",
"104052": "4.4.9",
"104053": "4.4.9.1",
"104054": "4.4.9.1",
"104055": "4.4.9.2",
"104056": "4.4.9.2",
"104057": "4.4.10 Beta 1",
"104058": "4.4.10 Beta 2",
"104059": "4.4.10 Beta 3",
"104060": "4.4.10 Beta 4",
"104061": "4.4.10",
"104062": "4.4.10",
"104063": "4.4.10",
"104064": "4.4.10",
"104065": "4.4.10",
"104066": "4.4.10",
"104067": "4.4.10",
"104068": "4.4.10",
"104069": "4.4.10",
"104070": "4.4.11",
"105013": "4.5.0 Beta 1",
"105014": "4.5.0 Beta 1",
"105015": "4.5.0 Beta 2",
@@ -606,41 +250,30 @@
"107751": "4.7.16",
"107760": "4.7.17 Beta 1",
"107761": "4.7.17 Beta 2",
"107762": "4.7.17 Beta 3",
"107763": "4.7.17",
"107764": "4.7.17",
"107765": "4.7.17",
"107770": "4.7.18 Beta 1",
"107771": "4.7.18 Beta 2",
"107772": "4.7.18 Beta 3",
"107773": "4.7.18",
"107774": "4.7.18",
"107775": "4.7.18",
"107780": "4.7.19 Beta 1",
"107781": "4.7.19 Beta 2",
"107782": "4.7.19 Beta 3",
"107783": "4.7.19 Beta 4",
"107784": "4.7.19",
"107785": "4.7.19",
"107786": "4.7.19",
"107787": "4.7.19",
"107795": "4.7.20 Beta 1",
"107796": "4.7.20 Beta 2",
"107797": "4.7.20 Beta 3",
"107798": "4.7.20 Beta 4",
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
"107802": "4.7.20",
"107803": "4.7.20",
"107810": "4.7.21 Beta 1",
"107811": "4.7.21",
"107815": "4.7.22 Beta 1",
"107816": "4.7.22 Beta 2",
"107817": "4.7.22",
"107818": "4.7.22",
"107819": "4.7.22",
"107820": "4.7.22",
"107826": "4.7.23 Beta 1",
"107827": "4.7.23"
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
"5000004": "5.0.0 Alpha 4",
"5000005": "5.0.0 Alpha 5",
"5000006": "5.0.0 Alpha 5",
"5000007": "5.0.0 Alpha 5",
"5000008": "5.0.0 Alpha 5",
"5000009": "5.0.0 Alpha 6",
"5000010": "5.0.0 Alpha 7",
"5000011": "5.0.0 Alpha 8",
"5000012": "5.0.0 Alpha 9",
"5000013": "5.0.0 Alpha 9",
"5000014": "5.0.0 Alpha 9",
"5000015": "5.0.0 Alpha 10",
"5000016": "5.0.0 Alpha 11",
"5000017": "5.0.0 Alpha 11",
"5000018": "5.0.0 Alpha 12",
"5000019": "5.0.0 Alpha 12",
"5000020": "5.0.0 Alpha 12",
"5000021": "5.0.0 Alpha 13",
"5000022": "5.0.0 Alpha 14",
"5000023": "5.0.0 Alpha 15",
"5000024": "5.0.0 Alpha 16",
"5000025": "5.0.0 Alpha 16",
"5000026": "5.0.0 Beta 1"
}
@@ -12,16 +12,20 @@
namespace IPS\gallery\extensions\core\AdvertisementLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\AdvertisementLocationsAbstract;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Advertisement locations extension
*/
class _ImageLightbox
class ImageLightbox extends AdvertisementLocationsAbstract
{
/**
* Get the locations and the additional settings
@@ -29,7 +33,7 @@ class _ImageLightbox
* @param array $settings Current setting values
* @return array Array with two elements: 'locations' which should have keys as the location keys and values as the fields to toggle, and 'settings' which are additional fields to add to the form
*/
public function getSettings( $settings )
public function getSettings( array $settings ): array
{
return array( 'locations' => array( 'ad_image_lightbox' => array() ), 'settings' => array() );
}
@@ -40,7 +44,7 @@ class _ImageLightbox
* @param array $values Values from the form submission
* @return array Array of setting key => value to store
*/
public function parseSettings( $values )
public function parseSettings( array $values ): array
{
return array();
}
@@ -12,87 +12,98 @@
namespace IPS\gallery\extensions\core\ContentRouter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Extensions\ContentRouterAbstract;
use IPS\gallery\Album\Item;
use IPS\gallery\Application;
use IPS\gallery\Image;
use IPS\gallery\Image\Table;
use IPS\Helpers\Table\Content;
use IPS\Http\Url;
use IPS\Member;
use IPS\Member\Group;
use IPS\Output;
use IPS\Request;
use IPS\Theme;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content Router extension: Gallery
*/
class _Gallery
class Gallery extends ContentRouterAbstract
{
/**
* @brief Content Item Classes
*/
public $classes = array();
/**
* @brief Item Classes for embed only
*/
public $embeddableContent = array( 'IPS\gallery\Album\Item' );
public array $embeddableContent = array( 'IPS\gallery\Album\Item' );
/**
* @brief Can be shown in similar content
*/
public $similarContent = TRUE;
public bool $similarContent = TRUE;
/**
* Constructor
*
* @param \IPS\Member|IPS\Member\Group|NULL $member If checking access, the member/group to check for, or NULL to not check access
* @return void
* @param Member|Group|null $member If checking access, the member/group to check for, or NULL to not check access
*/
public function __construct( $member = NULL )
public function __construct( Member|Group $member = NULL )
{
if ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'gallery', 'gallery', 'front' ) ) )
if ( $member === NULL or $member->canAccessModule( Module::get( 'gallery', 'gallery', 'front' ) ) )
{
$this->classes[] = 'IPS\gallery\Image';
$this->classes[] = 'IPS\gallery\Album\Item';
$this->classes[] = Image::class;
$this->classes[] = Item::class;
}
}
/**
* @brief Owned Node Classes
*/
public $ownedNodes = array( 'IPS\gallery\Album' );
public array $ownedNodes = array( 'IPS\gallery\Album' );
/**
* Use a custom table helper when building content item tables
*
* @param string $className The content item class
* @param \IPS\Http\Url $url The URL to use for the table
* @param array $where Custom where clause to pass to the table helper
* @return \IPS\Helpers\Table|void Custom table helper class to use
* @param string $className The content item class
* @param Url $url The URL to use for the table
* @param array $where Custom where clause to pass to the table helper
* @return Table|null Custom table helper class to use
*/
public function customTableHelper( $className, $url, $where=array() )
public function customTableHelper( string $className, Url $url, array $where=array() ): ?Content
{
if( !\in_array( $className, $this->classes ) or $className == 'IPS\gallery\Album\Item' )
if( !in_array( $className, $this->classes ) or $className == 'IPS\gallery\Album\Item' )
{
return new \IPS\Helpers\Table\Content( $className, $url, $where );
return new Content( $className, $url, $where );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_browse.js', 'gallery' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_global.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_browse.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_global.js', 'gallery' ) );
\IPS\gallery\Application::outputCss();
Application::outputCss();
$table = new \IPS\gallery\Image\Table( $className, $url, $where, NULL, FALSE );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'imageTable' );
$table = new Table( $className, $url, $where, NULL, FALSE );
$table->tableTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'imageTable' );
/* Get rows template */
if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'large' AND \IPS\Request::i()->controller != 'search' )
if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'large' AND Request::i()->controller != 'search' )
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsLarge' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsLarge' );
}
else if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'rows' AND \IPS\Request::i()->controller != 'search' )
else if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'rows' AND Request::i()->controller != 'search' )
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsRows' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsRows' );
}
else
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsThumbs' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsThumbs' );
}
return $table;
@@ -1,52 +0,0 @@
<?php
/**
* @brief Create Menu Extension : gallery
* @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
*/
namespace IPS\gallery\extensions\core\CreateMenu;
/* 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;
}
/**
* Create Menu Extension: gallery
*/
class _gallery
{
/**
* Get Items
*
* @return array
*/
public function getItems()
{
if ( \IPS\gallery\Category::canOnAny( 'add', NULL, \IPS\Settings::i()->club_nodes_in_apps ? array() : array( array( 'category_club_id IS NULL' ) ) ) )
{
return array(
'gallery_image' => array(
'link' => \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=submit&_new=1", 'front', 'gallery_submit' ),
'extraData' => array(
'data-ipsDialog-size' => "medium",
'data-ipsDialog' => 'true',
'data-ipsDialog-destructOnClose' => 'true',
'data-ipsDialog-close' => 'false',
'data-ipsDialog-extraClass' => 'cGalleryDialog_outer',
'data-ipsDialog-remoteSubmit' => 'true',
)
)
);
}
return array();
}
}
Whitespace-only changes.
@@ -12,23 +12,31 @@
namespace IPS\gallery\extensions\core\Dashboard;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\Extensions\DashboardAbstract;
use IPS\gallery\Image;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Dashboard extension: Overview
*/
class _Overview
class Overview extends DashboardAbstract
{
/**
* Can the current user view this dashboard item?
*
* @return bool
*/
public function canView()
public function canView(): bool
{
return TRUE;
}
@@ -38,26 +46,26 @@ class _Overview
*
* @return string
*/
public function getBlock()
public function getBlock(): string
{
/* Basic stats */
$data = array(
'total_disk_spaceg' => (int) \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first(),
'total_images' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first(),
'total_views' => (int) \IPS\Db::i()->select( 'SUM(image_views)', 'gallery_images' )->first(),
'total_comments' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_comments' )->first(),
'total_albums' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first(),
'total_disk_spaceg' => (int) Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first(),
'total_images' => (int) Db::i()->select( 'COUNT(*)', 'gallery_images' )->first(),
'total_views' => (int) Db::i()->select( 'SUM(image_views)', 'gallery_images' )->first(),
'total_comments' => (int) Db::i()->select( 'COUNT(*)', 'gallery_comments' )->first(),
'total_albums' => (int) Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first(),
);
/* Specific files (will fail if no files yet) */
try
{
$data['largest_image'] = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_file_size DESC', 1 )->first() );
$data['most_viewed_image'] = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_views DESC', 1 )->first() );
$data['largest_image'] = Image::constructFromData( Db::i()->select( '*', 'gallery_images', NULL, 'image_file_size DESC', 1 )->first() );
$data['most_viewed_image'] = Image::constructFromData( Db::i()->select( '*', 'gallery_images', NULL, 'image_views DESC', 1 )->first() );
}
catch ( \Exception $e ) { }
catch ( Exception ) { }
/* Display */
return \IPS\Theme::i()->getTemplate( 'dashboard', 'gallery' )->overview( $data );
return Theme::i()->getTemplate( 'dashboard', 'gallery' )->overview( $data );
}
}
@@ -12,36 +12,40 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Content;
use IPS\Db;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Album;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use IPS\Text\LegacyParser;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Albums
*/
class _Albums
class Albums extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return FALSE;
}
@@ -49,7 +53,7 @@ class _Albums
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -57,14 +61,14 @@ class _Albums
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$album = \IPS\gallery\Album::load( $id1 );
$album = Album::load( $id1 );
return $album->can( 'view', $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -76,12 +80,12 @@ class _Albums
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
return \IPS\gallery\Album::load( $id1 );
return Album::load( $id1 );
}
/**
@@ -92,19 +96,19 @@ class _Albums
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildContent( $offset, $max )
public function rebuildContent( ?int $offset, ?int $max ): int
{
$did = 0;
foreach( \IPS\Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $offset, $max ) ) as $album )
foreach( Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $offset, $max ) ) as $album )
{
$did++;
try
{
$rebuilt = \IPS\Text\LegacyParser::parseStatic( $album['album_description'] );
$rebuilt = LegacyParser::parseStatic( $album['album_description'] );
}
catch( \InvalidArgumentException $e )
catch( InvalidArgumentException $e )
{
if( $e->getcode() == 103014 )
{
@@ -118,7 +122,7 @@ class _Albums
if( $rebuilt !== FALSE )
{
\IPS\Db::i()->update( 'gallery_albums', array( 'album_description' => $rebuilt ), 'album_id=' . $album['album_id'] );
Db::i()->update( 'gallery_albums', array( 'album_description' => $rebuilt ), 'album_id=' . $album['album_id'] );
}
}
@@ -130,8 +134,8 @@ class _Albums
*
* @return int Total Count
*/
public function contentCount()
public function contentCount(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
}
}
@@ -12,36 +12,40 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Content;
use IPS\Db;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Category;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use IPS\Text\Parser;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Categories
*/
class _Categories
class Categories extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return NULL;
}
@@ -49,7 +53,7 @@ class _Categories
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -57,14 +61,14 @@ class _Categories
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$category = \IPS\gallery\Category::load( $id1 );
$category = Category::load( $id1 );
return $category->can( 'view', $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -76,25 +80,12 @@ class _Categories
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
return \IPS\gallery\Category::load( $id1 );
}
/**
* Rebuild attachment images in non-content item areas
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildAttachmentImages( $offset, $max )
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
return Category::load( $id1 );
}
/**
@@ -105,16 +96,11 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildContent( $offset, $max )
public function rebuildContent( ?int $offset, ?int $max ): int
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
}
/**
* @brief Use the cached image URL instead of the original URL
*/
protected $proxyUrl = FALSE;
/**
* Rebuild content to add or remove image proxy
*
@@ -124,17 +110,14 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildImageProxy( $offset, $max, $proxyUrl = FALSE )
public function rebuildImageProxy( ?int $offset, ?int $max, bool $proxyUrl = FALSE ): int
{
$this->proxyUrl = $proxyUrl;
return $this->performRebuild( $offset, $max, 'parseImageProxy' );
$callback = function( $value ) use ( $proxyUrl ) {
return Parser::removeImageProxy( $value, $proxyUrl );
};
return $this->performRebuild( $offset, $max, $callback );
}
/**
* @brief Store lazy loading status ( true = enabled )
*/
protected $_lazyLoadStatus = null;
/**
* Rebuild content to add or remove lazy loading
*
@@ -144,11 +127,9 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildLazyLoad( $offset, $max, $status=TRUE )
public function rebuildLazyLoad( ?int $offset, ?int $max ): int
{
$this->_lazyLoadStatus = $status;
return $this->performRebuild( $offset, $max, 'parseLazyLoad' );
return $this->performRebuild( $offset, $max, [ 'IPS\Text\Parser', 'parseLazyLoad' ] );
}
/**
@@ -159,31 +140,24 @@ class _Categories
* @param callable $callback Method to call to rebuild content
* @return int Number completed
*/
protected function performRebuild( $offset, $max, $callback )
protected function performRebuild( ?int $offset, ?int $max, callable $callback ): int
{
$did = 0;
/* Language bits */
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'", 'word_id ASC', array( $offset, $max ) ) as $word )
foreach( Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'", 'word_id ASC', array( $offset, $max ) ) as $word )
{
$did++;
$rebuilt = FALSE;
try
{
if( $callback == 'parseImageProxy' )
{
$rebuilt = \IPS\Text\Parser::removeImageProxy( $word['word_custom'], $this->proxyUrl );
}
elseif( $callback == 'parseLazyLoad' )
{
$rebuilt = \IPS\Text\Parser::parseLazyLoad( $word['word_custom'], $this->_lazyLoadStatus );
}
else
if( !empty( $word['word_custom'] ) )
{
$rebuilt = $callback( $word['word_custom'] );
}
}
catch( \InvalidArgumentException $e )
catch( InvalidArgumentException $e )
{
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
{
@@ -197,7 +171,7 @@ class _Categories
if( $rebuilt !== FALSE )
{
\IPS\Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
}
}
@@ -209,8 +183,8 @@ class _Categories
*
* @return int Total Count
*/
public function contentCount()
public function contentCount(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'" )->first();
return Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'" )->first();
}
}
@@ -12,25 +12,38 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content;
use IPS\gallery\Album;
use IPS\gallery\Album\Comment;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use LogicException;
use OutOfRangeException;
use RuntimeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Image comments
*/
class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
class Gallery extends Images
{
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return NULL;
}
@@ -38,7 +51,7 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -46,16 +59,16 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
if( $id3 and $id3 == 'album' )
{
try
{
$album = \IPS\gallery\Album::load( $id1 );
$album = Album::load( $id1 );
return $album->canView( $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -70,14 +83,14 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
if( $id3 and $id3 == 'album' )
{
return \IPS\gallery\Album\Comment::load( $id2 );
return Comment::load( $id2 );
}
return parent::attachmentLookup( $id1, $id2, $id3 );
@@ -87,11 +100,11 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* Can whatever is posted in this editor be moderated?
* If this returns TRUE, we must ensure the content is ran through word, link and image filters
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool
*/
public function canBeModerated( $member, $field )
public function canBeModerated( Member $member, Editor $field ): bool
{
/* Image comments/reviews */
if ( preg_match( '/^(?:editComment|reply|review)\-gallery\/gallery\-\d+/', $field->options['autoSaveKey'] ) )
@@ -103,9 +116,10 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
{
if ( \IPS\IN_DEV )
{
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
throw new RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
}
return FALSE;
return parent::canBeModerated( $member, $field );
}
}
}
@@ -12,61 +12,47 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\gallery\Image\Review;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Images
*/
class _Images
class Images extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return FALSE;
}
/**
* Can whatever is posted in this editor be moderated?
* If this returns TRUE, we must ensure the content is ran through word, link and image filters
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @return bool
*/
public function canBeModerated( $member, $field )
{
if ( \IPS\IN_DEV )
{
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
}
return FALSE;
}
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -74,14 +60,14 @@ class _Images
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$image = \IPS\gallery\Image::load( $id1 );
$image = Image::load( $id1 );
return $image->canView( $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -93,25 +79,25 @@ class _Images
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
if ( $id2 )
{
if ( $id3 === 'review' )
{
return \IPS\gallery\Image\Review::load( $id2 );
return Review::load( $id2 );
}
else
{
return \IPS\gallery\Image\Comment::load( $id2 );
return Comment::load( $id2 );
}
}
else
{
return \IPS\gallery\Image::load( $id1 );
return Image::load( $id1 );
}
}
@@ -12,26 +12,34 @@
namespace IPS\gallery\extensions\core\EditorMedia;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Extensions\EditorMediaAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Media: Images
*/
class _Images
class Images extends EditorMediaAbstract
{
/**
* Get Counts
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param string $postKey The post key
* @param string|null $search The search term (or NULL for all)
* @return array array( 'Title' => 0 )
* @return array|int array( 'Title' => 0 )
*/
public function count( $member, $postKey, $search=NULL )
public function count( Member $member, string $postKey, string $search=NULL ): array|int
{
$where = array(
array( "image_member_id=? AND image_approved=?", $member->member_id, 1 ),
@@ -40,14 +48,14 @@ class _Images
if ( $search )
{
$albumIds = [];
foreach( \IPS\Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
foreach( Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
{
$albumIds[] = $album;
}
if ( count( $albumIds ) )
{
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . \IPS\Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
}
else
{
@@ -55,20 +63,20 @@ class _Images
}
}
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', $where )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_images', $where )->first();
}
/**
* Get Files
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param string|null $search The search term (or NULL for all)
* @param string $postKey The post key
* @param int $page Page
* @param int $limit Number to get
* @return array array( 'Title' => array( (IPS\File, \IPS\File, ... ), ... )
*/
public function get( $member, $search, $postKey, $page, $limit )
public function get( Member $member, ?string $search, string $postKey, int $page, int $limit ): array
{
$where = array(
array( "image_member_id=? AND image_approved=?", $member->member_id, 1 ),
@@ -77,14 +85,14 @@ class _Images
if ( $search )
{
$albumIds = [];
foreach( \IPS\Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
foreach( Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
{
$albumIds[] = $album;
}
if ( count( $albumIds ) )
{
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . \IPS\Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
}
else
{
@@ -93,11 +101,11 @@ class _Images
}
$return = array();
foreach ( \IPS\Db::i()->select( '*', 'gallery_images', $where, 'image_date DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
foreach ( Db::i()->select( '*', 'gallery_images', $where, 'image_date DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
{
$image = \IPS\gallery\Image::load( $row['image_id'] );
$image = Image::load( $row['image_id'] );
$fileName = $image->masked_file_name ?: $image->original_file_name;
$obj = \IPS\File::get( 'gallery_Images', $fileName );
$obj = File::get( 'gallery_Images', $fileName );
$obj->contextInfo = $image->caption;
$return[ (string) $image->url() ] = $obj;
}
@@ -12,25 +12,34 @@
namespace IPS\gallery\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\Extensions\FileStorageAbstract;
use IPS\File;
use UnderflowException;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File Storage Extension: Images
*/
class _Images
class Images extends FileStorageAbstract
{
/**
* Count stored files
*
* @return int
*/
public function count()
public function count(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
}
/**
@@ -39,22 +48,22 @@ class _Images
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @return void
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
{
$image = \IPS\Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$image = Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$update = array();
if( $image['image_small_file_name'] )
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_small_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_small_file_name'] )->move( $storageConfiguration );
$update['image_small_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
@@ -70,10 +79,10 @@ class _Images
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_masked_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_masked_file_name'] )->move( $storageConfiguration );
$update['image_masked_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
@@ -90,76 +99,48 @@ class _Images
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_original_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_original_file_name'] )->move( $storageConfiguration );
$update['image_original_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
}
}
if ( \count( $update ) )
if ( count( $update ) )
{
foreach( $update as $k => $v )
{
if ( $update[ $k ] == $image[ $k ] )
if ( $v == $image[ $k ] )
{
unset( $update[ $k ] );
}
}
if ( \count( $update ) )
if ( count( $update ) )
{
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
}
}
}
/**
* Fix all URLs
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @return void
*/
public function fixUrls( $offset )
{
$image = \IPS\Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$update = array();
foreach( array( 'image_small_file_name', 'image_masked_file_name', 'image_original_file_name' ) as $key )
{
if( $image[ $key ] )
{
if ( $new = \IPS\File::repairUrl( $image[ $key ] ) )
{
$update[ $key ] = $new;
}
}
}
if ( \count( $update ) )
{
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
}
}
/**
* Check if a file is valid
*
* @param string $file The file path to check
* @param File|string $file The file path to check
* @return bool
*/
public function isValidFile( $file )
public function isValidFile( File|string $file ): bool
{
try
{
$record = \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_masked_file_name=? OR image_original_file_name=? OR image_small_file_name=?', (string) $file, (string) $file, (string) $file ) )->first();
$record = Db::i()->select( '*', 'gallery_images', array( 'image_masked_file_name=? OR image_original_file_name=? OR image_small_file_name=?', (string) $file, (string) $file, (string) $file ) )->first();
return TRUE;
}
catch ( \UnderflowException $e )
catch ( UnderflowException )
{
return FALSE;
}
@@ -170,9 +151,9 @@ class _Images
*
* @return void
*/
public function delete()
public function delete() : void
{
foreach( \IPS\Db::i()->select( '*', 'gallery_images' ) as $image )
foreach( Db::i()->select( '*', 'gallery_images' ) as $image )
{
foreach( array( 'image_masked_file_name', 'image_original_file_name', 'image_small_file_name' ) as $size )
{
@@ -180,9 +161,9 @@ class _Images
{
try
{
\IPS\File::get( 'gallery_Images', $image[ $size ] )->delete();
File::get( 'gallery_Images', $image[ $size ] )->delete();
}
catch( \Exception $e ){}
catch( Exception ){}
}
}
}
@@ -12,64 +12,78 @@
namespace IPS\gallery\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\core\FrontNavigation;
use IPS\core\FrontNavigation\FrontNavigationAbstract;
use IPS\Dispatcher;
use IPS\Http\Url;
use IPS\Member;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Gallery
*/
class _Gallery extends \IPS\core\FrontNavigation\FrontNavigationAbstract
class Gallery extends FrontNavigationAbstract
{
/**
* @var string Default icon
*/
public string $defaultIcon = '\f87c';
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
public static function typeTitle(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
return Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
}
/**
* Can the currently logged in user access the content this item links to?
*
* @return bool
* @return bool
*/
public function canAccessContent()
public function canAccessContent(): bool
{
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'gallery', 'gallery' ) );
return Member::loggedIn()->canAccessModule( Module::get( 'gallery', 'gallery' ) );
}
/**
* Get Title
*
* @return string
* @return string
*/
public function title()
public function title(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
return Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
}
/**
* Get Link
*
* @return \IPS\Http\Url
* @return string|Url|null
*/
public function link()
public function link(): Url|string|null
{
return \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=browse", 'front', 'gallery' );
return Url::internal( "app=gallery&module=gallery&controller=browse", 'front', 'gallery' );
}
/**
* Is Active?
*
* @return bool
* @return bool
*/
public function active()
public function active(): bool
{
return !\IPS\core\FrontNavigation::$clubTabActive and \IPS\Dispatcher::i()->application->directory === 'gallery';
return !FrontNavigation::$clubTabActive and !FrontNavigation::nodeExtensionIsActive( 'gallery' ) and Dispatcher::i()->application->directory === 'gallery';
}
}
@@ -12,83 +12,95 @@
namespace IPS\gallery\extensions\core\GroupForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupFormAbstract;
use IPS\gallery\Image;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use IPS\Member\Group;
use IPS\Settings;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Group Form
*/
class _Gallery
class Gallery extends GroupFormAbstract
{
/**
* Process Form
*
* @param \IPS\Helpers\Form $form The form
* @param \IPS\Member\Group $group Existing Group
* @param Form $form The form
* @param Group $group Existing Group
* @return void
*/
public function process( &$form, $group )
public function process( Form $form, Group $group ) : void
{
if( $group->g_id != \IPS\Settings::i()->guest_group )
if( $group->g_id != Settings::i()->guest_group )
{
$form->addHeader( 'gallery_album_permissions' );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums', $group->g_create_albums, FALSE, array( 'togglesOn' => array( 'g_create_albums_private', 'g_create_albums_fo', 'g_album_limit', 'g_img_album_limit' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums_private', $group->g_create_albums_private, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_private' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums_fo', $group->g_create_albums_fo, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_fo' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_album_limit', $group->g_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_album_limit' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_img_album_limit', $group->g_img_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_img_album_limit' ) );
$form->add( new YesNo( 'g_create_albums', $group->g_create_albums, FALSE, array( 'togglesOn' => array( 'g_create_albums_private', 'g_create_albums_fo', 'g_album_limit', 'g_img_album_limit' ) ) ) );
$form->add( new YesNo( 'g_create_albums_private', $group->g_create_albums_private, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_private' ) );
$form->add( new YesNo( 'g_create_albums_fo', $group->g_create_albums_fo, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_fo' ) );
$form->add( new Number( 'g_album_limit', $group->g_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_album_limit' ) );
$form->add( new Number( 'g_img_album_limit', $group->g_img_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_img_album_limit' ) );
}
$form->addHeader( 'gallery_restrictions' );
if( \IPS\Settings::i()->gallery_use_watermarks )
if( Settings::i()->gallery_use_watermarks )
{
$form->add( new \IPS\Helpers\Form\Radio( 'g_download_original', $group->g_download_original, FALSE, array( 'options' => array(
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_RAW => 'g_download_raw',
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_WATERMARKED => 'g_download_watermarked',
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_NONE => 'g_download_none'
$form->add( new Radio( 'g_download_original', $group->g_download_original, FALSE, array( 'options' => array(
Image::DOWNLOAD_ORIGINAL_RAW => 'g_download_raw',
Image::DOWNLOAD_ORIGINAL_WATERMARKED => 'g_download_watermarked',
Image::DOWNLOAD_ORIGINAL_NONE => 'g_download_none'
) ) ) );
}
else
{
$form->add( new \IPS\Helpers\Form\YesNo( 'g_download_original', $group->g_download_original, FALSE ) );
$form->add( new YesNo( 'g_download_original', $group->g_download_original, FALSE ) );
}
$form->add( new \IPS\Helpers\Form\YesNo( 'g_movies', $group->g_movies, FALSE, array( 'togglesOn' => array( 'g_movie_size' ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_movie_size', $group->g_movie_size, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb'), 'g_movie_size' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_upload', $group->g_max_upload, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb') ) );
$form->add( new YesNo( 'g_movies', $group->g_movies, FALSE, array( 'togglesOn' => array( 'g_movie_size' ) ) ) );
$form->add( new Number( 'g_movie_size', $group->g_movie_size, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb'), 'g_movie_size' ) );
$form->add( new Number( 'g_max_upload', $group->g_max_upload, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb') ) );
$form->addMessage( 'gallery_requires_log' );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_transfer', $group->g_max_transfer, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb_day') ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_views', $group->g_max_views, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_day') ) );
$form->add( new Number( 'g_max_transfer', $group->g_max_transfer, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb_day') ) );
$form->add( new Number( 'g_max_views', $group->g_max_views, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_day') ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member\Group $group The group
* @param Group $group The group
* @return void
*/
public function save( $values, &$group )
public function save( array $values, Group $group ) : void
{
if( $group->g_id != \IPS\Settings::i()->guest_group )
if( $group->g_id != Settings::i()->guest_group )
{
$group->g_create_albums = $values['g_create_albums'];
$group->g_create_albums_private = $values['g_create_albums_private'];
$group->g_create_albums_fo = $values['g_create_albums_fo'];
$group->g_album_limit = $values['g_album_limit'];
$group->g_img_album_limit = $values['g_img_album_limit'];
$group->g_create_albums = (int) $values['g_create_albums'];
$group->g_create_albums_private = (int) $values['g_create_albums_private'];
$group->g_create_albums_fo = (int) $values['g_create_albums_fo'];
$group->g_album_limit = (int) $values['g_album_limit'];
$group->g_img_album_limit = (int) $values['g_img_album_limit'];
}
$group->g_download_original = $values['g_download_original'];
$group->g_movies = $values['g_movies'];
$group->g_movie_size = $values['g_movie_size'];
$group->g_max_upload = $values['g_max_upload'];
$group->g_max_transfer = $values['g_max_transfer'];
$group->g_max_views = $values['g_max_views'];
$group->g_download_original = (int) $values['g_download_original'];
$group->g_movies = (int) $values['g_movies'];
$group->g_movie_size = (int) $values['g_movie_size'];
$group->g_max_upload = (int) $values['g_max_upload'];
$group->g_max_transfer = (int) $values['g_max_transfer'];
$group->g_max_views = (int) $values['g_max_views'];
}
}
@@ -12,9 +12,15 @@
namespace IPS\gallery\extensions\core\GroupLimits;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupLimitsAbstract;
use function count;
use function defined;
use function max;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
@@ -24,14 +30,14 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
* This extension is used to define which limit values "win" when a user has secondary groups defined
*
*/
class _Album
class Album extends GroupLimitsAbstract
{
/**
* Get group limits by priority
*
* @return array
*/
public function getLimits()
public function getLimits(): array
{
return array (
'exclude' => array(),
@@ -65,7 +71,7 @@ class _Album
}
}
return \count( $limits ) ? \max( $limits ) : 0;
return count( $limits ) ? max( $limits ) : 0;
} )
);
}
@@ -12,26 +12,35 @@
namespace IPS\gallery\extensions\core\LiveSearch;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Dispatcher;
use IPS\Extensions\LiveSearchAbstract;
use IPS\gallery\Category;
use IPS\Member;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief ACP Live Search Extension
*/
class _Categories
class Categories extends LiveSearchAbstract
{
/**
* Check we have access
*
* @return bool
*/
public function hasAccess()
public function hasAccess(): bool
{
/* Check Permissions */
return \IPS\Member::loggedIn()->hasAcpRestriction( 'gallery', 'gallery', 'categories_manage' );
return Member::loggedIn()->hasAcpRestriction( 'gallery', 'gallery', 'categories_manage' );
}
/**
@@ -40,7 +49,7 @@ class _Categories
* @param string $searchTerm Search Term
* @return array Array of results
*/
public function getResults( $searchTerm )
public function getResults( string $searchTerm ): array
{
/* Init */
$results = array();
@@ -50,10 +59,10 @@ class _Categories
if( $this->hasAccess() )
{
/* Perform the search */
$categories = \IPS\Db::i()->select(
$categories = Db::i()->select(
"*",
'gallery_categories',
array( "category_club_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, \IPS\Member::loggedIn()->language()->id ),
array( "category_club_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, Member::loggedIn()->language()->id ),
NULL,
NULL
)->join(
@@ -64,9 +73,9 @@ class _Categories
/* Format results */
foreach ( $categories as $category )
{
$category = \IPS\gallery\Category::constructFromData( $category );
$category = Category::constructFromData( $category );
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'gallery', 'admin' )->category( $category );
$results[] = Theme::i()->getTemplate( 'livesearch', 'gallery', 'admin' )->category( $category );
}
}
@@ -78,8 +87,8 @@ class _Categories
*
* @return bool
*/
public function isDefault()
public function isDefault(): bool
{
return \IPS\Dispatcher::i()->application->directory == 'gallery';
return Dispatcher::i()->application->directory == 'gallery';
}
}
@@ -11,60 +11,71 @@
namespace IPS\gallery\extensions\core\MemberACPProfileContentTab;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\MemberACPProfile\Block;
use IPS\Db;
use IPS\Helpers\Chart\Database;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output\Plugin\Filesize;
use IPS\Request;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Member ACP Profile - Content Statistics Tab: Gallery
*/
class _Gallery extends \IPS\core\MemberACPProfile\Block
class Gallery extends Block
{
/**
* Get output
*
* @return string
*/
public function output()
public function output(): string
{
$imageCount = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$diskspaceUsed = \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$numberOfViews = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$bandwidthUsed = \IPS\Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$imageCount = Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$diskspaceUsed = Db::i()->select( 'SUM(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$numberOfViews = Db::i()->select( 'COUNT(*)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$bandwidthUsed = Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$allImages = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
$totalFilesize = \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first();
$allBandwidth = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_bandwidth' )->first();
$totalBandwidth = \IPS\Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth' )->first();
$allImages = Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
$totalFilesize = Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first();
$allBandwidth = Db::i()->select( 'COUNT(*)', 'gallery_bandwidth' )->first();
$totalBandwidth = Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth' )->first();
return \IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->information( $this->member, \IPS\Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
return (string) Theme::i()->getTemplate( 'stats', 'gallery' )->information( $this->member, Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
'images_submitted' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $imageCount ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allImages ? ( 100 / $allImages ) : 0 ) * $imageCount ), 2 ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Member::loggedIn()->language()->formatNumber( $imageCount ),
Member::loggedIn()->language()->formatNumber( ( ( $allImages ? ( 100 / $allImages ) : 0 ) * $imageCount ), 2 ) ) )
),
'gdiskspace_used' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $diskspaceUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalFilesize ? ( 100 / $totalFilesize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Filesize::humanReadableFilesize( $diskspaceUsed ? :0 ),
Member::loggedIn()->language()->formatNumber( ( ( $totalFilesize ? ( 100 / $totalFilesize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
),
'gaverage_filesize' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_average' , FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first() ),
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(image_file_size)', 'gallery_images' )->first() ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_average' , FALSE, array( 'sprintf' => array(
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first() ? :0),
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(image_file_size)', 'gallery_images' )->first() ) ) ? :0)
),
'number_of_views' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $numberOfViews ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allBandwidth ? ( 100 / $allBandwidth ) : 0 ) * $imageCount ), 2 ) ))
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Member::loggedIn()->language()->formatNumber( $numberOfViews ),
Member::loggedIn()->language()->formatNumber( ( ( $allBandwidth ? ( 100 / $allBandwidth ) : 0 ) * $imageCount ), 2 ) ))
),
'gallery_bandwidth_used' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $bandwidthUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalBandwidth ? ( 100 / $totalBandwidth ) : 0 ) * $bandwidthUsed ), 2 ),
\IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->bandwidthButton( $this->member ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
Filesize::humanReadableFilesize( $bandwidthUsed ? :0 ),
Member::loggedIn()->language()->formatNumber( ( ( $totalBandwidth ? ( 100 / $totalBandwidth ) : 0 ) * $bandwidthUsed ), 2 ),
Theme::i()->getTemplate( 'stats', 'gallery' )->bandwidthButton( $this->member ) ) )
)
) ) );
}
@@ -74,12 +85,12 @@ class _Gallery extends \IPS\core\MemberACPProfile\Block
*
* @return string
*/
public function edit()
public function edit(): string
{
$bandwidthChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\gallery\\extensions\\core\\MemberACPProfileContentTab\\Gallery&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'gallery_bandwidth', 'bdate', '', array( 'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) ) ), 'LineChart', 'daily' );
$bandwidthChart = new Database( Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\gallery\\extensions\\core\\MemberACPProfileContentTab\\Gallery&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'gallery_bandwidth', 'bdate', '', array( 'vAxis' => array( 'title' => Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) ) ), 'LineChart', 'daily' );
$bandwidthChart->groupBy = 'bdate';
$bandwidthChart->where[] = array( 'member_id=?', $this->member->member_id );
$bandwidthChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth_use_gallery'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
return ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $bandwidthChart : \IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->graphs( (string) $bandwidthChart );
$bandwidthChart->addSeries( Member::loggedIn()->language()->addToStack('bandwidth_use_gallery'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
return ( Request::i()->isAjax() and isset( Request::i()->_graph ) ) ? (string) $bandwidthChart : Theme::i()->getTemplate( 'stats', 'gallery' )->graphs( (string) $bandwidthChart );
}
}
@@ -12,40 +12,50 @@
namespace IPS\gallery\extensions\core\MemberFilter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Db\Select;
use IPS\Extensions\MemberFilterAbstract;
use IPS\Helpers\Form\Radio;
use IPS\Member;
use LogicException;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Filter Extension
*/
class _Album
class Album extends MemberFilterAbstract
{
/**
* Determine if the filter is available in a given area
*
* @param string $area Area to check
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation)
* @return bool
*/
public function availableIn( $area )
public function availableIn( string $area ): bool
{
return \in_array( $area, array( 'bulkmail', 'group_promotions' ) );
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
}
/**
* Get Setting Field
*
* @param mixed $criteria Value returned from the save() method
* @param array $criteria Value returned from the save() method
* @return array Array of form elements
*/
public function getSettingField( $criteria )
public function getSettingField( array $criteria ): array
{
$options = array( 'any' => 'any', 'yes' => 'yes', 'no' => 'no' );
return array(
new \IPS\Helpers\Form\Radio( 'mf_has_album', isset( $criteria['has_album'] ) ? $criteria['has_album'] : 'any', FALSE, array( 'options' => $options ) ),
new Radio( 'mf_has_album', $criteria['has_album'] ?? 'any', FALSE, array( 'options' => $options ) ),
);
}
@@ -53,12 +63,12 @@ class _Album
* Save the filter data
*
* @param array $post Form values
* @return mixed False, or an array of data to use later when filtering the members
* @throws \LogicException
* @return array|bool False, or an array of data to use later when filtering the members
* @throws LogicException
*/
public function save( $post )
public function save( array $post ): array|bool
{
if( isset( $post['mf_has_album'] ) and \in_array( $post['mf_has_album'], array( 'yes', 'no' ) ) )
if( isset( $post['mf_has_album'] ) and in_array( $post['mf_has_album'], array( 'yes', 'no' ) ) )
{
return array( 'has_album' => $post['mf_has_album'] );
}
@@ -69,10 +79,10 @@ class _Album
/**
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @param array $data The array returned from the save() method
* @return array|NULL Where clause - must be a single array( "clause" )
*/
public function getQueryWhereClause( $data )
public function getQueryWhereClause( array $data ): ?array
{
if( isset( $data['has_album'] ) )
{
@@ -86,29 +96,28 @@ class _Album
* Callback for member retrieval database query
* Can be used to set joins
*
* @param mixed $data The array returned from the save() method
* @param \IPS\Db\Query $query The query
* @param array $data The array returned from the save() method
* @param Select $query The query
* @return void
*/
public function queryCallback( $data, &$query )
public function queryCallback( array $data, Select $query ) : void
{
if( isset( $data['has_album'] ) )
{
$query->join( 'gallery_albums', "core_members.member_id=gallery_albums.album_owner_id" );
}
return NULL;
}
/**
* Determine if a member matches specified filters
*
* @param Member $member
* @param array $filters
* @param object|null $object
* @note This is only necessary if availableIn() includes group_promotions
* @param \IPS\Member $member Member object to check
* @param array $filters Previously defined filters
* @return bool
*/
public function matches( \IPS\Member $member, $filters )
public function matches( Member $member, array $filters, ?object $object = NULL ): bool
{
/* If we aren't filtering by this, then any member matches */
if( !isset( $filters['has_album'] ) OR !$filters['has_album'] )
@@ -116,7 +125,7 @@ class _Album
return TRUE;
}
$result = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_owner_id=?', $member->member_id ) )->first();
$result = (bool) Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_owner_id=?', $member->member_id ) )->first();
return ( $filters['has_album'] == 'no' ) ? !$result : $result;
}
@@ -11,27 +11,35 @@
namespace IPS\gallery\extensions\core\MemberRestrictions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\MemberACPProfile\Restriction;
use IPS\Helpers\Form;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use function defined;
use function intval;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Member Restrictions: Gallery
*/
class _Gallery extends \IPS\core\MemberACPProfile\Restriction
class Gallery extends Restriction
{
/**
* Modify Edit Restrictions form
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @return void
*/
public function form( \IPS\Helpers\Form $form )
public function form( Form $form ) : void
{
$form->add( new \IPS\Helpers\Form\YesNo( 'remove_gallery_access', !$this->member->members_bitoptions['remove_gallery_access'], FALSE, array( 'togglesOn' => array( 'remove_gallery_upload' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'remove_gallery_upload', !$this->member->members_bitoptions['remove_gallery_upload'], FALSE, array(), NULL, NULL, NULL, 'remove_gallery_upload' ) );
$form->add( new YesNo( 'remove_gallery_access', !$this->member->members_bitoptions['remove_gallery_access'], FALSE, array( 'togglesOn' => array( 'remove_gallery_upload' ) ) ) );
$form->add( new YesNo( 'remove_gallery_upload', !$this->member->members_bitoptions['remove_gallery_upload'], FALSE, array(), NULL, NULL, NULL, 'remove_gallery_upload' ) );
}
/**
@@ -40,7 +48,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
* @param array $values Values from form
* @return array
*/
public function save( $values )
public function save( array $values ): array
{
$return = array();
@@ -64,7 +72,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
*
* @return array
*/
public function activeRestrictions()
public function activeRestrictions(): array
{
$return = array();
@@ -95,7 +103,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
{
if ( isset( $changes[ $k ] ) )
{
$return[] = \IPS\Member::loggedIn()->language()->addToStack( 'history_restrictions_' . $k . '_' . \intval( $changes[ $k ]['new'] ) );
$return[] = Member::loggedIn()->language()->addToStack( 'history_restrictions_' . $k . '_' . intval( $changes[ $k ]['new'] ) );
}
}
@@ -1,90 +0,0 @@
<?php
/**
* @brief Member Sync
* @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
*/
namespace IPS\gallery\extensions\core\MemberSync;
/* 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;
}
/**
* Member Sync
*/
class _Gallery
{
/**
* Member is merged with another member
*
* @param \IPS\Member $member Member being kept
* @param \IPS\Member $member2 Member being removed
* @return void
*/
public function onMerge( $member, $member2 )
{
\IPS\Db::i()->update( 'gallery_albums', array( 'album_owner_id' => $member->member_id ), array( 'album_owner_id=?', $member2->member_id ) );
\IPS\Db::i()->update( 'gallery_bandwidth', array( 'member_id' => $member->member_id ), array( 'member_id=?', $member2->member_id ) );
\IPS\Db::i()->update( 'gallery_images_uploads', array( 'upload_member_id' => $member->member_id ), array( 'upload_member_id=?', $member2->member_id ) );
foreach( \IPS\gallery\Album::loadByOwner( $member2 ) as $album )
{
$album->owner_id = $member->member_id;
$album->save();
}
}
/**
* Member is deleted
*
* @param $member \IPS\Member The member
* @return void
*/
public function onDelete( $member )
{
\IPS\Db::i()->delete( 'gallery_bandwidth', array( 'member_id=?', $member->member_id ) );
\IPS\Db::i()->delete( 'gallery_images_uploads', array( 'upload_member_id=?', $member->member_id ) );
foreach( \IPS\gallery\Album::loadByOwner( $member ) as $album )
{
//$album->delete();
$album->owner_id = 0;
$album->save();
}
}
/**
* Member is flagged as spammer
*
* @param $member \IPS\Member The member
* @return void
*/
public function onSetAsSpammer( $member )
{
$actions = explode( ',', \IPS\Settings::i()->spm_option );
/* Hide or delete */
if ( \in_array( 'unapprove', $actions ) or \in_array( 'delete', $actions ) )
{
foreach( \IPS\gallery\Album::loadByOwner( $member ) as $album )
{
$album->hidden = -1;
$album->save();
if( \in_array( 'delete', $actions ) )
{
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->id, 'deleteWhenDone' => TRUE ), 3 );
}
}
}
}
}
Whitespace-only changes.
@@ -12,31 +12,36 @@
namespace IPS\gallery\extensions\core\Permissions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\PermissionsAbstract;
use IPS\gallery\Category;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Permissions
*/
class _Permissions
class Permissions extends PermissionsAbstract
{
/**
* Get node classes
*
* @return array
*/
public function getNodeClasses()
public function getNodeClasses(): array
{
return array(
'IPS\gallery\Category' => function( $current, $group )
{
$rows = array();
foreach( \IPS\gallery\Category::roots( NULL ) AS $root )
foreach( Category::roots( NULL ) AS $root )
{
\IPS\gallery\Category::populatePermissionMatrix( $rows, $root, $group, $current );
Category::populatePermissionMatrix( $rows, $root, $group, $current );
}
return $rows;
@@ -12,33 +12,27 @@
namespace IPS\gallery\extensions\core\Profile;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Extensions\ProfileAbstract;
use IPS\gallery\Album\Table;
use IPS\gallery\Application;
use IPS\Member;
use IPS\Theme;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Profile extension: Gallery
*/
class _gallery
class gallery extends ProfileAbstract
{
/**
* Member
*/
protected \IPS\Member $member;
/**
* Constructor
*
* @param \IPS\Member $member Member whose profile we are viewing
* @return void
*/
public function __construct( \IPS\Member $member )
{
$this->member = $member;
}
/**
* Is there content to display?
*
@@ -48,18 +42,18 @@ class _gallery
{
$where = array( array( 'album_owner_id=?', $this->member->member_id ) );
if( \count( \IPS\Member::loggedIn()->socialGroups() ) )
if( count( Member::loggedIn()->socialGroups() ) )
{
$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 );
$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( ',', Member::loggedIn()->socialGroups() ) . ') ) ) ) )', Member::loggedIn()->member_id, Member::loggedIn()->member_id );
}
else
{
$where[] = array( '( album_type=1 OR ( album_type IN (2,3) AND album_owner_id=? ) )', \IPS\Member::loggedIn()->member_id );
$where[] = array( '( album_type=1 OR ( album_type IN (2,3) AND album_owner_id=? ) )', Member::loggedIn()->member_id );
}
$where[] = array( '(' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_view', \IPS\Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_view=? )', '*' );
$where[] = array( '(' . Db::i()->findInSet( 'core_permission_index.perm_view', Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_view=? )', '*' );
$select = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', $where );
$select = Db::i()->select( 'COUNT(*)', 'gallery_albums', $where );
$select->join( 'gallery_categories', array( "gallery_categories.category_id=gallery_albums.album_category_id" ) );
$select->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=gallery_categories.category_id", 'gallery', 'category' ) );
@@ -73,15 +67,15 @@ class _gallery
*/
public function render(): string
{
\IPS\gallery\Application::outputCss();
Application::outputCss();
$table = new \IPS\gallery\Album\Table( $this->member->url()->setQueryString( 'tab', 'node_gallery_gallery') );
$table = new Table( $this->member->url()->setQueryString( 'tab', 'node_gallery_gallery') );
$table->setOwner( $this->member );
$table->limit = 10;
$table->sortBy = 'album_last_img_date';
$table->sortDirection = 'desc';
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'global', 'gallery' ), 'profileAlbumTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
$table->tableTemplate = array( Theme::i()->getTemplate( 'global', 'gallery' ), 'profileAlbumTable' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
return (string) $table;
}
@@ -12,33 +12,24 @@
namespace IPS\gallery\extensions\core\Profile;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\Content\Filter;
use IPS\Extensions\ProfileAbstract;
use IPS\gallery\Image;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Profile extension: galleryImages
*/
class _galleryImages
class galleryImages extends ProfileAbstract
{
/**
* Member
*/
protected \IPS\Member $member;
/**
* Constructor
*
* @param \IPS\Member $member Member whose profile we are viewing
* @return void
*/
public function __construct( \IPS\Member $member )
{
$this->member = $member;
}
/**
* Is there content to display?
*
@@ -46,7 +37,12 @@ class _galleryImages
*/
public function showTab(): bool
{
return TRUE;
$where = [
[ 'image_member_id=?', $this->member->member_id ],
[ 'image_album_id=?', 0 ]
];
$items = Image::getItemsWithPermission( $where, null, 1, 'read', Filter::FILTER_AUTOMATIC, 0, null, false, false,false,true );
return $items > 0;
}
/**
@@ -57,7 +53,7 @@ class _galleryImages
public function render(): string
{
$table ="";
foreach ( \IPS\Application::load( 'gallery' )->extensions( 'core', 'ContentRouter' ) as $ext )
foreach ( Application::load( 'gallery' )->extensions( 'core', 'ContentRouter' ) as $ext )
{
$table = $ext->customTableHelper( 'IPS\gallery\Image', $this->member->url()->setQueryString( 'tab', 'node_gallery_galleryImages'), array( array( 'image_member_id=? and image_album_id=0', $this->member->member_id ) ) );
}
@@ -1,170 +0,0 @@
<?php
/**
* @brief Background Task
* @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 06 Mar 2018
*/
namespace IPS\gallery\extensions\core\Queue;
/* 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;
}
/**
* Background Task
*/
class _CleanUpGalleryImages
{
/**
* Parse data before queuing
*
* @param array $data
* @return array
*/
public function preQueueData( $data )
{
try
{
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
}
catch( \Exception $ex )
{
throw new \OutOfRangeException;
}
if( $data['count'] == 0 )
{
return null;
}
$data['did'] = 0;
return $data;
}
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
{
if ( !\IPS\Application::appIsEnabled( 'gallery' ) )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
$last = NULL;
foreach( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_media=? AND image_id > ?', 0, (int) $offset ), 'image_id ASC', \IPS\REBUILD_SLOW ) as $image )
{
$data['did']++;
/* Update the sizes array to remove the images we no longer support */
$sizes = json_decode( $image['image_data'], true );
if( isset( $sizes['thumb'] ) )
{
unset( $sizes['thumb'] );
}
if( isset( $sizes['medium'] ) )
{
unset( $sizes['medium'] );
}
$update = array( 'image_data' => json_encode( $sizes ) );
/* If we have a medium but no large image, or a thumb but no small image, adapt as appropriate. Also if one image is mapped for
multiple columns be sure we don't remove it if we still need it. */
$keepMedium = FALSE;
if( $image['image_medium_file_name'] == $image['image_masked_file_name'] )
{
$keepMedium = TRUE;
}
$keepThumb = FALSE;
if( $image['image_thumb_file_name'] == $image['image_masked_file_name'] )
{
$keepThumb = TRUE;
}
if( !$image['image_masked_file_name'] AND $image['image_medium_file_name'] )
{
$image['image_masked_file_name'] = $image['image_medium_file_name'];
$update['image_masked_file_name'] = $image['image_masked_file_name'];
$keepMedium = TRUE;
}
if( !$image['image_small_file_name'] AND $image['image_thumb_file_name'] )
{
$image['image_small_file_name'] = $image['image_thumb_file_name'];
$update['image_small_file_name'] = $image['image_small_file_name'];
$keepThumb = TRUE;
}
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
/* Delete the images we don't need now */
if( !$keepMedium AND $image['image_medium_file_name'] )
{
try
{
\IPS\File::get( 'gallery_Images', $image['image_medium_file_name'] )->delete();
}
catch( \Exception $e ) {}
}
if( !$keepThumb AND $image['image_thumb_file_name'] )
{
try
{
\IPS\File::get( 'gallery_Images', $image['image_thumb_file_name'] )->delete();
}
catch( \Exception $e ) {}
}
$last = $image['image_id'];
}
if ( $last === NULL )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
return $last;
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
{
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('cleaning_up_gallery_images'), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['did'], 2 ) ) : 100 );
}
/**
* Perform post-completion processing
*
* @param array $data Data returned from preQueueData
* @param bool $processed Was anything processed or not? If preQueueData returns NULL, this will be FALSE.
* @return void
*/
public function postComplete( $data, $processed = TRUE )
{
\IPS\Db::i()->query( "ALTER TABLE `" . \IPS\Db::i()->prefix . "gallery_images` DROP COLUMN image_thumb_file_name, DROP COLUMN image_medium_file_name" );
}
}
@@ -12,16 +12,27 @@
namespace IPS\gallery\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\QueueAbstract;
use IPS\gallery\Album;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Theme;
use OutOfRangeException;
use function defined;
use function is_null;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _Follow
class Follow extends QueueAbstract
{
/**
* Run Background Task
@@ -31,12 +42,13 @@ class _Follow
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
public function run( array &$data, int $offset ): int
{
$category = \IPS\gallery\Category::load( $data['category_id'] );
$album = ( !\is_null( $data['album_id'] ) ) ? \IPS\gallery\Album::load( $data['album_id'] ) : NULL;
$member = \IPS\Member::load( $data['member_id'] );
$newOffset = \IPS\gallery\Image::_sendNotificationsBatch( $category, $album, $member, $offset );
$category = Category::load( $data['category_id'] );
$album = ( !is_null( $data['album_id'] ) ) ? Album::load( $data['album_id'] ) : NULL;
$member = Member::load( $data['member_id'] );
$tags = $data['tags'] ?? null;
$newOffset = Image::_sendNotificationsBatch( $category, $album, $member, $tags, $offset );
if( $newOffset === NULL )
{
@@ -52,13 +64,24 @@ class _Follow
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
public function getProgress( mixed $data, int $offset ): array
{
$complete = $data['followerCount'] ? round( 100 / $data['followerCount'] * $offset, 2 ) : 100;
$directContainer = ( !\is_null( $data['album_id'] ) ) ? \IPS\gallery\Album::load( $data['album_id'] ) : \IPS\gallery\Category::load( $data['category_id'] );
$directContainer = ( !is_null( $data['album_id'] ) ) ? Album::load( $data['album_id'] ) : Category::load( $data['category_id'] );
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $directContainer->url(), TRUE, $directContainer->_title, FALSE ) ) ) ), 'complete' => $complete );
}
return array( 'text' => Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $directContainer->url(), TRUE, $directContainer->_title, FALSE ) ) ) ), 'complete' => $complete );
}
/**
* Parse data before queuing
*
* @param array $data
* @return array|null
*/
public function preQueueData( array $data ): ?array
{
return $data;
}
}
@@ -12,37 +12,49 @@
namespace IPS\gallery\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Application;
use IPS\Db;
use IPS\Extensions\QueueAbstract;
use IPS\File;
use IPS\Member;
use IPS\Patterns\ActiveRecordIterator;
use OutOfRangeException;
use function defined;
use const IPS\REBUILD_INTENSE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _RebuildGalleryImages
class RebuildGalleryImages extends QueueAbstract
{
/**
* @brief Number of content items to rebuild per cycle
*/
public $rebuild = \IPS\REBUILD_INTENSE;
public int $rebuild = REBUILD_INTENSE;
/**
* Parse data before queuing
*
* @param array $data
* @return array
* @return array|null
*/
public function preQueueData( $data )
public function preQueueData( array $data ): ?array
{
try
{
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
$data['count'] = Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
}
catch( \Exception $ex )
catch( Exception )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
if( $data['count'] == 0 )
@@ -63,14 +75,14 @@ class _RebuildGalleryImages
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( &$data, $offset )
public function run( mixed &$data, int $offset ): int
{
if ( !\IPS\Application::appIsEnabled( 'gallery' ) )
if ( !Application::appIsEnabled( 'gallery' ) )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
$iterator = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'gallery_images', array( array( 'image_media=? AND image_id>?', 0, $offset ) ), 'image_id ASC', array( 0, $this->rebuild ) ), 'IPS\\gallery\\Image' );
$iterator = new ActiveRecordIterator( Db::i()->select( '*', 'gallery_images', array( array( 'image_media=? AND image_id>?', 0, $offset ) ), 'image_id ASC', array( 0, $this->rebuild ) ), 'IPS\\gallery\\Image' );
$last = NULL;
foreach( $iterator as $image )
@@ -78,13 +90,16 @@ class _RebuildGalleryImages
try
{
/* Make sure the original image exists and has content */
$file = \IPS\File::get( 'gallery_Images', $image->original_file_name );
$file->contents();
if ( $image->original_file_name )
{
$file = File::get( 'gallery_Images', $image->original_file_name );
$file->contents();
$image->buildThumbnails( $file );
$image->save();
$image->buildThumbnails( $file );
$image->save();
}
}
catch ( \Exception $e ) {}
catch ( Exception ) {}
$last = $image->id;
$data['indexed']++;
@@ -104,10 +119,10 @@ class _RebuildGalleryImages
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
public function getProgress( mixed $data, int $offset ): array
{
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('rebuilding_gallery_images' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['indexed'], 2 ) ) : 100 );
return array( 'text' => Member::loggedIn()->language()->addToStack('rebuilding_gallery_images' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['indexed'], 2 ) ) : 100 );
}
}
@@ -0,0 +1,120 @@
<?php
/**
* @brief SearchContent extension: Albums
* @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 10 Jul 2023
*/
namespace IPS\gallery\extensions\core\SearchContent;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Content\Search\SearchContentAbstract;
use IPS\gallery\Album\Comment;
use IPS\gallery\Album\Item;
use IPS\gallery\Album\Review;
use IPS\Member;
use IPS\Settings;
use IPS\Theme;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief SearchContent extension: Albums
*/
class Albums extends SearchContentAbstract
{
/**
* @brief A classname applied to the search result block
*/
public static string $searchResultClassName = 'cGalleryAlbumSearchResult';
/**
* Return all searchable classes in your application,
* including comments and/or reviews
*
* @return array
*/
public static function supportedClasses() : array
{
return array(
Item::class,
Comment::class,
Review::class
);
}
/**
* Return the language string key to use in search results
*
* @note Normally we show "(user) posted a (thing) in (area)" but sometimes this may not be accurate, so this is abstracted to allow
* content classes the ability to override
* @param array $authorData Author data
* @param array $articles Articles language strings
* @param array $indexData Search index data
* @param array $itemData Data about the item
* @param bool $includeLinks Include links to member profile
* @return string
*/
public static function searchResultSummaryLanguage( array $authorData, array $articles, array $indexData, array $itemData, bool $includeLinks = TRUE ): string
{
if( $indexData['index_class'] == Item::class )
{
return Member::loggedIn()->language()->addToStack( "album_user_own_activity_item", FALSE, array( 'sprintf' => array( $articles['indefinite'] ), 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'front' )->userLinkFromData( $authorData['member_id'], $authorData['name'], $authorData['members_seo_name'], $authorData['member_group_id'] ?? Settings::i()->guest_group ) ) ) );
}
return parent::searchResultSummaryLanguage( $authorData, $articles, $indexData, $itemData, $includeLinks );
}
/**
* Get snippet HTML for search result display
*
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, string $view ): string
{
$images = ( isset( $itemData['extra'] ) AND count( $itemData['extra'] ) ) ? $itemData['extra'] : array();
if( $indexData['index_class'] == Item::class )
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultAlbumSnippet( $indexData, $itemData, $images, static::urlFromIndexData( $indexData, $itemData ), $view == 'condensed' );
}
else
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultAlbumCommentSnippet( $indexData, $itemData, $images, static::urlFromIndexData( $indexData, $itemData ), $reviewRating, $view == 'condensed' );
}
}
/**
* 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(): string
{
if( $this->object instanceof Item )
{
return $this->object->asNode()->searchIndexPermissions();
}
return parent::searchIndexPermissions();
}
}
@@ -0,0 +1,155 @@
<?php
/**
* @brief SearchContent extension: Images
* @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 10 Jul 2023
*/
namespace IPS\gallery\extensions\core\SearchContent;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Content\Search\SearchContentAbstract;
use IPS\Content\Search\Query;
use IPS\Dispatcher;
use IPS\gallery\Album;
use IPS\gallery\Album\Item;
use IPS\gallery\Application;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\gallery\Image\Review;
use IPS\Theme;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief SearchContent extension: Images
*/
class Images extends SearchContentAbstract
{
/**
* Return all searchable classes in your application,
* including comments and/or reviews
*
* @return array
*/
public static function supportedClasses() : array
{
return array(
Image::class,
Comment::class,
Review::class
);
}
/**
* Give class a chance to inspect and manipulate search engine filters for streams
*
* @param array $filters Filters to be used for activity stream
* @param Query $query Search query object
* @return void
*/
public static function searchEngineFiltering( array &$filters, Query &$query ): void
{
/* Make sure our CSS is output */
if( Dispatcher::hasInstance() )
{
Application::outputCss();
}
/* Loop through and see if we are also including albums */
$includingAlbums = FALSE;
if( !count( $filters ) )
{
$includingAlbums = TRUE;
}
else
{
foreach( $filters as $filter )
{
if( $filter->itemClass == Item::class )
{
$includingAlbums = TRUE;
}
}
}
if( $includingAlbums === TRUE )
{
if( count( $filters ) )
{
foreach( $filters as $k => $filter )
{
if( $filter->itemClass == Image::class )
{
/* container class can be category or album */
$filter->containerClasses = array( Category::class );
$filter->containerClassExclusions = array( Comment::class, Review::class );
}
}
}
else
{
$query->filterByContainerClasses( array( Album::class ), array( Comment::class, Review::class ) );
}
}
}
/**
* 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(): string
{
/* If this is a private album, only the author can view in search */
if ( method_exists( $this->object, 'directContainer' ) and $this->object->directContainer() instanceof Album and $this->object->directContainer()->type != Album::AUTH_TYPE_PUBLIC )
{
if ( $this->object->member_id )
{
return "m{$this->object->member_id}";
}
return '';
}
return parent::searchIndexPermissions();
}
/**
* Get snippet HTML for search result display
*
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, string $view ): string
{
if( $indexData['index_class'] == Image::class )
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultImageSnippet( $indexData, $itemData, ($itemData['extra'] ?? NULL), $itemData['image_small_file_name'], static::urlFromIndexData( $indexData, $itemData ), $view == 'condensed' );
}
else
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultCommentSnippet( $indexData, $itemData, $itemData['image_small_file_name'], static::urlFromIndexData( $indexData, $itemData ), $reviewRating, $view == 'condensed' );
}
}
}
@@ -12,28 +12,46 @@
namespace IPS\gallery\extensions\core\Sitemap;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Filter;
use IPS\Content\Item;
use IPS\core\extensions\core\Sitemap\Content;
use IPS\DateTime;
use IPS\Db;
use IPS\Extensions\SitemapAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Settings;
use IPS\Sitemap;
use UnderflowException;
use function defined;
use function intval;
use function is_array;
use const IPS\SITEMAP_MAX_PER_FILE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Support Images in sitemaps
*/
class _Images
class Images extends SitemapAbstract
{
/**
* @brief Recommended Settings
*/
public $recommendedSettings = array();
public array $recommendedSettings = array();
/**
* Add settings for ACP configuration to the form
*
* @return array
*/
public function settings()
public function settings(): array
{
return array();
}
@@ -43,9 +61,9 @@ class _Images
*
* @return array
*/
public function getFilenames()
public function getFilenames(): array
{
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$limit = ( isset( $settings["sitemap_{$class::$title}_count"] ) ) ? $settings["sitemap_{$class::$title}_count"] : -1;
@@ -54,10 +72,10 @@ class _Images
return array();
}
$count = \IPS\gallery\Image::getItemsWithPermission( array( 'image_media=?', 0 ), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE );
$count = Image::getItemsWithPermission( array( 'image_media=?', 0 ), NULL, 10, 'read', Filter::FILTER_AUTOMATIC, 0, new Member, FALSE, FALSE, FALSE, TRUE );
$files = array();
$count = ceil( $count / \IPS\SITEMAP_MAX_PER_FILE );
$count = ceil( $count / SITEMAP_MAX_PER_FILE );
for( $i=1; $i <= $count; $i++ )
{
@@ -71,21 +89,21 @@ class _Images
* Generate the sitemap
*
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param \IPS\Sitemap $sitemap Sitemap object reference
* @return void
* @param Sitemap $sitemap Sitemap object reference
* @return int|null
*/
public function generateSitemap( $filename, $sitemap )
public function generateSitemap( string $filename, Sitemap $sitemap ) : ?int
{
$entries = array();
$lastId = 0;
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$exploded = explode( '_', $filename );
$block = (int) array_pop( $exploded );
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
$limit = \IPS\SITEMAP_MAX_PER_FILE;
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * SITEMAP_MAX_PER_FILE;
$limit = SITEMAP_MAX_PER_FILE;
if ( ! $totalLimit )
{
@@ -106,7 +124,7 @@ class _Images
/* Try to fetch the highest ID built in the last sitemap, if it exists */
try
{
$lastId = \IPS\Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
$lastId = Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
if( $lastId > 0 )
{
@@ -114,12 +132,12 @@ class _Images
$limitClause = $limit;
}
}
catch( \UnderflowException $e ){}
catch( UnderflowException ){}
$idColumn = $class::$databaseColumnId;
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, \IPS\Content\Item::SELECT_IDS_FIRST, new \IPS\Member, TRUE ) as $item )
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', Filter::FILTER_PUBLIC_ONLY, Item::SELECT_IDS_FIRST, new Member, TRUE ) as $item )
{
if( !$item->canView( new \IPS\Member ) )
if( !$item->canView( new Member ) )
{
continue;
}
@@ -130,16 +148,16 @@ class _Images
if ( isset( $item::$databaseColumnMap['last_comment'] ) )
{
$lastCommentField = $item::$databaseColumnMap['last_comment'];
if ( \is_array( $lastCommentField ) )
if ( is_array( $lastCommentField ) )
{
foreach ( $lastCommentField as $column )
{
$lastMod = \IPS\DateTime::ts( $item->$column );
$lastMod = DateTime::ts( $item->$column );
}
}
else
{
$lastMod = \IPS\DateTime::ts( $item->$lastCommentField );
$lastMod = DateTime::ts( $item->$lastCommentField );
}
}
@@ -150,11 +168,11 @@ class _Images
/* Image sitemap data */
$data['image:image'] = array(
'image:loc' => (string) \IPS\File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'image:loc' => (string) File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'image:title' => $item->mapped('title')
);
$priority = ( $item->sitemapPriority() ?: ( \intval( isset( $settings["sitemap_{$class::$title}_priority"] ) ? $settings["sitemap_{$class::$title}_priority"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_PRIORITY ) ) );
$priority = ( $item->sitemapPriority() ?: ( intval($settings["sitemap_{$class::$title}_priority"] ?? Content::RECOMMENDED_ITEM_PRIORITY) ) );
if ( $priority !== -1 )
{
$data['priority'] = $priority;
@@ -165,7 +183,18 @@ class _Images
$lastId = $item->$idColumn;
}
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'image' => 'http://www.google.com/schemas/sitemap-image/1.1' ) );
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'image' => 'https://www.google.com/schemas/sitemap-image/1.1' ) );
return $lastId;
}
/**
* Save settings for ACP configuration
*
* @param array $values Values
* @return void
*/
public function saveSettings( array $values ): void
{
}
}
@@ -12,28 +12,46 @@
namespace IPS\gallery\extensions\core\Sitemap;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Filter;
use IPS\Content\Item;
use IPS\core\extensions\core\Sitemap\Content;
use IPS\DateTime;
use IPS\Db;
use IPS\Extensions\SitemapAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Settings;
use IPS\Sitemap;
use UnderflowException;
use function defined;
use function intval;
use function is_array;
use const IPS\SITEMAP_MAX_PER_FILE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Support Videos in sitemaps
*/
class _Videos
class Videos extends SitemapAbstract
{
/**
* @brief Recommended Settings
*/
public $recommendedSettings = array();
public array $recommendedSettings = array();
/**
* Add settings for ACP configuration to the form
*
* @return array
*/
public function settings()
public function settings(): array
{
return array();
}
@@ -43,9 +61,9 @@ class _Videos
*
* @return array
*/
public function getFilenames()
public function getFilenames(): array
{
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$limit = ( isset( $settings["sitemap_{$class::$title}_count"] ) ) ? $settings["sitemap_{$class::$title}_count"] : -1;
@@ -54,10 +72,10 @@ class _Videos
return array();
}
$count = \IPS\gallery\Image::getItemsWithPermission( array( 'image_media=?', 1 ), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE );
$count = Image::getItemsWithPermission( array( 'image_media=?', 1 ), NULL, 10, 'read', Filter::FILTER_AUTOMATIC, 0, new Member, FALSE, FALSE, FALSE, TRUE );
$files = array();
$count = ceil( $count / \IPS\SITEMAP_MAX_PER_FILE );
$count = ceil( $count / SITEMAP_MAX_PER_FILE );
for( $i=1; $i <= $count; $i++ )
{
@@ -71,21 +89,21 @@ class _Videos
* Generate the sitemap
*
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param \IPS\Sitemap $sitemap Sitemap object reference
* @return void
* @param Sitemap $sitemap Sitemap object reference
* @return int|null
*/
public function generateSitemap( $filename, $sitemap )
public function generateSitemap( string $filename, Sitemap $sitemap ) : ?int
{
$entries = array();
$lastId = 0;
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$exploded = explode( '_', $filename );
$block = (int) array_pop( $exploded );
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
$limit = \IPS\SITEMAP_MAX_PER_FILE;
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * SITEMAP_MAX_PER_FILE;
$limit = SITEMAP_MAX_PER_FILE;
if ( ! $totalLimit )
{
@@ -106,7 +124,7 @@ class _Videos
/* Try to fetch the highest ID built in the last sitemap, if it exists */
try
{
$lastId = \IPS\Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
$lastId = Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
if( $lastId > 0 )
{
@@ -114,12 +132,12 @@ class _Videos
$limitClause = $limit;
}
}
catch( \UnderflowException $e ){}
catch( UnderflowException ){}
$idColumn = $class::$databaseColumnId;
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, \IPS\Content\Item::SELECT_IDS_FIRST, new \IPS\Member, TRUE ) as $item )
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', Filter::FILTER_PUBLIC_ONLY, Item::SELECT_IDS_FIRST, new Member, TRUE ) as $item )
{
if( !$item->canView( new \IPS\Member ) )
if( !$item->canView( new Member ) )
{
continue;
}
@@ -130,16 +148,16 @@ class _Videos
if ( isset( $item::$databaseColumnMap['last_comment'] ) )
{
$lastCommentField = $item::$databaseColumnMap['last_comment'];
if ( \is_array( $lastCommentField ) )
if ( is_array( $lastCommentField ) )
{
foreach ( $lastCommentField as $column )
{
$lastMod = \IPS\DateTime::ts( $item->$column );
$lastMod = DateTime::ts( $item->$column );
}
}
else
{
$lastMod = \IPS\DateTime::ts( $item->$lastCommentField );
$lastMod = DateTime::ts( $item->$lastCommentField );
}
}
@@ -150,21 +168,21 @@ class _Videos
/* Video sitemap data */
$data['video:video'] = array(
'video:content_loc' => (string) \IPS\File::get( 'gallery_Images', $item->original_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'video:content_loc' => (string) File::get( 'gallery_Images', $item->original_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'video:description' => $item->mapped('content'),
'video:title' => $item->mapped('title'),
'video:rating' => $item->mapped('rating_average'),
'video:view_count' => $item->mapped('views'),
'video:publication_date' => \IPS\DateTime::ts( $item->date )->rfc3339(),
'video:publication_date' => DateTime::ts( $item->date )->rfc3339(),
'video:uploader' => array( 0 => $item->author()->name, 'info' => (string) $item->author()->url() ),
);
if( $item->masked_file_name )
{
$data['video:video']['video:thumbnail_loc'] = (string) \IPS\File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' );
$data['video:video']['video:thumbnail_loc'] = (string) File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' );
}
$priority = ( $item->sitemapPriority() ?: ( \intval( isset( $settings["sitemap_{$class::$title}_priority"] ) ? $settings["sitemap_{$class::$title}_priority"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_PRIORITY ) ) );
$priority = ( $item->sitemapPriority() ?: ( intval($settings["sitemap_{$class::$title}_priority"] ?? Content::RECOMMENDED_ITEM_PRIORITY) ) );
if ( $priority !== -1 )
{
$data['priority'] = $priority;
@@ -175,7 +193,18 @@ class _Videos
$lastId = $item->$idColumn;
}
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'video' => 'http://www.google.com/schemas/sitemap-video/1.1' ) );
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'video' => 'https://www.google.com/schemas/sitemap-video/1.1' ) );
return $lastId;
}
/**
* Save settings for ACP configuration
*
* @param array $values Values
* @return void
*/
public function saveSettings( array $values ): void
{
}
}
@@ -11,31 +11,43 @@
namespace IPS\gallery\extensions\core\Statistics;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\DateTime;
use IPS\gallery\Image;
use IPS\Helpers\Chart;
use IPS\Helpers\Chart\Database;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output\Plugin\Filesize;
use IPS\Theme;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Statistics Chart Extension
*/
class _Bandwidth extends \IPS\core\Statistics\Chart
class Bandwidth extends \IPS\core\Statistics\Chart
{
/**
* @brief Controller
*/
public $controller = 'gallery_stats_bandwidth';
public ?string $controller = 'gallery_stats_bandwidth';
/**
* Render Chart
*
* @param \IPS\Http\Url $url URL the chart is being shown on.
* @return \IPS\Helpers\Chart
* @param Url $url URL the chart is being shown on.
* @return Chart
*/
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
public function getChart( Url $url ): Chart
{
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=gallery&module=stats&controller=bandwidth" ), 'gallery_bandwidth', 'bdate', '', array(
$chart = new Database( Url::internal( "app=gallery&module=stats&controller=bandwidth" ), 'gallery_bandwidth', 'bdate', '', array(
'backgroundColor' => '#ffffff',
'colors' => array( '#10967e' ),
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
@@ -43,47 +55,47 @@ class _Bandwidth extends \IPS\core\Statistics\Chart
'areaOpacity' => 0.4,
'chartArea' => array( 'left' => 120, 'width' => '75%' ),
'vAxis' => array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' )
'title' => Member::loggedIn()->language()->addToStack( 'filesize_raw_k' )
)
), 'AreaChart', 'daily', array( 'start' => 0, 'end' => 0 ), array( 'member_id', 'image_id', 'bdate', 'bsize' ) );
$chart->setExtension( $this );
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
$chart->addSeries( Member::loggedIn()->language()->addToStack('bandwidth'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
$chart->tableParsers = array(
'member_id' => function( $val )
{
$member = \IPS\Member::load( $val );
$member = Member::load( $val );
if( $member->member_id )
{
$url = \IPS\Http\Url::internal( "app=gallery&module=stats&controller=member&do=images&id={$member->member_id}" );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $url, FALSE, $member->name );
$url = Url::internal( "app=gallery&module=stats&controller=member&do=images&id={$member->member_id}" );
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $url, FALSE, $member->name );
}
else
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
return Member::loggedIn()->language()->addToStack('deleted_member');
}
},
'image_id' => function( $val )
{
try
{
$image = \IPS\gallery\Image::load( $val );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $image->url(), TRUE, $image->caption );
$image = Image::load( $val );
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $image->url(), TRUE, $image->caption );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_image');
return Member::loggedIn()->language()->addToStack('deleted_image');
}
},
'bdate' => function( $val )
{
return (string) \IPS\DateTime::ts( $val );
return (string) DateTime::ts( $val );
},
'bsize' => function( $val )
{
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
return Filesize::humanReadableFilesize( $val );
}
);
+17 -13
View File
@@ -9,34 +9,38 @@
* @since 30 May 2013
*/
\define('REPORT_EXCEPTIONS', TRUE);
use IPS\Dispatcher\External;
use IPS\File;
use IPS\Output;
use IPS\Request;
define('REPORT_EXCEPTIONS', TRUE);
require_once str_replace( 'applications/gallery/interface/legacy/image.php', '', str_replace( '\\', '/', __FILE__ ) ) . 'init.php';
\IPS\Dispatcher\External::i();
External::i();
try
{
/* Get file and data */
$file = \IPS\File::get( 'gallery_Images', \IPS\Request::i()->path );
$file = File::get( 'gallery_Images', Request::i()->path );
$headers = array_merge( \IPS\Output::getCacheHeaders( time(), 360 ), array( "Content-Disposition" => \IPS\Output::getContentDisposition( 'inline', $file->originalFilename ), "X-Content-Type-Options" => "nosniff" ) );
$headers = array_merge( Output::getCacheHeaders( time(), 360 ), array( "Content-Disposition" => Output::getContentDisposition( 'inline', $file->originalFilename ), "X-Content-Type-Options" => "nosniff" ) );
/* Send headers and print file */
\IPS\Output::i()->sendStatusCodeHeader( 200 );
\IPS\Output::i()->sendHeader( "Content-type: " . \IPS\File::getMimeType( $file->originalFilename ) . ";charset=UTF-8" );
Output::i()->sendStatusCodeHeader( 200 );
Output::i()->sendHeader( "Content-type: " . File::getMimeType( $file->originalFilename ) . ";charset=UTF-8" );
foreach( $headers as $key => $header )
{
\IPS\Output::i()->sendHeader( $key . ': ' . $header );
Output::i()->sendHeader( $key . ': ' . $header );
}
\IPS\Output::i()->sendHeader( "Content-Length: " . $file->filesize() );
\IPS\Output::i()->sendHeader( "Content-Security-Policy: default-src 'none'; sandbox" );
\IPS\Output::i()->sendHeader( "X-Content-Security-Policy: default-src 'none'; sandbox" );
\IPS\Output::i()->sendHeader( "Cross-Origin-Opener-Policy: same-origin" );
Output::i()->sendHeader( "Content-Length: " . $file->filesize() );
Output::i()->sendHeader( "Content-Security-Policy: default-src 'none'; sandbox" );
Output::i()->sendHeader( "X-Content-Security-Policy: default-src 'none'; sandbox" );
$file->printFile();
exit;
}
catch ( \UnderflowException $e )
catch (UnderflowException $e )
{
\IPS\Output::i()->sendOutput( '', 404 );
Output::i()->sendOutput( '', 404 );
}
@@ -0,0 +1,99 @@
<?php
/**
* @brief Member Listener
* @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}
* @since 22 May 2023
*/
namespace IPS\gallery\listeners;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Db;
use IPS\Events\ListenerType\MemberListenerType;
use IPS\gallery\Album;
use IPS\Member;
use IPS\Settings;
use IPS\Task;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Listener
*/
class Gallery extends MemberListenerType
{
/**
* Member is merged with another member
*
* @param Member $member Member being kept
* @param Member $member2 Member being removed
* @return void
*/
public function onMerge( Member $member, Member $member2 ) : void
{
Db::i()->update( 'gallery_albums', array( 'album_owner_id' => $member->member_id ), array( 'album_owner_id=?', $member2->member_id ) );
Db::i()->update( 'gallery_bandwidth', array( 'member_id' => $member->member_id ), array( 'member_id=?', $member2->member_id ) );
Db::i()->update( 'gallery_images_uploads', array( 'upload_member_id' => $member->member_id ), array( 'upload_member_id=?', $member2->member_id ) );
foreach( Album::loadByOwner( $member2 ) as $album )
{
$album->owner_id = $member->member_id;
$album->save();
}
}
/**
* Member is deleted
*
* @param $member Member The member
* @return void
*/
public function onDelete( Member $member ) : void
{
Db::i()->delete( 'gallery_bandwidth', array( 'member_id=?', $member->member_id ) );
Db::i()->delete( 'gallery_images_uploads', array( 'upload_member_id=?', $member->member_id ) );
foreach( Album::loadByOwner( $member ) as $album )
{
//$album->delete();
$album->owner_id = 0;
$album->save();
}
}
/**
* Member is flagged as spammer
*
* @param $member Member The member
* @return void
*/
public function onSetAsSpammer( Member $member ) : void
{
$actions = explode( ',', Settings::i()->spm_option );
/* Hide or delete */
if ( in_array( 'unapprove', $actions ) or in_array( 'delete', $actions ) )
{
foreach( Album::loadByOwner( $member ) as $album )
{
$album->hidden = -1;
$album->save();
if( in_array( 'delete', $actions ) )
{
Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->id, 'deleteWhenDone' => TRUE ), 3 );
}
}
}
}
}
@@ -12,68 +12,86 @@
namespace IPS\gallery\modules\admin\gallery;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Dispatcher;
use IPS\gallery\Album;
use IPS\gallery\Album\Item;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Node;
use IPS\Member;
use IPS\Node\Controller;
use IPS\Node\Model;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Task;
use IPS\Theme;
use function defined;
use function get_class;
use function is_object;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Categories
*/
class _categories extends \IPS\Node\Controller
class categories extends Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
public static bool $csrfProtected = TRUE;
/**
* Node Class
*/
protected $nodeClass = 'IPS\gallery\Category';
protected string $nodeClass = 'IPS\gallery\Category';
/**
* Execute
*
* @return void
*/
public function execute()
public function execute() : void
{
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_manage' );
Dispatcher::i()->checkAcpPermission( 'categories_manage' );
parent::execute();
}
protected function form()
protected function form() : void
{
parent::form();
if ( \IPS\Request::i()->id )
if ( Request::i()->id )
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('edit_category') . ': ' . \IPS\Output::i()->title;
Output::i()->title = Member::loggedIn()->language()->addToStack('edit_category') . ': ' . Output::i()->title;
}
else
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('add_category');
Output::i()->title = Member::loggedIn()->language()->addToStack('add_category');
}
}
/**
* Build the form to mass move content
*
* @param \IPS\Helpers\Form $form The form helper object
* @param Form $form The form helper object
* @param mixed $data Data from the wizard helper
* @param string $nodeClass Node class
* @param \IPS\Node\Model $node Node we are working with
* @param Model $node Node we are working with
* @param string $contentItemClass Content item class (if there is one)
* @return \IPS\Helpers\Form
* @return Form
*/
protected function _buildMassMoveForm( $form, $data, $nodeClass, $node, $contentItemClass )
protected function _buildMassMoveForm(Form $form, mixed $data, string $nodeClass, Model $node, string $contentItemClass ): Form
{
/* Add an option to move or delete albums - we won't worry about filters */
$form->addHeader('node_mass_move_delete_albums');
$form->add( new \IPS\Helpers\Form\Node( 'node_move_subalbums', isset( $data['moveToAlbums'] ) ? $data['moveToClassAlbums']::load( $data['moveToAlbums'] ) : 0, TRUE, array( 'class' => $nodeClass, 'disabled' => array( $node->_id ), 'disabledLang' => 'node_move_delete', 'clubs' => TRUE, 'zeroVal' => 'node_delete_content', 'subnodes' => FALSE, 'permissionCheck' => function( $node )
$form->add( new Node( 'node_move_subalbums', isset( $data['moveToAlbums'] ) ? $data['moveToClassAlbums']::load( $data['moveToAlbums'] ) : 0, TRUE, array( 'class' => $nodeClass, 'disabled' => array( $node->_id ), 'disabledLang' => 'node_move_delete', 'clubs' => TRUE, 'zeroVal' => 'node_delete_content', 'subnodes' => FALSE, 'permissionCheck' => function( $node )
{
return $node->can('add');
} ) ) );
@@ -87,18 +105,18 @@ class _categories extends \IPS\Node\Controller
* @param array $values Values from form submission
* @param mixed $data Data from the wizard helper
* @param string $nodeClass Node class
* @param \IPS\Node\Model $node Node we are working with
* @param Model $node Node we are working with
* @param string $contentItemClass Content item class (if there is one)
* @return array Wizard helper data
*/
protected function _processMassMoveForm( $values, $data, $nodeClass, $node, $contentItemClass )
protected function _processMassMoveForm(array $values, mixed $data, string $nodeClass, Model $node, string $contentItemClass ): array
{
$data = parent::_processMassMoveForm( $values, $data, $nodeClass, $node, $contentItemClass );
/* What are we doing with the albums? */
if ( \is_object( $values['node_move_subalbums'] ) )
if ( is_object( $values['node_move_subalbums'] ) )
{
$data['moveToClassAlbums'] = \get_class( $values['node_move_subalbums'] );
$data['moveToClassAlbums'] = get_class( $values['node_move_subalbums'] );
$data['moveToAlbums'] = $values['node_move_subalbums']->_id;
}
else
@@ -114,21 +132,22 @@ class _categories extends \IPS\Node\Controller
* Actually perform the mass move operation (called from the wizard helper)
*
* @param mixed $data Data from the wizard helper
* @param \IPS\Node\Model $node Node we are working with
* @param Model $node Node we are working with
* @param string $contentItemClass Content item class (if there is one)
* @return mixed
*/
protected function _performMassMove( $data, $node, $contentItemClass )
protected function _performMassMove( mixed $data, Model $node, string $contentItemClass ): mixed
{
/* If we have confirmed the move, just handle albums now and then pass to the parent */
if ( isset( \IPS\Request::i()->confirm ) )
if ( isset( Request::i()->confirm ) )
{
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
/* Loop over our albums */
foreach( \IPS\gallery\Album\Item::getItemsWithPermission( array( array( 'album_category_id=?', $node->_id ) ), NULL, 1000, NULL, TRUE, 0, NULL, FALSE, FALSE, FALSE, FALSE, NULL, TRUE, FALSE, FALSE, FALSE ) as $album )
foreach( Item::getItemsWithPermission( array( array( 'album_category_id=?', $node->_id ) ), NULL, 1000, NULL, TRUE, 0, NULL, FALSE, FALSE, FALSE, FALSE, NULL, TRUE, FALSE, FALSE, FALSE ) as $albumItem )
{
$album = $album->asNode();
/* @var Album $album */
$album = $albumItem->asNode();
/* Are we moving albums? */
if ( isset( $data['moveToAlbums'] ) )
@@ -138,18 +157,18 @@ class _categories extends \IPS\Node\Controller
else
{
/* Store the task for deleting */
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Category', 'id' => $album->_id, 'deleteWhenDone' => FALSE ) );
Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Category', 'id' => $album->_id, 'deleteWhenDone' => FALSE ) );
}
}
if ( isset( $data['moveToAlbums'] ) )
{
$newNode = $data['moveToClassAlbums']::load( $data['moveToAlbums'] );
\IPS\Session::i()->log( 'acplog__catalbum_mass_move', array( $this->title => TRUE, $node->titleForLog() => FALSE, $newNode->titleForLog() => FALSE ) );
Session::i()->log( 'acplog__catalbum_mass_move', array( $this->title => TRUE, $node->titleForLog() => FALSE, $newNode->titleForLog() => FALSE ) );
}
else
{
\IPS\Session::i()->log( 'acplog__catalbum_mass_delete', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
Session::i()->log( 'acplog__catalbum_mass_delete', array( $this->title => TRUE, $node->titleForLog() => FALSE ) );
}
/* Then let the parent take over */
@@ -158,12 +177,12 @@ class _categories extends \IPS\Node\Controller
/* Otherwise show a slightly more useful confirmation message */
else
{
$albumCount = \IPS\gallery\Album\Item::getItemsWithPermission( array( array( 'album_category_id=?', $node->_id ) ), NULL, 1000, NULL, TRUE, 0, NULL, FALSE, FALSE, FALSE, TRUE, NULL, TRUE, FALSE, FALSE, FALSE );
$albumCount = Item::getItemsWithPermission( array( array( 'album_category_id=?', $node->_id ) ), NULL, 1000, NULL, TRUE, 0, NULL, FALSE, FALSE, FALSE, TRUE, NULL, TRUE, FALSE, FALSE, FALSE );
$itemDeletionWhere = $node->massMoveorDeleteWhere( $data );
$itemDeletionWhere[] = array( 'image_album_id=?', 0 );
return \IPS\Theme::i()->getTemplate( 'global', 'gallery' )->nodeMoveDeleteContent( $this->url->setQueryString( array( 'do' => 'massManageContent', 'id' => $node->_id ) )->csrf(), \IPS\Member::loggedIn()->language()->addToStack( $contentItemClass::$title . '_pl_lc' ), $node->getContentItems( NULL, NULL, $itemDeletionWhere, TRUE ), isset( $data['moveTo'] ) ? $data['moveToClass']::load( $data['moveTo'] ) : NULL, $albumCount, isset( $data['moveToAlbums'] ) ? $data['moveToClassAlbums']::load( $data['moveToAlbums'] ) : NULL );
return Theme::i()->getTemplate( 'global', 'gallery' )->nodeMoveDeleteContent( $this->url->setQueryString( array( 'do' => 'massManageContent', 'id' => $node->_id ) )->csrf(), Member::loggedIn()->language()->addToStack( $contentItemClass::$title . '_pl_lc' ), $node->getContentItems( NULL, NULL, $itemDeletionWhere, TRUE ), isset( $data['moveTo'] ) ? $data['moveToClass']::load( $data['moveTo'] ) : NULL, $albumCount, isset( $data['moveToAlbums'] ) ? $data['moveToClassAlbums']::load( $data['moveToAlbums'] ) : NULL );
}
}
}
@@ -12,30 +12,54 @@
namespace IPS\gallery\modules\admin\gallery;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Dispatcher;
use IPS\Dispatcher\Controller;
use IPS\File;
use IPS\GeoLocation;
use IPS\Helpers\Form;
use IPS\Helpers\Form\CheckboxSet;
use IPS\Helpers\Form\Interval;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\Upload;
use IPS\Helpers\Form\WidthHeight;
use IPS\Helpers\Form\YesNo;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Settings as SettingsClass;
use IPS\Task;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* settings
*/
class _settings extends \IPS\Dispatcher\Controller
class settings extends Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
public static bool $csrfProtected = TRUE;
/**
* Execute
*
* @return void
*/
public function execute()
public function execute() : void
{
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
Dispatcher::i()->checkAcpPermission( 'settings_manage' );
parent::execute();
}
@@ -44,7 +68,7 @@ class _settings extends \IPS\Dispatcher\Controller
*
* @return void
*/
protected function manage()
protected function manage() : void
{
$form = $this->_getForm();
@@ -52,39 +76,39 @@ class _settings extends \IPS\Dispatcher\Controller
{
$this->_saveSettingsForm( $form, $values );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=settings' ), 'saved' );
Output::i()->redirect( Url::internal( 'app=gallery&module=gallery&controller=settings' ), 'saved' );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
\IPS\Output::i()->output = $form;
Output::i()->title = Member::loggedIn()->language()->addToStack('settings');
Output::i()->output = $form;
}
/**
* Build and return the settings form
*
* @note Abstracted to allow third party devs to extend easier
* @return \IPS\Helpers\Form
* @return Form
*/
protected function _getForm()
protected function _getForm(): Form
{
$form = new \IPS\Helpers\Form;
$form = new Form;
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'admin_settings.js', 'gallery', 'admin' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js( 'admin_settings.js', 'gallery', 'admin' ) );
$form->attributes['data-controller'] = 'gallery.admin.settings.settings';
$form->hiddenValues['rebuildWatermarkScreenshots'] = \IPS\Request::i()->rebuildWatermarkScreenshots ?: 0;
$form->hiddenValues['rebuildWatermarkScreenshots'] = Request::i()->rebuildWatermarkScreenshots ?: 0;
$form->addTab( 'basic_settings' );
$form->addHeader( 'gallery_images' );
$form->addMessage( \IPS\Member::loggedIn()->language()->addToStack('gallery_dims_explanation'), '', FALSE );
$large = ( isset( \IPS\Settings::i()->gallery_large_dims ) ) ? explode( 'x', \IPS\Settings::i()->gallery_large_dims ) : array( 1600, 1200 );
$small = ( isset( \IPS\Settings::i()->gallery_small_dims ) ) ? explode( 'x', \IPS\Settings::i()->gallery_small_dims ) : array( 240, 240 );
$form->add( new \IPS\Helpers\Form\WidthHeight( 'gallery_large_dims', $large, TRUE, array( 'resizableDiv' => FALSE ) ) );
$form->add( new \IPS\Helpers\Form\WidthHeight( 'gallery_small_dims', $small, TRUE, array( 'resizableDiv' => FALSE ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_use_square_thumbnails', \IPS\Settings::i()->gallery_use_square_thumbnails ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_use_watermarks', \IPS\Settings::i()->gallery_use_watermarks, FALSE, array( 'togglesOn' => array( 'gallery_watermark_path', 'gallery_watermark_images' ) ) ) );
$form->add( new \IPS\Helpers\Form\Upload( 'gallery_watermark_path', \IPS\Settings::i()->gallery_watermark_path ? \IPS\File::get( 'core_Theme', \IPS\Settings::i()->gallery_watermark_path ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'core_Theme' ), NULL, NULL, NULL, 'gallery_watermark_path' ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'gallery_watermark_images',
\IPS\Settings::i()->gallery_watermark_images ? explode( ',', \IPS\Settings::i()->gallery_watermark_images ) : array(),
$form->addHtml( Theme::i()->getTemplate( 'forms', 'core' )->blurb( 'gallery_dims_explanation', true, true )) ;
$large = ( isset( SettingsClass::i()->gallery_large_dims ) ) ? explode( 'x', SettingsClass::i()->gallery_large_dims ) : array( 1600, 1200 );
$small = ( isset( SettingsClass::i()->gallery_small_dims ) ) ? explode( 'x', SettingsClass::i()->gallery_small_dims ) : array( 240, 240 );
$form->add( new WidthHeight( 'gallery_large_dims', $large, TRUE, array( 'resizableDiv' => FALSE ) ) );
$form->add( new WidthHeight( 'gallery_small_dims', $small, TRUE, array( 'resizableDiv' => FALSE ) ) );
$form->add( new YesNo( 'gallery_use_square_thumbnails', SettingsClass::i()->gallery_use_square_thumbnails ) );
$form->add( new YesNo( 'gallery_use_watermarks', SettingsClass::i()->gallery_use_watermarks, FALSE, array( 'togglesOn' => array( 'gallery_watermark_path', 'gallery_watermark_images' ) ) ) );
$form->add( new Upload( 'gallery_watermark_path', SettingsClass::i()->gallery_watermark_path ? File::get( 'core_Theme', SettingsClass::i()->gallery_watermark_path ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'core_Theme' ), NULL, NULL, NULL, 'gallery_watermark_path' ) );
$form->add( new CheckboxSet( 'gallery_watermark_images',
SettingsClass::i()->gallery_watermark_images ? explode( ',', SettingsClass::i()->gallery_watermark_images ) : array(),
FALSE,
array(
'multiple' => TRUE,
@@ -97,42 +121,42 @@ class _settings extends \IPS\Dispatcher\Controller
) );
$form->addHeader( 'gallery_bandwidth' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_detailed_bandwidth', \IPS\Settings::i()->gallery_detailed_bandwidth ) );
$form->add( new \IPS\Helpers\Form\Interval( 'gallery_bandwidth_period', \IPS\Settings::i()->gallery_bandwidth_period, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::HOURS, 'min' => NULL, 'unlimited' => -1 ), NULL, NULL, NULL, 'easypost_delivery_adjustment' ) );
$form->add( new YesNo( 'gallery_detailed_bandwidth', SettingsClass::i()->gallery_detailed_bandwidth ) );
$form->add( new Interval( 'gallery_bandwidth_period', SettingsClass::i()->gallery_bandwidth_period, FALSE, array( 'valueAs' => Interval::HOURS, 'min' => NULL, 'unlimited' => -1 ), NULL, NULL, NULL, 'gallery_bandwidth_period' ) );
$form->addHeader( 'gallery_options' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_rss_enabled', \IPS\Settings::i()->gallery_rss_enabled ) );
$form->add( new YesNo( 'gallery_rss_enabled', SettingsClass::i()->gallery_rss_enabled ) );
if( \IPS\GeoLocation::enabled() )
if( GeoLocation::enabled() )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_maps_default', \IPS\Settings::i()->gallery_maps_default ) );
$form->add( new YesNo( 'gallery_maps_default', SettingsClass::i()->gallery_maps_default ) );
}
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_nsfw', \IPS\Settings::i()->gallery_nsfw ) );
$form->add( new YesNo( 'gallery_nsfw', SettingsClass::i()->gallery_nsfw ) );
$form->addTab( 'gallery_overview_settings' );
$form->addHeader( 'gallery_featured_images' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_overview_show_carousel', \IPS\Settings::i()->gallery_overview_show_carousel, FALSE, array( 'togglesOn' => array( 'gallery_overview_carousel_count', 'gallery_overview_carousel_type' ) ) ) );
$form->add( new YesNo( 'gallery_overview_show_carousel', SettingsClass::i()->gallery_overview_show_carousel, FALSE, array( 'togglesOn' => array( 'gallery_overview_carousel_count', 'gallery_overview_carousel_type' ) ) ) );
$options = array(
'featured' => 'gallery_overview_carousel_featured',
'new' => 'gallery_overview_carousel_new'
);
$form->add( new \IPS\Helpers\Form\Radio( 'gallery_overview_carousel_type', \IPS\Settings::i()->gallery_overview_carousel_type, TRUE, array( 'options' => $options ), NULL, NULL, NULL, 'gallery_overview_carousel_type' ) );
$form->add( new \IPS\Helpers\Form\Number( 'gallery_overview_carousel_count', \IPS\Settings::i()->gallery_overview_carousel_count, FALSE, array(), NULL, NULL, NULL, 'gallery_overview_carousel_count' ) );
$form->add( new Radio( 'gallery_overview_carousel_type', SettingsClass::i()->gallery_overview_carousel_type, TRUE, array( 'options' => $options ), NULL, NULL, NULL, 'gallery_overview_carousel_type' ) );
$form->add( new Number( 'gallery_overview_carousel_count', SettingsClass::i()->gallery_overview_carousel_count, FALSE, array(), NULL, NULL, NULL, 'gallery_overview_carousel_count' ) );
$form->addHeader( 'gallery_overview_recent_comments' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_show_recent_comments', \IPS\Settings::i()->gallery_show_recent_comments, FALSE, array() ) );
$form->add( new YesNo( 'gallery_show_recent_comments', SettingsClass::i()->gallery_show_recent_comments, FALSE, array() ) );
$form->addHeader('gallery_overview_categories');
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_overview_show_categories', \IPS\Settings::i()->gallery_overview_show_categories, FALSE, array() ) );
$form->add( new YesNo( 'gallery_overview_show_categories', SettingsClass::i()->gallery_overview_show_categories, FALSE, array() ) );
$form->addHeader( 'gallery_overview_recent_updated_albums' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_show_recent_updated_albums', \IPS\Settings::i()->gallery_show_recent_updated_albums, FALSE, array( 'togglesOn' => array( 'gallery_recent_updated_albums_count' ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'gallery_recent_updated_albums_count', \IPS\Settings::i()->gallery_recent_updated_albums_count, FALSE, array(), NULL, NULL, NULL, 'gallery_recent_updated_albums_count' ) );
$form->add( new YesNo( 'gallery_show_recent_updated_albums', SettingsClass::i()->gallery_show_recent_updated_albums, FALSE, array( 'togglesOn' => array( 'gallery_recent_updated_albums_count' ) ) ) );
$form->add( new Number( 'gallery_recent_updated_albums_count', SettingsClass::i()->gallery_recent_updated_albums_count, FALSE, array(), NULL, NULL, NULL, 'gallery_recent_updated_albums_count' ) );
$form->addHeader( 'gallery_overview_new_images' );
$form->add( new \IPS\Helpers\Form\YesNo( 'gallery_show_new_images', \IPS\Settings::i()->gallery_show_new_images, FALSE, array( 'togglesOn' => array( 'gallery_new_images_count' ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'gallery_new_images_count', \IPS\Settings::i()->gallery_new_images_count, FALSE, array(), NULL, NULL, NULL, 'gallery_new_images_count' ) );
$form->add( new YesNo( 'gallery_show_new_images', SettingsClass::i()->gallery_show_new_images, FALSE, array( 'togglesOn' => array( 'gallery_new_images_count' ) ) ) );
$form->add( new Number( 'gallery_new_images_count', SettingsClass::i()->gallery_new_images_count, FALSE, array(), NULL, NULL, NULL, 'gallery_new_images_count' ) );
return $form;
}
@@ -140,10 +164,10 @@ class _settings extends \IPS\Dispatcher\Controller
/**
* Save the settings form
*
* @param \IPS\Helpers\Form $form The Form Object
* @param Form $form The Form Object
* @param array $values Values
*/
protected function _saveSettingsForm( \IPS\Helpers\Form $form, array $values )
protected function _saveSettingsForm( Form $form, array $values ) : void
{
$form->saveAsSettings( array(
'gallery_large_dims' => implode( 'x', $values['gallery_large_dims'] ),
@@ -168,12 +192,12 @@ class _settings extends \IPS\Dispatcher\Controller
'gallery_new_images_count' => $values['gallery_new_images_count'],
) );
\IPS\Session::i()->log( 'acplogs__gallery_settings' );
Session::i()->log( 'acplogs__gallery_settings' );
if( $values['rebuildWatermarkScreenshots'] )
{
\IPS\Db::i()->delete( 'core_queue', array( '`app`=? OR `key`=?', 'gallery', 'RebuildGalleryImages' ) );
\IPS\Task::queue( 'gallery', 'RebuildGalleryImages', array( ), 2 );
Db::i()->delete( 'core_queue', array( '`app`=? OR `key`=?', 'gallery', 'RebuildGalleryImages' ) );
Task::queue( 'gallery', 'RebuildGalleryImages', array( ), 2 );
}
}
}
@@ -12,35 +12,44 @@
namespace IPS\gallery\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\Statistics\Chart;
use IPS\Dispatcher;
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Gallery bandwidth statistics
*/
class _bandwidth extends \IPS\Dispatcher\Controller
class bandwidth extends Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
public static bool $csrfProtected = TRUE;
/**
* @brief Allow MySQL RW separation for efficiency
*/
public static $allowRWSeparation = TRUE;
public static bool $allowRWSeparation = TRUE;
/**
* Execute
*
* @return void
*/
public function execute()
public function execute() : void
{
\IPS\Dispatcher::i()->checkAcpPermission( 'bandwidth_manage' );
Dispatcher::i()->checkAcpPermission( 'bandwidth_manage' );
parent::execute();
}
@@ -49,9 +58,9 @@ class _bandwidth extends \IPS\Dispatcher\Controller
*
* @return void
*/
protected function manage()
protected function manage() : void
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('bandwidth_stats');
\IPS\Output::i()->output = (string) \IPS\core\Statistics\Chart::loadFromExtension( 'gallery', 'Bandwidth' )->getChart( \IPS\Http\Url::internal( "app=gallery&module=stats&controller=bandwidth" ) );
Output::i()->title = Member::loggedIn()->language()->addToStack('bandwidth_stats');
Output::i()->output = (string) Chart::loadFromExtension( 'gallery', 'Bandwidth' )->getChart( Url::internal( "app=gallery&module=stats&controller=bandwidth" ) );
}
}
@@ -12,37 +12,54 @@
namespace IPS\gallery\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\DateTime;
use IPS\Db;
use IPS\Dispatcher;
use IPS\Dispatcher\Controller;
use IPS\Helpers\Form;
use IPS\Helpers\Form\DateRange;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Theme;
use UnderflowException;
use function count;
use function defined;
use function intval;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Top uploaders
*/
class _diskspace extends \IPS\Dispatcher\Controller
class diskspace extends Controller
{
const PER_PAGE = 25;
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
public static bool $csrfProtected = TRUE;
/**
* @brief Allow MySQL RW separation for efficiency
*/
public static $allowRWSeparation = TRUE;
public static bool $allowRWSeparation = TRUE;
/**
* Execute
*
* @return void
*/
public function execute()
public function execute() : void
{
\IPS\Dispatcher::i()->checkAcpPermission( 'diskspace_manage' );
Dispatcher::i()->checkAcpPermission( 'diskspace_manage' );
parent::execute();
}
@@ -51,32 +68,32 @@ class _diskspace extends \IPS\Dispatcher\Controller
*
* @return void
*/
protected function manage()
protected function manage() : void
{
$where = array();
if ( isset( \IPS\Request::i()->form ) )
if ( isset( Request::i()->form ) )
{
$form = new \IPS\Helpers\Form( 'form', 'go' );
$form = new Form( 'form', 'go' );
$default = array(
'start' => \IPS\Request::i()->start ? \IPS\DateTime::ts( \IPS\Request::i()->start ) : NULL,
'end' => \IPS\Request::i()->end ? \IPS\DateTime::ts( \IPS\Request::i()->end ) : NULL
'start' => Request::i()->start ? DateTime::ts( Request::i()->start ) : NULL,
'end' => Request::i()->end ? DateTime::ts( Request::i()->end ) : NULL
);
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range', $default, FALSE, array( 'start' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 0, 0, 0 ), 'time' => FALSE ), 'end' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 23, 59, 59 ), 'time' => FALSE ) ) ) );
$form->add( new DateRange( 'stats_date_range', $default, FALSE, array( 'start' => array( 'max' => DateTime::ts( time() )->setTime( 0, 0, 0 ), 'time' => FALSE ), 'end' => array( 'max' => DateTime::ts( time() )->setTime( 23, 59, 59 ), 'time' => FALSE ) ) ) );
if ( !$values = $form->values() )
{
\IPS\Output::i()->output = $form;
Output::i()->output = $form;
return;
}
}
/* Figure out start and end parameters for links */
$params = array(
'start' => !empty( $values['stats_date_range']['start'] ) ? $values['stats_date_range']['start']->getTimestamp() : \IPS\Request::i()->start,
'end' => !empty( $values['stats_date_range']['end'] ) ? $values['stats_date_range']['end']->getTimestamp() : \IPS\Request::i()->end
'start' => !empty( $values['stats_date_range']['start'] ) ? $values['stats_date_range']['start']->getTimestamp() : Request::i()->start,
'end' => !empty( $values['stats_date_range']['end'] ) ? $values['stats_date_range']['end']->getTimestamp() : Request::i()->end
);
if( $params['start'] )
@@ -89,7 +106,7 @@ class _diskspace extends \IPS\Dispatcher\Controller
$where[] = array( 'image_date<?', $params['end'] );
}
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
$page = isset( Request::i()->page ) ? intval( Request::i()->page ) : 1;
if( $page < 1 )
{
@@ -97,16 +114,16 @@ class _diskspace extends \IPS\Dispatcher\Controller
}
try
{
$total = \IPS\Db::i()->select( 'COUNT(DISTINCT(image_member_id))', 'gallery_images', $where )->first();
$total = Db::i()->select( 'COUNT(DISTINCT(image_member_id))', 'gallery_images', $where )->first();
}
catch( \UnderflowException $e )
catch( UnderflowException )
{
$total = 0;
}
if( $total > 0 )
{
$select = \IPS\Db::i()->select( 'image_member_id, count(*) as images', 'gallery_images', $where, 'images DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'image_member_id' )->join( 'core_members', 'core_members.member_id=gallery_images.image_member_id' );
$select = Db::i()->select( 'image_member_id, count(*) as images', 'gallery_images', $where, 'images DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'image_member_id' )->join( 'core_members', 'core_members.member_id=gallery_images.image_member_id' );
$mids = array();
foreach( $select as $row )
@@ -115,35 +132,35 @@ class _diskspace extends \IPS\Dispatcher\Controller
}
$members = array();
if ( \count( $mids ) )
if ( count( $mids ) )
{
$members = iterator_to_array( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
$members = iterator_to_array( Db::i()->select( '*', 'core_members', array( Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=gallery&module=stats&controller=diskspace' )->setQueryString( $params ),
$pagination = Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
Url::internal( 'app=gallery&module=stats&controller=diskspace' )->setQueryString( $params ),
ceil( $total / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=gallery&module=stats&controller=diskspace&form=1' )->setQueryString( $params ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
'link' => Url::internal( 'app=gallery&module=stats&controller=diskspace&form=1' )->setQueryString( $params ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'stats_include_hidden_content' ), 'info' );
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate('stats')->uploadersTable( $select, $pagination, $members, $total );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__gallery_stats_diskspace');
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->message( Member::loggedIn()->language()->addToStack( 'stats_include_hidden_content' ), 'info' );
Output::i()->output .= Theme::i()->getTemplate('stats')->uploadersTable( $select, $pagination, $members, $total );
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__gallery_stats_diskspace');
}
else
{
/* Return the no results message */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( \IPS\Member::loggedIn()->language()->addToStack('menu__gallery_stats_diskspace'), \IPS\Member::loggedIn()->language()->addToStack('no_results'), FALSE , 'ipsPad', NULL, TRUE );
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->block( Member::loggedIn()->language()->addToStack('menu__gallery_stats_diskspace'), Member::loggedIn()->language()->addToStack('no_results'), FALSE , 'i-padding_3', NULL, TRUE );
}
}
}
@@ -12,34 +12,41 @@
namespace IPS\gallery\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Dispatcher\Controller;
use IPS\Http\Url;
use IPS\Output;
use IPS\Request;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Stats
*/
class _member extends \IPS\Dispatcher\Controller
class member extends Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
public static bool $csrfProtected = TRUE;
/**
* @brief Allow MySQL RW separation for efficiency
*/
public static $allowRWSeparation = TRUE;
public static bool $allowRWSeparation = TRUE;
/**
* Images
*
* @return void
*/
protected function images()
protected function images() : void
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal("app=core&module=members&controller=members&do=view&id=" . \IPS\Request::i()->id . "&blockKey=core_ContentStatistics&block[core_ContentStatistics]=gallery_Gallery") );
Output::i()->redirect( Url::internal("app=core&module=members&controller=members&do=view&id=" . Request::i()->id . "&blockKey=core_ContentStatistics&block[core_ContentStatistics]=gallery_Gallery") );
}
}
@@ -12,150 +12,182 @@
namespace IPS\gallery\modules\front\gallery;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Controller;
use IPS\Content\Filter;
use IPS\core\DataLayer;
use IPS\core\Facebook\Pixel;
use IPS\core\FrontNavigation;
use IPS\Dispatcher;
use IPS\gallery\Album;
use IPS\gallery\Album\Item;
use IPS\gallery\Album\Table as AlbumTable;
use IPS\gallery\Application;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\gallery\Image\Table;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Node;
use IPS\Helpers\Form\YesNo;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Settings;
use IPS\Task;
use IPS\Theme;
use OutOfRangeException;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Browse the gallery
*/
class _browse extends \IPS\Content\Controller
class browse extends Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\gallery\Category';
protected static string $contentModel = 'IPS\gallery\Category';
/**
* Execute
*
* @return void
*/
public function execute()
public function execute() : void
{
if( isset( \IPS\Request::i()->album ) )
if( isset( Request::i()->album ) )
{
\IPS\Request::i()->id = \IPS\Request::i()->album;
static::$contentModel = ( isset( \IPS\Request::i()->do ) ) ? 'IPS\gallery\Album\Item' : 'IPS\gallery\Album';
Request::i()->id = Request::i()->album;
static::$contentModel = ( isset( Request::i()->do ) ) ? 'IPS\gallery\Album\Item' : 'IPS\gallery\Album';
}
/* Gallery uses caption for title */
\IPS\Member::loggedIn()->language()->words[ "sort_title" ] = \IPS\Member::loggedIn()->language()->addToStack( "album_sort_caption", FALSE );
Member::loggedIn()->language()->words[ "sort_title" ] = Member::loggedIn()->language()->addToStack( "album_sort_caption", FALSE );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_browse.js', 'gallery' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_global.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_submit.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_global.js', 'gallery' ) );
\IPS\gallery\Application::outputCss();
Application::outputCss();
parent::execute();
}
/**
* Determine what to show
*
* @return void
* @return mixed
*/
protected function manage()
protected function manage() : mixed
{
/* Legacy 3.x redirect */
if ( isset( \IPS\Request::i()->image ) )
if ( isset( Request::i()->image ) )
{
try
{
\IPS\Output::i()->redirect( \IPS\gallery\Image::loadAndCheckPerms( \IPS\Request::i()->image )->url(), '', 301 );
Output::i()->redirect( Image::loadAndCheckPerms( Request::i()->image )->url() );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/A', 404, '' );
Output::i()->error( 'node_error', '2G189/A', 404, '' );
}
}
/* Add RSS feed */
if ( \IPS\Settings::i()->gallery_rss_enabled )
if ( Settings::i()->gallery_rss_enabled )
{
\IPS\Output::i()->rssFeeds['gallery_rss_title'] = \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse&do=rss', 'front', 'gallery_rss' );
Output::i()->rssFeeds['gallery_rss_title'] = Url::internal( 'app=gallery&module=gallery&controller=browse&do=rss', 'front', 'gallery_rss' );
if ( \IPS\Member::loggedIn()->member_id )
if ( Member::loggedIn()->member_id )
{
$key = \IPS\Member::loggedIn()->getUniqueMemberHash();
$key = Member::loggedIn()->getUniqueMemberHash();
\IPS\Output::i()->rssFeeds['gallery_rss_title'] = \IPS\Output::i()->rssFeeds['gallery_rss_title']->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
Output::i()->rssFeeds['gallery_rss_title'] = Output::i()->rssFeeds['gallery_rss_title']->setQueryString( array( 'member' => Member::loggedIn()->member_id , 'key' => $key ) );
}
}
/* And load data and display */
if ( isset( \IPS\Request::i()->category ) )
if ( isset( Request::i()->category ) )
{
try
{
$category = \IPS\gallery\Category::loadAndCheckPerms( \IPS\Request::i()->category, 'view' );
$category = Category::loadAndCheckPerms( Request::i()->category );
$category->clubCheckRules();
/* If we cannot view images and there's a custom error, show it now */
if( !$category->can( 'read' ) AND \IPS\Member::loggedIn()->language()->checkKeyExists( "gallery_category_{$category->id}_permerror" ) )
if( !$category->can( 'read' ) AND Member::loggedIn()->language()->checkKeyExists( "gallery_category_{$category->id}_permerror" ) )
{
\IPS\Output::i()->error( $category->errorMessage(), '1G189/B', 403, '' );
Output::i()->error( $category->errorMessage(), '1G189/B', 403, '' );
}
/* Add RSS feed */
if ( \IPS\Settings::i()->gallery_rss_enabled )
if ( Settings::i()->gallery_rss_enabled )
{
$rssUrl = \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse&do=rss&category=' . $category->id, 'front', 'gallery_rss' );
$rssUrl = Url::internal( 'app=gallery&module=gallery&controller=browse&do=rss&category=' . $category->id, 'front', 'gallery_rss' );
if ( \IPS\Member::loggedIn()->member_id )
if ( Member::loggedIn()->member_id )
{
$key = md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt );
$key = md5( ( Member::loggedIn()->members_pass_hash ?: Member::loggedIn()->email ) . Member::loggedIn()->members_pass_salt );
$rssUrl = $rssUrl->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
$rssUrl = $rssUrl->setQueryString( array( 'member' => Member::loggedIn()->member_id , 'key' => $key ) );
}
\IPS\Output::i()->rssFeeds[ \IPS\Member::loggedIn()->language()->addToStack( 'gallery_rss_title_container', FALSE, array( 'sprintf' => array( $category->_title ) ) ) ] = $rssUrl;
Output::i()->rssFeeds[ Member::loggedIn()->language()->addToStack( 'gallery_rss_title_container', FALSE, array( 'sprintf' => array( $category->_title ) ) ) ] = $rssUrl;
}
$this->_category( $category );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/1', 404, '' );
Output::i()->error( 'node_error', '2G189/1', 404, '' );
}
}
else if ( isset( \IPS\Request::i()->album ) )
else if ( isset( Request::i()->album ) )
{
try
{
$album = \IPS\gallery\Album::loadAndCheckPerms( \IPS\Request::i()->album, 'view' );
$album = Album::loadAndCheckPerms( Request::i()->album );
$album->category()->clubCheckRules();
$album->asItem()->updateViews();
/* Add RSS feed */
if ( \IPS\Settings::i()->gallery_rss_enabled )
if ( Settings::i()->gallery_rss_enabled )
{
$rssUrl = \IPS\Http\Url::internal('app=gallery&module=gallery&controller=browse&do=rss&album=' . $album->id, 'front', 'gallery_rss');
$rssUrl = Url::internal('app=gallery&module=gallery&controller=browse&do=rss&album=' . $album->id, 'front', 'gallery_rss');
if ( \IPS\Member::loggedIn()->member_id )
if ( Member::loggedIn()->member_id )
{
$key = md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt );
$key = md5( ( Member::loggedIn()->members_pass_hash ?: Member::loggedIn()->email ) . Member::loggedIn()->members_pass_salt );
$rssUrl = $rssUrl->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
$rssUrl = $rssUrl->setQueryString( array( 'member' => Member::loggedIn()->member_id , 'key' => $key ) );
}
\IPS\Output::i()->rssFeeds[ \IPS\Member::loggedIn()->language()->addToStack( 'gallery_rss_title_container', FALSE, array( 'sprintf' => array( $album->_title ) ) ) ] = $rssUrl;
Output::i()->rssFeeds[ Member::loggedIn()->language()->addToStack( 'gallery_rss_title_container', FALSE, array( 'sprintf' => array( $album->_title ) ) ) ] = $rssUrl;
}
$this->_album( $album );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/2', 404, '' );
Output::i()->error( 'node_error', '2G189/2', 404, '' );
}
}
else
{
$this->_index();
}
return null;
}
/**
@@ -163,30 +195,31 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function unsetCoverPhoto()
protected function unsetCoverPhoto() : void
{
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
if( \IPS\Request::i()->category )
$container = null;
if( Request::i()->category )
{
$container = \IPS\gallery\Category::loadAndCheckPerms( \IPS\Request::i()->category, 'view' );
$container = Category::loadAndCheckPerms( Request::i()->category );
}
elseif( \IPS\Request::i()->album )
elseif( Request::i()->album )
{
$container = \IPS\gallery\Album::loadAndCheckPerms( \IPS\Request::i()->album, 'view' );
$container = Album::loadAndCheckPerms( Request::i()->album );
}
if( \IPS\gallery\Image::modPermission( 'edit', \IPS\Member::loggedIn(), $container ) )
if( $container AND Image::modPermission( 'edit', Member::loggedIn(), $container ) )
{
$container->cover_img_id = 0;
$container->save();
}
else
{
\IPS\Output::i()->error( 'gallery_unset_cover_error', '2G189/E', 403, '' );
Output::i()->error( 'gallery_unset_cover_error', '2G189/E', 403, '' );
}
\IPS\Output::i()->redirect( $container->url(), 'gallery_cover_photo_isunset' );
Output::i()->redirect( $container->url(), 'gallery_cover_photo_isunset' );
}
/**
@@ -194,53 +227,53 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function _index()
protected function _index() : void
{
/* Get stuff */
$featured = array();
if( \IPS\Settings::i()->gallery_overview_show_carousel )
if( Settings::i()->gallery_overview_show_carousel )
{
switch( \IPS\Settings::i()->gallery_overview_carousel_type )
switch( Settings::i()->gallery_overview_carousel_type )
{
case 'featured':
$featured = iterator_to_array( \IPS\gallery\Image::featured( \IPS\Settings::i()->gallery_overview_carousel_count, NULL ) );
$featured = iterator_to_array( Image::featured( Settings::i()->gallery_overview_carousel_count, NULL ) );
break;
case 'new':
$featured = \IPS\gallery\Image::getItemsWithPermission( \IPS\gallery\Image::clubImageExclusion(), 'image_updated DESC', \IPS\Settings::i()->gallery_overview_carousel_count, 'view' );
$featured = Image::getItemsWithPermission( Image::clubImageExclusion(), 'image_updated DESC', Settings::i()->gallery_overview_carousel_count, 'view' );
break;
}
}
/* New images */
$new = array();
if( \IPS\Settings::i()->gallery_show_new_images )
if( Settings::i()->gallery_show_new_images )
{
$new = iterator_to_array( \IPS\gallery\Image::getItemsWithPermission( \IPS\gallery\Image::clubImageExclusion(), NULL, \IPS\Settings::i()->gallery_new_images_count, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, !\IPS\Settings::i()->club_nodes_in_apps, false, false, false, null, false, false, false ) );
$new = iterator_to_array( Image::getItemsWithPermission( Image::clubImageExclusion(), NULL, Settings::i()->gallery_new_images_count, 'read', Filter::FILTER_AUTOMATIC, 0, NULL, !Settings::i()->club_nodes_in_apps, false, false, false, null, false, false, false ) );
}
/* Recently updated albums */
$recentlyUpdatedAlbums = array();
if( \IPS\Settings::i()->gallery_show_recent_updated_albums )
if( Settings::i()->gallery_show_recent_updated_albums )
{
$recentlyUpdatedAlbums = \IPS\gallery\Album\Item::getItemsWithPermission( \IPS\gallery\Album\Item::clubAlbumExclusion(), 'album_last_img_date DESC', \IPS\Settings::i()->gallery_recent_updated_albums_count, 'view' );
$recentlyUpdatedAlbums = Item::getItemsWithPermission( Item::clubAlbumExclusion(), 'album_last_img_date DESC', Settings::i()->gallery_recent_updated_albums_count, 'view' );
}
/* Recently commented */
$recentComments = array();
if( \IPS\Settings::i()->gallery_show_recent_comments )
if( Settings::i()->gallery_show_recent_comments )
{
$commentWhere = \IPS\gallery\Image::clubImageExclusion();
$commentWhere = Image::clubImageExclusion();
$commentWhere[] = array( 'image_comments > 0' );
$recentComments = \IPS\gallery\Image::getItemsWithPermission( $commentWhere, 'image_last_comment DESC', 10, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, 0, NULL, !\IPS\Settings::i()->club_nodes_in_apps, false, false, false, null, false, false, false );
$recentComments = Image::getItemsWithPermission( $commentWhere, 'image_last_comment DESC', 10, 'read', Filter::FILTER_PUBLIC_ONLY, 0, NULL, !Settings::i()->club_nodes_in_apps, false, false, false, null, false, false, false );
}
/* Online User Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=gallery', 'front', 'gallery' ), array(), 'loc_gallery_browsing' );
Session::i()->setLocation( Url::internal( 'app=gallery', 'front', 'gallery' ), array(), 'loc_gallery_browsing' );
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('gallery_title');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->index( $featured, $new, $recentlyUpdatedAlbums, $recentComments );
Output::i()->title = Member::loggedIn()->language()->addToStack('gallery_title');
Output::i()->output = Theme::i()->getTemplate( 'browse' )->index( $featured, $new, $recentlyUpdatedAlbums, $recentComments );
}
/**
@@ -248,68 +281,68 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function categories()
protected function categories() : void
{
/* Online User Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse&do=categories', 'front', 'gallery_categories' ), array(), 'loc_gallery_browsing_categories' );
Session::i()->setLocation( Url::internal( 'app=gallery&module=gallery&controller=browse&do=categories', 'front', 'gallery_categories' ), array(), 'loc_gallery_browsing_categories' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('gallery_title');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->categories();
Output::i()->title = Member::loggedIn()->language()->addToStack('gallery_title');
Output::i()->output = Theme::i()->getTemplate( 'browse' )->categories();
}
/**
* Show Category
*
* @param \IPS\gallery\Category $category The category to show
* @param Category $category The category to show
* @return void
*/
protected function _category( $category )
protected function _category( Category $category ) : void
{
/* Online User Location */
$permissions = $category->permissions();
\IPS\Session::i()->setLocation( $category->url(), explode( ",", $permissions['perm_view'] ), 'loc_gallery_viewing_category', array( "gallery_category_{$category->id}" => TRUE ) );
Session::i()->setLocation( $category->url(), explode( ",", $permissions['perm_view'] ), 'loc_gallery_viewing_category', array( "gallery_category_{$category->id}" => TRUE ) );
/* Output */
\IPS\Output::i()->title = $category->_title;
Output::i()->title = $category->_title;
/* Need to show albums too */
$albums = NULL;
if( $category->allow_albums )
{
$albums = new \IPS\gallery\Album\Table( NULL, $category );
$albums = new AlbumTable( NULL, $category );
$albums->title = 'albums';
$albums->classes = array( 'ipsDataList_large' );
$albums->classes = array( 'ipsData--category', 'ipsData--gallery-category' );
$albums = ( $category->hasAlbums() ) ? (string) $albums : NULL;
}
\IPS\Output::i()->breadcrumb = array();
\IPS\Output::i()->breadcrumb['module'] = array( \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ), \IPS\Dispatcher::i()->module->_title );
Output::i()->breadcrumb = array();
Output::i()->breadcrumb['module'] = array( Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ), Dispatcher::i()->module->_title );
if( !\count( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_category_id=? AND image_album_id=?', $category->_id, 0 ) ) ) ) )
if( !count( Image::getItemsWithPermission( array( array( 'image_category_id=? AND image_album_id=?', $category->_id, 0 ) ) ) ) )
{
$table = ( $category->childrenCount() or $albums ) ? '' : \IPS\Theme::i()->getTemplate( 'browse' )->noImages( $category );
$table = ( $category->childrenCount() or $albums ) ? '' : Theme::i()->getTemplate( 'browse' )->noImages( $category );
$parents = iterator_to_array( $category->parents() );
if ( \count( $parents ) )
if ( count( $parents ) )
{
foreach( $parents AS $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
}
\IPS\Output::i()->breadcrumb[] = array( NULL, $category->_title );
Output::i()->breadcrumb[] = array( NULL, $category->_title );
}
else
{
/* Build table */
$table = new \IPS\gallery\Image\Table( 'IPS\gallery\Image', $category->url(), array( array( 'image_album_id=?', 0 ) ), $category );
$table = new Table( 'IPS\gallery\Image', $category->url(), array( array( 'image_album_id=?', 0 ) ), $category );
$table->limit = 50;
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'browse' ), 'imageTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse' ), $this->getTableRowsTemplate() );
$table->title = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get('num_images'), array( $category->count_imgs ) );
$table->tableTemplate = array( Theme::i()->getTemplate( 'browse' ), 'imageTable' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse' ), $this->getTableRowsTemplate() );
$table->title = Member::loggedIn()->language()->pluralize( Member::loggedIn()->language()->get('num_images'), array( $category->count_imgs ) );
$table->sortBy = \IPS\Request::i()->sortby ? $table->sortBy : $category->sort_options_img;
$table->sortBy = Request::i()->sortby ? $table->sortBy : $category->sort_options_img;
/* Make sure captions are sorted in the right order */
if ( $table->sortBy == "title" )
@@ -341,42 +374,42 @@ class _browse extends \IPS\Content\Controller
}
/* Data Layer Page Context */
if ( \IPS\Settings::i()->core_datalayer_enabled AND !\IPS\Request::i()->isAjax() )
if ( Settings::i()->core_datalayer_enabled AND !Request::i()->isAjax() )
{
foreach ( $category->getDataLayerProperties() as $property => $value )
{
\IPS\core\DataLayer::i()->addContextProperty( $property, $value, true );
DataLayer::i()->addContextProperty( $property, $value );
}
}
if ( !\IPS\Request::i()->isAjax() )
if ( !Request::i()->isAjax() )
{
$category->updateViews();
}
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item_categories' ) ] = array( 'type' => 'gallery_image', 'nodes' => $category->_id );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->category( $category, $albums, (string) $table );
Output::i()->contextualSearchOptions[ Member::loggedIn()->language()->addToStack( 'search_contextual_item_categories' ) ] = array( 'type' => 'gallery_image', 'nodes' => $category->_id );
Output::i()->output = Theme::i()->getTemplate( 'browse' )->category( $category, $albums, (string) $table );
}
/**
* Show Album
*
* @param \IPS\gallery\Album $album The album to show
* @param Album $album The album to show
* @return void
*/
protected function _album( $album )
protected function _album( Album $album ) : void
{
if( !\count( \IPS\gallery\Image::getItemsWithPermission( array( array( 'image_album_id=?', $album->id ) ) ) ) )
if( !count( Image::getItemsWithPermission( array( array( 'image_album_id=?', $album->id ) ) ) ) )
{
/* Show a 'no images' template if there's nothing to display */
$table = \IPS\Theme::i()->getTemplate( 'browse' )->noImages( $album );
$table = Theme::i()->getTemplate( 'browse' )->noImages( $album );
}
else
{
/* Build table */
$table = new \IPS\gallery\Image\Table( 'IPS\gallery\Image', $album->url(), array( array( 'image_album_id=?', $album->id ) ), $album->category() );
$table = new Table( 'IPS\gallery\Image', $album->url(), array( array( 'image_album_id=?', $album->id ) ), $album->category() );
$table->limit = 50;
$table->sortBy = \IPS\Request::i()->sortby ? $table->sortBy : $album->_sortBy;
$table->sortBy = Request::i()->sortby ? $table->sortBy : $album->_sortBy;
/* Make sure captions are sorted in the right order */
if ( $table->sortBy == "title" )
@@ -384,9 +417,9 @@ class _browse extends \IPS\Content\Controller
$table->sortDirection = "asc";
}
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'browse' ), 'imageTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse' ), $this->getTableRowsTemplate() );
$table->title = \IPS\Member::loggedIn()->language()->addToStack( 'num_images', FALSE, array( 'pluralize' => array( $album->count_imgs ) ) );
$table->tableTemplate = array( Theme::i()->getTemplate( 'browse' ), 'imageTable' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse' ), $this->getTableRowsTemplate() );
$table->title = Member::loggedIn()->language()->addToStack( 'num_images', FALSE, array( 'pluralize' => array( $album->count_imgs ) ) );
if( !$album->allow_comments )
{
@@ -416,12 +449,12 @@ class _browse extends \IPS\Content\Controller
/* Sort out comments and reviews */
$tabs = $asItem->commentReviewTabs();
$_tabs = array_keys( $tabs );
$tab = isset( \IPS\Request::i()->tab ) ? \IPS\Request::i()->tab : array_shift( $_tabs );
$tab = isset( Request::i()->tab ) ? Request::i()->tab : array_shift( $_tabs );
$activeTabContents = $asItem->commentReviews( $tab );
if ( \count( $tabs ) > 1 )
if ( count( $tabs ) > 1 )
{
$commentsAndReviews = \count( $tabs ) ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $album->url(), 'tab', FALSE, TRUE ) : NULL;
$commentsAndReviews = count( $tabs ) ? Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $album->url(), 'tab', FALSE, FALSE ) : NULL;
}
else
{
@@ -429,69 +462,69 @@ class _browse extends \IPS\Content\Controller
}
/* Fetching comments/reviews */
if( \IPS\Request::i()->isAjax() AND !isset( \IPS\Request::i()->listResort ) )
if( Request::i()->isAjax() AND !isset( Request::i()->listResort ) )
{
\IPS\Output::i()->output = $activeTabContents;
Output::i()->output = $activeTabContents;
return;
}
/* Online User Location */
$permissions = $album->category()->permissions();
\IPS\Session::i()->setLocation( $album->url(), explode( ",", $permissions['perm_view'] ), 'loc_gallery_viewing_album', array( $album->_title => FALSE ) );
Session::i()->setLocation( $album->url(), explode( ",", $permissions['perm_view'] ), 'loc_gallery_viewing_album', array( $album->_title => FALSE ) );
/* Output */
\IPS\Output::i()->title = $album->_title;
\IPS\Output::i()->breadcrumb = array();
Output::i()->title = $album->_title;
Output::i()->breadcrumb = array();
if ( $club = $album->category()->club() )
{
\IPS\core\FrontNavigation::$clubTabActive = TRUE;
\IPS\Output::i()->breadcrumb = array();
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), \IPS\Member::loggedIn()->language()->addToStack('module__core_clubs') );
\IPS\Output::i()->breadcrumb[] = array( $club->url(), $club->name );
\IPS\Output::i()->breadcrumb[] = array( $album->category()->url(), $album->category()->_title );
FrontNavigation::$clubTabActive = TRUE;
Output::i()->breadcrumb = array();
Output::i()->breadcrumb[] = array( Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), Member::loggedIn()->language()->addToStack('module__core_clubs') );
Output::i()->breadcrumb[] = array( $club->url(), $club->name );
Output::i()->breadcrumb[] = array( $album->category()->url(), $album->category()->_title );
if ( \IPS\Settings::i()->clubs_header == 'sidebar' )
if ( Settings::i()->clubs_header == 'sidebar' )
{
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'clubs', 'core' )->header( $club, $album->category(), 'sidebar' );
Output::i()->sidebar['contextual'] = Theme::i()->getTemplate( 'clubs', 'core' )->header( $club, $album->category(), 'sidebar' );
}
}
else
{
\IPS\Output::i()->breadcrumb['module'] = array( \IPS\Http\Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ), \IPS\Dispatcher::i()->module->_title );
Output::i()->breadcrumb['module'] = array( Url::internal( 'app=gallery&module=gallery&controller=browse', 'front', 'gallery' ), Dispatcher::i()->module->_title );
$parents = iterator_to_array( $album->category()->parents() );
if ( \count( $parents ) )
if ( count( $parents ) )
{
foreach( $parents AS $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
}
\IPS\Output::i()->breadcrumb[] = array( $album->category()->url(), $album->category()->_title );
Output::i()->breadcrumb[] = array( $album->category()->url(), $album->category()->_title );
}
if( $album->coverPhoto('masked') )
{
\IPS\Output::i()->metaTags['og:image'] = $album->coverPhoto('masked');
Output::i()->metaTags['og:image'] = $album->coverPhoto('masked');
}
\IPS\Output::i()->metaTags['og:title'] = $album->_title;
Output::i()->metaTags['og:title'] = $album->_title;
$albumItem = $album->asItem();
\IPS\core\Facebook\Pixel::i()->PageView = array(
Pixel::i()->PageView = array(
'item_id' => $album->id,
'item_name' => $albumItem->mapped('title'),
'item_type' => isset( $albumItem::$contentType ) ? $albumItem::$contentType : $albumItem::$title,
'item_type' => $albumItem::$contentType ?? $albumItem::$title,
'category_name' => $albumItem->container()->_title
);
if ( !\IPS\Request::i()->isAjax() )
if ( !Request::i()->isAjax() )
{
$albumItem->updateViews();
}
\IPS\Output::i()->breadcrumb[] = array( NULL, $album->_title );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->album( $album, (string) $table, $commentsAndReviews );
Output::i()->breadcrumb[] = array( NULL, $album->_title );
Output::i()->output = Theme::i()->getTemplate( 'browse' )->album( $album, (string) $table, $commentsAndReviews );
}
/**
@@ -499,13 +532,13 @@ class _browse extends \IPS\Content\Controller
*
* @return string
*/
protected function getTableRowsTemplate()
protected function getTableRowsTemplate(): string
{
if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'large' AND \IPS\Request::i()->controller != 'search' )
if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'large' AND Request::i()->controller != 'search' )
{
return 'tableRowsLarge';
}
else if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'rows' AND \IPS\Request::i()->controller != 'search' )
else if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'rows' AND Request::i()->controller != 'search' )
{
return 'tableRowsRows';
}
@@ -520,58 +553,58 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function editAlbum()
protected function editAlbum() : void
{
/* Load album and check permissions */
try
{
$album = \IPS\gallery\Album::loadAndCheckPerms( \IPS\Request::i()->album, 'read' );
$album = Album::loadAndCheckPerms( Request::i()->album, 'read' );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/5', 404, '' );
Output::i()->error( 'node_error', '2G189/5', 404, '' );
}
if( !$album->asItem()->canEdit() )
{
\IPS\Output::i()->error( 'node_error', '2G189/4', 403, '' );
Output::i()->error( 'node_error', '2G189/4', 403, '' );
}
/* Build form */
$form = new \IPS\Helpers\Form;
$form->class .= 'ipsForm_vertical';
$form = new Form;
$form->class .= 'ipsForm--vertical ipsForm--edit-album';
$album->form( $form, TRUE );
$album->form( $form );
/* Handle submissions */
if ( $values = $form->values() )
{
$values['album_owner'] = ( isset( $values['album_owner'] ) ) ? $values['album_owner'] : \IPS\Member::loggedIn();
$values['album_owner'] = ( isset( $values['album_owner'] ) ) ? $values['album_owner'] : Member::loggedIn();
if( !$values['album_name'] OR !$values['album_category'] )
{
if( !$values['album_name'] )
{
$form->elements['']['album_name']->error = \IPS\Member::loggedIn()->language()->addToStack('form_required');
$form->elements['']['album_name']->error = Member::loggedIn()->language()->addToStack('form_required');
}
if( !$values['album_category'] )
{
$form->elements['']['album_category']->error = \IPS\Member::loggedIn()->language()->addToStack('form_required');
$form->elements['']['album_category']->error = Member::loggedIn()->language()->addToStack('form_required');
}
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
Output::i()->output = $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
return;
}
$album->saveForm( $album->formatFormValues( $values ) );
\IPS\Output::i()->redirect( $album->url() );
Output::i()->redirect( $album->url() );
}
/* Display form */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'edit_album' );
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
Output::i()->title = Member::loggedIn()->language()->addToStack( 'edit_album' );
Output::i()->output = $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -579,32 +612,32 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function deleteAlbum()
protected function deleteAlbum() : void
{
/* Load album and check permissions */
try
{
$album = \IPS\gallery\Album::loadAndCheckPerms( \IPS\Request::i()->album, 'read' );
$album = Album::loadAndCheckPerms( Request::i()->album, 'read' );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G189/6', 404, '' );
Output::i()->error( 'node_error', '2G189/6', 404, '' );
}
if( !$album->canDelete() )
{
\IPS\Output::i()->error( 'node_error', '2G189/7', 403, '' );
Output::i()->error( 'node_error', '2G189/7', 403, '' );
}
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
/* Build form to move or delete images */
$form = new \IPS\Helpers\Form;
$form->class .= 'ipsForm_vertical';
$form = new Form;
$form->class .= 'ipsForm--vertical ipsForm--delete-images';
$form->add( new \IPS\Helpers\Form\YesNo( "delete_images", TRUE, FALSE, array( 'togglesOff' => array( 'move_image_category', 'move_image_album' ) ) ) );
$form->add( new YesNo( "delete_images", TRUE, FALSE, array( 'togglesOff' => array( 'move_image_category', 'move_image_album' ) ) ) );
$form->add( new \IPS\Helpers\Form\Node( 'move_image_category', NULL, FALSE, array(
$form->add( new Node( 'move_image_category', NULL, FALSE, array(
'class' => 'IPS\gallery\Category',
'permissionCheck' => function( $node ) {
@@ -624,7 +657,7 @@ class _browse extends \IPS\Content\Controller
}
), NULL, NULL, NULL, 'move_image_category' ) );
$form->add( new \IPS\Helpers\Form\Node( 'move_image_album', NULL, FALSE, array(
$form->add( new Node( 'move_image_album', NULL, FALSE, array(
'class' => 'IPS\gallery\Album',
'permissionCheck' => function( $node ) use ( $album )
{
@@ -661,23 +694,23 @@ class _browse extends \IPS\Content\Controller
$category->save();
/* Hide the album */
$album->type = \IPS\gallery\Album::AUTH_TYPE_DELETED;
$album->type = Album::AUTH_TYPE_DELETED;
$album->save();
/* Are we moving the images? */
if( !$values['delete_images'] )
{
if( ( !isset( $values['move_image_category'] ) OR !( $values['move_image_category'] instanceof \IPS\Node\Model ) ) AND
( !isset( $values['move_image_album'] ) OR !( $values['move_image_album'] instanceof \IPS\Node\Model ) ) )
if( ( !isset( $values['move_image_category'] ) OR !( $values['move_image_category'] instanceof Model ) ) AND
( !isset( $values['move_image_album'] ) OR !( $values['move_image_album'] instanceof Model ) ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('gallery_cat_or_album');
$form->error = Member::loggedIn()->language()->addToStack('gallery_cat_or_album');
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
Output::i()->output = $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
return;
}
$moveData = array( 'class' => 'IPS\gallery\Album', 'id' => $album->_id, 'deleteWhenDone' => TRUE );
if( isset( $values['move_image_category'] ) AND $values['move_image_category'] instanceof \IPS\Node\Model )
if( isset( $values['move_image_category'] ) AND $values['move_image_category'] instanceof Model )
{
$moveData['moveToClass'] = 'IPS\gallery\Category';
$moveData['moveTo'] = $values['move_image_category']->_id;
@@ -688,27 +721,27 @@ class _browse extends \IPS\Content\Controller
$moveData['moveTo'] = $values['move_image_album']->_id;
}
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', $moveData );
Task::queue( 'core', 'DeleteOrMoveContent', $moveData );
}
else
{
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->_id, 'deleteWhenDone' => TRUE ) );
Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->_id, 'deleteWhenDone' => TRUE ) );
}
/* And then redirect */
if( isset( $moveData['moveTo'] ) )
{
$target = $moveData['moveToClass']::load($moveData['moveTo']);
\IPS\Output::i()->redirect( $target->url() );
Output::i()->redirect( $target->url() );
}
else
{
\IPS\Output::i()->redirect( $album->category()->url() );
Output::i()->redirect( $album->category()->url() );
}
}
/* Display form */
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
Output::i()->output = $form->customTemplate( array( Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
@@ -716,9 +749,9 @@ class _browse extends \IPS\Content\Controller
*
* @return void
*/
protected function embed()
protected function embed() : void
{
\IPS\Request::i()->id = \IPS\Request::i()->album;
return parent::embed();
Request::i()->id = Request::i()->album;
parent::embed();
}
}
@@ -15,80 +15,96 @@
namespace IPS\gallery\modules\front\gallery;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Dispatcher\Controller;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use OutOfRangeException;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Store and retrieve image notes
*/
class _notes extends \IPS\Dispatcher\Controller
class notes extends Controller
{
/**
* @var Image|null
*/
protected ?Image $image = null;
/**
* Determine what to show
*
* @return void
*/
protected function manage()
protected function manage() : void
{
try
{
$this->image = \IPS\gallery\Image::load( \IPS\Request::i()->imageId );
$this->image = Image::load( Request::i()->imageId );
if ( !$this->image->canView( \IPS\Member::loggedIn() ) )
if ( !$this->image->canView( Member::loggedIn() ) )
{
\IPS\Output::i()->error( 'node_error', '2G191/1', 403, '' );
Output::i()->error( 'node_error', '2G191/1', 403, '' );
}
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
\IPS\Output::i()->error( 'node_error', '2G191/2', 404, '' );
Output::i()->error( 'node_error', '2G191/2', 404, '' );
}
$response = NULL;
/* jQuery-Notes will send 'image' parameter which we can ignore */
$noteId = \IPS\Request::i()->id;
$position = \IPS\Request::i()->position;
$note = strip_tags( \IPS\Request::i()->note );
$noteId = Request::i()->id;
$position = Request::i()->position;
$note = strip_tags( Request::i()->note );
if( \IPS\Request::i()->get )
if( Request::i()->get )
{
$response = $this->image->_notes;
}
else if( \IPS\Request::i()->add )
else if( Request::i()->add )
{
$response = $this->_addNote( $position, $note );
}
else if( \IPS\Request::i()->delete )
else if( Request::i()->delete )
{
$response = $this->_deleteNote( $noteId );
}
else if( \IPS\Request::i()->edit )
else if( Request::i()->edit )
{
$response = $this->_editNote( $noteId, $position, $note );
}
\IPS\Output::i()->json( $response );
Output::i()->json( $response );
}
/**
* Delete an image note
*
* @param int $id Note ID to delete
* @return bool
* @param int $id Note ID to delete
* @return bool|string
*/
protected function _deleteNote( $id )
protected function _deleteNote( int $id ): bool|string
{
/* Check permission */
if( !$this->image->canEdit() )
{
\IPS\Output::i()->error( 'notes_no_permission', '2G191/3', 403, '' );
Output::i()->error( 'notes_no_permission', '2G191/3', 403, '' );
}
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
$notes = $this->image->_notes;
@@ -111,23 +127,23 @@ class _notes extends \IPS\Dispatcher\Controller
* Add an image note
*
* @param mixed $position Note position
* @param string $note Note text
* @return bool
* @param string $note Note text
* @return bool|array
*/
protected function _addNote( $position, $note )
protected function _addNote( mixed $position, string $note ): array|bool
{
/* Check permission */
if( !$this->image->canEdit() )
{
\IPS\Output::i()->error( 'notes_no_permission', '2G191/4', 403, '' );
Output::i()->error( 'notes_no_permission', '2G191/4', 403, '' );
}
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
$notes = $this->image->_notes;
$position = explode( ',', $position );
if( \count( $position ) != 4 )
if( count( $position ) != 4 )
{
return FALSE;
}
@@ -160,20 +176,20 @@ class _notes extends \IPS\Dispatcher\Controller
/**
* Edit an image note
*
* @param int $id Note ID to edit
* @param mixed $position Note position
* @param string $note Note text
* @return bool
* @param int $id Note ID to edit
* @param mixed $position Note position
* @param string $noteText
* @return bool|string
*/
protected function _editNote( $id, $position='', $noteText='' )
protected function _editNote(int $id, mixed $position='', string $noteText='' ): bool|string
{
/* Check permission */
if( !$this->image->canEdit() )
{
\IPS\Output::i()->error( 'notes_no_permission', '2G191/5', 403, '' );
Output::i()->error( 'notes_no_permission', '2G191/5', 403, '' );
}
\IPS\Session::i()->csrfCheck();
Session::i()->csrfCheck();
$notes = $this->image->_notes;
$position = explode( ',', $position );
@@ -189,7 +205,7 @@ class _notes extends \IPS\Dispatcher\Controller
$notes[ $key ]['NOTE'] = trim( str_replace( "\n", ' ', str_replace( ' ', ' ', $noteText ) ) );
}
if( \count( $position ) == 4 )
if( count( $position ) == 4 )
{
$notes[ $key ]['LEFT'] = round( $position[0], 5 );
$notes[ $key ]['TOP'] = round( $position[1], 5 );
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
Whitespace-only changes.
@@ -1,71 +0,0 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @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 30 Oct 2014
*/
namespace IPS\gallery\setup\upg_100002;
/* 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;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Fix SEO titles
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* Older installs may not allow NULL */
$albums = \IPS\Db::i()->getTableDefinition( 'gallery_albums', TRUE );
if( !$albums['columns']['album_name_seo']['allow_null'] )
{
\IPS\Db::i()->dropIndex( 'gallery_albums', 'album_parent_id' );
\IPS\Db::i()->changeColumn( 'gallery_albums', 'album_name_seo', array( 'name' => 'album_name_seo', 'type' => 'VARCHAR', 'length' => 255, 'allow_null' => TRUE, 'default' => null ) );
\IPS\Db::i()->addIndex( 'gallery_albums', array(
'type' => 'key',
'name' => 'album_parent_id',
'columns' => array( 'album_category_id', 'album_name_seo' ),
'length' => array( null, 181 )
) );
}
$images = \IPS\Db::i()->getTableDefinition( 'gallery_images', TRUE );
if( !$images['columns']['image_caption_seo']['allow_null'] )
{
\IPS\Db::i()->changeColumn( 'gallery_images', 'image_caption_seo', array( 'name' => 'image_caption_seo', 'type' => 'VARCHAR', 'length' => 255, 'allow_null' => TRUE, 'default' => null ) );
}
\IPS\Db::i()->update( 'gallery_albums', array( 'album_name_seo' => null ) );
\IPS\Db::i()->update( 'gallery_categories', array( 'category_name_seo' => null ) );
\IPS\Db::i()->update( 'gallery_images', array( 'image_caption_seo' => null ) );
return true;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Resetting gallery friendly URL titles";
}
}
Whitespace-only changes.
@@ -1,23 +0,0 @@
{
"1": {
"method": "dropIndex",
"params": [
"gallery_comments",
"comment_text"
]
},
"2": {
"method": "dropIndex",
"params": [
"gallery_images",
"image_caption"
]
},
"3": {
"method": "dropIndex",
"params": [
"gallery_images",
"image_description"
]
}
}
Whitespace-only changes.
@@ -1,213 +0,0 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @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 18 Feb 2015
*/
namespace IPS\gallery\setup\upg_100015;
/* 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;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Fix gallery album serialization
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* Some init */
$did = 0;
$perCycle = 1000;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $limit, $perCycle ) ) as $album )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$update = array();
if( @unserialize( $album['album_last_x_images'] ) !== FALSE )
{
$update['album_last_x_images'] = json_encode( unserialize( $album['album_last_x_images'] ) );
}
if( @unserialize( $album['album_sort_options'] ) !== FALSE )
{
$_sort = unserialize( $album['album_sort_options'] );
$_new = 'updated';
switch( $_sort['key'] )
{
case 'image_rating':
$_new = 'rating';
break;
case 'image_comments':
$_new = 'num_comments';
break;
}
$update['album_sort_options'] = $_new;
}
if( \count( $update ) )
{
\IPS\Db::i()->update( 'gallery_albums', $update, 'album_id=' . $album['album_id'] );
}
}
/* And then continue */
if( $did AND $did == $perCycle )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step1Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step1Count'] ) )
{
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
}
return "Updating gallery album images (Updated so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
}
/**
* Fix references to small images that don't exist
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
/* Don't do this if we are coming from an older version as we've already done it */
if( isset( $_SESSION['40_gallery_images_done'] ) )
{
unset( $_SESSION['40_gallery_images_done'] );
return TRUE;
}
/* Some init */
$did = 0;
$perCycle = 200;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
/* Loop over images */
foreach( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_id ASC', array( $limit, $perCycle ) ) as $row )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$file = \IPS\File::get( 'gallery_Images', $row['image_small_file_name'] );
/* If the size is 0 (or NULL more likely) it does not exist */
if( !$file->filesize() )
{
$update = array( 'image_small_file_name' => $row['image_medium_file_name'] );
$data = json_decode( $row['image_data'], TRUE );
$data['small'] = $data['medium'];
$update['image_data'] = json_encode( $data );
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $row['image_id'] ) );
}
}
/* And then continue */
if( $did AND $did == $perCycle )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step2Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step2CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step2Count'] ) )
{
$_SESSION['_step2Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
}
return "Checking gallery images (Upgraded so far: " . ( ( $limit > $_SESSION['_step2Count'] ) ? $_SESSION['_step2Count'] : $limit ) . ' out of ' . $_SESSION['_step2Count'] . ')';
}
/**
* Finish - This is run after all apps have been upgraded
*
* @return mixed If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
* @note We opted not to let users run this immediately during the upgrade because of potential issues (it taking a long time and users stopping it or getting frustrated) but we can revisit later
*/
public function finish()
{
\IPS\Task::queue( 'core', 'RebuildItems', array( 'class' => 'IPS\gallery\Image' ), 3, array( 'class' ) );
\IPS\Task::queue( 'core', 'RebuildItemCounts', array( 'class' => 'IPS\gallery\Image', 'count' => 0 ), 4, array( 'class' ) );
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\gallery\Category', 'count' => 0 ), 5, array( 'class' ) );
}
}
Whitespace-only changes.
@@ -1,41 +0,0 @@
<?php
/**
* @brief 4.0.0 RC 5 Upgrade Code
* @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 5 May 2015
*/
namespace IPS\gallery\setup\upg_100018;
/* 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;
}
/**
* 4.0.0 RC 5 Upgrade Code
*/
class _Upgrade
{
/**
* Make sure all theme settings are applied to every theme.
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
\IPS\Task::queue( 'core', 'RebuildReputationIndex', array( 'class' => 'IPS\gallery\Image' ), 4 );
\IPS\Task::queue( 'core', 'RebuildReputationIndex', array( 'class' => 'IPS\gallery\Image\Comment' ), 4 );
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\gallery\Category', 'count' => 0 ), 5, array( 'class' ) );
return TRUE;
}
}
Whitespace-only changes.
@@ -1,39 +0,0 @@
{
"1": {
"method": "addIndex",
"params": [
"gallery_comments",
{
"type": "key",
"name": "comment_approved",
"columns": [
"comment_approved"
],
"length": [
null
]
}
]
},
"2": {
"method": "changeColumn",
"params": [
"gallery_images",
"image_metadata",
{
"name": "image_metadata",
"type": "MEDIUMTEXT",
"length": 0,
"decimals": null,
"values": [],
"allow_null": true,
"default": null,
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
Whitespace-only changes.
@@ -1,51 +0,0 @@
<?php
/**
* @brief 4.0.2 Upgrade Code
* @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 14 Apr 2015
*/
namespace IPS\gallery\setup\upg_100025;
/* 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;
}
/**
* 4.0.2 Upgrade Code
*/
class _Upgrade
{
/**
* Fix album counts
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
try
{
\IPS\Task::queue( 'core', 'RebuildContainerCounts', array( 'class' => 'IPS\gallery\Album', 'count' => 0 ), 5, array( 'class' ) );
}
catch( \OutOfRangeException $ex ) { }
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Rebuilding gallery album counts";
}
}
Whitespace-only changes.
@@ -1,42 +0,0 @@
{
"1": {
"method": "addColumn",
"params": [
"gallery_images",
{
"name": "image_hidden_comments",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": true,
"default": null,
"comment": "",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"2": {
"method": "addColumn",
"params": [
"gallery_images",
{
"name": "image_unapproved_comments",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": true,
"default": null,
"comment": "",
"unsigned": true,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
Whitespace-only changes.
@@ -1,42 +0,0 @@
<?php
/**
* @brief 4.0.5 Upgrade Code
* @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 5 May 2015
*/
namespace IPS\gallery\setup\upg_100028;
/* 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;
}
/**
* 4.0.5 Upgrade Code
*/
class _Upgrade
{
/**
* Make sure all theme settings are applied to every theme.
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
\IPS\core\Setup\Upgrade::repairFileUrls('gallery');
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\gallery\Image' ), 3, array( 'class' ) );
\IPS\Task::queue( 'core', 'RebuildContentImages', array( 'class' => 'IPS\gallery\Image\Comment' ), 3, array( 'class' ) );
\IPS\Task::queue( 'core', 'RebuildNonContentImages', array( 'extension' => 'gallery_Categories' ), 3, array( 'extension' ) );
return TRUE;
}
}
Whitespace-only changes.
@@ -1,90 +0,0 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @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 18 Feb 2015
*/
namespace IPS\gallery\setup\upg_100030;
/* 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;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Fix gallery images category_id
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* Some init */
$did = 0;
$perCycle = 250;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $limit, $perCycle ) ) as $album )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
if ( $album['album_category_id'] )
{
\IPS\Db::i()->update( 'gallery_images', array( 'image_category_id' => $album['album_category_id'] ), array( 'image_album_id=?', $album['album_id'] ) );
}
}
/* And then continue */
if( $did AND $did == $perCycle )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step1Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step1Count'] ) )
{
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
}
return "Updating gallery album images (Updated so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
}
}
Whitespace-only changes.
@@ -1,10 +0,0 @@
{
"1": {
"method": "update",
"params": [
"core_notifications",
"extra=CONCAT('[', extra, ']')",
"notification_key='new_content_bulk' AND item_class='IPS\\gallery\\Album'"
]
}
}
@@ -1,90 +0,0 @@
<?php
/**
* @brief 4.0.9 Upgrade Code
* @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 19 Jun 2015
*/
namespace IPS\gallery\setup\upg_100035;
/* 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;
}
/**
* 4.0.9 Upgrade Code
*/
class _Upgrade
{
/**
* Update widgets
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function finish()
{
$areas = array( 'core_widget_areas' );
if ( \IPS\Application::appIsEnabled('cms') )
{
$areas[] = 'cms_page_widget_areas';
}
foreach ( $areas as $table )
{
foreach ( \IPS\Db::i()->select( '*', $table ) as $area )
{
$widgetsColumn = $table == 'core_widget_areas' ? 'widgets' : 'area_widgets';
$whereClause = $table == 'core_widget_areas' ? array( 'id=? AND area=?', $area['id'], $area['area'] ) : array( 'area_page_id=? AND area_area=?', $area['area_page_id'], $area['area_area'] );
$widgets = json_decode( $area[ $widgetsColumn ], TRUE );
$update = FALSE;
foreach ( $widgets as $k => $widget )
{
if ( $widget['key'] == 'recentImages' )
{
$widgets[ $k ]['key'] = 'imageFeed';
if ( isset( $widgets[ $k ]['configuration']['number_to_show'] ) )
{
$widgets[ $k ]['configuration']['widget_feed_show'] = $widgets[ $k ]['configuration']['number_to_show'];
unset( $widgets[ $k ]['configuration']['number_to_show'] );
}
$update = TRUE;
}
if ( $widget['key'] == 'topImages' )
{
$widgets[ $k ]['key'] = 'imageFeed';
$widgets[ $k ]['configuration']['widget_feed_min_rating'] = 1;
$widgets[ $k ]['configuration']['widget_feed_sort_on'] = 'rating';
$widgets[ $k ]['configuration']['widget_feed_sort_dir'] = 'desc';
if ( isset( $widgets[ $k ]['configuration']['number_to_show'] ) )
{
$widgets[ $k ]['configuration']['widget_feed_show'] = $widgets[ $k ]['configuration']['number_to_show'];
unset( $widgets[ $k ]['configuration']['number_to_show'] );
}
$update = TRUE;
}
if ( $update )
{
\IPS\Db::i()->update( $table, array( $widgetsColumn => json_encode( $widgets ) ), $whereClause );
}
}
}
}
return TRUE;
}
}
Whitespace-only changes.
@@ -1,24 +0,0 @@
{
"1": {
"method": "delete",
"params": [
"core_widgets",
[
"app=? AND `key`=?",
"gallery",
"recentImages"
]
]
},
"2": {
"method": "delete",
"params": [
"core_widgets",
[
"app=? AND `key`=?",
"gallery",
"topImages"
]
]
}
}
Whitespace-only changes.
@@ -1,154 +0,0 @@
<?php
/**
* @brief 4.0.12 Upgrade Code
* @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 27 Jul 2015
*/
namespace IPS\gallery\setup\upg_100042;
/* 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;
}
/**
* 4.0.12 Upgrade Code
*/
class _Upgrade
{
/**
* We need to fix image data if any is bad - this is a relatively fast process typically
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
/* Some init */
$did = 0;
$perCycle = 1000;
$limit = 0;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
/* Loop over images */
foreach( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_id ASC', array( $limit, $perCycle ) ) as $row )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$imageData = json_decode( $row['image_data'], TRUE );
$rebuild = false;
if ( \is_array( $imageData ) )
{
foreach( $imageData as $size => $dimensions )
{
if( $dimensions[0] == 0 )
{
$rebuild = true;
break;
}
}
}
else
{
$rebuild = true;
}
if( $rebuild === true )
{
/* We use try/catch because getimagesize() will throw an \ErrorException if the file no longer exists */
try
{
$large = ( isset( $row['image_masked_file_name'] ) ) ? \IPS\File::get( 'gallery_Images', $row['image_masked_file_name'] )->getImageDimensions() : array( 0, 0 );
}
catch( \Exception $e )
{
$large = array( 0, 0 );
}
try
{
$medium = ( isset( $row['image_medium_file_name'] ) ) ? \IPS\File::get( 'gallery_Images', $row['image_medium_file_name'] )->getImageDimensions() : array( 0, 0 );
}
catch( \Exception $e )
{
$medium = array( 0, 0 );
}
try
{
$small = ( isset( $row['image_small_file_name'] ) ) ? \IPS\File::get( 'gallery_Images', $row['image_small_file_name'] )->getImageDimensions() : array( 0, 0 );
}
catch( \Exception $e )
{
$small = array( 0, 0 );
}
try
{
$thumb = ( isset( $row['image_thumb_file_name'] ) ) ? \IPS\File::get( 'gallery_Images', $row['image_thumb_file_name'] )->getImageDimensions() : array( 0, 0 );
}
catch( \Exception $e )
{
$thumb = array( 0, 0 );
}
$newData = array(
'large' => $large,
'medium' => $medium,
'small' => $small,
'thumb' => $thumb,
);
\IPS\Db::i()->update( 'gallery_images', array( 'image_data' => json_encode( $newData ) ), array( 'image_id=?', $row['image_id'] ) );
}
}
/* And then continue */
if( $did AND $did == $perCycle )
{
return $limit + $did;
}
else
{
unset( $_SESSION['_step1Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step1Count'] ) )
{
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
}
return "Fixing stored image dimensions (Upgraded so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
}
}
Whitespace-only changes.
@@ -1,446 +0,0 @@
{
"1": {
"method": "createTable",
"params": [
{
"name": "gallery_reviews",
"columns": {
"review_id": {
"allow_null": false,
"auto_increment": true,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 20,
"name": "review_id",
"type": "BIGINT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_author": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_author",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_author_name": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "",
"length": 255,
"name": "review_author_name",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_content": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 0,
"name": "review_content",
"type": "MEDIUMTEXT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_date": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_date",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_ip_address": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "",
"length": 46,
"name": "review_ip_address",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_edit_time": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_edit_time",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_edit_member_name": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "",
"length": 255,
"name": "review_edit_member_name",
"type": "VARCHAR",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_edit_show": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 1,
"name": "review_edit_show",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_rating": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_rating",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_votes_total": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_votes_total",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_votes_helpful": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 10,
"name": "review_votes_helpful",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_votes_data": {
"allow_null": true,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": null,
"length": 0,
"name": "review_votes_data",
"type": "TEXT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_approved": {
"allow_null": false,
"auto_increment": false,
"binary": false,
"comment": "",
"decimals": null,
"default": "0",
"length": 1,
"name": "review_approved",
"type": "INT",
"unsigned": false,
"values": [],
"zerofill": false
},
"review_image_id": {
"name": "review_image_id",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
},
"indexes": {
"PRIMARY": {
"type": "primary",
"name": "PRIMARY",
"length": [
null
],
"columns": [
"review_id"
]
},
"review_approved": {
"type": "key",
"name": "review_approved",
"length": [
null
],
"columns": [
"review_approved"
]
},
"review_ip": {
"type": "key",
"name": "review_ip",
"length": [
null
],
"columns": [
"review_ip_address"
]
},
"review_author": {
"type": "key",
"name": "review_author",
"length": [
null
],
"columns": [
"review_author"
]
}
},
"collation": "utf8mb4_unicode_ci"
}
]
},
"2": {
"method": "addColumn",
"params": [
"gallery_categories",
{
"name": "category_allow_reviews",
"type": "TINYINT",
"length": 4,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"3": {
"method": "addColumn",
"params": [
"gallery_categories",
{
"name": "category_review_moderate",
"type": "TINYINT",
"length": 4,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"4": {
"method": "addColumn",
"params": [
"gallery_albums",
{
"name": "album_allow_reviews",
"type": "TINYINT",
"length": 4,
"decimals": null,
"values": [],
"allow_null": true,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"5": {
"method": "addColumn",
"params": [
"gallery_albums",
{
"name": "album_count_reviews",
"type": "INT",
"length": 11,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"6": {
"method": "addColumn",
"params": [
"gallery_albums",
{
"name": "album_count_reviews_hidden",
"type": "INT",
"length": 11,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"7": {
"method": "addColumn",
"params": [
"gallery_images",
{
"name": "image_reviews",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"8": {
"method": "addColumn",
"params": [
"gallery_images",
{
"name": "image_reviews_queued",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"9": {
"method": "addColumn",
"params": [
"gallery_images",
{
"name": "image_hidden_reviews",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"10": {
"method": "changeColumn",
"params": [
"gallery_images",
"image_reviews_queued",
{
"name": "image_unapproved_reviews",
"type": "INT",
"length": 10,
"decimals": null,
"values": [],
"allow_null": false,
"default": "0",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
@@ -1,78 +0,0 @@
<?php
/**
* @brief 4.1.0 Beta 1 Upgrade Code
* @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 25 Sep 2015
*/
namespace IPS\gallery\setup\upg_101000;
/* 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;
}
/**
* 4.1.0 Beta 1 Upgrade Code
*/
class _Upgrade
{
/**
* Fix images in the root uploads directory as they'll get stripped by the orphaned attachments tool
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
$toRunQueries = array(
array(
'table' => 'gallery_images',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "gallery_images SET image_masked_file_name=SUBSTR( image_masked_file_name, 2 ) WHERE image_masked_file_name LIKE '/%'",
),
array(
'table' => 'gallery_images',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "gallery_images SET image_medium_file_name=SUBSTR( image_medium_file_name, 2 ) WHERE image_medium_file_name LIKE '/%'",
),
array(
'table' => 'gallery_images',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "gallery_images SET image_original_file_name=SUBSTR( image_original_file_name, 2 ) WHERE image_original_file_name LIKE '/%'",
),
array(
'table' => 'gallery_images',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "gallery_images SET image_thumb_file_name=SUBSTR( image_thumb_file_name, 2 ) WHERE image_thumb_file_name LIKE '/%'",
),
array(
'table' => 'gallery_images',
'query' => "UPDATE " . \IPS\Db::i()->prefix . "gallery_images SET image_small_file_name=SUBSTR( image_small_file_name, 2 ) WHERE image_small_file_name LIKE '/%'",
),
);
$toRun = \IPS\core\Setup\Upgrade::runManualQueries( $toRunQueries );
if ( \count( $toRun ) )
{
\IPS\core\Setup\Upgrade::adjustMultipleRedirect( array( 'extra' => array( '_upgradeStep' => 2 ) ) );
/* Queries to run manually */
return array( 'html' => \IPS\Theme::i()->getTemplate( 'forms' )->queries( $toRun, \IPS\Http\Url::internal( 'controller=upgrade' )->setQueryString( array( 'key' => $_SESSION['uniqueKey'], 'mr_continue' => 1, 'mr' => \IPS\Request::i()->mr ) ) ) );
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Fixing broken gallery image paths";
}
}
Whitespace-only changes.
@@ -1,15 +0,0 @@
{
"1": {
"method": "update",
"params": [
"gallery_images",
{
"image_metadata": null
},
[
"image_metadata=?",
"false"
]
]
}
}
Loaded 100 of 6736 files, more files were not shown because too many files have changed in this diff. Show more