Version 4.7.8
This commit is contained in:
1 parent
7b7404e741
commit
fd22d99e69
688 files changed
+19814
-10890
No files matched your search
+3
-10
@@ -29,7 +29,7 @@ Clipboard
|
||||
CKEditor
|
||||
Description: Provides the editor functionality for submitting content.
|
||||
Location: In development: applications/core/dev/ckeditor (custom build with additional plugins)
|
||||
Included version: 4.19.1
|
||||
Included version: 4.20.1
|
||||
Website: http://ckeditor.com
|
||||
License: http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
@@ -110,7 +110,7 @@ Howler
|
||||
HTMLPurifier
|
||||
Description: Validates and cleans submitted HTML for content
|
||||
Location: system/3rd_party/HTMLPurifier
|
||||
Included version: 4.14.0
|
||||
Included version: 4.15.0
|
||||
Website: http://htmlpurifier.org
|
||||
License: http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
@@ -211,13 +211,6 @@ JShrink
|
||||
Website: https://github.com/tedious/JShrink
|
||||
License: https://github.com/tedious/JShrink/blob/master/LICENSE
|
||||
|
||||
jsTimezoneDetect
|
||||
Description: Provides timezone detection
|
||||
Location: dev/js/library/jstz
|
||||
Included version: 1.0.6
|
||||
Website: https://bitbucket.org/pellepim/jstimezonedetect
|
||||
License: http://www.opensource.org/licenses/mit-license.php
|
||||
|
||||
JwtFramework
|
||||
Description: Provides JWT signing & encryption support
|
||||
Location: system/3rd_party/JwtFramework
|
||||
@@ -336,7 +329,7 @@ success.mp3 Notification Sound by RCP Tones
|
||||
Twemoji
|
||||
Description: Emoji images
|
||||
Location: Served from CDN
|
||||
Included version: 2.3
|
||||
Included version: 14.0.2
|
||||
Website: http://twitter.github.io/twemoji/
|
||||
License: https://github.com/twitter/twemoji/blob/gh-pages/LICENSE
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
=============================[NOTE]=============================
|
||||
IPS 4.7.6 (107601)
|
||||
IPS 4.7.8 (107643)
|
||||
=============================[NOTE]=============================
|
||||
|
||||
Invision Community End User License Agreement
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog mutations
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog mutationss GraphQL API
|
||||
*/
|
||||
abstract class _Mutation
|
||||
{
|
||||
/**
|
||||
* Get the supported query types in this app
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function mutations(): array
|
||||
{
|
||||
$return = [
|
||||
'createEntry' => new \IPS\blog\api\GraphQL\Mutations\CreateEntry(),
|
||||
'replyEntry' => new \IPS\blog\api\GraphQL\Mutations\ReplyEntry(),
|
||||
];
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Create blog entry mutation
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Mutations;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create blog entry mutation for GraphQL API
|
||||
*/
|
||||
class _CreateEntry extends \IPS\Content\Api\GraphQL\ItemMutator
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = \IPS\blog\Entry::class;
|
||||
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Create a new blog entry";
|
||||
|
||||
/*
|
||||
* Mutation arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return [
|
||||
'blog' => TypeRegistry::nonNull( TypeRegistry::id() )
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mutation return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::entry();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this mutation
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\blog\Blog
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
/* Get blog */
|
||||
try
|
||||
{
|
||||
$blog = \IPS\blog\Blog::loadAndCheckPerms( $args['blogID'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_BLOG', '1B300/1_graphql', 400 );
|
||||
}
|
||||
|
||||
/* Check permission */
|
||||
if ( !$blog->can( 'add', \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '1B300/A_graphql', 403 );
|
||||
}
|
||||
|
||||
/* Check we have a title and a post */
|
||||
if ( !$args['title'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_TITLE', '1B300/4_graphql', 400 );
|
||||
}
|
||||
if ( !$args['content'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1B300/5_grapqhl', 400 );
|
||||
}
|
||||
|
||||
|
||||
return $this->_create( $args, $blog, $args['postKey'] ?? NULL );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Reply to topic mutation
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Mutations;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reply to entry mutation for GraphQL API
|
||||
*/
|
||||
class _ReplyEntry extends \IPS\Content\Api\GraphQL\CommentMutator
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = \IPS\blog\Entry\Comment::class;
|
||||
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Create a new comment";
|
||||
|
||||
/*
|
||||
* Mutation arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return [
|
||||
'entryID' => TypeRegistry::nonNull( TypeRegistry::id() ),
|
||||
'content' => TypeRegistry::nonNull( TypeRegistry::string() ),
|
||||
'replyingTo' => TypeRegistry::id(),
|
||||
'postKey' => TypeRegistry::string()
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mutation return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::comment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this mutation
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\blog\Entry
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
/* Get topic */
|
||||
try
|
||||
{
|
||||
$entry = \IPS\blog\Entry::loadAndCheckPerms( $args['entryID'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_TOPIC', '1F295/1_graphql', 403 );
|
||||
}
|
||||
|
||||
/* Get author */
|
||||
if ( !$entry->canComment( \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '2F294/A_graphql', 403 );
|
||||
}
|
||||
|
||||
/* Check we have a post */
|
||||
if ( !$args['content'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1F295/3_graphql', 403 );
|
||||
}
|
||||
|
||||
$originalPost = NULL;
|
||||
|
||||
if( isset( $args['replyingTo'] ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$originalPost = \IPS\blog\Entry\Comment::loadAndCheckPerms( $args['replyingTo'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
// Just ignore it
|
||||
}
|
||||
}
|
||||
|
||||
/* Do it */
|
||||
return $this->_createComment( $args, $entry, $args['postKey'] ?? NULL, $originalPost );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog query for GraphQL API
|
||||
*/
|
||||
class _Blog
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a Blog";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::nonNull( TypeRegistry::id() ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::blog();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\blog\Blog
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
$blog = \IPS\blog\Blog::load( $args['id'] );
|
||||
|
||||
if( !$blog->can( 'view', $context['member'] ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
return $blog;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blogs query for GraphQL API
|
||||
*/
|
||||
class _Blogs
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of blogs";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::id()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\blog\api\GraphQL\TypeRegistry::blog() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return array
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
\IPS\blog\Blog::loadIntoMemory('view', $context['member']);
|
||||
return \IPS\blog\Blog::roots();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Topics query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Topics query for GraphQL API
|
||||
*/
|
||||
class _Entries
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of blog entries";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'blogs' => TypeRegistry::listOf( TypeRegistry::int() ),
|
||||
'offset' => [
|
||||
'type' => TypeRegistry::int(),
|
||||
'defaultValue' => 0
|
||||
],
|
||||
'limit' => [
|
||||
'type' => TypeRegistry::int(),
|
||||
'defaultValue' => 25
|
||||
],
|
||||
'orderBy' => [
|
||||
'type' => TypeRegistry::eNum([
|
||||
'name' => 'blog_order_by',
|
||||
'description' => 'Fields on which event can be sorted',
|
||||
'values' => \IPS\blog\api\GraphQL\Types\EntryType::getOrderByOptions()
|
||||
]),
|
||||
'defaultValue' => NULL // will use default sort option
|
||||
],
|
||||
'orderDir' => [
|
||||
'type' => TypeRegistry::eNum([
|
||||
'name' => 'entries_order_dir',
|
||||
'description' => 'Directions in which items can be sorted',
|
||||
'values' => [ 'ASC', 'DESC' ]
|
||||
]),
|
||||
'defaultValue' => 'DESC'
|
||||
],
|
||||
'honorPinned' => [
|
||||
'type' => TypeRegistry::boolean(),
|
||||
'defaultValue' => true
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\blog\api\GraphQL\TypeRegistry::entry() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\blog\Entry
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
\IPS\blog\Blog::loadIntoMemory('view', \IPS\Member::loggedIn() );
|
||||
|
||||
$blogIds = [];
|
||||
|
||||
/* Are we filtering by blogs? */
|
||||
if( isset( $args['blogs'] ) && \count( $args['blogs'] ) )
|
||||
{
|
||||
foreach( $args['blogs'] as $id )
|
||||
{
|
||||
$blog = \IPS\blog\Blog::loadAndCheckPerms( $id );
|
||||
$blogIds[] = $blog->id;
|
||||
}
|
||||
|
||||
if( \count( $blogIds ) )
|
||||
{
|
||||
$where['container'][] = array( \IPS\Db::i()->in( 'blog_blogs.blog_id', array_filter( $blogIds ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
/* Get sorting */
|
||||
try
|
||||
{
|
||||
if( $args['orderBy'] === NULL )
|
||||
{
|
||||
$orderBy = 'last_post';
|
||||
}
|
||||
else
|
||||
{
|
||||
$orderBy = \IPS\blog\Entry::$databaseColumnMap[ $args['orderBy'] ];
|
||||
}
|
||||
|
||||
if( $args['orderBy'] === 'last_comment' )
|
||||
{
|
||||
$orderBy = \is_array( $orderBy ) ? array_pop( $orderBy ) : $orderBy;
|
||||
}
|
||||
}
|
||||
catch (\Exception $e)
|
||||
{
|
||||
$orderBy = 'last_post';
|
||||
}
|
||||
|
||||
$sortBy = \IPS\blog\Entry::$databaseTable . '.' . \IPS\blog\Entry::$databasePrefix . "{$orderBy} {$args['orderDir']}";
|
||||
$offset = max( $args['offset'], 0 );
|
||||
$limit = min( $args['limit'], 50 );
|
||||
|
||||
/* Figure out pinned status */
|
||||
if ( $args['honorPinned'] )
|
||||
{
|
||||
$column = \IPS\blog\Entry::$databaseTable . '.' . \IPS\blog\Entry::$databasePrefix . \IPS\blog\Entry::$databaseColumnMap['pinned'];
|
||||
$sortBy = "{$column} DESC, {$sortBy}";
|
||||
}
|
||||
|
||||
return \IPS\blog\Entry::getItemsWithPermission( $where, $sortBy, array( $offset, $limit ), 'read' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Entry query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry query for GraphQL API
|
||||
*/
|
||||
class _Entry
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a Blog Entry";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::nonNull( TypeRegistry::id() )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::entry();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\blog\Entry
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
try
|
||||
{
|
||||
$entry = \IPS\blog\Entry::loadAndCheckPerms( $args['id'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_TOPIC', '2B300/A_graphql', 400 );
|
||||
}
|
||||
|
||||
if( !$entry->can('read') )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_PERMISSION', '2B300/9_graphql', 403 );
|
||||
}
|
||||
|
||||
return $entry;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog queries
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog queries for GraphQL API
|
||||
*/
|
||||
abstract class _Query
|
||||
{
|
||||
/**
|
||||
* Get the supported query types in this app
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function queries(): array
|
||||
{
|
||||
return [
|
||||
'blogs' => new \IPS\blog\api\GraphQL\Queries\Blogs(),
|
||||
'blog' => new \IPS\blog\api\GraphQL\Queries\Blog(),
|
||||
'entries' => new \IPS\blog\api\GraphQL\Queries\Entries(),
|
||||
'entry' => new \IPS\blog\api\GraphQL\Queries\Entry(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Types registry
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
use IPS\blog\api\GraphQL\Types\_BlogType;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
class _TypeRegistry
|
||||
{
|
||||
/**
|
||||
* The blog type instance
|
||||
* @var \IPS\blog\api\GraphQL\Types\BlogType
|
||||
*/
|
||||
protected static $blog;
|
||||
|
||||
/**
|
||||
* The blog entry type instance
|
||||
* @var \IPS\blog\api\GraphQL\Types\EntryType
|
||||
*/
|
||||
protected static $entry;
|
||||
|
||||
/**
|
||||
* The entry comment instance
|
||||
* @var \IPS\blog\api\GraphQL\Types\CommentType
|
||||
*/
|
||||
protected static $comment;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Defined to suppress static warnings
|
||||
}
|
||||
|
||||
/**
|
||||
* @return BlogType
|
||||
*/
|
||||
public static function blog(): \IPS\blog\api\GraphQL\Types\BlogType
|
||||
{
|
||||
return self::$blog ?: (self::$blog = new \IPS\blog\api\GraphQL\Types\BlogType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EntryType
|
||||
*/
|
||||
public static function entry(): \IPS\blog\api\GraphQL\Types\EntryType
|
||||
{
|
||||
return self::$entry ?: (self::$entry = new \IPS\blog\api\GraphQL\Types\EntryType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CommentType
|
||||
*/
|
||||
public static function comment(): \IPS\blog\api\GraphQL\Types\CommentType
|
||||
{
|
||||
return self::$comment ?: (self::$comment = new \IPS\blog\api\GraphQL\Types\CommentType());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* BlogType for GraphQL API
|
||||
*/
|
||||
class _BlogType extends \IPS\Node\Api\GraphQL\NodeType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $nodeClass = \IPS\blog\Blog::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'blog_Blog';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A blog';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array('app' => 'blog', 'area' => 'blog');
|
||||
|
||||
|
||||
/**
|
||||
* Get the item type that goes with this node type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
public static function getItemType()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::entry();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Post Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* PostType for GraphQL API
|
||||
*/
|
||||
class _CommentType extends \IPS\Content\Api\GraphQL\CommentType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $commentClass = \IPS\blog\Entry\Comment::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'blog_Comment';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A blog comment';
|
||||
|
||||
/**
|
||||
* Get the item type that goes with this item type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
public static function getItemType()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::comment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fields available in this type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
$defaultFields = parent::fields();
|
||||
$postFields = array(
|
||||
'entry' => [
|
||||
'type' => \IPS\blog\api\GraphQL\TypeRegistry::entry(),
|
||||
'resolve' => function ($comment) {
|
||||
return $comment->item();
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
// Remove duplicated fields
|
||||
unset( $defaultFields['item'] );
|
||||
|
||||
return array_merge( $defaultFields, $postFields );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Topic Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\blog\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\_TypeRegistry;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry for GraphQL API
|
||||
*/
|
||||
class _EntryType extends \IPS\Content\Api\GraphQL\ItemType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $itemClass = \IPS\blog\Entry::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'blog_Entry';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A blog entry';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array('app' => 'blogs', 'area' => 'entry');
|
||||
|
||||
/**
|
||||
* Get the comment type that goes with this item type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
protected static function getCommentType()
|
||||
{
|
||||
return \IPS\blog\api\GraphQL\TypeRegistry::comment();
|
||||
}
|
||||
}
|
||||
@@ -34,6 +34,7 @@ class _blogs extends \IPS\Node\Api\NodeController
|
||||
* Get list of blogs
|
||||
*
|
||||
* @note For requests using an OAuth Access Token for a particular member, only blogs that are not disabled and not belonging to a particular club or social group will be included
|
||||
* @apiparam string ids Comma-delimited list of blog ids
|
||||
* @apiparam string owners Comma-delimited list of member IDs - if provided, only blogs owned by those members are returned (can be used in conjection with groups or set to 0 to exclude member-created blogs)
|
||||
* @apiparam string groups Comma-delimited list of group IDs - if provided, only blogs owned by those groups are returned (can be used in conjection with members or set to 0 to exclude group blogs)
|
||||
* @apiparam int pinned If 1, only blogs which are pinned are returned, if 0 only not pinned
|
||||
@@ -46,8 +47,8 @@ class _blogs extends \IPS\Node\Api\NodeController
|
||||
public function GETindex()
|
||||
{
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
|
||||
$where = $this->_globalWhere();
|
||||
|
||||
/* Owners */
|
||||
if ( isset( \IPS\Request::i()->owners ) and isset( \IPS\Request::i()->groups ) )
|
||||
{
|
||||
|
||||
@@ -33,6 +33,7 @@ class _categories extends \IPS\Node\Api\NodeController
|
||||
* GET /blog/categories
|
||||
* Get list of blog categories
|
||||
*
|
||||
* @apiparam string ids Comma-delimited list of category ids
|
||||
* @apiparam string sortBy What to sort by. Can be 'count_entries' for number of entries, 'last_edate' for last entry date or do not specify for ID
|
||||
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
|
||||
* @apiparam int page Page number
|
||||
@@ -42,7 +43,7 @@ class _categories extends \IPS\Node\Api\NodeController
|
||||
public function GETindex()
|
||||
{
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
$where = $this->_globalWhere();
|
||||
|
||||
/* Sort */
|
||||
if ( isset( \IPS\Request::i()->sortBy ) and \in_array( \IPS\Request::i()->sortBy, array( 'position' ) ) )
|
||||
|
||||
@@ -33,6 +33,7 @@ class _entries extends \IPS\Content\Api\ItemController
|
||||
* Get list of entries
|
||||
*
|
||||
* @note For requests using an OAuth Access Token for a particular member, only entries that are published and in blogs that are not disabled and not belonging to a particular club or social group will be included
|
||||
* @apiparam string ids Comma-delimited list of entry IDs
|
||||
* @apiparam string blogs Comma-delimited list of blog IDs
|
||||
* @apiparam string authors Comma-delimited list of member IDs - if provided, only entries started by those members are returned
|
||||
* @apiparam int locked If 1, only entries which are locked are returned, if 0 only unlocked
|
||||
|
||||
@@ -45,6 +45,14 @@ class _entrycategories extends \IPS\Node\Api\NodeController
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
|
||||
$class = $this->class;
|
||||
|
||||
if ( isset( \IPS\Request::i()->ids ) )
|
||||
{
|
||||
$idField = $class::$databaseTable . '.' . $class::$databasePrefix . '.' . $class::$databaseColumnId;
|
||||
$where[] = array( \IPS\Db::i()->in( $idField, array_map( 'intval', explode( ',', \IPS\Request::i()->ids ) ) ) );
|
||||
}
|
||||
|
||||
/* Blog */
|
||||
if ( isset( \IPS\Request::i()->blog ) )
|
||||
{
|
||||
|
||||
@@ -1,16 +1,16 @@
|
||||
{
|
||||
"blogs": {
|
||||
"settings": {
|
||||
"tab": "community",
|
||||
"controller": "settings",
|
||||
"do": "",
|
||||
"restriction": "settings_manage"
|
||||
},
|
||||
"blogs": {
|
||||
"tab": "community",
|
||||
"controller": "blogs",
|
||||
"do": "",
|
||||
"restriction": "blogs_manage"
|
||||
},
|
||||
"settings": {
|
||||
"tab": "community",
|
||||
"controller": "settings",
|
||||
"do": "",
|
||||
"restriction": "settings_manage"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<javascript app="blog">
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.grid.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.grid.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.list.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050">/**
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.list.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -66,7 +66,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.manageCategories.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.manageCategories.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -343,7 +343,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.view.js" javascript_type="template" javascript_version="107601" javascript_position="1000150"><![CDATA[/* CLASS LIST TEMPLATES */
|
||||
<file javascript_app="blog" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.view.js" javascript_type="template" javascript_version="107643" javascript_position="1000150"><![CDATA[/* CLASS LIST TEMPLATES */
|
||||
ips.templates.set('blog.view.addButton', "\
|
||||
<button type=\"button\" class=\"ipsButton ipsButton_primary ipsHide\" data-action=\"addNew\">{{#lang}}manage_cats_new_row{{/lang}}</button>\
|
||||
");
|
||||
@@ -373,7 +373,6 @@ controllers</order>
|
||||
<order app="global" path="/dev/js//library/">underscore
|
||||
jquery
|
||||
mustache
|
||||
jstz
|
||||
IntersectionObserver
|
||||
Debug.js
|
||||
app.js</order>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="blog" version="107601">
|
||||
<app key="blog" version="107643">
|
||||
<word key="__app_blog" js="0">Blogs</word>
|
||||
<word key="frontnavigation_blogs" js="0">Blogs</word>
|
||||
<word key="__indefart_blog_entry_comment" js="0">a comment on a blog entry</word>
|
||||
|
||||
@@ -1270,7 +1270,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class='ipsFlex-flex:01 ipsResponsive_hidePhone'>
|
||||
<div class='ipsFlex ipsFlex-ai:center ipsFlex-jc:center ipsGap:3 ipsGap_row:0'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if \count( $entry->shareLinks() )}}
|
||||
{template="shareButton" app="core" group="sharelinks" params="$entry"}
|
||||
{{endif}}
|
||||
@@ -1384,18 +1384,12 @@
|
||||
</article>
|
||||
|
||||
<div class='ipsBox ipsPadding ipsResponsive_pull ipsResponsive_showPhone ipsMargin_vertical'>
|
||||
<div class='ipsGap:3'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if \count( $entry->shareLinks() )}}
|
||||
<div>
|
||||
{template="shareButton" app="core" group="sharelinks" params="$entry, 'verySmall', 'light'"}
|
||||
</div>
|
||||
{template="shareButton" app="core" group="sharelinks" params="$entry, 'verySmall', 'light'"}
|
||||
{{endif}}
|
||||
<div>
|
||||
{template="follow" app="core" group="global" params="'blog', 'entry', $entry->id, $entry->followersCount()"}
|
||||
</div>
|
||||
<div>
|
||||
{template="promote" app="core" group="global" params="$entry"}
|
||||
</div>
|
||||
{template="follow" app="core" group="global" params="'blog', 'entry', $entry->id, $entry->followersCount()"}
|
||||
{template="promote" app="core" group="global" params="$entry"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1588,7 +1582,7 @@
|
||||
<template template_group="widgets" template_name="blogCommentFeed" template_data="$comments, $title, $orientation='vertical'" template_location="front" template_app="blog"><![CDATA[{{if !empty( $comments ) }}
|
||||
<h3 class='ipsType_reset ipsWidget_title'>{$title}</h3>
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsWidget_inner ipsPad_half'>
|
||||
<div class='ipsWidget_inner'>
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $comments as $comment}}
|
||||
<li class='ipsDataItem'>
|
||||
@@ -1596,8 +1590,8 @@
|
||||
{template="userPhoto" group="global" app="core" params="$comment->author(), 'tiny'"}
|
||||
</div>
|
||||
<div class='ipsDataItem_main'>
|
||||
<div class='ipsType_break ipsContained'><a href="{$comment->url()}" class='ipsType_medium ipsTruncate ipsTruncate_line'>{$comment->item()->name}</a></div>
|
||||
<p class='ipsType_reset ipsType_medium ipsType_light ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$comment->author()->link()"} · <a href="{$comment->url()}" class='ipsDataItem_title ipsType_break ipsType_blendLinks'>{$comment->dateLine()|raw}</a></p>
|
||||
<div class='ipsType_break ipsContained'><a href="{$comment->url()}" class='ipsDataItem_title'>{$comment->item()->name}</a></div>
|
||||
<p class='ipsType_reset ipsType_medium ipsType_light ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$comment->author()->link()"} · <a href="{$comment->url()}" class='ipsType_break ipsType_blendLinks'>{$comment->dateLine()|raw}</a></p>
|
||||
<div class='ipsType_medium ipsType_textBlock ipsType_richText ipsType_break ipsContained ipsSpacer_top ipsSpacer_half' data-ipsTruncate data-ipsTruncate-type='remove' data-ipsTruncate-size='{{if $orientation == 'vertical'}}6 lines{{else}}2 lines{{endif}}'>
|
||||
{$comment->truncated( true )|raw}
|
||||
</div>
|
||||
@@ -1680,7 +1674,7 @@
|
||||
]]></template>
|
||||
<template template_group="widgets" template_name="blogs" template_data="$blogs, $title, $orientation='vertical'" template_location="front" template_app="blog"><![CDATA[<h3 class='ipsType_reset ipsWidget_title'>{$title}</h3>
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsPad_half ipsWidget_inner'>
|
||||
<div class='ipsWidget_inner ipsPadding:half'>
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $blogs as $blog}}
|
||||
<li class='ipsDataItem'>
|
||||
@@ -1797,26 +1791,24 @@
|
||||
<template template_group="widgets" template_name="blogStatistics" template_data="$stats, $orientation='vertical'" template_location="front" template_app="blog"><![CDATA[<h3 class='ipsType_reset ipsWidget_title'>{lang="block_blogStatistics"}</h3>
|
||||
<div class='ipsWidget_inner'>
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsPad_half'>
|
||||
<ul class='ipsDataList' id='elBlogStats'>
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_main ipsPos_middle'>
|
||||
<strong>{lang="total_blogs"}</strong>
|
||||
</div>
|
||||
<div class='ipsDataItem_stats ipsDataItem_statsLarge'>
|
||||
<span class='ipsDataItem_stats_number'>{number="$stats['total_blogs']"}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_main ipsPos_middle'>
|
||||
<strong>{lang="total_entries"}</strong>
|
||||
</div>
|
||||
<div class='ipsDataItem_stats ipsDataItem_statsLarge'>
|
||||
<span class='ipsDataItem_stats_number'>{number="$stats['total_entries']"}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul class='ipsDataList' id='elBlogStats'>
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_main ipsPos_middle'>
|
||||
<strong>{lang="total_blogs"}</strong>
|
||||
</div>
|
||||
<div class='ipsDataItem_stats ipsDataItem_statsLarge'>
|
||||
<span class='ipsDataItem_stats_number'>{number="$stats['total_blogs']"}</span>
|
||||
</div>
|
||||
</li>
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_main ipsPos_middle'>
|
||||
<strong>{lang="total_entries"}</strong>
|
||||
</div>
|
||||
<div class='ipsDataItem_stats ipsDataItem_statsLarge'>
|
||||
<span class='ipsDataItem_stats_number'>{number="$stats['total_entries']"}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{{else}}
|
||||
<div class='ipsGrid ipsGrid_collapsePhone ipsWidget_stats'>
|
||||
<div class='ipsGrid_span6 ipsType_center'>
|
||||
@@ -1832,7 +1824,7 @@
|
||||
</div>]]></template>
|
||||
<template template_group="widgets" template_name="entryFeed" template_data="$entries, $title, $orientation='vertical'" template_location="front" template_app="blog"><![CDATA[{{if !empty( $entries ) }}
|
||||
<h3 class='ipsType_reset ipsWidget_title'>{$title}</h3>
|
||||
<div class='ipsPad_half ipsWidget_inner'>
|
||||
<div class='ipsWidget_inner'>
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $entries as $entry}}
|
||||
{template="entryRow" group="widgets" app="blog" params="$entry, $orientation"}
|
||||
@@ -1845,14 +1837,16 @@
|
||||
{template="userPhoto" app="core" params="$entry->author(), 'tiny'" group="global"}
|
||||
</div>
|
||||
<div class='ipsDataItem_main'>
|
||||
<div class='ipsContained ipsType_break'><a href="{$entry->url('getLastComment')}" title='{lang="view_this_entry" sprintf="$entry->_title"}' class='ipsType_medium ipsTruncate ipsTruncate_line'>{$entry->name}</a></div>
|
||||
<span class='ipsType_blendLinks ipsType_light ipsType_medium ipsType_break ipsContained'>{lang="byline_nodate" htmlsprintf="$entry->author()->link()"} {lang="in"} <a href='{$entry->container()->url()}' class='ipsType_blendLinks ipsTruncate ipsTruncate_line'>{$entry->container()->_title}</a></span>
|
||||
{{if \IPS\Settings::i()->blog_enable_rating}}
|
||||
{template="rating" group="global" location="front" app="core" params="'small', $entry->averageRating(), 5, $entry->memberRating()"}
|
||||
{{endif}}
|
||||
<span class='ipsType_medium ipsType_reset'>{{if !$entry->num_comments}}<span class='ipsType_light'>{{endif}}<i class='fa fa-comment'></i> {number="$entry->num_comments"}{{if !$entry->num_comments}}</span>{{endif}}</span>
|
||||
<div class='ipsContained ipsType_break'><a href="{$entry->url('getLastComment')}" title='{lang="view_this_entry" sprintf="$entry->_title"}' class='ipsDataItem_title'>{$entry->name}</a></div>
|
||||
<div class='ipsType_blendLinks ipsType_light ipsType_break ipsContained'>{lang="byline_nodate" htmlsprintf="$entry->author()->link()"} {lang="in"} <a href='{$entry->container()->url()}' class='ipsType_blendLinks'>{$entry->container()->_title}</a></div>
|
||||
<div class='ipsMargin_top:half'>
|
||||
{{if \IPS\Settings::i()->blog_enable_rating}}
|
||||
{template="rating" group="global" location="front" app="core" params="'small', $entry->averageRating(), 5, $entry->memberRating()"}
|
||||
{{endif}}
|
||||
<span {{if !$entry->num_comments}}class='ipsType_light'{{endif}}>{number="$entry->num_comments"} {lang="blog_comments" pluralize="$entry->num_comments"}</span>
|
||||
</div>
|
||||
{{if $orientation == 'horizontal'}}
|
||||
<div class='ipsType_medium ipsType_richText ipsType_break' data-ipsTruncate data-ipsTruncate-type='remove' data-ipsTruncate-size='2 lines'>
|
||||
<div class='ipsMargin_top:half ipsType_medium ipsType_richText ipsType_break' data-ipsTruncate data-ipsTruncate-type='remove' data-ipsTruncate-size='2 lines'>
|
||||
{$entry->truncated()|raw}
|
||||
</div>
|
||||
{{endif}}
|
||||
|
||||
@@ -535,5 +535,19 @@
|
||||
"107504": "4.7.5",
|
||||
"107505": "4.7.5",
|
||||
"107600": "4.7.6 Beta 1",
|
||||
"107601": "4.7.6"
|
||||
"107601": "4.7.6",
|
||||
"107602": "4.7.6",
|
||||
"107620": "4.7.7 Beta 1",
|
||||
"107621": "4.7.7 Beta 2",
|
||||
"107622": "4.7.7 Beta 2",
|
||||
"107623": "4.7.7 Beta 3",
|
||||
"107624": "4.7.7 Beta 4",
|
||||
"107625": "4.7.7",
|
||||
"107626": "4.7.7",
|
||||
"107627": "4.7.7",
|
||||
"107628": "4.7.7",
|
||||
"107640": "4.7.8 Beta 1",
|
||||
"107641": "4.7.8 Beta 2",
|
||||
"107642": "4.7.8 Beta 3",
|
||||
"107643": "4.7.8"
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107602,
|
||||
"name": "4.7.6",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107620,
|
||||
"name": "4.7.7 Beta 1",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": true,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": true,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"orders": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"global\/\/dev\/js\/\/library\/"
|
||||
],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107621,
|
||||
"name": "4.7.7 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107622,
|
||||
"name": "4.7.7 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107623,
|
||||
"name": "4.7.7 Beta 3",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107624,
|
||||
"name": "4.7.7 Beta 4",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107625,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107626,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107627,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107628,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107640,
|
||||
"name": "4.7.8 Beta 1",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": true,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"html": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"front\/view\/entry",
|
||||
"front\/widgets\/blogCommentFeed",
|
||||
"front\/widgets\/blogs",
|
||||
"front\/widgets\/blogStatistics",
|
||||
"front\/widgets\/entryFeed",
|
||||
"front\/widgets\/entryRow"
|
||||
],
|
||||
"removed": []
|
||||
},
|
||||
"css": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"resources": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107641,
|
||||
"name": "4.7.8 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107642,
|
||||
"name": "4.7.8 Beta 3",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107643,
|
||||
"name": "4.7.8",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -1322,7 +1322,7 @@ class _Blog extends \IPS\Node\Model implements \IPS\Node\Ratings, \IPS\Content\E
|
||||
|
||||
if( $club->type == 'closed' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'club_node_public', $this->id ? $this->isPublic() : FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'club_node_public', $this->id ? $this->isPublic() : 0, TRUE, array( 'options' => array( '0' => 'club_node_public_no', '1' => 'club_node_public_view', '2' => 'club_node_public_participate' ) ) ) );
|
||||
}
|
||||
|
||||
/* Categories */
|
||||
|
||||
@@ -81,11 +81,6 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'blog-entries';
|
||||
|
||||
/**
|
||||
* @brief Whether to track the sentiment scores in cloud_sentiment_scores for this content
|
||||
*/
|
||||
public $trackSentimentScore = true;
|
||||
|
||||
/**
|
||||
* Get items with permission check
|
||||
|
||||
@@ -155,11 +155,6 @@ class _Entry extends \IPS\Content\Item implements
|
||||
* @brief Use a default cover photo
|
||||
*/
|
||||
public static $coverPhotoDefault = true;
|
||||
|
||||
/**
|
||||
* @brief Whether to track the sentiment scores in cloud_sentiment_scores for this content
|
||||
*/
|
||||
public $trackSentimentScore = true;
|
||||
|
||||
/**
|
||||
* Set the title
|
||||
@@ -296,6 +291,16 @@ class _Entry extends \IPS\Content\Item implements
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unclaim attachments
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function unclaimAttachments()
|
||||
{
|
||||
\IPS\File::unclaimAttachments( 'blog_Entries', $this->id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get items with permisison check
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Calendar mutations
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog mutationss GraphQL API
|
||||
*/
|
||||
abstract class _Mutation
|
||||
{
|
||||
/**
|
||||
* Get the supported query types in this app
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function mutations(): array
|
||||
{
|
||||
$return = [
|
||||
'createEvent' => new \IPS\calendar\api\GraphQL\Mutations\CreateEvent(),
|
||||
];
|
||||
return $return;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Create entry mutation
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Mutations;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create Event mutation for GraphQL API
|
||||
*/
|
||||
class _CreateEvent extends \IPS\Content\Api\GraphQL\ItemMutator
|
||||
{
|
||||
/**
|
||||
* Class
|
||||
*/
|
||||
protected $class = \IPS\calendar\Event::class;
|
||||
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Create a new calendar event";
|
||||
|
||||
/*
|
||||
* Mutation arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
$args = parent::args();
|
||||
$args['calendar'] = TypeRegistry::nonNull( TypeRegistry::id() );
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the mutation return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this mutation
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
/* Get calendar */
|
||||
try
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::loadAndCheckPerms( $args['calendarID'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_CALENDAR', '1L296/6_graphql', 400 );
|
||||
}
|
||||
|
||||
/* Check permission */
|
||||
if ( !$calendar->can( 'add', \IPS\Member::loggedIn() ) )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\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 );
|
||||
}
|
||||
if ( !$args['content'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_POST', '1L296/9_grapqhl', 400 );
|
||||
}
|
||||
|
||||
if ( !$args['start'] )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_START', '1L296/A_grapqhl', 400 );
|
||||
}
|
||||
|
||||
return $this->_create( $args, $calendar, $args['postKey'] ?? NULL );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Forum query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar query for GraphQL API
|
||||
*/
|
||||
class _calendar
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a calendar";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::nonNull( TypeRegistry::id() ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::calendar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Calendar
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::load( $args['id'] );
|
||||
|
||||
if( !$calendar->can( 'view', $context['member'] ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Forums query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Forums query for GraphQL API
|
||||
*/
|
||||
class _Calendars
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of calendars";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::id()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\calendar\api\GraphQL\TypeRegistry::calendar() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return array
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
\IPS\calendar\Calendar::loadIntoMemory('view', $context['member']);
|
||||
return \IPS\calendar\Calendar::roots();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Topic query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Event query for GraphQL API
|
||||
*/
|
||||
class _Event
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns an event";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return array(
|
||||
'id' => TypeRegistry::nonNull( TypeRegistry::id() )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
*/
|
||||
public function resolve($val, $args, $context, $info)
|
||||
{
|
||||
try
|
||||
{
|
||||
$event = \IPS\calendar\Event::loadAndCheckPerms( $args['id'] );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'NO_EVENT', '1F294/2_graphql', 400 );
|
||||
}
|
||||
|
||||
if( !$event->can('read') )
|
||||
{
|
||||
throw new \IPS\Api\GraphQL\SafeException( 'INVALID_ID', '2F294/9_graphql', 403 );
|
||||
}
|
||||
|
||||
return $event;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Calender Events query
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 26 January 2023
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Queries;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER[ 'SERVER_PROTOCOL' ] ) ? $_SERVER[ 'SERVER_PROTOCOL' ] : 'HTTP/1.0' ).' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calendar Events query for GraphQL API
|
||||
*/
|
||||
class _Events
|
||||
{
|
||||
/*
|
||||
* @brief Query description
|
||||
*/
|
||||
public static $description = "Returns a list of events";
|
||||
|
||||
/*
|
||||
* Query arguments
|
||||
*/
|
||||
public function args(): array
|
||||
{
|
||||
return [
|
||||
'calendar' => TypeRegistry::listOf( TypeRegistry::int() ),
|
||||
'offset' => [
|
||||
'type' => TypeRegistry::int(),
|
||||
'defaultValue' => 0,
|
||||
],
|
||||
'limit' => [
|
||||
'type' => TypeRegistry::int(),
|
||||
'defaultValue' => 25,
|
||||
],
|
||||
'orderBy' => [
|
||||
'type' => TypeRegistry::eNum( [
|
||||
'name' => 'events_order_by',
|
||||
'description' => 'Fields on which events can be sorted',
|
||||
'values' => \IPS\calendar\api\GraphQL\Types\EventType::getOrderByOptions(),
|
||||
] ),
|
||||
'defaultValue' => NULL, // will use default sort option
|
||||
],
|
||||
'orderDir' => [
|
||||
'type' => TypeRegistry::eNum( [
|
||||
'name' => 'events_order_dir',
|
||||
'description' => 'Directions in which items can be sorted',
|
||||
'values' => [ 'ASC', 'DESC' ],
|
||||
] ),
|
||||
'defaultValue' => 'DESC',
|
||||
],
|
||||
'honorPinned' => [
|
||||
'type' => TypeRegistry::boolean(),
|
||||
'defaultValue' => TRUE,
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the query return type
|
||||
*/
|
||||
public function type()
|
||||
{
|
||||
return TypeRegistry::listOf( \IPS\calendar\api\GraphQL\TypeRegistry::event() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves this query
|
||||
*
|
||||
* @param mixed Value passed into this resolver
|
||||
* @param array Arguments
|
||||
* @param array Context values
|
||||
* @return \IPS\calendar\Event
|
||||
*/
|
||||
public function resolve( $val, $args, $context, $info )
|
||||
{
|
||||
$where = [];
|
||||
\IPS\calendar\Calendar::loadIntoMemory( 'view', \IPS\Member::loggedIn() );
|
||||
|
||||
$calendarIDs = [];
|
||||
|
||||
/* Are we filtering by calendards? */
|
||||
if( isset( $args[ 'calendars' ] ) && \count( $args[ 'calendars' ] ) )
|
||||
{
|
||||
foreach( $args[ 'calendars' ] as $id )
|
||||
{
|
||||
$calendar = \IPS\calendar\Calendar::loadAndCheckPerms( $id );
|
||||
$calendarIDs[] = $calendar->id;
|
||||
}
|
||||
|
||||
if( \count( $calendarIDs ) )
|
||||
{
|
||||
$where[ 'container' ][] = [ \IPS\Db::i()->in( 'calendar_events.event_calendar_id', array_filter( $calendarIDs ) ) ];
|
||||
}
|
||||
}
|
||||
|
||||
/* Get sorting */
|
||||
|
||||
if( $args[ 'orderBy' ] === NULL )
|
||||
{
|
||||
$orderBy = 'saved';
|
||||
}
|
||||
else if( \in_array( $args[ 'orderBy' ], \IPS\calendar\api\GraphQL\Types\EventType::getOrderByOptions() ) )
|
||||
{
|
||||
$orderBy = $args[ 'orderBy' ];
|
||||
}
|
||||
|
||||
$sortBy = \IPS\calendar\Event::$databaseTable.'.'.\IPS\calendar\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' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Calendar queries
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Blog queries for GraphQL API
|
||||
*/
|
||||
abstract class _Query
|
||||
{
|
||||
/**
|
||||
* Get the supported query types in this app
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function queries()
|
||||
{
|
||||
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(),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Types registry
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\Types;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
|
||||
class _TypeRegistry
|
||||
{
|
||||
/**
|
||||
* The calendar type instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
*/
|
||||
protected static $calendar;
|
||||
|
||||
/**
|
||||
* The event type instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\EventType
|
||||
*/
|
||||
protected static $event;
|
||||
|
||||
/**
|
||||
* The event comment instance
|
||||
* @var \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
*/
|
||||
protected static $comment;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// Defined to suppress static warnings
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CalendarType
|
||||
*/
|
||||
public static function calendar() : \IPS\calendar\api\GraphQL\Types\CalendarType
|
||||
{
|
||||
return self::$calendar ?: (self::$calendar = new \IPS\calendar\api\GraphQL\Types\CalendarType());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return EventType
|
||||
*/
|
||||
public static function event() : \IPS\calendar\api\GraphQL\Types\EventType
|
||||
{
|
||||
return self::$event ?: (self::$event = new \IPS\calendar\api\GraphQL\Types\EventType());
|
||||
}
|
||||
|
||||
public static function comment() : \IPS\calendar\api\GraphQL\Types\CommentType
|
||||
{
|
||||
return self::$comment ?: ( self::$comment = new \IPS\calendar\api\GraphQL\Types\CommentType() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Blog Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 22 Oct 2022
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* CalendarType for GraphQL API
|
||||
*/
|
||||
class _CalendarType extends \IPS\Node\Api\GraphQL\NodeType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $nodeClass = \IPS\calendar\Calendar::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Calendar';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A calendar';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array('app' => 'calendar', 'area' => 'calendar');
|
||||
|
||||
|
||||
/**
|
||||
* Get the item type that goes with this node type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
public static function getItemType()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::event();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Post Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* PostType for GraphQL API
|
||||
*/
|
||||
class _CommentType extends \IPS\Content\Api\GraphQL\CommentType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $commentClass = \IPS\calendar\Event\Comment::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Comment';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $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();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fields available in this type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
$defaultFields = parent::fields();
|
||||
$postFields = array(
|
||||
'event' => [
|
||||
'type' => \IPS\calendar\api\GraphQL\TypeRegistry::event(),
|
||||
'resolve' => function ($comment) {
|
||||
return $comment->item();
|
||||
}
|
||||
],
|
||||
);
|
||||
|
||||
// Remove duplicated fields
|
||||
unset( $defaultFields['item'] );
|
||||
|
||||
return array_merge( $defaultFields, $postFields );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief GraphQL: Topic Type
|
||||
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
|
||||
* @copyright (c) 2001 - 2016 Invision Power Services, Inc.
|
||||
* @license http://www.invisionpower.com/legal/standards/
|
||||
* @package IPS Community Suite
|
||||
* @since 10 May 2017
|
||||
* @version SVN_VERSION_NUMBER
|
||||
*/
|
||||
|
||||
namespace IPS\calendar\api\GraphQL\Types;
|
||||
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use IPS\Api\GraphQL\_TypeRegistry;
|
||||
use IPS\Api\GraphQL\TypeRegistry;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER[ 'SERVER_PROTOCOL' ] ) ? $_SERVER[ 'SERVER_PROTOCOL' ] : 'HTTP/1.0' ).' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry for GraphQL API
|
||||
*/
|
||||
class _EventType extends \IPS\Content\Api\GraphQL\ItemType
|
||||
{
|
||||
/*
|
||||
* @brief The item classname we use for this type
|
||||
*/
|
||||
protected static $itemClass = \IPS\calendar\Event::class;
|
||||
|
||||
/*
|
||||
* @brief GraphQL type name
|
||||
*/
|
||||
protected static $typeName = 'calendar_Event';
|
||||
|
||||
/*
|
||||
* @brief GraphQL type description
|
||||
*/
|
||||
protected static $typeDescription = 'A calendar event';
|
||||
|
||||
/*
|
||||
* @brief Follow data passed in to FollowType resolver
|
||||
*/
|
||||
protected static $followData = array( 'app' => 'calendar', 'area' => 'event' );
|
||||
|
||||
/**
|
||||
* Get the comment type that goes with this item type
|
||||
*
|
||||
* @return ObjectType
|
||||
*/
|
||||
protected static function getCommentType()
|
||||
{
|
||||
return \IPS\calendar\api\GraphQL\TypeRegistry::comment();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the fields available in this type
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function fields()
|
||||
{
|
||||
// Extend our fields with image-specific stuff
|
||||
$defaultFields = parent::fields();
|
||||
$imageFields = array(
|
||||
'start' => [
|
||||
'type' => TypeRegistry::string(),
|
||||
'resolve' => function( $event ){
|
||||
return $event->start_date;
|
||||
}
|
||||
]
|
||||
|
||||
);
|
||||
|
||||
// Remove duplicated fields
|
||||
unset( $defaultFields[ 'poll' ], $defaultFields[ 'isLocked' ], $defaultFields[ 'isPinned' ], $defaultFields[ 'isFeatured' ] );
|
||||
|
||||
return array_merge( $defaultFields, $imageFields );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the sort options available for this type
|
||||
*
|
||||
* @return array|string[]
|
||||
*/
|
||||
public static function getOrderByOptions(): array
|
||||
{
|
||||
return array_merge( parent::getOrderByOptions(), array(
|
||||
'saved','last_comment','start_date'
|
||||
) );
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ class _events extends \IPS\Content\Api\ItemController
|
||||
* Get list of events
|
||||
*
|
||||
* @note For requests using an OAuth Access Token for a particular member, only events the authorized user can view will be included
|
||||
* @apiparam string ids Comma-delimited list of event IDs
|
||||
* @apiparam string calendars Comma-delimited list of calendar IDs
|
||||
* @apiparam string authors Comma-delimited list of member IDs - if provided, only events started by those members are returned
|
||||
* @apiparam int locked If 1, only events which are locked are returned, if 0 only unlocked
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<javascript app="calendar">
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.main.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.main.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -112,7 +112,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/browse" javascript_name="ips.browse.monthView.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -231,7 +231,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.carousel.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.carousel.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -291,7 +291,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.eventList.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.eventList.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -409,7 +409,7 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.nearMe.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.nearMe.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -776,7 +776,7 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.search.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/overview" javascript_name="ips.overview.search.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -808,8 +808,6 @@ var PER_PAGE = 16;
|
||||
*/
|
||||
setup: function () {
|
||||
|
||||
var self = this;
|
||||
|
||||
// Other setup
|
||||
this._gotCoords = false;
|
||||
this._offset = 0;
|
||||
@@ -837,6 +835,34 @@ var PER_PAGE = 16;
|
||||
|
||||
|
||||
// Get map ready to show
|
||||
if( ips.getSetting( 'mapProvider' ) === 'google' ){
|
||||
this.setupGoogle();
|
||||
} else {
|
||||
this.setupMapbox();
|
||||
}
|
||||
},
|
||||
|
||||
setupGoogle: function(){
|
||||
var self = this;
|
||||
self._mapReady = true;
|
||||
Debug.log( self._resultsContainer.find('[data-eventid]') );
|
||||
Debug.log( self._mapContainer.attr('data-markers') );
|
||||
|
||||
if( self._resultsContainer.find('[data-eventid]').length && self._mapContainer.attr('data-markers') ){
|
||||
Debug.log('here');
|
||||
try {
|
||||
var markers = JSON.parse( self._mapContainer.attr('data-markers') );
|
||||
Debug.log( markers );
|
||||
self._updateGoogleMap( markers );
|
||||
} catch (err) {
|
||||
Debug.log("Invalid marker JSON");
|
||||
Debug.log(err);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
setupMapbox: function(){
|
||||
var self = this;
|
||||
$('head').append( "<link rel='stylesheet' type='text/css' media='all' href='https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.css'><link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.css' rel='stylesheet' /><link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-markercluster/v1.0.0/MarkerCluster.Default.css' rel='stylesheet' /><link rel='stylesheet' type='text/css' media='all' href='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css' />" );
|
||||
|
||||
ips.loader.get( [ 'https://api.mapbox.com/mapbox.js/v3.3.1/mapbox.js' ] ).then( function () {
|
||||
@@ -844,17 +870,12 @@ var PER_PAGE = 16;
|
||||
'https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js' ] ).then( function () {
|
||||
|
||||
self._mapReady = true;
|
||||
|
||||
Debug.log( self._resultsContainer.find('[data-eventid]') );
|
||||
Debug.log( self._mapContainer.attr('data-markers') );
|
||||
|
||||
|
||||
if( self._resultsContainer.find('[data-eventid]').length && self._mapContainer.attr('data-markers') ){
|
||||
Debug.log('here');
|
||||
|
||||
try {
|
||||
var markers = JSON.parse( self._mapContainer.attr('data-markers') );
|
||||
Debug.log( markers );
|
||||
self._updateMap( markers );
|
||||
self._updateMapboxMap( markers );
|
||||
} catch (err) {
|
||||
Debug.log("Invalid marker JSON");
|
||||
Debug.log(err);
|
||||
@@ -862,7 +883,6 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
getInitialLocation: function () {
|
||||
@@ -1076,7 +1096,57 @@ var PER_PAGE = 16;
|
||||
});
|
||||
},
|
||||
|
||||
_updateMap: function (markers) {
|
||||
_updateMap: function ( markers ){
|
||||
if( ips.getSetting( 'mapProvider' ) === 'google' ){
|
||||
this._updateGoogleMap( markers );
|
||||
} else {
|
||||
this._updateMapboxMap( markers );
|
||||
}
|
||||
},
|
||||
|
||||
_updateGoogleMap: function (markers){
|
||||
|
||||
if( !this._map ){
|
||||
this._map = new window.google.maps.Map( document.querySelector( '[data-role="searchResultsMap"]' ) );
|
||||
this._mapMarkers = [];
|
||||
}
|
||||
|
||||
this._mapContainer.removeClass('cEvents__searchMap--loading');
|
||||
|
||||
/* Clear existing markers before we rebuild */
|
||||
if( this._mapMarkers.length ){
|
||||
for ( let marker of Object.values(this._mapMarkers) ) {
|
||||
marker.setMap(null);
|
||||
}
|
||||
this._mapMarkers = [];
|
||||
}
|
||||
|
||||
var bounds = new google.maps.LatLngBounds();
|
||||
for ( let marker of Object.values(markers) ) {
|
||||
let mapMarker = new window.google.maps.Marker({
|
||||
position: {lat: marker.lat, lng: marker.long},
|
||||
map: this._map,
|
||||
title: marker.title
|
||||
});
|
||||
this._mapMarkers.push( mapMarker );
|
||||
|
||||
var coords = new google.maps.LatLng( marker.lat, marker.long );
|
||||
if( !( bounds.contains( coords ) ) ){
|
||||
bounds.extend( coords );
|
||||
}
|
||||
}
|
||||
|
||||
/* If we have only one marker in here, fitting to the bounds zooms in way too much */
|
||||
if( this._mapMarkers.length === 1 ){
|
||||
this._map.setZoom(15);
|
||||
this._map.setCenter(bounds.getCenter());
|
||||
} else {
|
||||
this._map.fitBounds( bounds );
|
||||
}
|
||||
this._mapContainer.show();
|
||||
},
|
||||
|
||||
_updateMapboxMap: function (markers) {
|
||||
if( !this._map ){
|
||||
L.mapbox.accessToken = ips.getSetting('mapApiKey');
|
||||
this._map = L.mapbox
|
||||
@@ -1270,8 +1340,9 @@ var PER_PAGE = 16;
|
||||
this._page.find('[data-role="searchResultsWrapper"]').hide();
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="107601" javascript_position="1000150"><![CDATA[/**
|
||||
}(jQuery, _));
|
||||
]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.dates.js" javascript_type="controller" javascript_version="107643" javascript_position="1000150"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1844,7 +1915,7 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/venue" javascript_name="ips.venue.main.js" javascript_type="controller" javascript_version="107601" javascript_position="1000200"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/venue" javascript_name="ips.venue.main.js" javascript_type="controller" javascript_version="107643" javascript_position="1000200"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1956,7 +2027,7 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderButton.js" javascript_type="controller" javascript_version="107601" javascript_position="1000250"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderButton.js" javascript_type="controller" javascript_version="107643" javascript_position="1000250"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2039,7 +2110,7 @@ var PER_PAGE = 16;
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderForm.js" javascript_type="controller" javascript_version="107601" javascript_position="1000250">/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.reminderForm.js" javascript_type="controller" javascript_version="107643" javascript_position="1000250">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2149,7 +2220,7 @@ var PER_PAGE = 16;
|
||||
});
|
||||
}(jQuery, _));
|
||||
</file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.calendar.templates.js" javascript_type="framework" javascript_version="107601" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.calendar.templates.js" javascript_type="framework" javascript_version="107643" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*/
|
||||
@@ -2158,7 +2229,7 @@ var PER_PAGE = 16;
|
||||
ips.templates.set('calendar.reminder.loading', " \
|
||||
<div class='ipsLoading ipsLoading_tiny'></div>\
|
||||
");]]></file>
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.overview.js" javascript_type="template" javascript_version="107601" javascript_position="1000300"><![CDATA[ips.templates.set("eventLoading", "\
|
||||
<file javascript_app="calendar" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.overview.js" javascript_type="template" javascript_version="107643" javascript_position="1000300"><![CDATA[ips.templates.set("eventLoading", "\
|
||||
<li class='ipsBox ipsBox--child event event--withImage event--loading'>\
|
||||
<div class='cEvents__skeleton cEvents__skeleton--eventImage'></div>\
|
||||
<div class='cEvents__details'>\
|
||||
@@ -2184,7 +2255,6 @@ controllers</order>
|
||||
<order app="global" path="/dev/js//library/">underscore
|
||||
jquery
|
||||
mustache
|
||||
jstz
|
||||
IntersectionObserver
|
||||
Debug.js
|
||||
app.js</order>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="calendar" version="107601">
|
||||
<app key="calendar" version="107643">
|
||||
<word key="__app_calendar" js="0">Events</word>
|
||||
<word key="frontnavigation_calendar" js="0">Events</word>
|
||||
<word key="__indefart_calendar_event_comment" js="0">a comment on an event</word>
|
||||
@@ -480,6 +480,7 @@
|
||||
<word key="AchievementAction__Rsvp_log" js="0">RSVP'd to %s</word>
|
||||
<word key="AchievementAction__Rsvp_title" js="0">Event RSVP</word>
|
||||
<word key="menu__calendar_stats" js="0">Calendar</word>
|
||||
<word key="emailstats__notification_event_reminder" js="0">Event Reminders</word>
|
||||
<word key="menu__calendar_stats_rsvp" js="0">RSVP</word>
|
||||
<word key="calendar_stats_rsvp_title" js="0">RSVPs over time</word>
|
||||
<word key="calendar_stats_rsvp_response_0" js="0">Not Going</word>
|
||||
|
||||
@@ -624,7 +624,7 @@
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 4,
|
||||
"length": 1,
|
||||
"name": "event_rsvp",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
@@ -636,7 +636,7 @@
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 4,
|
||||
"length": 1,
|
||||
"name": "event_approved",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
@@ -792,7 +792,7 @@
|
||||
"comment": "Whether the event is locked (for new comments\/reviews) or not",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 3,
|
||||
"length": 1,
|
||||
"name": "event_locked",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
@@ -804,7 +804,7 @@
|
||||
"comment": "Whether the event is featured or not",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 3,
|
||||
"length": 1,
|
||||
"name": "event_featured",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
@@ -876,7 +876,7 @@
|
||||
"comment": "Maximum number of attendees allowed for the event",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 11,
|
||||
"length": 10,
|
||||
"name": "event_rsvp_limit",
|
||||
"type": "INT",
|
||||
"unsigned": false,
|
||||
@@ -1020,7 +1020,7 @@
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 11,
|
||||
"length": 10,
|
||||
"name": "event_edit_time",
|
||||
"type": "INT",
|
||||
"unsigned": false,
|
||||
@@ -1044,7 +1044,7 @@
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 4,
|
||||
"length": 1,
|
||||
"name": "event_append_edit",
|
||||
"type": "TINYINT",
|
||||
"unsigned": false,
|
||||
@@ -1062,6 +1062,42 @@
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_author_name": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 255,
|
||||
"name": "event_author_name",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_is_anon": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 10,
|
||||
"name": "event_is_anon",
|
||||
"type": "INT",
|
||||
"unsigned": true,
|
||||
"values": []
|
||||
},
|
||||
"event_external_url": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 255,
|
||||
"name": "event_external_url",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_latitude": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
@@ -1086,33 +1122,45 @@
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_author_name": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 255,
|
||||
"name": "event_author_name",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_is_anon": {
|
||||
"event_online": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 10,
|
||||
"name": "event_is_anon",
|
||||
"type": "INT",
|
||||
"length": 3,
|
||||
"name": "event_online",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
"values": []
|
||||
},
|
||||
"event_online": {
|
||||
"name": "event_online",
|
||||
"type": "TINYINT",
|
||||
"event_url": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 250,
|
||||
"name": "event_url",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_online_type": {
|
||||
"allow_null": true,
|
||||
"auto_increment": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": null,
|
||||
"length": 250,
|
||||
"name": "event_online_type",
|
||||
"type": "VARCHAR",
|
||||
"unsigned": false,
|
||||
"values": []
|
||||
},
|
||||
"event_livetopic_id": {
|
||||
"name": "event_livetopic_id",
|
||||
"type": "INT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
@@ -1121,30 +1169,6 @@
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"auto_increment": false
|
||||
},
|
||||
"event_url": {
|
||||
"name": "event_url",
|
||||
"type": "VARCHAR",
|
||||
"length": 250,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"auto_increment": false
|
||||
},
|
||||
"event_online_type": {
|
||||
"name": "event_online_type",
|
||||
"type": "VARCHAR",
|
||||
"length": 250,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
"allow_null": true,
|
||||
"default": null,
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"auto_increment": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
|
||||
@@ -340,7 +340,7 @@
|
||||
</ul>
|
||||
</form>
|
||||
</div>]]></template>
|
||||
<template template_group="events" template_name="event" template_data="$event, $size='normal'" template_location="front" template_app="calendar"><![CDATA[
|
||||
<template template_group="events" template_name="event" template_data="$event, $size='normal', $date=NULL" template_location="front" template_app="calendar"><![CDATA[{{$date = $date ?: \IPS\calendar\Date::getDate();}}
|
||||
{{$sameDay = FALSE;}}
|
||||
{{if $event->_end_date}}
|
||||
{{$sameDay = !( ($event->_start_date->mday != $event->_end_date->mday) or ($event->_start_date->mon != $event->_end_date->mon) or ($event->_start_date->year != $event->_end_date->year) );}}
|
||||
@@ -364,8 +364,8 @@
|
||||
</a>
|
||||
<div class='cEvent__dateAside'>
|
||||
{{if $event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )}}
|
||||
<span class='cEvent__dateAside__month'>{lang="_date_month_short" pluralize="$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->format( 'n' )"}</span>
|
||||
<span class='cEvent__dateAside__day'>{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->format( 'd' )}</span>
|
||||
<span class='cEvent__dateAside__month'>{lang="_date_month_short" pluralize="$event->nextOccurrence( $date, 'startDate' )->format( 'n' )"}</span>
|
||||
<span class='cEvent__dateAside__day'>{$event->nextOccurrence( $date, 'startDate' )->format( 'd' )}</span>
|
||||
{{else}}
|
||||
<span class='cEvent__dateAside__month'>{lang="_date_month_short" pluralize="$event->lastOccurrence( 'startDate' )->format( 'n' )"}</span>
|
||||
<span class='cEvent__dateAside__day'>{$event->lastOccurrence( 'startDate' )->format('d')}</span>
|
||||
@@ -431,9 +431,9 @@
|
||||
" data-ipsTooltip>{$event->_happening}</span>
|
||||
{{else}}
|
||||
<time datetime='{expression="$event->_start_date->format( 'Y-m-d' )"}'>
|
||||
{{if $event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )}}
|
||||
<span data-controller="core.global.core.datetime" data-time="{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->format('c')}" data-format="{expression="\IPS\calendar\Date::calendarDateFormat()"}{{if !$event->all_day}}, {{endif}}">
|
||||
{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->calendarDate()}{{if !$event->all_day}}, {{endif}}
|
||||
{{if $event->nextOccurrence( $date, 'startDate' )}}
|
||||
<span data-controller="core.global.core.datetime" data-time="{$event->nextOccurrence( $date, 'startDate' )->format('c')}" data-format="{expression="\IPS\calendar\Date::calendarDateFormat()"}{{if !$event->all_day}}, {{endif}}">
|
||||
{$event->nextOccurrence( $date, 'startDate' )->calendarDate()}{{if !$event->all_day}}, {{endif}}
|
||||
</span>
|
||||
{{if !$event->all_day}}
|
||||
<span data-controller="core.global.core.datetime" data-time="{$event->nextOccurrence( \IPS\calendar\Date::getDate(), 'startDate' )->format('c')}" data-format="{expression="\IPS\calendar\Date::localeTimeFormat( FALSE )"}">
|
||||
@@ -537,7 +537,7 @@
|
||||
|
||||
<div data-item="{$idx + 1}" class='cFeaturedEvents__event cFeaturedEvents__event--{$idx + 1}'>
|
||||
{{if $image}}
|
||||
<img class='cFeaturedEvents__image' src='{backgroundimage="$image->url"}' alt=''>
|
||||
<img class='cFeaturedEvents__image' src='{$image->url}' alt=''>
|
||||
{{endif}}
|
||||
|
||||
<div class='cFeaturedEvents__event-details'>
|
||||
@@ -714,9 +714,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
{{if $mapMarkers and $mapMarkers !== '[]'}}
|
||||
<div class='cEvents__searchMap cEvents__searchMap--loading event ipsAreaBackground ipsPad ipsSpacer_bottom ipsSpacer_double' data-role='searchResultsMap' {{if $mapMarkers}}data-markers="{$mapMarkers}"{{endif}}></div>
|
||||
{{endif}}
|
||||
<div class='cEvents__searchMap cEvents__searchMap--loading event ipsAreaBackground ipsPad ipsSpacer_bottom ipsSpacer_double' data-role='searchResultsMap' {{if $mapMarkers}}data-markers="{$mapMarkers}"{{endif}}></div>
|
||||
<ul class='eventList {{if !\count( $results )}}ipsHide{{endif}}' data-role='searchResults'>
|
||||
{template="searchResults" app="calendar" group="events" params="$results"}
|
||||
</ul>
|
||||
@@ -1327,8 +1325,7 @@
|
||||
<p class='ipsType_light'>{$reason}</p>
|
||||
</div>
|
||||
{{endif}}]]></template>
|
||||
<template template_group="overview" template_name="byMonth" template_data="$calendars, $date, $featured, $events, $thisCalendar, $months=array()" template_location="front" template_app="calendar"><![CDATA[
|
||||
<section class='ipsBox' data-controller="calendar.front.overview.eventList">
|
||||
<template template_group="overview" template_name="byMonth" template_data="$calendars, $date, $featured, $events, $thisCalendar, $months=array()" template_location="front" template_app="calendar"><![CDATA[<section class='ipsBox' data-controller="calendar.front.overview.eventList">
|
||||
<h2 class='ipsType_sectionTitle'>{lang="events_browse_by_month"}</h2>
|
||||
<div class='ipsPadding ipsAreaBackground_light ipsRadius:bl ipsRadius:br'>
|
||||
<div class='cEvents__monthNav' data-role='monthNav'>
|
||||
@@ -1344,7 +1341,7 @@
|
||||
{{if \count($events) }}
|
||||
<ul class='eventList' data-role='eventList'>
|
||||
{{foreach $events as $event}}
|
||||
{template="event" app="calendar" group="events" params="$event"}
|
||||
{template="event" app="calendar" group="events" params="$event, 'normal', \IPS\calendar\Date::getDate( $date->firstDayOfMonth('year'), $date->firstDayOfMonth('mon'), $date->firstDayOfMonth('mday') )"}
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
<div class='ipsPadding_top ipsType_center'>
|
||||
@@ -1366,12 +1363,36 @@
|
||||
|
||||
<ul class="ipsToolList ipsToolList_horizontal ipsClearfix">
|
||||
<li class="ipsToolList_primaryAction">
|
||||
{{if !\IPS\Settings::i()->club_nodes_in_apps and $theOnlyNode = \IPS\calendar\Calendar::theOnlyNode() }}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href="{url="app=calendar&module=calendar&controller=submit&do=submit&id={$theOnlyNode->_id}" seoTemplate="calendar_submit"}">{lang="create_event"}</a>
|
||||
{{elseif ( $thisCalendar AND $thisCalendar->can('add') )}}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href='{url="app=calendar&module=calendar&controller=submit&do=submit&id={$thisCalendar->_id}" seoTemplate="calendar_submit"}' data-ipsTooltip title='{lang="add_event"}'>{lang="create_event"}</a>
|
||||
{{elseif \IPS\calendar\Calendar::canOnAny('add')}}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href="{url="app=calendar&module=calendar&controller=submit" seoTemplate="calendar_submit"}" data-ipsdialog="" data-ipsdialog-size="narrow" data-ipsdialog-title="{lang="select_calendar"}">{lang="create_event"}</a>
|
||||
{{if \IPS\Application::appIsEnabled('cloud') and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'cloud', 'livetopics' ) ) and \IPS\cloud\LiveTopic::canCreate( \IPS\Member::loggedIn() )}}
|
||||
<a href="#elEventCreate_menu" id="elEventCreate" class="ipsButton ipsButton_medium ipsButton_important" data-ipsMenu>{lang="livetopic_create_event"} <i class="fa fa-caret-down"></i></a>
|
||||
<ul id="elEventCreate_menu" class="ipsMenu ipsMenu_normal ipsHide">
|
||||
<li class="ipsMenu_item" data-menuItem="livetopic">
|
||||
{{if !\IPS\Settings::i()->club_nodes_in_apps and $theOnlyNode = \IPS\calendar\Calendar::theOnlyNode() }}
|
||||
<a class="ipsMenu_link" href="{url="app=calendar&module=calendar&controller=submit&do=livetopic&id={$theOnlyNode->_id}" seoTemplate="calendar_submit"}">{lang="event_create_livetopic"}</a>
|
||||
{{elseif ( $thisCalendar AND $thisCalendar->can('add') )}}
|
||||
<a class="ipsMenu_link" href='{url="app=calendar&module=calendar&controller=submit&do=livetopic&id={$thisCalendar->_id}" seoTemplate="calendar_submit"}' data-ipsTooltip title='{lang="add_event"}'>{lang="event_create_livetopic"}</a>
|
||||
{{elseif \IPS\calendar\Calendar::canOnAny('add')}}
|
||||
<a class="ipsMenu_link" href="{url="app=calendar&module=calendar&controller=submit&do=livetopic" seoTemplate="calendar_submit"}">{lang="event_create_livetopic"}</a>
|
||||
{{endif}}
|
||||
</li>
|
||||
<li class="ipsMenu_item" data-menuItem="event">
|
||||
{{if !\IPS\Settings::i()->club_nodes_in_apps and $theOnlyNode = \IPS\calendar\Calendar::theOnlyNode() }}
|
||||
<a class="ipsMenu_link" href="{url="app=calendar&module=calendar&controller=submit&do=submit&id={$theOnlyNode->_id}" seoTemplate="calendar_submit"}">{lang="event_create_normal"}</a>
|
||||
{{elseif ( $thisCalendar AND $thisCalendar->can('add') )}}
|
||||
<a class="ipsMenu_link" href='{url="app=calendar&module=calendar&controller=submit&do=submit&id={$thisCalendar->_id}" seoTemplate="calendar_submit"}' data-ipsTooltip title='{lang="add_event"}'>{lang="event_create_normal"}</a>
|
||||
{{elseif \IPS\calendar\Calendar::canOnAny('add')}}
|
||||
<a class="ipsMenu_link" href="{url="app=calendar&module=calendar&controller=submit" seoTemplate="calendar_submit"}" data-ipsdialog="" data-ipsdialog-size="narrow" data-ipsdialog-title="{lang="select_calendar"}">{lang="event_create_normal"}</a>
|
||||
{{endif}}
|
||||
</li>
|
||||
</ul>
|
||||
{{else}}
|
||||
{{if !\IPS\Settings::i()->club_nodes_in_apps and $theOnlyNode = \IPS\calendar\Calendar::theOnlyNode() }}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href="{url="app=calendar&module=calendar&controller=submit&do=submit&id={$theOnlyNode->_id}" seoTemplate="calendar_submit"}">{lang="create_event"}</a>
|
||||
{{elseif ( $thisCalendar AND $thisCalendar->can('add') )}}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href='{url="app=calendar&module=calendar&controller=submit&do=submit&id={$thisCalendar->_id}" seoTemplate="calendar_submit"}' data-ipsTooltip title='{lang="add_event"}'>{lang="create_event"}</a>
|
||||
{{elseif \IPS\calendar\Calendar::canOnAny('add')}}
|
||||
<a class="ipsButton ipsButton_medium ipsButton_important" href="{url="app=calendar&module=calendar&controller=submit" seoTemplate="calendar_submit"}" data-ipsdialog="" data-ipsdialog-size="narrow" data-ipsdialog-title="{lang="select_calendar"}">{lang="create_event"}</a>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</li>
|
||||
<li>
|
||||
@@ -1723,6 +1744,10 @@
|
||||
|
||||
{template="pageHeader" group="global" app="core" params="$pageHeader"}
|
||||
|
||||
{{if isset( \IPS\Request::i()->do ) and \IPS\Request::i()->do === 'livetopic'}}
|
||||
<div class="ipsMargin_top ipsMargin_bottom">{lang="ai_service_livetopics_desc"}</div>
|
||||
{{endif}}
|
||||
|
||||
{$output|raw}]]></template>
|
||||
<template template_group="venue" template_name="upcomingStream" template_data="$date, $events, $venue" template_location="front" template_app="calendar"><![CDATA[
|
||||
<div class='ipsPager cCalendarNav ipsSpacer_bottom lg:ipsPos_sticky'>
|
||||
@@ -2168,6 +2193,11 @@
|
||||
</div>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
{{if $livetopic = $event->_livetopic_id}}
|
||||
<div class='ipsBox ipsResponsive_pull ipsMargin_bottom ipsPadding'>
|
||||
<a href='{$livetopic->url()}' target='_blank' class='ipsButton ipsButton_important ipsButton_fullWidth ipsMargin_bottom:half'>{lang="open_event"} <i class="fa fa-external-link" aria-hidden="true" style='margin-inline:.4em'></i></a>
|
||||
</div>
|
||||
{{endif}}
|
||||
|
||||
{{if $event->rsvp }}
|
||||
<div class='ipsBox ipsResponsive_pull'>
|
||||
@@ -2483,7 +2513,7 @@
|
||||
{{endif}}
|
||||
</div>]]></template>
|
||||
<template template_group="view" template_name="rsvpControls" template_data="$event, $attendees" template_location="front" template_app="calendar"><![CDATA[<!-- Don't use IDs here, this template is called twice in view -->
|
||||
{{if \IPS\Member::loggedIn()->member_id AND ( isset( $attendees[0][ \IPS\Member::loggedIn()->member_id ] ) OR isset( $attendees[1][ \IPS\Member::loggedIn()->member_id ] ) OR isset( $attendees[2][ \IPS\Member::loggedIn()->member_id ] ) )}}
|
||||
{{if \IPS\Member::loggedIn()->member_id AND ( isset( $attendees[0][ \IPS\Member::loggedIn()->member_id ] ) OR isset( $attendees[1][ \IPS\Member::loggedIn()->member_id ] ) OR ( isset( $attendees[2][ \IPS\Member::loggedIn()->member_id ] ) ) AND \count( $attendees[1] ) < $event->rsvp_limit )}}
|
||||
<div class='{{if isset( $attendees[1][ \IPS\Member::loggedIn()->member_id ] )}}ipsAreaBackground_positive{{elseif isset( $attendees[0][ \IPS\Member::loggedIn()->member_id ] )}}ipsAreaBackground_negative{{else}}ipsAreaBackground_reset{{endif}} ipsPadding'>
|
||||
<p class='ipsType_large ipsType_center ipsType_reset'>
|
||||
<strong>
|
||||
@@ -2592,7 +2622,7 @@
|
||||
|
||||
{template="contentItemMessages" group="global" app="core" params="$event->getMessages(), $event"}
|
||||
<div id="sidebarWrapper">
|
||||
{{if $event->rsvp || $address || $event->map( 270, 270 ) || $event->online }}
|
||||
{{if $event->rsvp || $address || $event->map( 270, 270 ) || $event->online || $event->_livetopic_id }}
|
||||
<div class='ipsColumns ipsColumns_collapsePhone'>
|
||||
<div class='ipsColumn ipsColumn_fluid'>
|
||||
{{endif}}
|
||||
@@ -2608,7 +2638,7 @@
|
||||
{{endif}}
|
||||
</div>
|
||||
<div class='ipsFlex-flex:01 ipsResponsive_hidePhone'>
|
||||
<div class='ipsFlex ipsFlex-ai:center ipsFlex-fw:wrap ipsGap:2'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if \count( $event->shareLinks() )}}
|
||||
{template="shareButton" app="core" group="sharelinks" params="$event"}
|
||||
{{endif}}
|
||||
@@ -2715,7 +2745,7 @@
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{if $event->rsvp || $address || $event->map( 270, 270 ) || ( $event->online and $event->url and !$event->hasPassed() ) }}
|
||||
{{if $event->rsvp || $address || $event->map( 270, 270 ) || ( $event->online and $event->url and !$event->hasPassed() ) || $event->_livetopic_id}}
|
||||
</div>
|
||||
<aside class='ipsColumn ipsColumn_veryWide'>
|
||||
<div>
|
||||
@@ -2728,23 +2758,15 @@
|
||||
</section>
|
||||
|
||||
<div class='ipsBox ipsPadding ipsResponsive_pull ipsResponsive_showPhone ipsMargin_top'>
|
||||
<div class='ipsGap_row:3'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if \count( $event->shareLinks() )}}
|
||||
<div>
|
||||
{template="shareButton" app="core" group="sharelinks" params="$event, 'verySmall', 'light'"}
|
||||
</div>
|
||||
{template="shareButton" app="core" group="sharelinks" params="$event, 'verySmall', 'light'"}
|
||||
{{endif}}
|
||||
{{if $event->canRemind()}}
|
||||
<div>
|
||||
{template="reminder" app="calendar" group="view" params="$event, $reminder, 'ipsButton_fullWidth'"}
|
||||
</div>
|
||||
{template="reminder" app="calendar" group="view" params="$event, $reminder, 'ipsButton_fullWidth'"}
|
||||
{{endif}}
|
||||
<div>
|
||||
{template="follow" app="core" group="global" params="'calendar', 'event', $event->id, $event->followersCount()"}
|
||||
</div>
|
||||
<div>
|
||||
{template="promote" app="core" group="global" params="$event"}
|
||||
</div>
|
||||
{template="follow" app="core" group="global" params="'calendar', 'event', $event->id, $event->followersCount()"}
|
||||
{template="promote" app="core" group="global" params="$event"}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -2766,27 +2788,25 @@
|
||||
<template template_group="widgets" template_name="recentReviews" template_data="$reviews, $orientation='vertical'" template_location="front" template_app="calendar"><![CDATA[<h3 class='ipsType_reset ipsWidget_title'>{lang="block_recentReviews"}</h3>
|
||||
<div class='ipsWidget_inner'>
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsPad_half'>
|
||||
{{if !empty( $reviews ) }}
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $reviews as $review}}
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_icon'>
|
||||
{template="userPhoto" app="core" group="global" params="$review->author(), 'tiny'"}
|
||||
</div>
|
||||
<div class='ipsDataItem_main ipsType_break ipsContained'>
|
||||
<a href="{$review->item()->url( "getPrefComment" )}" title='{lang="view_this_event" sprintf="$review->item()->title"}' class='ipsTruncate ipsTruncate_line'>{$review->item()->title}</a><br>
|
||||
<span class='ipsType_light ipsType_medium'>{lang="byline_nodate" htmlsprintf="$review->author()->link()"}</span><br>
|
||||
{template="rating" group="global" location="front" app="core" params="'small', $review->rating, \IPS\Settings::i()->reviews_rating_out_of"}
|
||||
<span class='ipsType_small ipsType_reset'><time datetime="{$review->mapped('date')}">{datetime="$review->mapped('date')" norelative="true"}</time></span>
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<div class='ipsType_light ipsPad_half ipsType_center'>{lang="no_recent_reviews"}</div>
|
||||
{{endif}}
|
||||
</div>
|
||||
{{if !empty( $reviews ) }}
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $reviews as $review}}
|
||||
<li class='ipsDataItem'>
|
||||
<div class='ipsDataItem_icon'>
|
||||
{template="userPhoto" app="core" group="global" params="$review->author(), 'tiny'"}
|
||||
</div>
|
||||
<div class='ipsDataItem_main ipsType_break ipsContained'>
|
||||
<a href="{$review->item()->url( "getPrefComment" )}" title='{lang="view_this_event" sprintf="$review->item()->title"}' class='ipsTruncate ipsTruncate_line'>{$review->item()->title}</a><br>
|
||||
<span class='ipsType_light ipsType_medium'>{lang="byline_nodate" htmlsprintf="$review->author()->link()"}</span><br>
|
||||
{template="rating" group="global" location="front" app="core" params="'small', $review->rating, \IPS\Settings::i()->reviews_rating_out_of"}
|
||||
<span class='ipsType_small ipsType_reset'><time datetime="{$review->mapped('date')}">{datetime="$review->mapped('date')" norelative="true"}</time></span>
|
||||
</div>
|
||||
</li>
|
||||
{{endforeach}}
|
||||
</ul>
|
||||
{{else}}
|
||||
<div class='ipsType_light ipsPadding:half ipsType_center'>{lang="no_recent_reviews"}</div>
|
||||
{{endif}}
|
||||
{{else}}
|
||||
{{if !empty( $reviews ) }}
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
@@ -2813,10 +2833,6 @@
|
||||
<template template_group="widgets" template_name="upcomingEvents" template_data="$events, $today, $orientation='vertical'" template_location="front" template_app="calendar"><![CDATA[<h3 class='ipsType_reset ipsWidget_title'>{lang="block_upcomingEvents"}</h3>
|
||||
<div class='ipsWidget_inner'>
|
||||
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsPad_half'>
|
||||
{{endif}}
|
||||
|
||||
{{if !empty( $events ) }}
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
|
||||
@@ -2889,10 +2905,6 @@
|
||||
<div class='ipsType_light ipsPad_half ipsType_center'>{lang="no_upcoming_events"}</div>
|
||||
{{endif}}
|
||||
|
||||
{{if $orientation == 'vertical'}}
|
||||
</div>
|
||||
{{endif}}
|
||||
|
||||
</div>]]></template>
|
||||
<css css_location="front" css_app="calendar" css_attributes="" css_path="." css_name="calendar_responsive.css"><![CDATA[/* BOTH */
|
||||
@media screen and (max-width: 979px) {
|
||||
|
||||
@@ -507,5 +507,19 @@
|
||||
"107504": "4.7.5",
|
||||
"107505": "4.7.5",
|
||||
"107600": "4.7.6 Beta 1",
|
||||
"107601": "4.7.6"
|
||||
"107601": "4.7.6",
|
||||
"107602": "4.7.6",
|
||||
"107620": "4.7.7 Beta 1",
|
||||
"107621": "4.7.7 Beta 2",
|
||||
"107622": "4.7.7 Beta 2",
|
||||
"107623": "4.7.7 Beta 3",
|
||||
"107624": "4.7.7 Beta 4",
|
||||
"107625": "4.7.7",
|
||||
"107626": "4.7.7",
|
||||
"107627": "4.7.7",
|
||||
"107628": "4.7.7",
|
||||
"107640": "4.7.8 Beta 1",
|
||||
"107641": "4.7.8 Beta 2",
|
||||
"107642": "4.7.8 Beta 3",
|
||||
"107643": "4.7.8"
|
||||
}
|
||||
@@ -369,6 +369,18 @@ class _event extends \IPS\Content\Controller
|
||||
*/
|
||||
protected function edit()
|
||||
{
|
||||
if ( \IPS\Application::appIsEnabled('cloud') and $this->event->livetopic_id )
|
||||
{
|
||||
/* Allow live topic edit form to handle this */
|
||||
try
|
||||
{
|
||||
/* Make sure it's a valid topic */
|
||||
$liveTopic = \IPS\cloud\LiveTopic::load( $this->event->livetopic_id );
|
||||
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=core&module=modcp&controller=modcp&tab=livetopics&action=create&fromEvent=1&id=' . $liveTopic->id, 'front', 'modcp_livetopics' ) );
|
||||
}
|
||||
catch( \Exception ) { }
|
||||
}
|
||||
|
||||
/* Are we blocking changes to past events? */
|
||||
if( $this->event->hasPassed() AND \IPS\Settings::i()->calendar_block_past_changes )
|
||||
{
|
||||
|
||||
@@ -648,7 +648,7 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
/* Build an array of month objects for the nav */
|
||||
$months = new \DatePeriod( (new \DateTime)->setDate( date('Y'), date('m'), 1 ), new \DateInterval( 'P1M' ), 11 );
|
||||
|
||||
$stream = \IPS\Theme::i()->getTemplate( 'overview', 'calendar' )->byMonth( $calendars, $date, $featured, $events, NULL, $months );
|
||||
$stream = \IPS\Theme::i()->getTemplate( 'overview', 'calendar' )->byMonth( $calendars, \IPS\calendar\Date::getDate( $date->firstDayOfMonth('year'), $date->firstDayOfMonth('mon'), $date->firstDayOfMonth('mday') ), $featured, $events, NULL, $months );
|
||||
|
||||
$form = $this->getForm();
|
||||
|
||||
@@ -762,16 +762,14 @@ class _view extends \IPS\Dispatcher\Controller
|
||||
{
|
||||
$having[] = 'distance < 500';
|
||||
}
|
||||
|
||||
if( isset( \IPS\Request::i()->sortBy ) && \IPS\Request::i()->sortBy == 'nearest' )
|
||||
{
|
||||
$sort = 'distance asc';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$sort = 'event_start_date asc';
|
||||
|
||||
if( isset( \IPS\Request::i()->sortBy ) && \IPS\Request::i()->sortBy == 'nearest' && $location )
|
||||
{
|
||||
$sort = 'distance asc';
|
||||
}
|
||||
|
||||
/* Filter? */
|
||||
if( isset( \IPS\Request::i()->show ) && \IPS\Request::i()->show !== 'all' )
|
||||
{
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_appened_edit",
|
||||
"name": "event_append_edit",
|
||||
"type": "TINYINT",
|
||||
"length": 1,
|
||||
"decimals": null,
|
||||
@@ -128,7 +128,7 @@
|
||||
"method": "changeColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
"event_appened_edit",
|
||||
"event_append_edit",
|
||||
{
|
||||
"name": "event_append_edit",
|
||||
"type": "TINYINT",
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107602,
|
||||
"name": "4.7.6",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107620,
|
||||
"name": "4.7.7 Beta 1",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": true,
|
||||
"theme": true,
|
||||
"themeSettings": false,
|
||||
"javascript": true,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": true,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"orders": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"global\/\/dev\/js\/\/library\/"
|
||||
],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"normal": {
|
||||
"added": [
|
||||
"emailstats__notification_event_reminder"
|
||||
],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"js": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"html": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"front\/events\/event",
|
||||
"front\/overview\/byMonth"
|
||||
],
|
||||
"removed": []
|
||||
},
|
||||
"css": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"resources": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107621,
|
||||
"name": "4.7.7 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107622,
|
||||
"name": "4.7.7 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107623,
|
||||
"name": "4.7.7 Beta 3",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107624,
|
||||
"name": "4.7.7 Beta 4",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107625,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107626,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107627,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107628,
|
||||
"name": "4.7.7",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107640,
|
||||
"name": "4.7.8 Beta 1",
|
||||
"steps": {
|
||||
"queries": true,
|
||||
"lang": false,
|
||||
"theme": true,
|
||||
"themeSettings": false,
|
||||
"javascript": true,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"files": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"calendar\/front\/controllers\/overview\/ips.overview.search.js"
|
||||
],
|
||||
"removed": []
|
||||
},
|
||||
"orders": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"1": {
|
||||
"method": "addColumn",
|
||||
"params": [
|
||||
"calendar_events",
|
||||
{
|
||||
"name": "event_livetopic_id",
|
||||
"type": "INT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
"allow_null": false,
|
||||
"default": 0,
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"auto_increment": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"html": {
|
||||
"added": [],
|
||||
"edited": [
|
||||
"front\/events\/featuredEvent",
|
||||
"front\/events\/searchResultsWrapper",
|
||||
"front\/overview\/header",
|
||||
"front\/submit\/submitPage",
|
||||
"front\/view\/eventSidebar",
|
||||
"front\/view\/rsvpControls",
|
||||
"front\/view\/view",
|
||||
"front\/widgets\/recentReviews",
|
||||
"front\/widgets\/upcomingEvents"
|
||||
],
|
||||
"removed": []
|
||||
},
|
||||
"css": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
},
|
||||
"resources": {
|
||||
"added": [],
|
||||
"edited": [],
|
||||
"removed": []
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107641,
|
||||
"name": "4.7.8 Beta 2",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107642,
|
||||
"name": "4.7.8 Beta 3",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"id": 107643,
|
||||
"name": "4.7.8",
|
||||
"steps": {
|
||||
"queries": false,
|
||||
"lang": false,
|
||||
"theme": false,
|
||||
"themeSettings": false,
|
||||
"javascript": false,
|
||||
"emailTemplates": false,
|
||||
"hooks": false,
|
||||
"acpSearchKeywords": false,
|
||||
"settings": false,
|
||||
"tasks": false,
|
||||
"modules": false,
|
||||
"widgets": false,
|
||||
"customOptions": false,
|
||||
"customRoutines": false
|
||||
},
|
||||
"forceMainUpgrader": false,
|
||||
"forceManualDownloadNoCiC": false,
|
||||
"forceManualDownloadCiC": false
|
||||
}
|
||||
@@ -332,7 +332,7 @@ class _Calendar extends \IPS\Node\Model implements \IPS\Node\Permissions
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'cal_allow_reviews', $this->id ? $this->allow_reviews : FALSE, FALSE, array( 'togglesOn' => array( 'cal_review_moderate' ) ) ) );
|
||||
if( $club->type == 'closed' )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'club_node_public', $this->id ? $this->isPublic() : FALSE ) );
|
||||
$form->add( new \IPS\Helpers\Form\Radio( 'club_node_public', $this->id ? $this->isPublic() : 0, TRUE, array( 'options' => array( '0' => 'club_node_public_no', '1' => 'club_node_public_view', '2' => 'club_node_public_participate' ) ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -334,7 +334,13 @@ class _Date extends \IPS\DateTime
|
||||
public function adjust( $adjustment )
|
||||
{
|
||||
$datetime = \IPS\DateTime::ts( $this->dateInformation[0] )->setTimezone( new \DateTimeZone( "UTC" ) );
|
||||
$datetime->add( \DateInterval::createFromDateString( $adjustment ) );
|
||||
$dateInterval=\DateInterval::createFromDateString( $adjustment );
|
||||
|
||||
if( $dateInterval )
|
||||
{
|
||||
$datetime->add( $dateInterval );
|
||||
}
|
||||
|
||||
|
||||
return static::getDate( gmdate( 'Y', $datetime->getTimestamp() ), gmdate( 'm', $datetime->getTimestamp() ), gmdate( 'd', $datetime->getTimestamp() ), gmdate( 'H', $datetime->getTimestamp() ), gmdate( 'i', $datetime->getTimestamp() ), gmdate( 's', $datetime->getTimestamp() ) );
|
||||
}
|
||||
|
||||
@@ -81,11 +81,6 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'calendar-events';
|
||||
|
||||
/**
|
||||
* @brief Whether to track the sentiment scores in cloud_sentiment_scores for this content
|
||||
*/
|
||||
public $trackSentimentScore = true;
|
||||
|
||||
/**
|
||||
* Get URL for doing stuff
|
||||
|
||||
@@ -472,7 +472,7 @@ class _Event extends \IPS\Content\Item implements
|
||||
$results[] = array( 'startDate' => $date, 'endDate' => $eDate );
|
||||
}
|
||||
|
||||
/* Figure out which of teh days is next. For example, if the start date is a Wednesday, and the
|
||||
/* Figure out which of the days is next. For example, if the start date is a Wednesday, and the
|
||||
event repeats every Monday and Friday, we need to start with Friday (not Monday) because that's
|
||||
when the first occurance is */
|
||||
$nextTimes = array();
|
||||
@@ -1053,6 +1053,28 @@ class _Event extends \IPS\Content\Item implements
|
||||
|
||||
return $this->dateObjects['end'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the live topic, or NULL if one not available
|
||||
*
|
||||
* @return \IPS\cloud\LiveTopic|null
|
||||
*/
|
||||
public function get__livetopic_id(): ?\IPS\cloud\LiveTopic
|
||||
{
|
||||
if ( ! \IPS\Application::appIsEnabled('cloud') )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
return \IPS\cloud\LiveTopic::load( $this->livetopic_id );
|
||||
}
|
||||
catch( \Exception )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a string with the event date/times in the timezone of the user who created the event
|
||||
@@ -2304,8 +2326,11 @@ class _Event extends \IPS\Content\Item implements
|
||||
public function hasPassed()
|
||||
{
|
||||
// Get the end date. If none is available use the start date plus an hour so that online event join links show for a short while after the start
|
||||
$lastOccurrence = $this->lastOccurrence( 'endDate' ) ?? $this->lastOccurrence( 'startDate' )->add( new \DateInterval("PT1H") );
|
||||
if ( $lastOccurrence < \IPS\DateTime::ts( time() ) )
|
||||
$lastOccurrence = $this->lastOccurrence( 'endDate' ) ?? $this->lastOccurrence( 'startDate' );
|
||||
|
||||
$lastOccurrenceClone = clone $lastOccurrence;
|
||||
$lastOccurrenceClone = $lastOccurrenceClone->add( new \DateInterval("PT1H") );
|
||||
if ( $lastOccurrenceClone < \IPS\DateTime::ts( time() ) )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -85,11 +85,6 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
|
||||
* @brief [Content] Key for hide reasons
|
||||
*/
|
||||
public static $hideLogKey = 'calendar-events-rev';
|
||||
|
||||
/**
|
||||
* @brief Whether to track the sentiment scores in cloud_sentiment_scores for this content
|
||||
*/
|
||||
public $trackSentimentScore = true;
|
||||
|
||||
/**
|
||||
* Get URL for doing stuff
|
||||
|
||||
@@ -48,7 +48,7 @@ spl_autoload_register( function( $class )
|
||||
public static \$databaseColumnMap = array(
|
||||
'author' => 'member_id',
|
||||
'container' => 'category_id',
|
||||
'date' => 'record_publish_date',
|
||||
'date' => 'record_saved',
|
||||
'is_future_entry' => 'record_future_date',
|
||||
'future_date' => 'record_publish_date',
|
||||
'title' => 'field_{$titleField}',
|
||||
@@ -76,6 +76,7 @@ spl_autoload_register( function( $class )
|
||||
'meta_data' => 'record_meta_data',
|
||||
'author_name' => 'record_author_name',
|
||||
'is_anon' => 'record_is_anon',
|
||||
'last_comment_anon' => 'record_last_comment_anon'
|
||||
);
|
||||
public static \$pagePath;
|
||||
}
|
||||
|
||||
@@ -71,6 +71,7 @@ class _records extends \IPS\Content\Api\ItemController
|
||||
*
|
||||
* @note For requests using an OAuth Access Token for a particular member, only records the authorized user can view will be included
|
||||
* @param int $database Database ID
|
||||
* @apiparam string ids Comma-delimited list of record IDs
|
||||
* @apiparam string categories Comma-delimited list of category IDs
|
||||
* @apiparam string authors Comma-delimited list of member IDs - if provided, only records started by those members are returned
|
||||
* @apiparam int locked If 1, only records which are locked are returned, if 0 only unlocked
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
</span>
|
||||
</h2>
|
||||
<p class='ipsType_light ipsType_reset cmsInformation'>
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->record_publish_date"}
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->mapped( 'date' )"}
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
@@ -221,7 +221,7 @@
|
||||
{{endif}}
|
||||
</h2>
|
||||
<p class='ipsType_light ipsType_reset cmsInformation'>
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->record_publish_date"}
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->mapped( 'date' )"}
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
@@ -406,7 +406,7 @@
|
||||
</span>
|
||||
</h2>
|
||||
<p class='ipsType_light ipsType_reset'>
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->record_publish_date"}
|
||||
{lang="cms_byline" htmlsprintf="$record->author()->link( NULL, NULL, $record->isAnonymous() ), $record->container()->url(), $record->container()->_title"}{datetime="$record->mapped( 'date' )"}
|
||||
</p>
|
||||
</div>
|
||||
</header>
|
||||
@@ -536,7 +536,11 @@
|
||||
{{if $lastPost}}
|
||||
<li>{template="userPhoto" app="core" group="global" params="$lastPost['author'], 'tiny'"}</li>
|
||||
<li><div class='ipsType_break ipsContained'><a href="{$lastPost['record_url']}" class='ipsTruncate ipsTruncate_line' title='{$lastPost['record_title']}'>{$lastPost['record_title']}</a></div></li>
|
||||
<li class='ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$lastPost['author']->link()"}</li>
|
||||
{{if $category->last_poster_anon}}
|
||||
<li class='ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$lastPost['author']->link( NULL, NULL, TRUE )"}</li>
|
||||
{{else}}
|
||||
<li class='ipsType_blendLinks'>{lang="byline_nodate" htmlsprintf="$lastPost['author']->link()"}</li>
|
||||
{{endif}}
|
||||
<li data-short="1 dy" class="ipsType_light"><a href='{$lastPost['record_url']->setQueryString( 'do', 'getLastComment' )}' title='{lang="get_last_post"}' class='ipsType_blendLinks'>{datetime="$lastPost['date']"}</a></li>
|
||||
{{else}}
|
||||
<li class='ipsType_light ipsResponsive_showDesktop'>{lang="content_categories_index_no_records" sprintf="\IPS\cms\Databases::load( $category->database_id )->recordWord()"}</li>
|
||||
@@ -936,7 +940,7 @@
|
||||
{{endif}}
|
||||
</p>
|
||||
<ul class='ipsList_inline'>
|
||||
<li>{datetime="$record->record_publish_date"}</li>
|
||||
<li>{datetime="$record->mapped( 'date' )"}</li>
|
||||
{{foreach $record->customFieldsForDisplay('display_top') as $fieldId => $fieldValue}}
|
||||
{{if $fieldValue}}
|
||||
{$fieldValue|raw}
|
||||
@@ -947,7 +951,7 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class='ipsFlex-flex:00 ipsResponsive_hidePhone'>
|
||||
<div class='ipsFlex ipsFlex-ai:center ipsGap:3 ipsGap_row:0'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if !$record->container()->disable_sharelinks}}
|
||||
{template="shareButton" app="core" group="sharelinks" params="$record"}
|
||||
{{endif}}
|
||||
@@ -1081,19 +1085,15 @@
|
||||
</article>
|
||||
|
||||
<div class='ipsBox ipsPadding ipsResponsive_pull ipsResponsive_showPhone ipsMargin_top'>
|
||||
{{if !$record->container()->disable_sharelinks}}
|
||||
<div class='ipsResponsive_noFloat ipsResponsive_block ipsMargin_bottom:half'>
|
||||
<div class='ipsShareLinks'>
|
||||
{{if !$record->container()->disable_sharelinks}}
|
||||
{template="shareButton" app="core" group="sharelinks" params="$record, 'verySmall', 'light'"}
|
||||
</div>
|
||||
{{endif}}
|
||||
<div class='ipsResponsive_noFloat ipsResponsive_block'>
|
||||
{{endif}}
|
||||
{template="follow" app="core" group="global" params="'cms', 'records'.$record::$customDatabaseId, $record->primary_id_field, $record->followersCount()"}
|
||||
</div>
|
||||
{{if $record->canPromoteToSocialMedia() and ( $record instanceof \IPS\Content or $record instanceof \IPS\Node\Model )}}
|
||||
<div class='ipsResponsive_noFloat ipsResponsive_block ipsMargin_top:half'>
|
||||
{{if $record->canPromoteToSocialMedia() and ( $record instanceof \IPS\Content or $record instanceof \IPS\Node\Model )}}
|
||||
{template="promote" app="core" group="global" params="$record"}
|
||||
</div>
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='ipsPager ipsSpacer_top'>
|
||||
@@ -2032,7 +2032,7 @@
|
||||
</div>
|
||||
{{endif}}
|
||||
<div class='ipsDataItem_meta ipsType_reset ipsType_light ipsType_blendLinks'>
|
||||
<span>{lang="byline" htmlsprintf="$row->author()->link( $row->warningRef(), NULL, $row->isAnonymous() )"}{datetime="$row->_publishDate"}</span>
|
||||
<span>{lang="byline" htmlsprintf="$row->author()->link( $row->warningRef(), NULL, $row->isAnonymous() )"}{datetime="$row->mapped( 'date' )"}</span>
|
||||
{{if \count( $row->tags() )}}
|
||||
|
||||
{template="tags" group="global" app="core" params="$row->tags(), true"}
|
||||
@@ -2090,13 +2090,13 @@
|
||||
{{if $row->record_edit_time > 0}}
|
||||
{lang="cms_row_updated_by" htmlsprintf="\IPS\Member::load( $row->record_edit_member_id )->link()"}
|
||||
{{else}}
|
||||
{lang="cms_row_added_by" htmlsprintf="$row->author()->link()"}
|
||||
{lang="cms_row_added_by" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() )"}
|
||||
{{endif}}
|
||||
{{else}}
|
||||
{{if $row->record_edit_time > 0}}
|
||||
{lang="cms_row_updated_by" htmlsprintf="$row->lastCommenter()->link()"}
|
||||
{{else}}
|
||||
{lang="cms_row_added_by" htmlsprintf="$row->author()->link()"}
|
||||
{lang="cms_row_added_by" htmlsprintf="$row->author()->link( NULL, NULL, $row->isAnonymous() )"}
|
||||
{{endif}}
|
||||
{{endif}}
|
||||
</li>
|
||||
|
||||
@@ -777,6 +777,22 @@
|
||||
"unsigned": true,
|
||||
"values": [
|
||||
|
||||
],
|
||||
"zerofill": false
|
||||
},
|
||||
"record_last_comment_anon": {
|
||||
"allow_null": false,
|
||||
"auto_increment": false,
|
||||
"binary": false,
|
||||
"comment": "",
|
||||
"decimals": null,
|
||||
"default": "0",
|
||||
"length": 1,
|
||||
"name": "record_last_comment_anon",
|
||||
"type": "TINYINT",
|
||||
"unsigned": true,
|
||||
"values": [
|
||||
|
||||
],
|
||||
"zerofill": false
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<javascript app="cms">
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/blocks" javascript_name="ips.blocks.form.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/blocks" javascript_name="ips.blocks.form.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -76,7 +76,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/databases" javascript_name="ips.databases.download.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100">/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/databases" javascript_name="ips.databases.download.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -121,7 +121,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/databases" javascript_name="ips.databases.form.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/databases" javascript_name="ips.databases.form.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -197,7 +197,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/external" javascript_name="ips.external.communication.js" javascript_type="controller" javascript_version="107601" javascript_position="1000050"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/external" javascript_name="ips.external.communication.js" javascript_type="controller" javascript_version="107643" javascript_position="1000050"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -332,7 +332,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/fields" javascript_name="ips.fields.form.js" javascript_type="controller" javascript_version="107601" javascript_position="1000150">/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/fields" javascript_name="ips.fields.form.js" javascript_type="controller" javascript_version="107643" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -369,7 +369,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/media" javascript_name="ips.media.main.js" javascript_type="controller" javascript_version="107601" javascript_position="1000200"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/media" javascript_name="ips.media.main.js" javascript_type="controller" javascript_version="107643" javascript_position="1000200"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1009,7 +1009,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/pages" javascript_name="ips.pages.embed.js" javascript_type="controller" javascript_version="107601" javascript_position="1000250"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/pages" javascript_name="ips.pages.embed.js" javascript_type="controller" javascript_version="107643" javascript_position="1000250"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1055,7 +1055,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/pages" javascript_name="ips.pages.form.js" javascript_type="controller" javascript_version="107601" javascript_position="1000250"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/pages" javascript_name="ips.pages.form.js" javascript_type="controller" javascript_version="107643" javascript_position="1000250"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1177,7 +1177,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/records" javascript_name="ips.records.form.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/records" javascript_name="ips.records.form.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1289,7 +1289,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/records" javascript_name="ips.records.revisions.js" javascript_type="controller" javascript_version="107601" javascript_position="1000100">/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="controllers/records" javascript_name="ips.records.revisions.js" javascript_type="controller" javascript_version="107643" javascript_position="1000100">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1344,7 +1344,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.addForm.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300">/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.addForm.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1394,7 +1394,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.conflict.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300">/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.conflict.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -1466,7 +1466,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.fileEditor.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.fileEditor.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2422,7 +2422,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.fileList.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.fileList.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2765,7 +2765,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.main.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.main.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2934,7 +2934,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.variablesDialog.js" javascript_type="controller" javascript_version="107601" javascript_position="1000300">/**
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="controllers/templates" javascript_name="ips.templates.variablesDialog.js" javascript_type="controller" javascript_version="107643" javascript_position="1000300">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -2979,7 +2979,7 @@
|
||||
}
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.builder.area.js" javascript_type="mixins" javascript_version="107601" javascript_position="1000150"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.builder.area.js" javascript_type="mixins" javascript_version="107643" javascript_position="1000150"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -3049,7 +3049,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.builder.block.js" javascript_type="mixins" javascript_version="107601" javascript_position="1000150"><![CDATA[/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.builder.block.js" javascript_type="mixins" javascript_version="107643" javascript_position="1000150"><![CDATA[/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -3157,7 +3157,7 @@
|
||||
|
||||
});
|
||||
}(jQuery, _));]]></file>
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.comment.js" javascript_type="mixins" javascript_version="107601" javascript_position="1000150">/**
|
||||
<file javascript_app="cms" javascript_location="front" javascript_path="mixins" javascript_name="ips.cms.comment.js" javascript_type="mixins" javascript_version="107643" javascript_position="1000150">/**
|
||||
* Invision Community
|
||||
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
|
||||
*
|
||||
@@ -3184,7 +3184,7 @@
|
||||
});
|
||||
});
|
||||
}(jQuery, _));</file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.media.js" javascript_type="template" javascript_version="107601" javascript_position="1000300"><![CDATA[ips.templates.set( 'templates.media.grid', "\
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.media.js" javascript_type="template" javascript_version="107643" javascript_position="1000300"><![CDATA[ips.templates.set( 'templates.media.grid', "\
|
||||
<ul class='ipsGrid' data-ipsGrid data-ipsGrid-minItemSize='100' data-ipsGrid-maxItemSize='200'>\
|
||||
{{{contents}}}\
|
||||
</ul>\
|
||||
@@ -3201,7 +3201,7 @@ ips.templates.set( 'templates.media.noSearchResults', "\
|
||||
{{#lang}}mediaNoResults{{/lang}}\
|
||||
</div>\
|
||||
");]]></file>
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.templates.js" javascript_type="template" javascript_version="107601" javascript_position="1000300"><![CDATA[/* TEMPLATE EDITOR TEMPLATES */
|
||||
<file javascript_app="cms" javascript_location="admin" javascript_path="templates" javascript_name="ips.templates.templates.js" javascript_type="template" javascript_version="107643" javascript_position="1000300"><![CDATA[/* TEMPLATE EDITOR TEMPLATES */
|
||||
/* TEMPLATECEPTION */
|
||||
ips.templates.set('templates.editor.newTab', " \
|
||||
<li data-fileid='{{fileid}}' data-location='{{location}}'>\
|
||||
@@ -3250,7 +3250,6 @@ controllers</order>
|
||||
<order app="global" path="/dev/js//library/">underscore
|
||||
jquery
|
||||
mustache
|
||||
jstz
|
||||
IntersectionObserver
|
||||
Debug.js
|
||||
app.js</order>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<language>
|
||||
<app key="cms" version="107601">
|
||||
<app key="cms" version="107643">
|
||||
<word key="__app_cms" js="0">Pages</word>
|
||||
<word key="menutab__cms" js="0">Pages</word>
|
||||
<word key="menutab__cms_icon" js="0">files-o</word>
|
||||
@@ -285,6 +285,9 @@
|
||||
<word key="page_folder_id" js="0">Page Folder</word>
|
||||
<word key="page_meta_keywords" js="0">Meta Keywords</word>
|
||||
<word key="page_meta_description" js="0">Meta Description</word>
|
||||
<word key="page_meta_index" js="0">Index</word>
|
||||
<word key="page_meta_index_desc" js="0">Allow Search Engines to index this page.</word>
|
||||
<word key="page_meta_index_desc_disabled" js="0">The page is not visible to guests, so it cannot be indexed.</word>
|
||||
<word key="page_show_sidebar" js="0">Show the suite sidebar on this page</word>
|
||||
<word key="page_type" js="0">Content Editor</word>
|
||||
<word key="page_type_builder" js="0">Page Builder</word>
|
||||
|
||||
@@ -1683,6 +1683,18 @@
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"auto_increment": false
|
||||
},
|
||||
"category_last_poster_anon": {
|
||||
"name": "category_last_poster_anon",
|
||||
"type": "TINYINT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
"allow_null": true,
|
||||
"default": "0",
|
||||
"comment": "",
|
||||
"unsigned": true,
|
||||
"auto_increment": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
@@ -2939,6 +2951,18 @@
|
||||
"unsigned": true,
|
||||
"values": [],
|
||||
"zerofill": false
|
||||
},
|
||||
"page_meta_index": {
|
||||
"name": "page_meta_index",
|
||||
"type": "TINYINT",
|
||||
"length": null,
|
||||
"decimals": null,
|
||||
"values": null,
|
||||
"allow_null": false,
|
||||
"default": "1",
|
||||
"comment": "",
|
||||
"unsigned": false,
|
||||
"auto_increment": false
|
||||
}
|
||||
},
|
||||
"indexes": {
|
||||
|
||||
@@ -1191,7 +1191,7 @@
|
||||
<template template_group="widgets" template_name="RecordFeed" template_data="$records, $title, $orientation='vertical'" template_location="front" template_app="cms"><![CDATA[{{if !empty( $records ) }}
|
||||
<h3 class='ipsWidget_title ipsType_reset'>{$title}</h3>
|
||||
{{if $orientation == 'vertical'}}
|
||||
<div class='ipsPad_half ipsWidget_inner'>
|
||||
<div class='ipsWidget_inner'>
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing ipsContained_container'>
|
||||
{{foreach $records as $record}}
|
||||
<li class='ipsDataItem {{if $record->hidden()}} ipsModerated{{endif}}'>
|
||||
@@ -1241,7 +1241,7 @@
|
||||
{{endif}}]]></template>
|
||||
<template template_group="widgets" template_name="Rss" template_data="$items, $title, $orientation='vertical'" template_location="front" template_app="cms"><![CDATA[{{if !empty( $items ) }}
|
||||
<h3 class='ipsWidget_title ipsType_reset'>{$title}</h3>
|
||||
<div class='ipsPad_half ipsWidget_inner'>
|
||||
<div class='ipsWidget_inner'>
|
||||
<ul class='ipsDataList ipsDataList_reducedSpacing'>
|
||||
{{foreach $items as $item}}
|
||||
<li class='ipsDataItem'>
|
||||
|
||||
@@ -543,5 +543,19 @@
|
||||
"107504": "4.7.5",
|
||||
"107505": "4.7.5",
|
||||
"107600": "4.7.6 Beta 1",
|
||||
"107601": "4.7.6"
|
||||
"107601": "4.7.6",
|
||||
"107602": "4.7.6",
|
||||
"107620": "4.7.7 Beta 1",
|
||||
"107621": "4.7.7 Beta 2",
|
||||
"107622": "4.7.7 Beta 2",
|
||||
"107623": "4.7.7 Beta 3",
|
||||
"107624": "4.7.7 Beta 4",
|
||||
"107625": "4.7.7",
|
||||
"107626": "4.7.7",
|
||||
"107627": "4.7.7",
|
||||
"107628": "4.7.7",
|
||||
"107640": "4.7.8 Beta 1",
|
||||
"107641": "4.7.8 Beta 2",
|
||||
"107642": "4.7.8 Beta 3",
|
||||
"107643": "4.7.8"
|
||||
}
|
||||
@@ -122,7 +122,7 @@ class _Databases
|
||||
}
|
||||
|
||||
/* And however many for the content items */
|
||||
$count = ceil( max( (int) $class::getItemsWithPermission( $class::sitemapWhere(), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE ), \IPS\Settings::i()->sitemap_databases_count ) / \IPS\Sitemap::MAX_PER_FILE );
|
||||
$count = ceil( max( (int) $class::getItemsWithPermission( $class::sitemapWhere(), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE ), \IPS\Settings::i()->sitemap_databases_count ) / \IPS\SITEMAP_MAX_PER_FILE );
|
||||
for( $i=1; $i <= $count; $i++ )
|
||||
{
|
||||
$files[] = $database->id . '_sitemap_database_records_' . $i;
|
||||
@@ -193,8 +193,8 @@ class _Databases
|
||||
$exploded = explode( '_', $filename );
|
||||
$block = (int) array_pop( $exploded );
|
||||
|
||||
$offset = ( $block - 1 ) * \IPS\Sitemap::MAX_PER_FILE;
|
||||
$limit = \IPS\Sitemap::MAX_PER_FILE;
|
||||
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
|
||||
$limit = \IPS\SITEMAP_MAX_PER_FILE;
|
||||
|
||||
$totalLimit = \IPS\Settings::i()->sitemap_databases_count;
|
||||
if ( $totalLimit > -1 and ( $offset + $limit ) > $totalLimit )
|
||||
|
||||
@@ -84,12 +84,13 @@ class _Pages
|
||||
$permissionCheck = 'view';
|
||||
|
||||
$where = array( array( '(' . \IPS\Db::i()->findInSet( 'perm_' . $class::$permissionMap[ $permissionCheck ], $member->groups ) . ' OR ' . 'perm_' . $class::$permissionMap[ $permissionCheck ] . '=? )', '*' ) );
|
||||
$where[] = [ 'page_meta_index=?', 1 ];
|
||||
|
||||
$count = \IPS\Db::i()->select( '*', $class::$databaseTable, $where )
|
||||
->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $class::$databaseTable . "." . $class::$databasePrefix . $class::$databaseColumnId, $class::$permApp, $class::$permType ) )
|
||||
->count();
|
||||
|
||||
$count = ceil( max( $count, \IPS\Settings::i()->sitemap_pages_count ) / \IPS\Sitemap::MAX_PER_FILE );
|
||||
$count = ceil( max( $count, \IPS\Settings::i()->sitemap_pages_count ) / \IPS\SITEMAP_MAX_PER_FILE );
|
||||
|
||||
for( $i=1; $i <= $count; $i++ )
|
||||
{
|
||||
@@ -123,8 +124,8 @@ class _Pages
|
||||
$exploded = explode( '_', $filename );
|
||||
$block = (int) array_pop( $exploded );
|
||||
|
||||
$offset = ( $block - 1 ) * \IPS\Sitemap::MAX_PER_FILE;
|
||||
$limit = \IPS\Sitemap::MAX_PER_FILE;
|
||||
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
|
||||
$limit = \IPS\SITEMAP_MAX_PER_FILE;
|
||||
|
||||
$totalLimit = \IPS\Settings::i()->sitemap_pages_count;
|
||||
if ( $totalLimit > -1 and ( $offset + $limit ) > $totalLimit )
|
||||
@@ -140,8 +141,8 @@ class _Pages
|
||||
}
|
||||
|
||||
$where = array( array( '(' . \IPS\Db::i()->findInSet( 'perm_' . $class::$permissionMap[ $permissionCheck ], $member->groups ) . ' OR ' . 'perm_' . $class::$permissionMap[ $permissionCheck ] . '=? )', '*' ) );
|
||||
|
||||
$direction = ( $totalLimit > \IPS\Sitemap::MAX_PER_FILE ) ? ' ASC' : ' DESC';
|
||||
$where[] = [ 'page_meta_index=?', 1 ];
|
||||
$direction = ( $totalLimit > \IPS\SITEMAP_MAX_PER_FILE ) ? ' ASC' : ' DESC';
|
||||
$select = \IPS\Db::i()->select( '*', $class::$databaseTable, $where, 'page_id' . $direction, array( $offset, $limit ) )
|
||||
->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=" . $class::$databaseTable . "." . $class::$databasePrefix . $class::$databaseColumnId, $class::$permApp, $class::$permType ) );
|
||||
|
||||
|
||||
@@ -362,23 +362,26 @@ FILE;
|
||||
*/
|
||||
protected function _afterSave( ?\IPS\Node\Model $old, \IPS\Node\Model $new, $lastUsedTab = FALSE )
|
||||
{
|
||||
/* If this page was the default in a folder, and it was moved to a new folder that already has a default, we need to unset the
|
||||
default page flag or there will be two defaults in the destination folder */
|
||||
if( $old !== NULL AND $old->folder_id != $new->folder_id AND $old->default )
|
||||
/* Is there a default page in the folder? */
|
||||
try
|
||||
{
|
||||
/* Is there already a default page in the new folder? */
|
||||
try
|
||||
{
|
||||
$existingDefault = \IPS\Db::i()->select( 'page_id', 'cms_pages', array( 'page_folder_id=? and page_default=?', $new->folder_id, 1 ) )->first();
|
||||
$existingDefault = \IPS\Db::i()->select( 'page_id', 'cms_pages', array( 'page_folder_id=? and page_default=? and page_id <> ?', $new->folder_id, 1, $new->id ) )->first();
|
||||
|
||||
/* If this page was the default in a folder, and it was moved to a new folder that already has a default, we need to unset the
|
||||
default page flag or there will be two defaults in the destination folder */
|
||||
if( $old !== NULL AND $old->folder_id != $new->folder_id AND $old->default )
|
||||
{
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_default' => 0 ), array( 'page_id=?', $new->id ) );
|
||||
|
||||
\IPS\cms\Pages\Page::buildPageUrlStore();
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* No default found in destination folder, do nothing */
|
||||
}
|
||||
}
|
||||
catch( \UnderflowException $e )
|
||||
{
|
||||
/* No default found in destination folder, make this the default */
|
||||
\IPS\Db::i()->update( 'cms_pages', array( 'page_default' => 1 ), array( 'page_id=?', $new->id ) );
|
||||
|
||||
\IPS\cms\Pages\Page::buildPageUrlStore();
|
||||
}
|
||||
|
||||
/* If page filename changes or the folder ID changes, we need to clear front navigation cache*/
|
||||
|
||||
@@ -276,6 +276,11 @@ class _category extends \IPS\cms\Databases\Controller
|
||||
$table->hover = TRUE;
|
||||
$table->sortBy = ( isset( \IPS\Request::i()->sortby ) ) ? \IPS\Request::i()->sortby : ( $database->field_sort ? $RecordsClass::$databaseTable . '.' . $RecordsClass::$databasePrefix . $database->field_sort : 'record_last_comment' );
|
||||
$table->sortDirection = ( isset( \IPS\Request::i()->sortdirection ) ) ? \IPS\Request::i()->sortdirection : ( $database->field_direction ? $database->field_direction : 'desc' );
|
||||
if ( $database->field_sort )
|
||||
{
|
||||
$table->defaultSortBy = $RecordsClass::$databasePrefix . $database->field_sort;
|
||||
$table->defaultSortDirection = $database->field_direction;
|
||||
}
|
||||
$table->limit = $database->field_perpage ? $database->field_perpage : 25;
|
||||
$table->title = \IPS\Member::loggedIn()->language()->addToStack( $database->use_categories ? 'x_records_in_this_category' : 'x_records' , FALSE, array( 'sprintf' => array( $category->_items, $database->recordWord( $category->_items ) ) ) );
|
||||
|
||||
|
||||
Loaded 100 of 688 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user