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

@@ -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 );
}