Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -10,20 +10,20 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
use IPS\calendar\api\GraphQL\Mutations\CreateEvent;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog mutationss GraphQL API
|
||||
*/
|
||||
abstract class _Mutation
|
||||
abstract class Mutation
|
||||
{
|
||||
/**
|
||||
* Get the supported query types in this app
|
||||
@@ -32,9 +32,8 @@ abstract class _Mutation
|
||||
*/
|
||||
public static function mutations(): array
|
||||
{
|
||||
$return = [
|
||||
'createEvent' => new \IPS\calendar\api\GraphQL\Mutations\CreateEvent(),
|
||||
return [
|
||||
'createEvent' => new CreateEvent(),
|
||||
];
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -10,30 +10,38 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Mutations;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\SafeException;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\Types\EventType;
|
||||
use IPS\calendar\Calendar;
|
||||
use IPS\calendar\Event;
|
||||
use IPS\Content\Api\GraphQL\ItemMutator;
|
||||
use IPS\Content\Item;
|
||||
use IPS\Member;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Event mutation for GraphQL API
|
||||
*/
|
||||
class _CreateEvent extends \IPS\Content\Api\GraphQL\ItemMutator
|
||||
class CreateEvent extends ItemMutator
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = \IPS\calendar\Event::class;
|
||||
protected string $class = Event::class;
|
||||
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Create a new calendar event";
|
||||
public static string $description = "Create a new calendar event";
|
||||
|
||||
/*
|
||||
* Mutation arguments
|
||||
@@ -48,7 +56,7 @@ class _CreateEvent extends \IPS\Content\Api\GraphQL\ItemMutator
|
||||
/**
|
||||
* Return the mutation return type
|
||||
*/
|
||||
public function type()
|
||||
public function type(): EventType
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
}
|
||||
@@ -56,42 +64,43 @@ class _CreateEvent extends \IPS\Content\Api\GraphQL\ItemMutator
|
||||
/**
|
||||
* Resolves this mutation
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
* @param mixed $val Value passed into this resolver
|
||||
* @param array $args Arguments
|
||||
* @param array $context Context values
|
||||
* @param array $info
|
||||
* @return Event
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
public function resolve( mixed $val, array $args, array $context, array $info): Item
|
||||
{
|
||||
/* Get calendar */
|
||||
try
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::loadAndCheckPerms( $args['calendarID'] );
|
||||
$calendar = Calendar::loadAndCheckPerms( $args['calendarID'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_CALENDAR', '1L296/6_graphql', 400 );
|
||||
throw new SafeException( 'NO_CALENDAR', '1L296/6_graphql', 400 );
|
||||
}
|
||||
|
||||
/* Check permission */
|
||||
if ( !$calendar->can( 'add', \IPS\Member::loggedIn() ) )
|
||||
if ( !$calendar->can( 'add', Member::loggedIn() ) )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '1L296/7_graphql', 403 );
|
||||
throw new SafeException( 'NO_PERMISSION', '1L296/7_graphql', 403 );
|
||||
}
|
||||
|
||||
/* Check we have a title and a post */
|
||||
if ( !$args['title'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_TITLE', '1L296/8_graphql', 400 );
|
||||
throw new SafeException( 'NO_TITLE', '1L296/8_graphql', 400 );
|
||||
}
|
||||
if ( !$args['content'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1L296/9_grapqhl', 400 );
|
||||
throw new SafeException( 'NO_POST', '1L296/9_grapqhl', 400 );
|
||||
}
|
||||
|
||||
if ( !$args['start'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_START', '1L296/A_grapqhl', 400 );
|
||||
throw new SafeException( 'INVALID_START', '1L296/A_grapqhl', 400 );
|
||||
}
|
||||
|
||||
return $this->_create( $args, $calendar, $args['postKey'] ?? NULL );
|
||||
|
||||
@@ -10,25 +10,28 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\Types\CalendarType;
|
||||
use IPS\calendar\Calendar as CalendarClass;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar query for GraphQL API
|
||||
*/
|
||||
class _calendar
|
||||
class Calendar
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a calendar";
|
||||
public static string $description = "Returns a calendar";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
@@ -43,7 +46,7 @@ class _calendar
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
public function type(): CalendarType
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::calendar();
|
||||
}
|
||||
@@ -51,18 +54,19 @@ class _calendar
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Calendar
|
||||
* @param mixed $val Value passed into this resolver
|
||||
* @param array $args Arguments
|
||||
* @param array $context Context values
|
||||
* @param array $info
|
||||
* @return CalendarClass
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
public function resolve( mixed $val, array$args, array $context, array $info): CalendarClass
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::load( $args['id'] );
|
||||
$calendar = CalendarClass::load( $args['id'] );
|
||||
|
||||
if( !$calendar->can( 'view', $context['member'] ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
@@ -10,25 +10,27 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ListOfType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\Calendar;
|
||||
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 query for GraphQL API
|
||||
*/
|
||||
class _Calendars
|
||||
class Calendars
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of calendars";
|
||||
public static string $description = "Returns a list of calendars";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
@@ -43,7 +45,7 @@ class _Calendars
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
public function type(): ListOfType
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\calendar\api\GraphQL\TypeRegistry::calendar() );
|
||||
}
|
||||
@@ -51,14 +53,15 @@ class _Calendars
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @param mixed $val Value passed into this resolver
|
||||
* @param array $args Arguments
|
||||
* @param array $context Context values
|
||||
* @param array $info
|
||||
* @return array
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
public function resolve( mixed $val, array $args, array $context, array $info): array
|
||||
{
|
||||
\IPS\calendar\Calendar::loadIntoMemory('view', $context['member']);
|
||||
return \IPS\calendar\Calendar::roots();
|
||||
Calendar::loadIntoMemory('view', $context['member']);
|
||||
return Calendar::roots();
|
||||
}
|
||||
}
|
||||
@@ -10,25 +10,29 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\SafeException;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\Types\EventType;
|
||||
use IPS\calendar\Event as EventClass;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event query for GraphQL API
|
||||
*/
|
||||
class _Event
|
||||
class Event
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns an event";
|
||||
public static string $description = "Returns an event";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
@@ -43,7 +47,7 @@ class _Event
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
public function type(): EventType
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
}
|
||||
@@ -51,25 +55,26 @@ class _Event
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
* @param mixed $val Value passed into this resolver
|
||||
* @param array $args Arguments
|
||||
* @param array $context Context values
|
||||
* @param array $info
|
||||
* @return EventClass
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
public function resolve( mixed $val, array $args, array $context, array $info): EventClass
|
||||
{
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::loadAndCheckPerms( $args['id'] );
|
||||
$event = EventClass::loadAndCheckPerms( $args['id'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_EVENT', '1F294/2_graphql', 400 );
|
||||
throw new SafeException( 'NO_EVENT', '1F294/2_graphql', 400 );
|
||||
}
|
||||
|
||||
if( !$event->can('read') )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_ID', '2F294/9_graphql', 403 );
|
||||
throw new SafeException( 'INVALID_ID', '2F294/9_graphql', 403 );
|
||||
}
|
||||
|
||||
return $event;
|
||||
|
||||
@@ -11,25 +11,34 @@
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\ListOfType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\Types\EventType;
|
||||
use IPS\calendar\Calendar;
|
||||
use IPS\calendar\Event;
|
||||
use IPS\Db;
|
||||
use IPS\Member;
|
||||
use IPS\Patterns\ActiveRecordIterator;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar Events query for GraphQL API
|
||||
*/
|
||||
class _Events
|
||||
class Events
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of events";
|
||||
public static string $description = "Returns a list of events";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
@@ -50,7 +59,7 @@ class _Events
|
||||
'type' => TypeRegistry::eNum( [
|
||||
'name' => 'events_order_by',
|
||||
'description' => 'Fields on which events can be sorted',
|
||||
'values' => \IPS\calendar\api\GraphQL\Types\EventType::getOrderByOptions(),
|
||||
'values' => EventType::getOrderByOptions(),
|
||||
] ),
|
||||
'defaultValue' => NULL, // will use default sort option
|
||||
],
|
||||
@@ -72,7 +81,7 @@ class _Events
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
public function type(): ListOfType
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\calendar\api\GraphQL\TypeRegistry::event() );
|
||||
}
|
||||
@@ -80,30 +89,31 @@ class _Events
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
* @param mixed $val Value passed into this resolver
|
||||
* @param array $args Arguments
|
||||
* @param array $context Context values
|
||||
* @param array $info
|
||||
* @return ActiveRecordIterator
|
||||
*/
|
||||
public function resolve( $val, $args, $context, $info )
|
||||
public function resolve( mixed $val, array $args, array $context, array $info ): ActiveRecordIterator
|
||||
{
|
||||
$where = [];
|
||||
\IPS\calendar\Calendar::loadIntoMemory( 'view', \IPS\Member::loggedIn() );
|
||||
Calendar::loadIntoMemory( 'view', Member::loggedIn() );
|
||||
|
||||
$calendarIDs = [];
|
||||
|
||||
/* Are we filtering by calendards? */
|
||||
if( isset( $args[ 'calendars' ] ) && \count( $args[ 'calendars' ] ) )
|
||||
if( isset( $args[ 'calendars' ] ) && count( $args[ 'calendars' ] ) )
|
||||
{
|
||||
foreach( $args[ 'calendars' ] as $id )
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::loadAndCheckPerms( $id );
|
||||
$calendar = Calendar::loadAndCheckPerms( $id );
|
||||
$calendarIDs[] = $calendar->id;
|
||||
}
|
||||
|
||||
if( \count( $calendarIDs ) )
|
||||
if( count( $calendarIDs ) )
|
||||
{
|
||||
$where[ 'container' ][] = [ \IPS\Db::i()->in( 'calendar_events.event_calendar_id', array_filter( $calendarIDs ) ) ];
|
||||
$where[ 'container' ][] = [ Db::i()->in( 'calendar_events.event_calendar_id', array_filter( $calendarIDs ) ) ];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,15 +123,15 @@ class _Events
|
||||
{
|
||||
$orderBy = 'saved';
|
||||
}
|
||||
else if( \in_array( $args[ 'orderBy' ], \IPS\calendar\api\GraphQL\Types\EventType::getOrderByOptions() ) )
|
||||
else if( in_array( $args[ 'orderBy' ], EventType::getOrderByOptions() ) )
|
||||
{
|
||||
$orderBy = $args[ 'orderBy' ];
|
||||
}
|
||||
|
||||
$sortBy = \IPS\calendar\Event::$databaseTable.'.'.\IPS\calendar\Event::$databasePrefix."{$orderBy} {$args['orderDir']}";
|
||||
$sortBy = Event::$databaseTable.'.'. Event::$databasePrefix."{$orderBy} {$args['orderDir']}";
|
||||
$offset = max( $args[ 'offset' ], 0 );
|
||||
$limit = min( $args[ 'limit' ], 50 );
|
||||
|
||||
return \IPS\calendar\Event::getItemsWithPermission( $where, $sortBy, [ $offset, $limit ], 'read' );
|
||||
return Event::getItemsWithPermission( $where, $sortBy, [ $offset, $limit ] );
|
||||
}
|
||||
}
|
||||
@@ -10,33 +10,36 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
use IPS\calendar\api\GraphQL\Queries\Calendar;
|
||||
use IPS\calendar\api\GraphQL\Queries\Calendars;
|
||||
use IPS\calendar\api\GraphQL\Queries\Event;
|
||||
use IPS\calendar\api\GraphQL\Queries\Events;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog 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 [
|
||||
'calendar' => new \IPS\calendar\api\GraphQL\Queries\Calendar(),
|
||||
'calendars' => new \IPS\calendar\api\GraphQL\Queries\Calendars(),
|
||||
'events' => new \IPS\calendar\api\GraphQL\Queries\Events(),
|
||||
'event' => new \IPS\calendar\api\GraphQL\Queries\Event(),
|
||||
'calendar' => new Calendar(),
|
||||
'calendars' => new Calendars(),
|
||||
'events' => new Events(),
|
||||
'event' => new Event(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -10,36 +10,38 @@
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
use IPS\calendar\api\GraphQL\Types\CalendarType;
|
||||
use IPS\calendar\api\GraphQL\Types\CommentType;
|
||||
use IPS\calendar\api\GraphQL\Types\EventType;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
class _TypeRegistry
|
||||
class TypeRegistry
|
||||
{
|
||||
/**
|
||||
* The calendar type instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
* @var CalendarType
|
||||
*/
|
||||
protected static $calendar;
|
||||
protected static CalendarType $calendar;
|
||||
|
||||
/**
|
||||
* The event type instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\EventType
|
||||
* @var EventType
|
||||
*/
|
||||
protected static $event;
|
||||
protected static EventType $event;
|
||||
|
||||
/**
|
||||
* The event comment instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
* @var CommentType
|
||||
*/
|
||||
protected static $comment;
|
||||
protected static CommentType $comment;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -52,21 +54,21 @@ class _TypeRegistry
|
||||
/**
|
||||
* @return CalendarType
|
||||
*/
|
||||
public static function calendar() : \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
public static function calendar() : CalendarType
|
||||
{
|
||||
return self::$calendar ?: (self::$calendar = new \IPS\calendar\api\GraphQL\Types\CalendarType());
|
||||
return self::$calendar ?? (self::$calendar = new CalendarType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventType
|
||||
*/
|
||||
public static function event() : \IPS\calendar\api\GraphQL\Types\EventType
|
||||
public static function event() : EventType
|
||||
{
|
||||
return self::$event ?: (self::$event = new \IPS\calendar\api\GraphQL\Types\EventType());
|
||||
return self::$event ?? (self::$event = new EventType());
|
||||
}
|
||||
|
||||
public static function comment() : \IPS\calendar\api\GraphQL\Types\CommentType
|
||||
public static function comment() : CommentType
|
||||
{
|
||||
return self::$comment ?: ( self::$comment = new \IPS\calendar\api\GraphQL\Types\CommentType() );
|
||||
return self::$comment ?? ( self::$comment = new CommentType() );
|
||||
}
|
||||
}
|
||||
@@ -11,39 +11,42 @@
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\Calendar;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* CalendarType for GraphQL API
|
||||
*/
|
||||
class _CalendarType extends \IPS\Node\Api\GraphQL\NodeType
|
||||
class CalendarType extends NodeType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $nodeClass = \IPS\calendar\Calendar::class;
|
||||
protected static string $nodeClass = Calendar::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Calendar';
|
||||
protected static string $typeName = 'calendar_Calendar';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A calendar';
|
||||
protected static string $typeDescription = 'A calendar';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array('app' => 'calendar', 'area' => 'calendar');
|
||||
protected static array $followData = array('app' => 'calendar', 'area' => 'calendar');
|
||||
|
||||
|
||||
/**
|
||||
@@ -51,9 +54,9 @@ class _CalendarType extends \IPS\Node\Api\GraphQL\NodeType
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
public static function getItemType()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
public static function getItemType(): ObjectType
|
||||
{
|
||||
return TypeRegistry::event();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,43 +11,46 @@
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\Event\Comment;
|
||||
use IPS\Content\Api\GraphQL\CommentType as ApiCommentType;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* PostType for GraphQL API
|
||||
*/
|
||||
class _CommentType extends \IPS\Content\Api\GraphQL\CommentType
|
||||
class CommentType extends ApiCommentType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $commentClass = \IPS\calendar\Event\Comment::class;
|
||||
protected static string $commentClass = Comment::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Comment';
|
||||
protected static string $typeName = 'calendar_Comment';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A calendar event comment';
|
||||
protected static string $typeDescription = 'A calendar event comment';
|
||||
|
||||
/**
|
||||
* Get the item type that goes with this item type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
public static function getItemType()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::comment();
|
||||
public static function getItemType(): ObjectType
|
||||
{
|
||||
return TypeRegistry::comment();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,12 +58,12 @@ class _CommentType extends \IPS\Content\Api\GraphQL\CommentType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
public function fields(): array
|
||||
{
|
||||
$defaultFields = parent::fields();
|
||||
$postFields = array(
|
||||
'event' => [
|
||||
'type' => \IPS\calendar\api\GraphQL\TypeRegistry::event(),
|
||||
'type' => TypeRegistry::event(),
|
||||
'resolve' => function ($comment) {
|
||||
return $comment->item();
|
||||
}
|
||||
|
||||
@@ -12,47 +12,49 @@
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\_TypeRegistry;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
use IPS\calendar\Event;
|
||||
use IPS\Content\Api\GraphQL\ItemType;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry for GraphQL API
|
||||
*/
|
||||
class _EventType extends \IPS\Content\Api\GraphQL\ItemType
|
||||
class EventType extends ItemType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $itemClass = \IPS\calendar\Event::class;
|
||||
protected static string $itemClass = Event::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Event';
|
||||
protected static string $typeName = 'calendar_Event';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A calendar event';
|
||||
protected static string $typeDescription = 'A calendar event';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array( 'app' => 'calendar', 'area' => 'event' );
|
||||
protected static array $followData = array( 'app' => 'calendar', 'area' => 'event' );
|
||||
|
||||
/**
|
||||
* Get the comment type that goes with this item type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
protected static function getCommentType()
|
||||
protected static function getCommentType(): ObjectType
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::comment();
|
||||
}
|
||||
@@ -62,7 +64,7 @@ class _EventType extends \IPS\Content\Api\GraphQL\ItemType
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
public function fields(): array
|
||||
{
|
||||
// Extend our fields with image-specific stuff
|
||||
$defaultFields = parent::fields();
|
||||
|
||||
@@ -12,21 +12,34 @@
|
||||
namespace IPS\calendar\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\calendar\Calendar;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Lang;
|
||||
use IPS\Node\Api\NodeController;
|
||||
use IPS\Node\Model;
|
||||
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 Calendars API
|
||||
*/
|
||||
class _calendars extends \IPS\Node\Api\NodeController
|
||||
class calendars extends NodeController
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = 'IPS\calendar\Calendar';
|
||||
protected string $class = 'IPS\calendar\Calendar';
|
||||
|
||||
/**
|
||||
* GET /calendar/calendars
|
||||
@@ -36,9 +49,10 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @note For requests using an OAuth Access Token for a particular member, only calendars the authorized user can view will be included
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\calendar\Calendar>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Calendar>
|
||||
* @return PaginatedResponse<Calendar>
|
||||
*/
|
||||
public function GETindex()
|
||||
public function GETindex(): PaginatedResponse
|
||||
{
|
||||
/* Return */
|
||||
return $this->_list();
|
||||
@@ -50,17 +64,18 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 1L364/1 INVALID_ID The calendar does not exist or the authorized user does not have permission to view it
|
||||
* @return \IPS\calendar\Calendar
|
||||
* @apireturn \IPS\calendar\Calendar
|
||||
* @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', '1L364/1', 404 );
|
||||
throw new Exception( 'INVALID_ID', '1L364/1', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,17 +92,18 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
* @apiparam int allow_reviews 0|1 Allow reviews
|
||||
* @apiparam int approve_reviews 0|1 Reviews must be approved
|
||||
* @apiparam object permissions An object with the keys as permission options (view, read, add, reply, review, askrsvp, rsvp) and values as permissions to use (which may be * to grant access to all groups, or an array of group IDs to permit access to)
|
||||
* @return \IPS\calendar\Calendar
|
||||
* @apireturn \IPS\calendar\Calendar
|
||||
* @throws 1L364/2 NO_TITLE A title for the calendar must be supplied
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTindex()
|
||||
public function POSTindex(): Response
|
||||
{
|
||||
if ( !\IPS\Request::i()->title )
|
||||
if ( !Request::i()->title )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_TITLE', '1L364/2', 400 );
|
||||
throw new Exception( 'NO_TITLE', '1L364/2', 400 );
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 201, $this->_create()->apiOutput( $this->member ) );
|
||||
return new Response( 201, $this->_create()->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,14 +120,16 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
* @apiparam int approve_reviews 0|1 Reviews must be approved
|
||||
* @apiparam object permissions An object with the keys as permission options (view, read, add, reply, review, askrsvp, rsvp) and values as permissions to use (which may be * to grant access to all groups, or an array of group IDs to permit access to)
|
||||
* @param int $id ID Number
|
||||
* @return \IPS\calendar\Calendar
|
||||
* @apireturn \IPS\calendar\Calendar
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
public function POSTitem( int $id ): Response
|
||||
{
|
||||
/* @var Calendar $class */
|
||||
$class = $this->class;
|
||||
$calendar = $class::load( $id );
|
||||
|
||||
return new \IPS\Api\Response( 200, $this->_createOrUpdate( $calendar )->apiOutput( $this->member ) );
|
||||
return new Response( 200, $this->_createOrUpdate( $calendar )->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -120,9 +138,10 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
*
|
||||
* @apiclientonly
|
||||
* @param int $id ID Number
|
||||
* @return void
|
||||
* @apireturn void
|
||||
* @return Response
|
||||
*/
|
||||
public function DELETEitem( $id )
|
||||
public function DELETEitem( int $id ): Response
|
||||
{
|
||||
return $this->_delete( $id );
|
||||
}
|
||||
@@ -130,27 +149,27 @@ class _calendars extends \IPS\Node\Api\NodeController
|
||||
/**
|
||||
* Create or update node
|
||||
*
|
||||
* @param \IPS\node\Model $calendar The node
|
||||
* @return \IPS\node\Model
|
||||
* @param Model $calendar The node
|
||||
* @return Model
|
||||
*/
|
||||
protected function _createOrUpdate( \IPS\Node\Model $calendar )
|
||||
protected function _createOrUpdate( Model $calendar ): Model
|
||||
{
|
||||
if ( \IPS\Request::i()->title )
|
||||
if ( Request::i()->title )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'calendar', 'calendar_calendar_' . $calendar->id, \IPS\Request::i()->title );
|
||||
$calendar->title_seo = \IPS\Http\Url\Friendly::seoTitle( \IPS\Request::i()->title );
|
||||
Lang::saveCustom( 'calendar', 'calendar_calendar_' . $calendar->id, Request::i()->title );
|
||||
$calendar->title_seo = Friendly::seoTitle( Request::i()->title );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->color ) )
|
||||
if ( isset( Request::i()->color ) )
|
||||
{
|
||||
$calendar->color = \IPS\Request::i()->color;
|
||||
$calendar->color = Request::i()->color;
|
||||
}
|
||||
|
||||
$calendar->moderate = (int) isset( \IPS\Request::i()->approve_events ) ? \IPS\Request::i()->approve_events : 0;
|
||||
$calendar->allow_comments = (int) isset( \IPS\Request::i()->allow_comments ) ? \IPS\Request::i()->allow_comments : 0;
|
||||
$calendar->comment_moderate = (int) isset( \IPS\Request::i()->approve_comments ) ? \IPS\Request::i()->approve_comments : 0;
|
||||
$calendar->allow_reviews = (int) isset( \IPS\Request::i()->allow_reviews ) ? \IPS\Request::i()->allow_reviews : 0;
|
||||
$calendar->review_moderate = (int) isset( \IPS\Request::i()->approve_reviews ) ? \IPS\Request::i()->approve_reviews : 0;
|
||||
$calendar->moderate = (int) isset( Request::i()->approve_events ) ? Request::i()->approve_events : 0;
|
||||
$calendar->allow_comments = (int) isset( Request::i()->allow_comments ) ? Request::i()->allow_comments : 0;
|
||||
$calendar->comment_moderate = (int) isset( Request::i()->approve_comments ) ? Request::i()->approve_comments : 0;
|
||||
$calendar->allow_reviews = (int) isset( Request::i()->allow_reviews ) ? Request::i()->allow_reviews : 0;
|
||||
$calendar->review_moderate = (int) isset( Request::i()->approve_reviews ) ? Request::i()->approve_reviews : 0;
|
||||
|
||||
return parent::_createOrUpdate( $calendar );
|
||||
}
|
||||
|
||||
@@ -12,21 +12,34 @@
|
||||
namespace IPS\calendar\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\calendar\Event;
|
||||
use IPS\calendar\Event\Comment;
|
||||
use IPS\Content\Api\CommentController;
|
||||
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 Calendar Events Comments API
|
||||
*/
|
||||
class _comments extends \IPS\Content\Api\CommentController
|
||||
class comments extends CommentController
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = 'IPS\calendar\Event\Comment';
|
||||
protected string $class = 'IPS\calendar\Event\Comment';
|
||||
|
||||
/**
|
||||
* GET /calendar/comments
|
||||
@@ -42,9 +55,10 @@ 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\calendar\Event\Comment>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Event\Comment>
|
||||
* @return PaginatedResponse<Comment>
|
||||
*/
|
||||
public function GETindex()
|
||||
public function GETindex(): PaginatedResponse
|
||||
{
|
||||
return $this->_list( array(), 'calendars' );
|
||||
}
|
||||
@@ -55,12 +69,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\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\Comment
|
||||
* @return Response
|
||||
*/
|
||||
public function GETitem( $id )
|
||||
public function GETitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
/* @var Comment $class */
|
||||
$class = $this->class;
|
||||
if ( $this->member )
|
||||
{
|
||||
@@ -71,11 +87,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', '2L297/1', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L297/1', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,18 +112,19 @@ class _comments extends \IPS\Content\Api\CommentController
|
||||
* @throws 1L297/4 NO_AUTHOR The author ID does not exist
|
||||
* @throws 1L297/5 NO_CONTENT No content was supplied
|
||||
* @throws 2L297/8 NO_PERMISSION The authorized user does not have permission to comment on that event
|
||||
* @return \IPS\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\Comment
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTindex()
|
||||
public function POSTindex(): Response
|
||||
{
|
||||
/* Get event */
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( \IPS\Request::i()->event );
|
||||
$event = Event::load( Request::i()->event );
|
||||
}
|
||||
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 */
|
||||
@@ -115,38 +132,38 @@ class _comments extends \IPS\Content\Api\CommentController
|
||||
{
|
||||
if ( !$event->canComment( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2L297/8', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L297/8', 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', '1L297/4', 404 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L297/4', 404 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (int) \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', '1L297/4', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L297/4', 400 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check we have a post */
|
||||
if ( !\IPS\Request::i()->content )
|
||||
if ( !Request::i()->content )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_CONTENT', '1L297/5', 403 );
|
||||
throw new Exception( 'NO_CONTENT', '1L297/5', 403 );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
@@ -167,21 +184,22 @@ class _comments extends \IPS\Content\Api\CommentController
|
||||
* @throws 2L297/6 INVALID_ID The comment ID does not exist or the authorized user does not have permission to view it
|
||||
* @throws 1L297/7 NO_AUTHOR The author ID does not exist
|
||||
* @throws 2L297/9 NO_PERMISSION The authorized user does not have permission to edit the comment
|
||||
* @return \IPS\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\Comment
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
public function POSTitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Load */
|
||||
$comment = \IPS\calendar\Event\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', '2L297/9', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L297/9', 403 );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
@@ -189,14 +207,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', '1L297/7', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L297/7', 400 );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L297/6', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L297/6', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,25 +225,27 @@ class _comments extends \IPS\Content\Api\CommentController
|
||||
* @param int $id ID Number
|
||||
* @throws 2L297/2 INVALID_ID The comment ID does not exist
|
||||
* @throws 2L297/A 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', '2L297/A', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L297/A', 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', '2L297/2', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L297/2', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -236,14 +256,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\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\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 );
|
||||
}
|
||||
@@ -254,13 +275,14 @@ class _comments extends \IPS\Content\Api\CommentController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @apiparam int author ID of the member who reacted
|
||||
* @return \IPS\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\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 );
|
||||
}
|
||||
@@ -275,9 +297,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\calendar\Event\Comment
|
||||
* @apireturn \IPS\calendar\Event\Comment
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem_report( $id )
|
||||
public function POSTitem_report( int $id ): Response
|
||||
{
|
||||
return $this->_report( $id );
|
||||
}
|
||||
|
||||
@@ -12,21 +12,46 @@
|
||||
namespace IPS\calendar\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\Api\Webhook;
|
||||
use IPS\calendar\Calendar;
|
||||
use IPS\calendar\Date;
|
||||
use IPS\calendar\Event;
|
||||
use IPS\calendar\Event\Comment;
|
||||
use IPS\calendar\Event\Review;
|
||||
use IPS\Content\Api\ItemController;
|
||||
use IPS\Content\Item;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\IPS;
|
||||
use IPS\Member;
|
||||
use IPS\Request;
|
||||
use IPS\Text\Parser;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
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 Calendar Events API
|
||||
*/
|
||||
class _events extends \IPS\Content\Api\ItemController
|
||||
class events extends ItemController
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = 'IPS\calendar\Event';
|
||||
protected string $class = 'IPS\calendar\Event';
|
||||
|
||||
/**
|
||||
* GET /calendar/events
|
||||
@@ -45,50 +70,51 @@ class _events 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\calendar\Event>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Event>
|
||||
* @throws 1L296/M INVALID_DATE The rangeStart and/or rangeEnd value was not a valid date in YYYY-MM-DD format
|
||||
* @return PaginatedResponse<Event>
|
||||
*/
|
||||
public function GETindex()
|
||||
public function GETindex(): PaginatedResponse
|
||||
{
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
|
||||
/* Are we limiting to a date range? */
|
||||
if( isset( \IPS\Request::i()->rangeStart ) OR isset( \IPS\Request::i()->rangeEnd ) )
|
||||
if( isset( Request::i()->rangeStart ) OR isset( Request::i()->rangeEnd ) )
|
||||
{
|
||||
$startDate = $endDate = NULL;
|
||||
|
||||
foreach( array( 'start', 'end' ) as $limiter )
|
||||
{
|
||||
$inputKey = 'range' . mb_ucfirst( $limiter );
|
||||
$inputKey = 'range' . IPS::mb_ucfirst( $limiter );
|
||||
|
||||
if( \IPS\Request::i()->$inputKey )
|
||||
if( Request::i()->$inputKey )
|
||||
{
|
||||
$datePieces = explode( '-', \IPS\Request::i()->$inputKey );
|
||||
$datePieces = explode( '-', Request::i()->$inputKey );
|
||||
|
||||
/* Let's make sure the date is valid... */
|
||||
if( @checkdate( $datePieces[1], $datePieces[2], $datePieces[0] ) )
|
||||
{
|
||||
if( $limiter === 'start' )
|
||||
{
|
||||
$startDate = \IPS\calendar\Date::getDate( $datePieces[0], $datePieces[1], $datePieces[2] );
|
||||
$startDate = Date::getDate( $datePieces[0], $datePieces[1], $datePieces[2] );
|
||||
}
|
||||
else
|
||||
{
|
||||
$endDate = \IPS\calendar\Date::getDate( $datePieces[0], $datePieces[1], $datePieces[2], 23, 59, 59 );
|
||||
$endDate = Date::getDate( $datePieces[0], $datePieces[1], $datePieces[2], 23, 59, 59 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_DATE', '1L296/M', 403 );
|
||||
throw new Exception( 'INVALID_DATE', '1L296/M', 403 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the events within this range */
|
||||
$events = \IPS\calendar\Event::retrieveEvents( $startDate, $endDate, NULL, NULL, FALSE, new \IPS\Member, NULL, TRUE );
|
||||
$events = Event::retrieveEvents( $startDate, $endDate, NULL, NULL, FALSE, new Member, NULL, TRUE );
|
||||
|
||||
if( !\count( $events ) )
|
||||
if( !count( $events ) )
|
||||
{
|
||||
/* Force no results */
|
||||
$where[] = array( '0=1' );
|
||||
@@ -102,9 +128,9 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
/* Sort by */
|
||||
$sortBy = NULL;
|
||||
|
||||
if ( isset( \IPS\Request::i()->sortBy ) and \in_array( \IPS\Request::i()->sortBy, array( 'start', 'end' ) ) )
|
||||
if ( isset( Request::i()->sortBy ) and in_array( Request::i()->sortBy, array( 'start', 'end' ) ) )
|
||||
{
|
||||
$sortBy = 'event_' . \IPS\Request::i()->sortBy . '_date';
|
||||
$sortBy = 'event_' . Request::i()->sortBy . '_date';
|
||||
}
|
||||
|
||||
/* Return */
|
||||
@@ -117,17 +143,18 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 1F294/1 INVALID_ID The event ID does not exist or the authorized user does not have permission to view it
|
||||
* @return \IPS\calendar\Event
|
||||
* @apireturn \IPS\calendar\Event
|
||||
* @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', '2L296/1', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L296/1', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,18 +188,19 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @throws 1L296/A INVALID_START The start date is invalid
|
||||
* @throws 1L296/B INVALID_END The end date is invalid
|
||||
* @throws 2L296/C NO_PERMISSION The authorized user does not have permission to create an event in that calendar
|
||||
* @return \IPS\calendar\Event
|
||||
* @apireturn \IPS\calendar\Event
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTindex()
|
||||
public function POSTindex(): Response
|
||||
{
|
||||
/* Get calendar */
|
||||
try
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::load( \IPS\Request::i()->calendar );
|
||||
$calendar = Calendar::load( Request::i()->calendar );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_CALENDAR', '1L296/6', 400 );
|
||||
throw new Exception( 'NO_CALENDAR', '1L296/6', 400 );
|
||||
}
|
||||
|
||||
/* Get author */
|
||||
@@ -180,66 +208,66 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
{
|
||||
if ( !$calendar->can( 'add', $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2L296/C', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L296/C', 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', '1L296/7', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L296/7', 400 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (int) \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', '1L296/7', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L296/7', 400 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check we have a title and a description */
|
||||
if ( !\IPS\Request::i()->title )
|
||||
if ( !Request::i()->title )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_TITLE', '1L296/8', 400 );
|
||||
throw new Exception( 'NO_TITLE', '1L296/8', 400 );
|
||||
}
|
||||
if ( !\IPS\Request::i()->description )
|
||||
if ( !Request::i()->description )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_DESC', '1L296/9', 400 );
|
||||
throw new Exception( 'NO_DESC', '1L296/9', 400 );
|
||||
}
|
||||
|
||||
/* Validate dates */
|
||||
try
|
||||
{
|
||||
new \IPS\DateTime( \IPS\Request::i()->start );
|
||||
new DateTime( Request::i()->start );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_START', '1L296/A', 400 );
|
||||
throw new Exception( 'INVALID_START', '1L296/A', 400 );
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->end ) )
|
||||
if ( isset( Request::i()->end ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
new \IPS\DateTime( \IPS\Request::i()->end );
|
||||
new DateTime( Request::i()->end );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_END', '1L296/B', 400 );
|
||||
throw new Exception( 'INVALID_END', '1L296/B', 400 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
return new \IPS\Api\Response( 201, $this->_create( $calendar, $author )->apiOutput( $this->member ) );
|
||||
return new Response( 201, $this->_create( $calendar, $author )->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -264,87 +292,89 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @apiparam int hidden 0 = unhidden; 1 = hidden, pending moderator approval; -1 = hidden (as if hidden by a moderator)
|
||||
* @apiparam int featured 1/0 indicating if the event should be featured
|
||||
* @apiparam bool anonymous If 1, the item will be posted anonymously.
|
||||
* @param int $id
|
||||
* @throws 1L296/I INVALID_ID The event ID is invalid or the authorized user does not have permission to view it
|
||||
* @throws 1L296/D NO_CALENDAR The calendar ID does not exist or the authorized user does not have permission to post in it
|
||||
* @throws 1L296/E NO_AUTHOR The author ID does not exist
|
||||
* @throws 1L296/G INVALID_START The start date is invalid
|
||||
* @throws 1L296/H INVALID_END The end date is invalid
|
||||
* @throws 2L296/D NO_PERMISSION The authorized user does not have permission to edit the topic
|
||||
* @return \IPS\calendar\Event
|
||||
* @apireturn \IPS\calendar\Event
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
public function POSTitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( $id );
|
||||
$event = Event::load( $id );
|
||||
if ( $this->member and !$event->can( 'read', $this->member ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
if ( $this->member and !$event->canEdit( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2L296/D', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L296/D', 403 );
|
||||
}
|
||||
|
||||
/* New calendar */
|
||||
if ( isset( \IPS\Request::i()->calendar ) and \IPS\Request::i()->calendar != $event->calendar_id and ( !$this->member or $event->canMove( $this->member ) ) )
|
||||
if ( isset( Request::i()->calendar ) and Request::i()->calendar != $event->calendar_id and ( !$this->member or $event->canMove( $this->member ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$newCalendar = \IPS\calendar\Calendar::load( \IPS\Request::i()->calendar );
|
||||
$newCalendar = Calendar::load( Request::i()->calendar );
|
||||
if ( $this->member and !$newCalendar->can( 'add', $this->member ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$event->move( $newCalendar );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_CALENDAR', '1L296/D', 400 );
|
||||
throw new Exception( 'NO_CALENDAR', '1L296/D', 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;
|
||||
}
|
||||
|
||||
$event->changeAuthor( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1L296/E', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L296/E', 400 );
|
||||
}
|
||||
}
|
||||
|
||||
/* Validate dates */
|
||||
if ( isset( \IPS\Request::i()->start ) )
|
||||
if ( isset( Request::i()->start ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
new \IPS\DateTime( \IPS\Request::i()->start );
|
||||
new DateTime( Request::i()->start );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_START', '1L296/G', 400 );
|
||||
throw new Exception( 'INVALID_START', '1L296/G', 400 );
|
||||
}
|
||||
}
|
||||
if ( isset( \IPS\Request::i()->end ) )
|
||||
if ( isset( Request::i()->end ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
new \IPS\DateTime( \IPS\Request::i()->end );
|
||||
new DateTime( Request::i()->end );
|
||||
}
|
||||
catch ( \Exception $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_END', '1L296/H', 400 );
|
||||
throw new Exception( 'INVALID_END', '1L296/H', 400 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -353,11 +383,11 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
|
||||
/* Save and return */
|
||||
$event->save();
|
||||
return new \IPS\Api\Response( 200, $event->apiOutput( $this->member ) );
|
||||
return new Response( 200, $event->apiOutput( $this->member ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '1L296/D', 404 );
|
||||
throw new Exception( 'INVALID_ID', '1L296/D', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -371,17 +401,18 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @throws 2L296/2 INVALID_ID The event ID does not exist or the authorized user does not have permission to view it
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\calendar\Event\Comment>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Event\Comment>
|
||||
* @return PaginatedResponse<Comment>
|
||||
*/
|
||||
public function GETitem_comments( $id )
|
||||
public function GETitem_comments( int $id ): PaginatedResponse
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->_comments( $id, 'IPS\calendar\Event\Comment' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L296/2', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L296/2', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,17 +426,18 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @throws 2L296/3 INVALID_ID The event ID does not exist or the authorized user does not have permission to view it
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\calendar\Event\Review>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Event\Review>
|
||||
* @return PaginatedResponse<Review>
|
||||
*/
|
||||
public function GETitem_reviews( $id )
|
||||
public function GETitem_reviews( int $id ): PaginatedResponse
|
||||
{
|
||||
try
|
||||
{
|
||||
return $this->_comments( $id, 'IPS\calendar\Event\Review' );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L296/3', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L296/3', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -415,23 +447,24 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 2L296/3 INVALID_ID The event ID does not exist or the authorized user does not have permission to view it
|
||||
* @return array
|
||||
* @apireturn array
|
||||
* @apiresponse [\IPS\Member] attending Members that have confirmed they are attending the event
|
||||
* @apiresponse [\IPS\Member] notAttending Members that have confirmed they are not attending the event
|
||||
* @apiresponse [\IPS\Member] maybeAttending Members that have said they may attend the event
|
||||
* @return Response
|
||||
*/
|
||||
public function GETitem_rsvps( $id )
|
||||
public function GETitem_rsvps( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( $id );
|
||||
$event = Event::load( $id );
|
||||
if ( $this->member and !$event->can( 'read', $this->member ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$attendees = $event->attendees();
|
||||
return new \IPS\Api\Response( 200, array(
|
||||
return new Response( 200, array(
|
||||
'attending' => array_values( array_map( function( $member ) {
|
||||
return $member->apiOutput( $this->member );
|
||||
}, $attendees[1] ) ),
|
||||
@@ -443,9 +476,9 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
}, $attendees[2] ) ),
|
||||
) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L296/4', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L296/4', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -459,53 +492,63 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @param int $memberId Member ID NUmber
|
||||
* @throws 2L296/J INVALID_ID The event ID does not exist
|
||||
* @throws 2L296/K INVALID_MEMBER The member ID was not valid
|
||||
* @return void
|
||||
* @apireturn void
|
||||
* @return Response
|
||||
*/
|
||||
public function PUTitem_rsvps( $id, $memberId )
|
||||
public function PUTitem_rsvps( int $id, int $memberId ): Response
|
||||
{
|
||||
if ( !isset( \IPS\Request::i()->response ) or !\in_array( (int) \IPS\Request::i()->response, range( 0, 2 ) ) )
|
||||
if ( !isset( Request::i()->response ) or !in_array( (int) Request::i()->response, range( 0, 2 ) ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_RESPONSE', '1L296/L', 400 );
|
||||
throw new Exception( 'INVALID_RESPONSE', '1L296/L', 400 );
|
||||
}
|
||||
|
||||
if ( $this->member and $memberId != $this->member->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
throw new Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( $id );
|
||||
$event = Event::load( $id );
|
||||
|
||||
try
|
||||
{
|
||||
$member = \IPS\Member::load( $memberId );
|
||||
$member = Member::load( $memberId );
|
||||
if ( !$member->member_id )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
throw new Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_event_id=? AND rsvp_member_id=?', $event->id, $member->member_id ) );
|
||||
Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_event_id=? AND rsvp_member_id=?', $event->id, $member->member_id ) );
|
||||
|
||||
\IPS\Db::i()->insert( 'calendar_event_rsvp', array(
|
||||
Db::i()->insert( 'calendar_event_rsvp', array(
|
||||
'rsvp_event_id' => $event->id,
|
||||
'rsvp_member_id' => $member->member_id,
|
||||
'rsvp_date' => time(),
|
||||
'rsvp_response' => (int) \IPS\Request::i()->response
|
||||
'rsvp_response' => (int) Request::i()->response
|
||||
) );
|
||||
|
||||
$webhookData = [
|
||||
'event' => $event->apiOutput(),
|
||||
'action' => (int) Request::i()->response,
|
||||
'attendee' => $member->apiOutput(),
|
||||
];
|
||||
|
||||
|
||||
Webhook::fire( 'calendarEvent_rsvp', $webhookData );
|
||||
|
||||
$member->achievementAction( 'calendar', 'Rsvp', $event );
|
||||
|
||||
return new \IPS\Api\Response( 200, NULL );
|
||||
return new Response( 200, NULL );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_EVENT', '2L296/J', 404 );
|
||||
throw new Exception( 'INVALID_EVENT', '2L296/J', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -516,36 +559,37 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* @note For requests using an OAuth Access Token for a particular member, the member ID must be the authorized member's ID
|
||||
* @param int $id Event ID NUmber
|
||||
* @param int $memberId Member ID NUmber
|
||||
* @return void
|
||||
* @apireturn void
|
||||
* @throws 2L296/K INVALID_MEMBER The member ID was not valid
|
||||
* @return Response
|
||||
*/
|
||||
public function DELETEitem_rsvps( $id, $memberId )
|
||||
public function DELETEitem_rsvps( int $id, int $memberId ): Response
|
||||
{
|
||||
if ( $this->member and $memberId != $this->member->member_id )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
throw new Exception( 'INVALID_MEMBER', '2L296/K', 404 );
|
||||
}
|
||||
|
||||
\IPS\Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_event_id=? AND rsvp_member_id=?', \intval( $id ), \intval( $memberId ) ) );
|
||||
return new \IPS\Api\Response( 200, NULL );
|
||||
Db::i()->delete( 'calendar_event_rsvp', array( 'rsvp_event_id=? AND rsvp_member_id=?', $id, $memberId ) );
|
||||
return new Response( 200, NULL );
|
||||
}
|
||||
|
||||
/**
|
||||
* Create or update event
|
||||
*
|
||||
* @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
|
||||
{
|
||||
/* Start/End date */
|
||||
$startDate = new \IPS\DateTime( \IPS\Request::i()->start );
|
||||
$startDate = new DateTime( Request::i()->start );
|
||||
$item->start_date = $startDate->format( 'Y-m-d H:i' );
|
||||
$item->end_date = NULL;
|
||||
if ( isset( \IPS\Request::i()->end ) )
|
||||
if ( isset( Request::i()->end ) )
|
||||
{
|
||||
$endDate = new \IPS\DateTime( \IPS\Request::i()->end );
|
||||
$endDate = new DateTime( Request::i()->end );
|
||||
$item->end_date = $endDate->format( 'Y-m-d H:i' );
|
||||
}
|
||||
else
|
||||
@@ -554,26 +598,26 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
}
|
||||
|
||||
/* Recurrence */
|
||||
if ( isset( \IPS\Request::i()->recurrence ) )
|
||||
if ( isset( Request::i()->recurrence ) )
|
||||
{
|
||||
$item->recurring = \IPS\Request::i()->recurrence;
|
||||
$item->recurring = Request::i()->recurrence;
|
||||
}
|
||||
|
||||
/* Description */
|
||||
$descriptionContents = \IPS\Request::i()->description;
|
||||
$descriptionContents = Request::i()->description;
|
||||
if ( $this->member )
|
||||
{
|
||||
$descriptionContents = \IPS\Text\Parser::parseStatic( $descriptionContents, TRUE, NULL, $this->member, 'calendar_Calendar' );
|
||||
$descriptionContents = Parser::parseStatic( $descriptionContents, NULL, $this->member, 'calendar_Calendar' );
|
||||
}
|
||||
$item->content = $descriptionContents;
|
||||
|
||||
/* RSVP */
|
||||
if ( isset( \IPS\Request::i()->rsvp ) and ( !$this->member or $item->container()->can( 'askrsvp', $this->member ) ) )
|
||||
if ( isset( Request::i()->rsvp ) and ( !$this->member or $item->container()->can( 'askrsvp', $this->member ) ) )
|
||||
{
|
||||
$item->rsvp = \intval( \IPS\Request::i()->rsvp );
|
||||
if ( $item->rsvp and isset( \IPS\Request::i()->rsvpLimit ) and \IPS\Request::i()->rsvpLimit )
|
||||
$item->rsvp = intval( Request::i()->rsvp );
|
||||
if ( $item->rsvp and isset( Request::i()->rsvpLimit ) and Request::i()->rsvpLimit )
|
||||
{
|
||||
$item->rsvp_limit = \IPS\Request::i()->rsvpLimit;
|
||||
$item->rsvp_limit = Request::i()->rsvpLimit;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -582,11 +626,11 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
}
|
||||
|
||||
/* Location */
|
||||
if ( isset( \IPS\Request::i()->location ) )
|
||||
if ( isset( Request::i()->location ) )
|
||||
{
|
||||
if ( \IPS\Request::i()->location )
|
||||
if ( Request::i()->location )
|
||||
{
|
||||
$location = \IPS\GeoLocation::buildFromJson( json_encode( \IPS\Request::i()->location ) );
|
||||
$location = GeoLocation::buildFromJson( json_encode( Request::i()->location ) );
|
||||
if ( !$location->lat or !$location->long )
|
||||
{
|
||||
try
|
||||
@@ -609,25 +653,26 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 2L296/5 INVALID_ID The event ID does not exist
|
||||
* @return void
|
||||
* @apireturn void
|
||||
* @return Response
|
||||
*/
|
||||
public function DELETEitem( $id )
|
||||
public function DELETEitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
$item = \IPS\calendar\Event::load( $id );
|
||||
$item = Event::load( $id );
|
||||
if ( $this->member and !$item->canDelete( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2F294/B', 404 );
|
||||
throw new Exception( 'NO_PERMISSION', '2F294/B', 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', '2L296/5', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L296/5', 404 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,21 +12,36 @@
|
||||
namespace IPS\calendar\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\calendar\Event;
|
||||
use IPS\calendar\Event\Review;
|
||||
use IPS\Content\Api\CommentController;
|
||||
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 Calendar Events Reviews API
|
||||
*/
|
||||
class _reviews extends \IPS\Content\Api\CommentController
|
||||
class reviews extends CommentController
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = 'IPS\calendar\Event\Review';
|
||||
protected string $class = 'IPS\calendar\Event\Review';
|
||||
|
||||
/**
|
||||
* GET /calendar/reviews
|
||||
@@ -42,9 +57,10 @@ 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\calendar\Event\Review>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Event\Review>
|
||||
* @return PaginatedResponse<Review>
|
||||
*/
|
||||
public function GETindex()
|
||||
public function GETindex(): PaginatedResponse
|
||||
{
|
||||
return $this->_list( array(), 'calendars' );
|
||||
}
|
||||
@@ -55,12 +71,14 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 2L298/1 INVALID_ID The review ID does not exist or the authorized user does not have permission to view it
|
||||
* @return \IPS\calendar\Event\Review
|
||||
* @apireturn \IPS\calendar\Event\Review
|
||||
* @return Response
|
||||
*/
|
||||
public function GETitem( $id )
|
||||
public function GETitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
/* @var Review $class */
|
||||
$class = $this->class;
|
||||
if ( $this->member )
|
||||
{
|
||||
@@ -71,11 +89,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', '2L298/1', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L298/1', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -98,18 +116,19 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
* @throws 1L298/4 NO_CONTENT No content was supplied
|
||||
* @throws 1L298/8 INVALID_RATING The rating is not a valid number up to the maximum rating
|
||||
* @throws 2L298/A NO_PERMISSION The authorized user does not have permission to review that event
|
||||
* @return \IPS\calendar\Event\Review
|
||||
* @apireturn \IPS\calendar\Event\Review
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTindex()
|
||||
public function POSTindex(): Response
|
||||
{
|
||||
/* Get event */
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::load( \IPS\Request::i()->event );
|
||||
$event = Event::load( Request::i()->event );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L298/2', 403 );
|
||||
throw new Exception( 'INVALID_ID', '2L298/2', 403 );
|
||||
}
|
||||
|
||||
/* Get author */
|
||||
@@ -117,44 +136,44 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
{
|
||||
if ( !$event->canReview( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2L298/A', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L298/A', 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', '1L298/3', 404 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L298/3', 404 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( (int) \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', '1L298/3', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L298/3', 400 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Check we have a post */
|
||||
if ( !\IPS\Request::i()->content )
|
||||
if ( !Request::i()->content )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_CONTENT', '1L298/4', 403 );
|
||||
throw new Exception( 'NO_CONTENT', '1L298/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', '1L298/8', 403 );
|
||||
throw new Exception( 'INVALID_RATING', '1L298/8', 403 );
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
@@ -177,41 +196,42 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
* @throws 1L298/6 NO_AUTHOR The author ID does not exist
|
||||
* @throws 1L298/9 INVALID_RATING The rating is not a valid number up to the maximum rating
|
||||
* @throws 2L298/B NO_PERMISSION The authorized user does not have permission to edit the review
|
||||
* @return \IPS\calendar\Event\Review
|
||||
* @apireturn \IPS\calendar\Event\Review
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
public function POSTitem( int $id ): Response
|
||||
{
|
||||
try
|
||||
{
|
||||
/* Load */
|
||||
$comment = \IPS\calendar\Event\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', '2L298/B', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L298/B', 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', '1L298/9', 403 );
|
||||
throw new Exception( 'INVALID_RATING', '1L298/9', 403 );
|
||||
}
|
||||
/* Do it */
|
||||
try
|
||||
{
|
||||
return $this->_edit( $comment );
|
||||
}
|
||||
catch ( \InvalidArgumentException $e )
|
||||
catch ( InvalidArgumentException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_AUTHOR', '1L298/6', 400 );
|
||||
throw new Exception( 'NO_AUTHOR', '1L298/6', 400 );
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2L298/5', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L298/5', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,25 +242,27 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
* @param int $id ID Number
|
||||
* @throws 2L298/7 INVALID_ID The review ID does not exist
|
||||
* @throws 2L298/C 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 Review $class */
|
||||
$class = $this->class;
|
||||
$object = $class::load( $id );
|
||||
if ( $this->member and !$object->canDelete( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2L298/C', 403 );
|
||||
throw new Exception( 'NO_PERMISSION', '2L298/C', 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', '2L298/7', 404 );
|
||||
throw new Exception( 'INVALID_ID', '2L298/7', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -251,14 +273,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\calendar\Event\Review
|
||||
* @apireturn \IPS\calendar\Event\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 );
|
||||
}
|
||||
@@ -269,13 +292,14 @@ class _reviews extends \IPS\Content\Api\CommentController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @apiparam int author ID of the member who reacted
|
||||
* @return \IPS\calendar\Event\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 );
|
||||
}
|
||||
@@ -289,9 +313,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\calendar\Event\Review
|
||||
* @apireturn \IPS\calendar\Event\Review
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem_report( $id )
|
||||
public function POSTitem_report( int $id ): Response
|
||||
{
|
||||
return $this->_report( $id );
|
||||
}
|
||||
|
||||
@@ -12,21 +12,38 @@
|
||||
namespace IPS\calendar\api;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use BadMethodCallException;
|
||||
use IPS\Api\Exception;
|
||||
use IPS\Api\PaginatedResponse;
|
||||
use IPS\Api\Response;
|
||||
use IPS\calendar\Venue;
|
||||
use IPS\GeoLocation;
|
||||
use IPS\Http\Url\Friendly;
|
||||
use IPS\Lang;
|
||||
use IPS\Node\Api\NodeController;
|
||||
use IPS\Node\Model;
|
||||
use IPS\Request;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use function in_array;
|
||||
use function is_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 Calendar Venues API
|
||||
*/
|
||||
class _venues extends \IPS\Node\Api\NodeController
|
||||
class venues extends NodeController
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = 'IPS\calendar\Venue';
|
||||
protected string $class = 'IPS\calendar\Venue';
|
||||
|
||||
/**
|
||||
* GET /calendar/venues
|
||||
@@ -34,9 +51,10 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
*
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
* @return \IPS\Api\PaginatedResponse<IPS\calendar\Venue>
|
||||
* @apireturn PaginatedResponse<IPS\calendar\Venue>
|
||||
* @return PaginatedResponse<Venue>
|
||||
*/
|
||||
public function GETindex()
|
||||
public function GETindex(): PaginatedResponse
|
||||
{
|
||||
/* Return */
|
||||
return $this->_list();
|
||||
@@ -48,17 +66,18 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
*
|
||||
* @param int $id ID Number
|
||||
* @throws 1L384/1 INVALID_ID The venue does not exist
|
||||
* @return \IPS\calendar\Venue
|
||||
* @apireturn \IPS\calendar\Venue
|
||||
* @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', '1L384/1', 404 );
|
||||
throw new Exception( 'INVALID_ID', '1L384/1', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,16 +89,17 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
* @reqapiparam string title The venue title
|
||||
* @reqapiparam \IPS\GeoLocation address The venue address (latitude and longitude do not need to be supplied and will be ignored)
|
||||
* @apiparam string description The venue description
|
||||
* @return \IPS\calendar\Venue
|
||||
* @apireturn \IPS\calendar\Venue
|
||||
* @throws 1L384/2 NO_ADDRESS An address is required for the venue but was not supplied
|
||||
* @throws 1L384/3 INVALID_ADDRESS An invalid address was supplied
|
||||
* @throws 1L384/4 NO_TITLE No title was supplied for the venue
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTindex()
|
||||
public function POSTindex(): Response
|
||||
{
|
||||
if( !\IPS\Request::i()->address OR !\is_array( \IPS\Request::i()->address ) )
|
||||
if( !Request::i()->address OR !is_array( Request::i()->address ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_ADDRESS', '1L384/2', 400 );
|
||||
throw new Exception( 'NO_ADDRESS', '1L384/2', 400 );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -87,12 +107,12 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
$this->_getGeoLocationObject();
|
||||
}
|
||||
|
||||
if ( !\IPS\Request::i()->title )
|
||||
if ( !Request::i()->title )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_TITLE', '1L384/4', 400 );
|
||||
throw new Exception( 'NO_TITLE', '1L384/4', 400 );
|
||||
}
|
||||
|
||||
return new \IPS\Api\Response( 201, $this->_create()->apiOutput( $this->member ) );
|
||||
return new Response( 201, $this->_create()->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -104,17 +124,19 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
* @reqapiparam \IPS\GeoLocation address The venue address (latitude and longitude do not need to be supplied and will be ignored)
|
||||
* @apiparam string description The venue description
|
||||
* @param int $id ID Number
|
||||
* @return \IPS\calendar\Venue
|
||||
* @apireturn \IPS\calendar\Venue
|
||||
* @throws 1L384/2 NO_ADDRESS An address is required for the venue but was not supplied
|
||||
* @throws 1L384/3 INVALID_ADDRESS An invalid address was supplied
|
||||
* @throws 1L384/4 NO_TITLE No title was supplied for the venue
|
||||
* @return Response
|
||||
*/
|
||||
public function POSTitem( $id )
|
||||
public function POSTitem( int $id ): Response
|
||||
{
|
||||
/* @var Venue $class */
|
||||
$class = $this->class;
|
||||
$venue = $class::load( $id );
|
||||
|
||||
return new \IPS\Api\Response( 200, $this->_createOrUpdate( $venue )->apiOutput( $this->member ) );
|
||||
return new Response( 200, $this->_createOrUpdate( $venue )->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -123,9 +145,10 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
*
|
||||
* @apiclientonly
|
||||
* @param int $id ID Number
|
||||
* @return void
|
||||
* @apireturn void
|
||||
* @return Response
|
||||
*/
|
||||
public function DELETEitem( $id )
|
||||
public function DELETEitem( int $id ): Response
|
||||
{
|
||||
return $this->_delete( $id );
|
||||
}
|
||||
@@ -133,27 +156,27 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
/**
|
||||
* Create or update node
|
||||
*
|
||||
* @param \IPS\node\Model $venue The node
|
||||
* @return \IPS\node\Model
|
||||
* @param Model $venue The node
|
||||
* @return Model
|
||||
*/
|
||||
protected function _createOrUpdate( \IPS\Node\Model $venue )
|
||||
protected function _createOrUpdate( Model $venue ): Model
|
||||
{
|
||||
if( \IPS\Request::i()->address AND \is_array( \IPS\Request::i()->address ) )
|
||||
if( Request::i()->address AND is_array( Request::i()->address ) )
|
||||
{
|
||||
$geoLocation = $this->_getGeoLocationObject();
|
||||
|
||||
$venue->address = json_encode( $geoLocation );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->title ) )
|
||||
if ( isset( Request::i()->title ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'calendar', 'calendar_venue_' . $venue->id, \IPS\Request::i()->title );
|
||||
$venue->title_seo = \IPS\Http\Url\Friendly::seoTitle( \IPS\Request::i()->title );
|
||||
Lang::saveCustom( 'calendar', 'calendar_venue_' . $venue->id, Request::i()->title );
|
||||
$venue->title_seo = Friendly::seoTitle( Request::i()->title );
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->description ) )
|
||||
if( isset( Request::i()->description ) )
|
||||
{
|
||||
\IPS\Lang::saveCustom( 'calendar', 'calendar_venue_' . $venue->id .'_desc', \IPS\Request::i()->description );
|
||||
Lang::saveCustom( 'calendar', 'calendar_venue_' . $venue->id .'_desc', Request::i()->description );
|
||||
}
|
||||
|
||||
return parent::_createOrUpdate( $venue );
|
||||
@@ -162,16 +185,16 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
/**
|
||||
* Get geolocation object
|
||||
*
|
||||
* @return array
|
||||
* @return GeoLocation
|
||||
*/
|
||||
protected function _getGeoLocationObject()
|
||||
protected function _getGeoLocationObject(): GeoLocation
|
||||
{
|
||||
$geoLocation = new \IPS\GeoLocation;
|
||||
$geoLocation = new GeoLocation;
|
||||
$geoLocation->addressLines = array();
|
||||
|
||||
foreach( \IPS\Request::i()->address as $k => $v )
|
||||
foreach( Request::i()->address as $k => $v )
|
||||
{
|
||||
if( \in_array( $k, array( 'city', 'postalCode', 'region', 'addressLines', 'country' ) ) )
|
||||
if( in_array( $k, array( 'city', 'postalCode', 'region', 'addressLines', 'country' ) ) )
|
||||
{
|
||||
$geoLocation->$k = $v;
|
||||
}
|
||||
@@ -181,9 +204,9 @@ class _venues extends \IPS\Node\Api\NodeController
|
||||
{
|
||||
$geoLocation->getLatLong();
|
||||
}
|
||||
catch( \BadMethodCallException $e )
|
||||
catch( BadMethodCallException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ADDRESS', '1L384/3', 400 );
|
||||
throw new Exception( 'INVALID_ADDRESS', '1L384/3', 400 );
|
||||
}
|
||||
|
||||
return $geoLocation;
|
||||
|
||||
Reference in new issue
Block a user