Version 5.0.0 beta 1

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

No files matched your search

@@ -12,16 +12,20 @@
namespace IPS\gallery\extensions\core\AdvertisementLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\AdvertisementLocationsAbstract;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Advertisement locations extension
*/
class _ImageLightbox
class ImageLightbox extends AdvertisementLocationsAbstract
{
/**
* Get the locations and the additional settings
@@ -29,7 +33,7 @@ class _ImageLightbox
* @param array $settings Current setting values
* @return array Array with two elements: 'locations' which should have keys as the location keys and values as the fields to toggle, and 'settings' which are additional fields to add to the form
*/
public function getSettings( $settings )
public function getSettings( array $settings ): array
{
return array( 'locations' => array( 'ad_image_lightbox' => array() ), 'settings' => array() );
}
@@ -40,7 +44,7 @@ class _ImageLightbox
* @param array $values Values from the form submission
* @return array Array of setting key => value to store
*/
public function parseSettings( $values )
public function parseSettings( array $values ): array
{
return array();
}
@@ -12,87 +12,98 @@
namespace IPS\gallery\extensions\core\ContentRouter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\Extensions\ContentRouterAbstract;
use IPS\gallery\Album\Item;
use IPS\gallery\Application;
use IPS\gallery\Image;
use IPS\gallery\Image\Table;
use IPS\Helpers\Table\Content;
use IPS\Http\Url;
use IPS\Member;
use IPS\Member\Group;
use IPS\Output;
use IPS\Request;
use IPS\Theme;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content Router extension: Gallery
*/
class _Gallery
class Gallery extends ContentRouterAbstract
{
/**
* @brief Content Item Classes
*/
public $classes = array();
/**
* @brief Item Classes for embed only
*/
public $embeddableContent = array( 'IPS\gallery\Album\Item' );
public array $embeddableContent = array( 'IPS\gallery\Album\Item' );
/**
* @brief Can be shown in similar content
*/
public $similarContent = TRUE;
public bool $similarContent = TRUE;
/**
* Constructor
*
* @param \IPS\Member|IPS\Member\Group|NULL $member If checking access, the member/group to check for, or NULL to not check access
* @return void
* @param Member|Group|null $member If checking access, the member/group to check for, or NULL to not check access
*/
public function __construct( $member = NULL )
public function __construct( Member|Group $member = NULL )
{
if ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'gallery', 'gallery', 'front' ) ) )
if ( $member === NULL or $member->canAccessModule( Module::get( 'gallery', 'gallery', 'front' ) ) )
{
$this->classes[] = 'IPS\gallery\Image';
$this->classes[] = 'IPS\gallery\Album\Item';
$this->classes[] = Image::class;
$this->classes[] = Item::class;
}
}
/**
* @brief Owned Node Classes
*/
public $ownedNodes = array( 'IPS\gallery\Album' );
public array $ownedNodes = array( 'IPS\gallery\Album' );
/**
* Use a custom table helper when building content item tables
*
* @param string $className The content item class
* @param \IPS\Http\Url $url The URL to use for the table
* @param array $where Custom where clause to pass to the table helper
* @return \IPS\Helpers\Table|void Custom table helper class to use
* @param string $className The content item class
* @param Url $url The URL to use for the table
* @param array $where Custom where clause to pass to the table helper
* @return Table|null Custom table helper class to use
*/
public function customTableHelper( $className, $url, $where=array() )
public function customTableHelper( string $className, Url $url, array $where=array() ): ?Content
{
if( !\in_array( $className, $this->classes ) or $className == 'IPS\gallery\Album\Item' )
if( !in_array( $className, $this->classes ) or $className == 'IPS\gallery\Album\Item' )
{
return new \IPS\Helpers\Table\Content( $className, $url, $where );
return new Content( $className, $url, $where );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_browse.js', 'gallery' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js('front_global.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_browse.js', 'gallery' ) );
Output::i()->jsFiles = array_merge( Output::i()->jsFiles, Output::i()->js('front_global.js', 'gallery' ) );
\IPS\gallery\Application::outputCss();
Application::outputCss();
$table = new \IPS\gallery\Image\Table( $className, $url, $where, NULL, FALSE );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'imageTable' );
$table = new Table( $className, $url, $where, NULL, FALSE );
$table->tableTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'imageTable' );
/* Get rows template */
if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'large' AND \IPS\Request::i()->controller != 'search' )
if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'large' AND Request::i()->controller != 'search' )
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsLarge' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsLarge' );
}
else if( isset( \IPS\Request::i()->cookie['thumbnailSize'] ) AND \IPS\Request::i()->cookie['thumbnailSize'] == 'rows' AND \IPS\Request::i()->controller != 'search' )
else if( isset( Request::i()->cookie['thumbnailSize'] ) AND Request::i()->cookie['thumbnailSize'] == 'rows' AND Request::i()->controller != 'search' )
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsRows' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsRows' );
}
else
{
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsThumbs' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'tableRowsThumbs' );
}
return $table;
@@ -1,52 +0,0 @@
<?php
/**
* @brief Create Menu Extension : gallery
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 04 Mar 2014
*/
namespace IPS\gallery\extensions\core\CreateMenu;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Create Menu Extension: gallery
*/
class _gallery
{
/**
* Get Items
*
* @return array
*/
public function getItems()
{
if ( \IPS\gallery\Category::canOnAny( 'add', NULL, \IPS\Settings::i()->club_nodes_in_apps ? array() : array( array( 'category_club_id IS NULL' ) ) ) )
{
return array(
'gallery_image' => array(
'link' => \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=submit&_new=1", 'front', 'gallery_submit' ),
'extraData' => array(
'data-ipsDialog-size' => "medium",
'data-ipsDialog' => 'true',
'data-ipsDialog-destructOnClose' => 'true',
'data-ipsDialog-close' => 'false',
'data-ipsDialog-extraClass' => 'cGalleryDialog_outer',
'data-ipsDialog-remoteSubmit' => 'true',
)
)
);
}
return array();
}
}
Whitespace-only changes.
@@ -12,23 +12,31 @@
namespace IPS\gallery\extensions\core\Dashboard;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\Extensions\DashboardAbstract;
use IPS\gallery\Image;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Dashboard extension: Overview
*/
class _Overview
class Overview extends DashboardAbstract
{
/**
* Can the current user view this dashboard item?
*
* @return bool
*/
public function canView()
public function canView(): bool
{
return TRUE;
}
@@ -38,26 +46,26 @@ class _Overview
*
* @return string
*/
public function getBlock()
public function getBlock(): string
{
/* Basic stats */
$data = array(
'total_disk_spaceg' => (int) \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first(),
'total_images' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first(),
'total_views' => (int) \IPS\Db::i()->select( 'SUM(image_views)', 'gallery_images' )->first(),
'total_comments' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_comments' )->first(),
'total_albums' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first(),
'total_disk_spaceg' => (int) Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first(),
'total_images' => (int) Db::i()->select( 'COUNT(*)', 'gallery_images' )->first(),
'total_views' => (int) Db::i()->select( 'SUM(image_views)', 'gallery_images' )->first(),
'total_comments' => (int) Db::i()->select( 'COUNT(*)', 'gallery_comments' )->first(),
'total_albums' => (int) Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first(),
);
/* Specific files (will fail if no files yet) */
try
{
$data['largest_image'] = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_file_size DESC', 1 )->first() );
$data['most_viewed_image'] = \IPS\gallery\Image::constructFromData( \IPS\Db::i()->select( '*', 'gallery_images', NULL, 'image_views DESC', 1 )->first() );
$data['largest_image'] = Image::constructFromData( Db::i()->select( '*', 'gallery_images', NULL, 'image_file_size DESC', 1 )->first() );
$data['most_viewed_image'] = Image::constructFromData( Db::i()->select( '*', 'gallery_images', NULL, 'image_views DESC', 1 )->first() );
}
catch ( \Exception $e ) { }
catch ( Exception ) { }
/* Display */
return \IPS\Theme::i()->getTemplate( 'dashboard', 'gallery' )->overview( $data );
return Theme::i()->getTemplate( 'dashboard', 'gallery' )->overview( $data );
}
}
@@ -12,36 +12,40 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Content;
use IPS\Db;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Album;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use IPS\Text\LegacyParser;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Albums
*/
class _Albums
class Albums extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return FALSE;
}
@@ -49,7 +53,7 @@ class _Albums
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -57,14 +61,14 @@ class _Albums
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$album = \IPS\gallery\Album::load( $id1 );
$album = Album::load( $id1 );
return $album->can( 'view', $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -76,12 +80,12 @@ class _Albums
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
return \IPS\gallery\Album::load( $id1 );
return Album::load( $id1 );
}
/**
@@ -92,19 +96,19 @@ class _Albums
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildContent( $offset, $max )
public function rebuildContent( ?int $offset, ?int $max ): int
{
$did = 0;
foreach( \IPS\Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $offset, $max ) ) as $album )
foreach( Db::i()->select( '*', 'gallery_albums', NULL, 'album_id ASC', array( $offset, $max ) ) as $album )
{
$did++;
try
{
$rebuilt = \IPS\Text\LegacyParser::parseStatic( $album['album_description'] );
$rebuilt = LegacyParser::parseStatic( $album['album_description'] );
}
catch( \InvalidArgumentException $e )
catch( InvalidArgumentException $e )
{
if( $e->getcode() == 103014 )
{
@@ -118,7 +122,7 @@ class _Albums
if( $rebuilt !== FALSE )
{
\IPS\Db::i()->update( 'gallery_albums', array( 'album_description' => $rebuilt ), 'album_id=' . $album['album_id'] );
Db::i()->update( 'gallery_albums', array( 'album_description' => $rebuilt ), 'album_id=' . $album['album_id'] );
}
}
@@ -130,8 +134,8 @@ class _Albums
*
* @return int Total Count
*/
public function contentCount()
public function contentCount(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_albums' )->first();
}
}
@@ -12,36 +12,40 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use InvalidArgumentException;
use IPS\Content;
use IPS\Db;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Category;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use IPS\Text\Parser;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Categories
*/
class _Categories
class Categories extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return NULL;
}
@@ -49,7 +53,7 @@ class _Categories
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -57,14 +61,14 @@ class _Categories
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$category = \IPS\gallery\Category::load( $id1 );
$category = Category::load( $id1 );
return $category->can( 'view', $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -76,25 +80,12 @@ class _Categories
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
return \IPS\gallery\Category::load( $id1 );
}
/**
* Rebuild attachment images in non-content item areas
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildAttachmentImages( $offset, $max )
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
return Category::load( $id1 );
}
/**
@@ -105,16 +96,11 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildContent( $offset, $max )
public function rebuildContent( ?int $offset, ?int $max ): int
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
}
/**
* @brief Use the cached image URL instead of the original URL
*/
protected $proxyUrl = FALSE;
/**
* Rebuild content to add or remove image proxy
*
@@ -124,17 +110,14 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildImageProxy( $offset, $max, $proxyUrl = FALSE )
public function rebuildImageProxy( ?int $offset, ?int $max, bool $proxyUrl = FALSE ): int
{
$this->proxyUrl = $proxyUrl;
return $this->performRebuild( $offset, $max, 'parseImageProxy' );
$callback = function( $value ) use ( $proxyUrl ) {
return Parser::removeImageProxy( $value, $proxyUrl );
};
return $this->performRebuild( $offset, $max, $callback );
}
/**
* @brief Store lazy loading status ( true = enabled )
*/
protected $_lazyLoadStatus = null;
/**
* Rebuild content to add or remove lazy loading
*
@@ -144,11 +127,9 @@ class _Categories
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildLazyLoad( $offset, $max, $status=TRUE )
public function rebuildLazyLoad( ?int $offset, ?int $max ): int
{
$this->_lazyLoadStatus = $status;
return $this->performRebuild( $offset, $max, 'parseLazyLoad' );
return $this->performRebuild( $offset, $max, [ 'IPS\Text\Parser', 'parseLazyLoad' ] );
}
/**
@@ -159,31 +140,24 @@ class _Categories
* @param callable $callback Method to call to rebuild content
* @return int Number completed
*/
protected function performRebuild( $offset, $max, $callback )
protected function performRebuild( ?int $offset, ?int $max, callable $callback ): int
{
$did = 0;
/* Language bits */
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'", 'word_id ASC', array( $offset, $max ) ) as $word )
foreach( Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'", 'word_id ASC', array( $offset, $max ) ) as $word )
{
$did++;
$rebuilt = FALSE;
try
{
if( $callback == 'parseImageProxy' )
{
$rebuilt = \IPS\Text\Parser::removeImageProxy( $word['word_custom'], $this->proxyUrl );
}
elseif( $callback == 'parseLazyLoad' )
{
$rebuilt = \IPS\Text\Parser::parseLazyLoad( $word['word_custom'], $this->_lazyLoadStatus );
}
else
if( !empty( $word['word_custom'] ) )
{
$rebuilt = $callback( $word['word_custom'] );
}
}
catch( \InvalidArgumentException $e )
catch( InvalidArgumentException $e )
{
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
{
@@ -197,7 +171,7 @@ class _Categories
if( $rebuilt !== FALSE )
{
\IPS\Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
}
}
@@ -209,8 +183,8 @@ class _Categories
*
* @return int Total Count
*/
public function contentCount()
public function contentCount(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'" )->first();
return Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'gallery_album_%_desc' OR word_key LIKE 'gallery_category_%_desc' OR word_key LIKE 'gallery_category_%_permerror' OR word_key LIKE 'gallery_category_%_rules'" )->first();
}
}
@@ -12,25 +12,38 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content;
use IPS\gallery\Album;
use IPS\gallery\Album\Comment;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use LogicException;
use OutOfRangeException;
use RuntimeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Image comments
*/
class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
class Gallery extends Images
{
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return NULL;
}
@@ -38,7 +51,7 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -46,16 +59,16 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
if( $id3 and $id3 == 'album' )
{
try
{
$album = \IPS\gallery\Album::load( $id1 );
$album = Album::load( $id1 );
return $album->canView( $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -70,14 +83,14 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
if( $id3 and $id3 == 'album' )
{
return \IPS\gallery\Album\Comment::load( $id2 );
return Comment::load( $id2 );
}
return parent::attachmentLookup( $id1, $id2, $id3 );
@@ -87,11 +100,11 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
* Can whatever is posted in this editor be moderated?
* If this returns TRUE, we must ensure the content is ran through word, link and image filters
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool
*/
public function canBeModerated( $member, $field )
public function canBeModerated( Member $member, Editor $field ): bool
{
/* Image comments/reviews */
if ( preg_match( '/^(?:editComment|reply|review)\-gallery\/gallery\-\d+/', $field->options['autoSaveKey'] ) )
@@ -103,9 +116,10 @@ class _Gallery extends \IPS\gallery\extensions\core\EditorLocations\Images
{
if ( \IPS\IN_DEV )
{
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
throw new RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
}
return FALSE;
return parent::canBeModerated( $member, $field );
}
}
}
@@ -12,61 +12,47 @@
namespace IPS\gallery\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content;
use IPS\Extensions\EditorLocationsAbstract;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\gallery\Image\Review;
use IPS\Helpers\Form\Editor;
use IPS\Http\Url;
use IPS\Member;
use IPS\Node\Model;
use LogicException;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Images
*/
class _Images
class Images extends EditorLocationsAbstract
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @param Member $member The member
* @param Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
public function canAttach( Member $member, Editor $field ): ?bool
{
return FALSE;
}
/**
* Can whatever is posted in this editor be moderated?
* If this returns TRUE, we must ensure the content is ran through word, link and image filters
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @return bool
*/
public function canBeModerated( $member, $field )
{
if ( \IPS\IN_DEV )
{
throw new \RuntimeException( 'Unknown canBeModerated: ' . $field->options['autoSaveKey'] );
}
return FALSE;
}
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
@@ -74,14 +60,14 @@ class _Images
* @param bool $viewOnly If true, just check if the user can see the attachment rather than download it
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3, $attachment, $viewOnly=FALSE )
public function attachmentPermissionCheck( Member $member, ?int $id1, ?int $id2, ?string $id3, array $attachment, bool $viewOnly=FALSE ): bool
{
try
{
$image = \IPS\gallery\Image::load( $id1 );
$image = Image::load( $id1 );
return $image->canView( $member );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return FALSE;
}
@@ -93,25 +79,25 @@ class _Images
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
* @return Url|Content|Model|Member|null
* @throws LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
public function attachmentLookup( int $id1=NULL, int $id2=NULL, string $id3=NULL ): Model|Content|Url|Member|null
{
if ( $id2 )
{
if ( $id3 === 'review' )
{
return \IPS\gallery\Image\Review::load( $id2 );
return Review::load( $id2 );
}
else
{
return \IPS\gallery\Image\Comment::load( $id2 );
return Comment::load( $id2 );
}
}
else
{
return \IPS\gallery\Image::load( $id1 );
return Image::load( $id1 );
}
}
@@ -12,26 +12,34 @@
namespace IPS\gallery\extensions\core\EditorMedia;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Extensions\EditorMediaAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Media: Images
*/
class _Images
class Images extends EditorMediaAbstract
{
/**
* Get Counts
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param string $postKey The post key
* @param string|null $search The search term (or NULL for all)
* @return array array( 'Title' => 0 )
* @return array|int array( 'Title' => 0 )
*/
public function count( $member, $postKey, $search=NULL )
public function count( Member $member, string $postKey, string $search=NULL ): array|int
{
$where = array(
array( "image_member_id=? AND image_approved=?", $member->member_id, 1 ),
@@ -40,14 +48,14 @@ class _Images
if ( $search )
{
$albumIds = [];
foreach( \IPS\Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
foreach( Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
{
$albumIds[] = $album;
}
if ( count( $albumIds ) )
{
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . \IPS\Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
}
else
{
@@ -55,20 +63,20 @@ class _Images
}
}
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', $where )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_images', $where )->first();
}
/**
* Get Files
*
* @param \IPS\Member $member The member
* @param Member $member The member
* @param string|null $search The search term (or NULL for all)
* @param string $postKey The post key
* @param int $page Page
* @param int $limit Number to get
* @return array array( 'Title' => array( (IPS\File, \IPS\File, ... ), ... )
*/
public function get( $member, $search, $postKey, $page, $limit )
public function get( Member $member, ?string $search, string $postKey, int $page, int $limit ): array
{
$where = array(
array( "image_member_id=? AND image_approved=?", $member->member_id, 1 ),
@@ -77,14 +85,14 @@ class _Images
if ( $search )
{
$albumIds = [];
foreach( \IPS\Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
foreach( Db::i()->select( 'album_id', 'gallery_albums', array( "album_owner_id=? AND album_name LIKE ( CONCAT( '%', ?, '%' ) )", $member->member_id, $search ), NULL, 250 ) as $album )
{
$albumIds[] = $album;
}
if ( count( $albumIds ) )
{
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . \IPS\Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
$where[] = array( "( image_caption LIKE ( CONCAT( '%', ?, '%' ) ) OR ( " . Db::i()->in( 'image_album_id', $albumIds ) . " ) )", $search );
}
else
{
@@ -93,11 +101,11 @@ class _Images
}
$return = array();
foreach ( \IPS\Db::i()->select( '*', 'gallery_images', $where, 'image_date DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
foreach ( Db::i()->select( '*', 'gallery_images', $where, 'image_date DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
{
$image = \IPS\gallery\Image::load( $row['image_id'] );
$image = Image::load( $row['image_id'] );
$fileName = $image->masked_file_name ?: $image->original_file_name;
$obj = \IPS\File::get( 'gallery_Images', $fileName );
$obj = File::get( 'gallery_Images', $fileName );
$obj->contextInfo = $image->caption;
$return[ (string) $image->url() ] = $obj;
}
@@ -12,25 +12,34 @@
namespace IPS\gallery\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Db;
use IPS\Extensions\FileStorageAbstract;
use IPS\File;
use UnderflowException;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File Storage Extension: Images
*/
class _Images
class Images extends FileStorageAbstract
{
/**
* Count stored files
*
* @return int
*/
public function count()
public function count(): int
{
return \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
return Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
}
/**
@@ -39,22 +48,22 @@ class _Images
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @throws Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @return void
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
{
$image = \IPS\Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$image = Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$update = array();
if( $image['image_small_file_name'] )
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_small_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_small_file_name'] )->move( $storageConfiguration );
$update['image_small_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
@@ -70,10 +79,10 @@ class _Images
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_masked_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_masked_file_name'] )->move( $storageConfiguration );
$update['image_masked_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
@@ -90,76 +99,48 @@ class _Images
{
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'gallery_Images', $image['image_original_file_name'] )->move( $storageConfiguration );
$file = File::get( $oldConfiguration ?: 'gallery_Images', $image['image_original_file_name'] )->move( $storageConfiguration );
$update['image_original_file_name'] = (string) $file;
}
catch( \Exception $e )
catch( Exception )
{
/* Any issues are logged */
}
}
}
if ( \count( $update ) )
if ( count( $update ) )
{
foreach( $update as $k => $v )
{
if ( $update[ $k ] == $image[ $k ] )
if ( $v == $image[ $k ] )
{
unset( $update[ $k ] );
}
}
if ( \count( $update ) )
if ( count( $update ) )
{
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
}
}
}
/**
* Fix all URLs
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @return void
*/
public function fixUrls( $offset )
{
$image = \IPS\Db::i()->select( '*', 'gallery_images', array(), 'image_id', array( $offset, 1 ) )->first();
$update = array();
foreach( array( 'image_small_file_name', 'image_masked_file_name', 'image_original_file_name' ) as $key )
{
if( $image[ $key ] )
{
if ( $new = \IPS\File::repairUrl( $image[ $key ] ) )
{
$update[ $key ] = $new;
}
}
}
if ( \count( $update ) )
{
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
}
}
/**
* Check if a file is valid
*
* @param string $file The file path to check
* @param File|string $file The file path to check
* @return bool
*/
public function isValidFile( $file )
public function isValidFile( File|string $file ): bool
{
try
{
$record = \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_masked_file_name=? OR image_original_file_name=? OR image_small_file_name=?', (string) $file, (string) $file, (string) $file ) )->first();
$record = Db::i()->select( '*', 'gallery_images', array( 'image_masked_file_name=? OR image_original_file_name=? OR image_small_file_name=?', (string) $file, (string) $file, (string) $file ) )->first();
return TRUE;
}
catch ( \UnderflowException $e )
catch ( UnderflowException )
{
return FALSE;
}
@@ -170,9 +151,9 @@ class _Images
*
* @return void
*/
public function delete()
public function delete() : void
{
foreach( \IPS\Db::i()->select( '*', 'gallery_images' ) as $image )
foreach( Db::i()->select( '*', 'gallery_images' ) as $image )
{
foreach( array( 'image_masked_file_name', 'image_original_file_name', 'image_small_file_name' ) as $size )
{
@@ -180,9 +161,9 @@ class _Images
{
try
{
\IPS\File::get( 'gallery_Images', $image[ $size ] )->delete();
File::get( 'gallery_Images', $image[ $size ] )->delete();
}
catch( \Exception $e ){}
catch( Exception ){}
}
}
}
@@ -12,64 +12,78 @@
namespace IPS\gallery\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application\Module;
use IPS\core\FrontNavigation;
use IPS\core\FrontNavigation\FrontNavigationAbstract;
use IPS\Dispatcher;
use IPS\Http\Url;
use IPS\Member;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Gallery
*/
class _Gallery extends \IPS\core\FrontNavigation\FrontNavigationAbstract
class Gallery extends FrontNavigationAbstract
{
/**
* @var string Default icon
*/
public string $defaultIcon = '\f87c';
/**
* Get Type Title which will display in the AdminCP Menu Manager
*
* @return string
*/
public static function typeTitle()
public static function typeTitle(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
return Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
}
/**
* Can the currently logged in user access the content this item links to?
*
* @return bool
* @return bool
*/
public function canAccessContent()
public function canAccessContent(): bool
{
return \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'gallery', 'gallery' ) );
return Member::loggedIn()->canAccessModule( Module::get( 'gallery', 'gallery' ) );
}
/**
* Get Title
*
* @return string
* @return string
*/
public function title()
public function title(): string
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
return Member::loggedIn()->language()->addToStack('frontnavigation_gallery');
}
/**
* Get Link
*
* @return \IPS\Http\Url
* @return string|Url|null
*/
public function link()
public function link(): Url|string|null
{
return \IPS\Http\Url::internal( "app=gallery&module=gallery&controller=browse", 'front', 'gallery' );
return Url::internal( "app=gallery&module=gallery&controller=browse", 'front', 'gallery' );
}
/**
* Is Active?
*
* @return bool
* @return bool
*/
public function active()
public function active(): bool
{
return !\IPS\core\FrontNavigation::$clubTabActive and \IPS\Dispatcher::i()->application->directory === 'gallery';
return !FrontNavigation::$clubTabActive and !FrontNavigation::nodeExtensionIsActive( 'gallery' ) and Dispatcher::i()->application->directory === 'gallery';
}
}
@@ -12,83 +12,95 @@
namespace IPS\gallery\extensions\core\GroupForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupFormAbstract;
use IPS\gallery\Image;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Number;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use IPS\Member\Group;
use IPS\Settings;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Group Form
*/
class _Gallery
class Gallery extends GroupFormAbstract
{
/**
* Process Form
*
* @param \IPS\Helpers\Form $form The form
* @param \IPS\Member\Group $group Existing Group
* @param Form $form The form
* @param Group $group Existing Group
* @return void
*/
public function process( &$form, $group )
public function process( Form $form, Group $group ) : void
{
if( $group->g_id != \IPS\Settings::i()->guest_group )
if( $group->g_id != Settings::i()->guest_group )
{
$form->addHeader( 'gallery_album_permissions' );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums', $group->g_create_albums, FALSE, array( 'togglesOn' => array( 'g_create_albums_private', 'g_create_albums_fo', 'g_album_limit', 'g_img_album_limit' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums_private', $group->g_create_albums_private, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_private' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'g_create_albums_fo', $group->g_create_albums_fo, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_fo' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_album_limit', $group->g_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_album_limit' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_img_album_limit', $group->g_img_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_img_album_limit' ) );
$form->add( new YesNo( 'g_create_albums', $group->g_create_albums, FALSE, array( 'togglesOn' => array( 'g_create_albums_private', 'g_create_albums_fo', 'g_album_limit', 'g_img_album_limit' ) ) ) );
$form->add( new YesNo( 'g_create_albums_private', $group->g_create_albums_private, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_private' ) );
$form->add( new YesNo( 'g_create_albums_fo', $group->g_create_albums_fo, FALSE, array(), NULL, NULL, NULL, 'g_create_albums_fo' ) );
$form->add( new Number( 'g_album_limit', $group->g_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_album_limit' ) );
$form->add( new Number( 'g_img_album_limit', $group->g_img_album_limit, FALSE, array( 'unlimited' => 0 ), NULL, NULL, NULL, 'g_img_album_limit' ) );
}
$form->addHeader( 'gallery_restrictions' );
if( \IPS\Settings::i()->gallery_use_watermarks )
if( Settings::i()->gallery_use_watermarks )
{
$form->add( new \IPS\Helpers\Form\Radio( 'g_download_original', $group->g_download_original, FALSE, array( 'options' => array(
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_RAW => 'g_download_raw',
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_WATERMARKED => 'g_download_watermarked',
\IPS\gallery\Image::DOWNLOAD_ORIGINAL_NONE => 'g_download_none'
$form->add( new Radio( 'g_download_original', $group->g_download_original, FALSE, array( 'options' => array(
Image::DOWNLOAD_ORIGINAL_RAW => 'g_download_raw',
Image::DOWNLOAD_ORIGINAL_WATERMARKED => 'g_download_watermarked',
Image::DOWNLOAD_ORIGINAL_NONE => 'g_download_none'
) ) ) );
}
else
{
$form->add( new \IPS\Helpers\Form\YesNo( 'g_download_original', $group->g_download_original, FALSE ) );
$form->add( new YesNo( 'g_download_original', $group->g_download_original, FALSE ) );
}
$form->add( new \IPS\Helpers\Form\YesNo( 'g_movies', $group->g_movies, FALSE, array( 'togglesOn' => array( 'g_movie_size' ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_movie_size', $group->g_movie_size, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb'), 'g_movie_size' ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_upload', $group->g_max_upload, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb') ) );
$form->add( new YesNo( 'g_movies', $group->g_movies, FALSE, array( 'togglesOn' => array( 'g_movie_size' ) ) ) );
$form->add( new Number( 'g_movie_size', $group->g_movie_size, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb'), 'g_movie_size' ) );
$form->add( new Number( 'g_max_upload', $group->g_max_upload, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb') ) );
$form->addMessage( 'gallery_requires_log' );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_transfer', $group->g_max_transfer, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_kb_day') ) );
$form->add( new \IPS\Helpers\Form\Number( 'g_max_views', $group->g_max_views, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('gallery_suffix_day') ) );
$form->add( new Number( 'g_max_transfer', $group->g_max_transfer, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_kb_day') ) );
$form->add( new Number( 'g_max_views', $group->g_max_views, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('gallery_suffix_day') ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member\Group $group The group
* @param Group $group The group
* @return void
*/
public function save( $values, &$group )
public function save( array $values, Group $group ) : void
{
if( $group->g_id != \IPS\Settings::i()->guest_group )
if( $group->g_id != Settings::i()->guest_group )
{
$group->g_create_albums = $values['g_create_albums'];
$group->g_create_albums_private = $values['g_create_albums_private'];
$group->g_create_albums_fo = $values['g_create_albums_fo'];
$group->g_album_limit = $values['g_album_limit'];
$group->g_img_album_limit = $values['g_img_album_limit'];
$group->g_create_albums = (int) $values['g_create_albums'];
$group->g_create_albums_private = (int) $values['g_create_albums_private'];
$group->g_create_albums_fo = (int) $values['g_create_albums_fo'];
$group->g_album_limit = (int) $values['g_album_limit'];
$group->g_img_album_limit = (int) $values['g_img_album_limit'];
}
$group->g_download_original = $values['g_download_original'];
$group->g_movies = $values['g_movies'];
$group->g_movie_size = $values['g_movie_size'];
$group->g_max_upload = $values['g_max_upload'];
$group->g_max_transfer = $values['g_max_transfer'];
$group->g_max_views = $values['g_max_views'];
$group->g_download_original = (int) $values['g_download_original'];
$group->g_movies = (int) $values['g_movies'];
$group->g_movie_size = (int) $values['g_movie_size'];
$group->g_max_upload = (int) $values['g_max_upload'];
$group->g_max_transfer = (int) $values['g_max_transfer'];
$group->g_max_views = (int) $values['g_max_views'];
}
}
@@ -12,9 +12,15 @@
namespace IPS\gallery\extensions\core\GroupLimits;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\GroupLimitsAbstract;
use function count;
use function defined;
use function max;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
@@ -24,14 +30,14 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
* This extension is used to define which limit values "win" when a user has secondary groups defined
*
*/
class _Album
class Album extends GroupLimitsAbstract
{
/**
* Get group limits by priority
*
* @return array
*/
public function getLimits()
public function getLimits(): array
{
return array (
'exclude' => array(),
@@ -65,7 +71,7 @@ class _Album
}
}
return \count( $limits ) ? \max( $limits ) : 0;
return count( $limits ) ? max( $limits ) : 0;
} )
);
}
@@ -12,26 +12,35 @@
namespace IPS\gallery\extensions\core\LiveSearch;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Dispatcher;
use IPS\Extensions\LiveSearchAbstract;
use IPS\gallery\Category;
use IPS\Member;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief ACP Live Search Extension
*/
class _Categories
class Categories extends LiveSearchAbstract
{
/**
* Check we have access
*
* @return bool
*/
public function hasAccess()
public function hasAccess(): bool
{
/* Check Permissions */
return \IPS\Member::loggedIn()->hasAcpRestriction( 'gallery', 'gallery', 'categories_manage' );
return Member::loggedIn()->hasAcpRestriction( 'gallery', 'gallery', 'categories_manage' );
}
/**
@@ -40,7 +49,7 @@ class _Categories
* @param string $searchTerm Search Term
* @return array Array of results
*/
public function getResults( $searchTerm )
public function getResults( string $searchTerm ): array
{
/* Init */
$results = array();
@@ -50,10 +59,10 @@ class _Categories
if( $this->hasAccess() )
{
/* Perform the search */
$categories = \IPS\Db::i()->select(
$categories = Db::i()->select(
"*",
'gallery_categories',
array( "category_club_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, \IPS\Member::loggedIn()->language()->id ),
array( "category_club_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, Member::loggedIn()->language()->id ),
NULL,
NULL
)->join(
@@ -64,9 +73,9 @@ class _Categories
/* Format results */
foreach ( $categories as $category )
{
$category = \IPS\gallery\Category::constructFromData( $category );
$category = Category::constructFromData( $category );
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'gallery', 'admin' )->category( $category );
$results[] = Theme::i()->getTemplate( 'livesearch', 'gallery', 'admin' )->category( $category );
}
}
@@ -78,8 +87,8 @@ class _Categories
*
* @return bool
*/
public function isDefault()
public function isDefault(): bool
{
return \IPS\Dispatcher::i()->application->directory == 'gallery';
return Dispatcher::i()->application->directory == 'gallery';
}
}
@@ -11,60 +11,71 @@
namespace IPS\gallery\extensions\core\MemberACPProfileContentTab;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\MemberACPProfile\Block;
use IPS\Db;
use IPS\Helpers\Chart\Database;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output\Plugin\Filesize;
use IPS\Request;
use IPS\Theme;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Member ACP Profile - Content Statistics Tab: Gallery
*/
class _Gallery extends \IPS\core\MemberACPProfile\Block
class Gallery extends Block
{
/**
* Get output
*
* @return string
*/
public function output()
public function output(): string
{
$imageCount = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$diskspaceUsed = \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$numberOfViews = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$bandwidthUsed = \IPS\Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$imageCount = Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$diskspaceUsed = Db::i()->select( 'SUM(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first();
$numberOfViews = Db::i()->select( 'COUNT(*)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$bandwidthUsed = Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth', array( 'member_id=?', $this->member->member_id ) )->first();
$allImages = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
$totalFilesize = \IPS\Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first();
$allBandwidth = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_bandwidth' )->first();
$totalBandwidth = \IPS\Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth' )->first();
$allImages = Db::i()->select( 'COUNT(*)', 'gallery_images' )->first();
$totalFilesize = Db::i()->select( 'SUM(image_file_size)', 'gallery_images' )->first();
$allBandwidth = Db::i()->select( 'COUNT(*)', 'gallery_bandwidth' )->first();
$totalBandwidth = Db::i()->select( 'SUM(bsize)', 'gallery_bandwidth' )->first();
return \IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->information( $this->member, \IPS\Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
return (string) Theme::i()->getTemplate( 'stats', 'gallery' )->information( $this->member, Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
'images_submitted' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $imageCount ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allImages ? ( 100 / $allImages ) : 0 ) * $imageCount ), 2 ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Member::loggedIn()->language()->formatNumber( $imageCount ),
Member::loggedIn()->language()->formatNumber( ( ( $allImages ? ( 100 / $allImages ) : 0 ) * $imageCount ), 2 ) ) )
),
'gdiskspace_used' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $diskspaceUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalFilesize ? ( 100 / $totalFilesize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Filesize::humanReadableFilesize( $diskspaceUsed ? :0 ),
Member::loggedIn()->language()->formatNumber( ( ( $totalFilesize ? ( 100 / $totalFilesize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
),
'gaverage_filesize' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_average' , FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first() ),
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(image_file_size)', 'gallery_images' )->first() ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_average' , FALSE, array( 'sprintf' => array(
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(image_file_size)', 'gallery_images', array( 'image_member_id=?', $this->member->member_id ) )->first() ? :0),
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(image_file_size)', 'gallery_images' )->first() ) ) ? :0)
),
'number_of_views' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $numberOfViews ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allBandwidth ? ( 100 / $allBandwidth ) : 0 ) * $imageCount ), 2 ) ))
Member::loggedIn()->language()->addToStack( 'images_stat_of_total', FALSE, array( 'sprintf' => array(
Member::loggedIn()->language()->formatNumber( $numberOfViews ),
Member::loggedIn()->language()->formatNumber( ( ( $allBandwidth ? ( 100 / $allBandwidth ) : 0 ) * $imageCount ), 2 ) ))
),
'gallery_bandwidth_used' =>
\IPS\Member::loggedIn()->language()->addToStack( 'images_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $bandwidthUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalBandwidth ? ( 100 / $totalBandwidth ) : 0 ) * $bandwidthUsed ), 2 ),
\IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->bandwidthButton( $this->member ) ) )
Member::loggedIn()->language()->addToStack( 'images_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
Filesize::humanReadableFilesize( $bandwidthUsed ? :0 ),
Member::loggedIn()->language()->formatNumber( ( ( $totalBandwidth ? ( 100 / $totalBandwidth ) : 0 ) * $bandwidthUsed ), 2 ),
Theme::i()->getTemplate( 'stats', 'gallery' )->bandwidthButton( $this->member ) ) )
)
) ) );
}
@@ -74,12 +85,12 @@ class _Gallery extends \IPS\core\MemberACPProfile\Block
*
* @return string
*/
public function edit()
public function edit(): string
{
$bandwidthChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\gallery\\extensions\\core\\MemberACPProfileContentTab\\Gallery&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'gallery_bandwidth', 'bdate', '', array( 'vAxis' => array( 'title' => \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) ) ), 'LineChart', 'daily' );
$bandwidthChart = new Database( Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\gallery\\extensions\\core\\MemberACPProfileContentTab\\Gallery&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'gallery_bandwidth', 'bdate', '', array( 'vAxis' => array( 'title' => Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) ) ), 'LineChart', 'daily' );
$bandwidthChart->groupBy = 'bdate';
$bandwidthChart->where[] = array( 'member_id=?', $this->member->member_id );
$bandwidthChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth_use_gallery'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
return ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $bandwidthChart : \IPS\Theme::i()->getTemplate( 'stats', 'gallery' )->graphs( (string) $bandwidthChart );
$bandwidthChart->addSeries( Member::loggedIn()->language()->addToStack('bandwidth_use_gallery'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
return ( Request::i()->isAjax() and isset( Request::i()->_graph ) ) ? (string) $bandwidthChart : Theme::i()->getTemplate( 'stats', 'gallery' )->graphs( (string) $bandwidthChart );
}
}
@@ -12,40 +12,50 @@
namespace IPS\gallery\extensions\core\MemberFilter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Db\Select;
use IPS\Extensions\MemberFilterAbstract;
use IPS\Helpers\Form\Radio;
use IPS\Member;
use LogicException;
use function defined;
use function in_array;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Filter Extension
*/
class _Album
class Album extends MemberFilterAbstract
{
/**
* Determine if the filter is available in a given area
*
* @param string $area Area to check
* @param string $area Area to check (bulkmail, group_promotions, automatic_moderation)
* @return bool
*/
public function availableIn( $area )
public function availableIn( string $area ): bool
{
return \in_array( $area, array( 'bulkmail', 'group_promotions' ) );
return in_array( $area, array( 'bulkmail', 'group_promotions' ) );
}
/**
* Get Setting Field
*
* @param mixed $criteria Value returned from the save() method
* @param array $criteria Value returned from the save() method
* @return array Array of form elements
*/
public function getSettingField( $criteria )
public function getSettingField( array $criteria ): array
{
$options = array( 'any' => 'any', 'yes' => 'yes', 'no' => 'no' );
return array(
new \IPS\Helpers\Form\Radio( 'mf_has_album', isset( $criteria['has_album'] ) ? $criteria['has_album'] : 'any', FALSE, array( 'options' => $options ) ),
new Radio( 'mf_has_album', $criteria['has_album'] ?? 'any', FALSE, array( 'options' => $options ) ),
);
}
@@ -53,12 +63,12 @@ class _Album
* Save the filter data
*
* @param array $post Form values
* @return mixed False, or an array of data to use later when filtering the members
* @throws \LogicException
* @return array|bool False, or an array of data to use later when filtering the members
* @throws LogicException
*/
public function save( $post )
public function save( array $post ): array|bool
{
if( isset( $post['mf_has_album'] ) and \in_array( $post['mf_has_album'], array( 'yes', 'no' ) ) )
if( isset( $post['mf_has_album'] ) and in_array( $post['mf_has_album'], array( 'yes', 'no' ) ) )
{
return array( 'has_album' => $post['mf_has_album'] );
}
@@ -69,10 +79,10 @@ class _Album
/**
* Get where clause to add to the member retrieval database query
*
* @param mixed $data The array returned from the save() method
* @param array $data The array returned from the save() method
* @return array|NULL Where clause - must be a single array( "clause" )
*/
public function getQueryWhereClause( $data )
public function getQueryWhereClause( array $data ): ?array
{
if( isset( $data['has_album'] ) )
{
@@ -86,29 +96,28 @@ class _Album
* Callback for member retrieval database query
* Can be used to set joins
*
* @param mixed $data The array returned from the save() method
* @param \IPS\Db\Query $query The query
* @param array $data The array returned from the save() method
* @param Select $query The query
* @return void
*/
public function queryCallback( $data, &$query )
public function queryCallback( array $data, Select $query ) : void
{
if( isset( $data['has_album'] ) )
{
$query->join( 'gallery_albums', "core_members.member_id=gallery_albums.album_owner_id" );
}
return NULL;
}
/**
* Determine if a member matches specified filters
*
* @param Member $member
* @param array $filters
* @param object|null $object
* @note This is only necessary if availableIn() includes group_promotions
* @param \IPS\Member $member Member object to check
* @param array $filters Previously defined filters
* @return bool
*/
public function matches( \IPS\Member $member, $filters )
public function matches( Member $member, array $filters, ?object $object = NULL ): bool
{
/* If we aren't filtering by this, then any member matches */
if( !isset( $filters['has_album'] ) OR !$filters['has_album'] )
@@ -116,7 +125,7 @@ class _Album
return TRUE;
}
$result = (bool) \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_owner_id=?', $member->member_id ) )->first();
$result = (bool) Db::i()->select( 'COUNT(*)', 'gallery_albums', array( 'album_owner_id=?', $member->member_id ) )->first();
return ( $filters['has_album'] == 'no' ) ? !$result : $result;
}
@@ -11,27 +11,35 @@
namespace IPS\gallery\extensions\core\MemberRestrictions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\core\MemberACPProfile\Restriction;
use IPS\Helpers\Form;
use IPS\Helpers\Form\YesNo;
use IPS\Member;
use function defined;
use function intval;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Member Restrictions: Gallery
*/
class _Gallery extends \IPS\core\MemberACPProfile\Restriction
class Gallery extends Restriction
{
/**
* Modify Edit Restrictions form
*
* @param \IPS\Helpers\Form $form The form
* @param Form $form The form
* @return void
*/
public function form( \IPS\Helpers\Form $form )
public function form( Form $form ) : void
{
$form->add( new \IPS\Helpers\Form\YesNo( 'remove_gallery_access', !$this->member->members_bitoptions['remove_gallery_access'], FALSE, array( 'togglesOn' => array( 'remove_gallery_upload' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'remove_gallery_upload', !$this->member->members_bitoptions['remove_gallery_upload'], FALSE, array(), NULL, NULL, NULL, 'remove_gallery_upload' ) );
$form->add( new YesNo( 'remove_gallery_access', !$this->member->members_bitoptions['remove_gallery_access'], FALSE, array( 'togglesOn' => array( 'remove_gallery_upload' ) ) ) );
$form->add( new YesNo( 'remove_gallery_upload', !$this->member->members_bitoptions['remove_gallery_upload'], FALSE, array(), NULL, NULL, NULL, 'remove_gallery_upload' ) );
}
/**
@@ -40,7 +48,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
* @param array $values Values from form
* @return array
*/
public function save( $values )
public function save( array $values ): array
{
$return = array();
@@ -64,7 +72,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
*
* @return array
*/
public function activeRestrictions()
public function activeRestrictions(): array
{
$return = array();
@@ -95,7 +103,7 @@ class _Gallery extends \IPS\core\MemberACPProfile\Restriction
{
if ( isset( $changes[ $k ] ) )
{
$return[] = \IPS\Member::loggedIn()->language()->addToStack( 'history_restrictions_' . $k . '_' . \intval( $changes[ $k ]['new'] ) );
$return[] = Member::loggedIn()->language()->addToStack( 'history_restrictions_' . $k . '_' . intval( $changes[ $k ]['new'] ) );
}
}
@@ -1,90 +0,0 @@
<?php
/**
* @brief Member Sync
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 04 Mar 2014
*/
namespace IPS\gallery\extensions\core\MemberSync;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Sync
*/
class _Gallery
{
/**
* Member is merged with another member
*
* @param \IPS\Member $member Member being kept
* @param \IPS\Member $member2 Member being removed
* @return void
*/
public function onMerge( $member, $member2 )
{
\IPS\Db::i()->update( 'gallery_albums', array( 'album_owner_id' => $member->member_id ), array( 'album_owner_id=?', $member2->member_id ) );
\IPS\Db::i()->update( 'gallery_bandwidth', array( 'member_id' => $member->member_id ), array( 'member_id=?', $member2->member_id ) );
\IPS\Db::i()->update( 'gallery_images_uploads', array( 'upload_member_id' => $member->member_id ), array( 'upload_member_id=?', $member2->member_id ) );
foreach( \IPS\gallery\Album::loadByOwner( $member2 ) as $album )
{
$album->owner_id = $member->member_id;
$album->save();
}
}
/**
* Member is deleted
*
* @param $member \IPS\Member The member
* @return void
*/
public function onDelete( $member )
{
\IPS\Db::i()->delete( 'gallery_bandwidth', array( 'member_id=?', $member->member_id ) );
\IPS\Db::i()->delete( 'gallery_images_uploads', array( 'upload_member_id=?', $member->member_id ) );
foreach( \IPS\gallery\Album::loadByOwner( $member ) as $album )
{
//$album->delete();
$album->owner_id = 0;
$album->save();
}
}
/**
* Member is flagged as spammer
*
* @param $member \IPS\Member The member
* @return void
*/
public function onSetAsSpammer( $member )
{
$actions = explode( ',', \IPS\Settings::i()->spm_option );
/* Hide or delete */
if ( \in_array( 'unapprove', $actions ) or \in_array( 'delete', $actions ) )
{
foreach( \IPS\gallery\Album::loadByOwner( $member ) as $album )
{
$album->hidden = -1;
$album->save();
if( \in_array( 'delete', $actions ) )
{
\IPS\Task::queue( 'core', 'DeleteOrMoveContent', array( 'class' => 'IPS\gallery\Album', 'id' => $album->id, 'deleteWhenDone' => TRUE ), 3 );
}
}
}
}
}
Whitespace-only changes.
@@ -12,31 +12,36 @@
namespace IPS\gallery\extensions\core\Permissions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\PermissionsAbstract;
use IPS\gallery\Category;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Permissions
*/
class _Permissions
class Permissions extends PermissionsAbstract
{
/**
* Get node classes
*
* @return array
*/
public function getNodeClasses()
public function getNodeClasses(): array
{
return array(
'IPS\gallery\Category' => function( $current, $group )
{
$rows = array();
foreach( \IPS\gallery\Category::roots( NULL ) AS $root )
foreach( Category::roots( NULL ) AS $root )
{
\IPS\gallery\Category::populatePermissionMatrix( $rows, $root, $group, $current );
Category::populatePermissionMatrix( $rows, $root, $group, $current );
}
return $rows;
@@ -12,33 +12,27 @@
namespace IPS\gallery\extensions\core\Profile;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Db;
use IPS\Extensions\ProfileAbstract;
use IPS\gallery\Album\Table;
use IPS\gallery\Application;
use IPS\Member;
use IPS\Theme;
use function count;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Profile extension: Gallery
*/
class _gallery
class gallery extends ProfileAbstract
{
/**
* Member
*/
protected \IPS\Member $member;
/**
* Constructor
*
* @param \IPS\Member $member Member whose profile we are viewing
* @return void
*/
public function __construct( \IPS\Member $member )
{
$this->member = $member;
}
/**
* Is there content to display?
*
@@ -48,18 +42,18 @@ class _gallery
{
$where = array( array( 'album_owner_id=?', $this->member->member_id ) );
if( \count( \IPS\Member::loggedIn()->socialGroups() ) )
if( count( Member::loggedIn()->socialGroups() ) )
{
$where[] = array( '( album_type=1 OR ( album_type=2 AND album_owner_id=? ) OR ( album_type=3 AND ( album_owner_id=? OR ( album_allowed_access IS NOT NULL AND album_allowed_access IN(' . implode( ',', \IPS\Member::loggedIn()->socialGroups() ) . ') ) ) ) )', \IPS\Member::loggedIn()->member_id, \IPS\Member::loggedIn()->member_id );
$where[] = array( '( album_type=1 OR ( album_type=2 AND album_owner_id=? ) OR ( album_type=3 AND ( album_owner_id=? OR ( album_allowed_access IS NOT NULL AND album_allowed_access IN(' . implode( ',', Member::loggedIn()->socialGroups() ) . ') ) ) ) )', Member::loggedIn()->member_id, Member::loggedIn()->member_id );
}
else
{
$where[] = array( '( album_type=1 OR ( album_type IN (2,3) AND album_owner_id=? ) )', \IPS\Member::loggedIn()->member_id );
$where[] = array( '( album_type=1 OR ( album_type IN (2,3) AND album_owner_id=? ) )', Member::loggedIn()->member_id );
}
$where[] = array( '(' . \IPS\Db::i()->findInSet( 'core_permission_index.perm_view', \IPS\Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_view=? )', '*' );
$where[] = array( '(' . Db::i()->findInSet( 'core_permission_index.perm_view', Member::loggedIn()->groups ) . ' OR ' . 'core_permission_index.perm_view=? )', '*' );
$select = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_albums', $where );
$select = Db::i()->select( 'COUNT(*)', 'gallery_albums', $where );
$select->join( 'gallery_categories', array( "gallery_categories.category_id=gallery_albums.album_category_id" ) );
$select->join( 'core_permission_index', array( "core_permission_index.app=? AND core_permission_index.perm_type=? AND core_permission_index.perm_type_id=gallery_categories.category_id", 'gallery', 'category' ) );
@@ -73,15 +67,15 @@ class _gallery
*/
public function render(): string
{
\IPS\gallery\Application::outputCss();
Application::outputCss();
$table = new \IPS\gallery\Album\Table( $this->member->url()->setQueryString( 'tab', 'node_gallery_gallery') );
$table = new Table( $this->member->url()->setQueryString( 'tab', 'node_gallery_gallery') );
$table->setOwner( $this->member );
$table->limit = 10;
$table->sortBy = 'album_last_img_date';
$table->sortDirection = 'desc';
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'global', 'gallery' ), 'profileAlbumTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
$table->tableTemplate = array( Theme::i()->getTemplate( 'global', 'gallery' ), 'profileAlbumTable' );
$table->rowsTemplate = array( Theme::i()->getTemplate( 'browse', 'gallery' ), 'albums' );
return (string) $table;
}
@@ -12,33 +12,24 @@
namespace IPS\gallery\extensions\core\Profile;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Application;
use IPS\Content\Filter;
use IPS\Extensions\ProfileAbstract;
use IPS\gallery\Image;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Profile extension: galleryImages
*/
class _galleryImages
class galleryImages extends ProfileAbstract
{
/**
* Member
*/
protected \IPS\Member $member;
/**
* Constructor
*
* @param \IPS\Member $member Member whose profile we are viewing
* @return void
*/
public function __construct( \IPS\Member $member )
{
$this->member = $member;
}
/**
* Is there content to display?
*
@@ -46,7 +37,12 @@ class _galleryImages
*/
public function showTab(): bool
{
return TRUE;
$where = [
[ 'image_member_id=?', $this->member->member_id ],
[ 'image_album_id=?', 0 ]
];
$items = Image::getItemsWithPermission( $where, null, 1, 'read', Filter::FILTER_AUTOMATIC, 0, null, false, false,false,true );
return $items > 0;
}
/**
@@ -57,7 +53,7 @@ class _galleryImages
public function render(): string
{
$table ="";
foreach ( \IPS\Application::load( 'gallery' )->extensions( 'core', 'ContentRouter' ) as $ext )
foreach ( Application::load( 'gallery' )->extensions( 'core', 'ContentRouter' ) as $ext )
{
$table = $ext->customTableHelper( 'IPS\gallery\Image', $this->member->url()->setQueryString( 'tab', 'node_gallery_galleryImages'), array( array( 'image_member_id=? and image_album_id=0', $this->member->member_id ) ) );
}
@@ -1,170 +0,0 @@
<?php
/**
* @brief Background Task
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 06 Mar 2018
*/
namespace IPS\gallery\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _CleanUpGalleryImages
{
/**
* Parse data before queuing
*
* @param array $data
* @return array
*/
public function preQueueData( $data )
{
try
{
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
}
catch( \Exception $ex )
{
throw new \OutOfRangeException;
}
if( $data['count'] == 0 )
{
return null;
}
$data['did'] = 0;
return $data;
}
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
{
if ( !\IPS\Application::appIsEnabled( 'gallery' ) )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
$last = NULL;
foreach( \IPS\Db::i()->select( '*', 'gallery_images', array( 'image_media=? AND image_id > ?', 0, (int) $offset ), 'image_id ASC', \IPS\REBUILD_SLOW ) as $image )
{
$data['did']++;
/* Update the sizes array to remove the images we no longer support */
$sizes = json_decode( $image['image_data'], true );
if( isset( $sizes['thumb'] ) )
{
unset( $sizes['thumb'] );
}
if( isset( $sizes['medium'] ) )
{
unset( $sizes['medium'] );
}
$update = array( 'image_data' => json_encode( $sizes ) );
/* If we have a medium but no large image, or a thumb but no small image, adapt as appropriate. Also if one image is mapped for
multiple columns be sure we don't remove it if we still need it. */
$keepMedium = FALSE;
if( $image['image_medium_file_name'] == $image['image_masked_file_name'] )
{
$keepMedium = TRUE;
}
$keepThumb = FALSE;
if( $image['image_thumb_file_name'] == $image['image_masked_file_name'] )
{
$keepThumb = TRUE;
}
if( !$image['image_masked_file_name'] AND $image['image_medium_file_name'] )
{
$image['image_masked_file_name'] = $image['image_medium_file_name'];
$update['image_masked_file_name'] = $image['image_masked_file_name'];
$keepMedium = TRUE;
}
if( !$image['image_small_file_name'] AND $image['image_thumb_file_name'] )
{
$image['image_small_file_name'] = $image['image_thumb_file_name'];
$update['image_small_file_name'] = $image['image_small_file_name'];
$keepThumb = TRUE;
}
\IPS\Db::i()->update( 'gallery_images', $update, array( 'image_id=?', $image['image_id'] ) );
/* Delete the images we don't need now */
if( !$keepMedium AND $image['image_medium_file_name'] )
{
try
{
\IPS\File::get( 'gallery_Images', $image['image_medium_file_name'] )->delete();
}
catch( \Exception $e ) {}
}
if( !$keepThumb AND $image['image_thumb_file_name'] )
{
try
{
\IPS\File::get( 'gallery_Images', $image['image_thumb_file_name'] )->delete();
}
catch( \Exception $e ) {}
}
$last = $image['image_id'];
}
if ( $last === NULL )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
return $last;
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
{
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('cleaning_up_gallery_images'), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['did'], 2 ) ) : 100 );
}
/**
* Perform post-completion processing
*
* @param array $data Data returned from preQueueData
* @param bool $processed Was anything processed or not? If preQueueData returns NULL, this will be FALSE.
* @return void
*/
public function postComplete( $data, $processed = TRUE )
{
\IPS\Db::i()->query( "ALTER TABLE `" . \IPS\Db::i()->prefix . "gallery_images` DROP COLUMN image_thumb_file_name, DROP COLUMN image_medium_file_name" );
}
}
@@ -12,16 +12,27 @@
namespace IPS\gallery\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Extensions\QueueAbstract;
use IPS\gallery\Album;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Theme;
use OutOfRangeException;
use function defined;
use function is_null;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _Follow
class Follow extends QueueAbstract
{
/**
* Run Background Task
@@ -31,12 +42,13 @@ class _Follow
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
public function run( array &$data, int $offset ): int
{
$category = \IPS\gallery\Category::load( $data['category_id'] );
$album = ( !\is_null( $data['album_id'] ) ) ? \IPS\gallery\Album::load( $data['album_id'] ) : NULL;
$member = \IPS\Member::load( $data['member_id'] );
$newOffset = \IPS\gallery\Image::_sendNotificationsBatch( $category, $album, $member, $offset );
$category = Category::load( $data['category_id'] );
$album = ( !is_null( $data['album_id'] ) ) ? Album::load( $data['album_id'] ) : NULL;
$member = Member::load( $data['member_id'] );
$tags = $data['tags'] ?? null;
$newOffset = Image::_sendNotificationsBatch( $category, $album, $member, $tags, $offset );
if( $newOffset === NULL )
{
@@ -52,13 +64,24 @@ class _Follow
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
public function getProgress( mixed $data, int $offset ): array
{
$complete = $data['followerCount'] ? round( 100 / $data['followerCount'] * $offset, 2 ) : 100;
$directContainer = ( !\is_null( $data['album_id'] ) ) ? \IPS\gallery\Album::load( $data['album_id'] ) : \IPS\gallery\Category::load( $data['category_id'] );
$directContainer = ( !is_null( $data['album_id'] ) ) ? Album::load( $data['album_id'] ) : Category::load( $data['category_id'] );
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $directContainer->url(), TRUE, $directContainer->_title, FALSE ) ) ) ), 'complete' => $complete );
}
return array( 'text' => Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $directContainer->url(), TRUE, $directContainer->_title, FALSE ) ) ) ), 'complete' => $complete );
}
/**
* Parse data before queuing
*
* @param array $data
* @return array|null
*/
public function preQueueData( array $data ): ?array
{
return $data;
}
}
@@ -12,37 +12,49 @@
namespace IPS\gallery\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use Exception;
use IPS\Application;
use IPS\Db;
use IPS\Extensions\QueueAbstract;
use IPS\File;
use IPS\Member;
use IPS\Patterns\ActiveRecordIterator;
use OutOfRangeException;
use function defined;
use const IPS\REBUILD_INTENSE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _RebuildGalleryImages
class RebuildGalleryImages extends QueueAbstract
{
/**
* @brief Number of content items to rebuild per cycle
*/
public $rebuild = \IPS\REBUILD_INTENSE;
public int $rebuild = REBUILD_INTENSE;
/**
* Parse data before queuing
*
* @param array $data
* @return array
* @return array|null
*/
public function preQueueData( $data )
public function preQueueData( array $data ): ?array
{
try
{
$data['count'] = \IPS\Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
$data['count'] = Db::i()->select( 'COUNT(*)', 'gallery_images', array( 'image_media=?', 0 ) )->first();
}
catch( \Exception $ex )
catch( Exception )
{
throw new \OutOfRangeException;
throw new OutOfRangeException;
}
if( $data['count'] == 0 )
@@ -63,14 +75,14 @@ class _RebuildGalleryImages
* @return int New offset
* @throws \IPS\Task\Queue\OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( &$data, $offset )
public function run( mixed &$data, int $offset ): int
{
if ( !\IPS\Application::appIsEnabled( 'gallery' ) )
if ( !Application::appIsEnabled( 'gallery' ) )
{
throw new \IPS\Task\Queue\OutOfRangeException;
}
$iterator = new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( '*', 'gallery_images', array( array( 'image_media=? AND image_id>?', 0, $offset ) ), 'image_id ASC', array( 0, $this->rebuild ) ), 'IPS\\gallery\\Image' );
$iterator = new ActiveRecordIterator( Db::i()->select( '*', 'gallery_images', array( array( 'image_media=? AND image_id>?', 0, $offset ) ), 'image_id ASC', array( 0, $this->rebuild ) ), 'IPS\\gallery\\Image' );
$last = NULL;
foreach( $iterator as $image )
@@ -78,13 +90,16 @@ class _RebuildGalleryImages
try
{
/* Make sure the original image exists and has content */
$file = \IPS\File::get( 'gallery_Images', $image->original_file_name );
$file->contents();
if ( $image->original_file_name )
{
$file = File::get( 'gallery_Images', $image->original_file_name );
$file->contents();
$image->buildThumbnails( $file );
$image->save();
$image->buildThumbnails( $file );
$image->save();
}
}
catch ( \Exception $e ) {}
catch ( Exception ) {}
$last = $image->id;
$data['indexed']++;
@@ -104,10 +119,10 @@ class _RebuildGalleryImages
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaining task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
public function getProgress( mixed $data, int $offset ): array
{
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('rebuilding_gallery_images' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['indexed'], 2 ) ) : 100 );
return array( 'text' => Member::loggedIn()->language()->addToStack('rebuilding_gallery_images' ), 'complete' => $data['count'] ? ( round( 100 / $data['count'] * $data['indexed'], 2 ) ) : 100 );
}
}
@@ -0,0 +1,120 @@
<?php
/**
* @brief SearchContent extension: Albums
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 10 Jul 2023
*/
namespace IPS\gallery\extensions\core\SearchContent;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Content\Search\SearchContentAbstract;
use IPS\gallery\Album\Comment;
use IPS\gallery\Album\Item;
use IPS\gallery\Album\Review;
use IPS\Member;
use IPS\Settings;
use IPS\Theme;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief SearchContent extension: Albums
*/
class Albums extends SearchContentAbstract
{
/**
* @brief A classname applied to the search result block
*/
public static string $searchResultClassName = 'cGalleryAlbumSearchResult';
/**
* Return all searchable classes in your application,
* including comments and/or reviews
*
* @return array
*/
public static function supportedClasses() : array
{
return array(
Item::class,
Comment::class,
Review::class
);
}
/**
* Return the language string key to use in search results
*
* @note Normally we show "(user) posted a (thing) in (area)" but sometimes this may not be accurate, so this is abstracted to allow
* content classes the ability to override
* @param array $authorData Author data
* @param array $articles Articles language strings
* @param array $indexData Search index data
* @param array $itemData Data about the item
* @param bool $includeLinks Include links to member profile
* @return string
*/
public static function searchResultSummaryLanguage( array $authorData, array $articles, array $indexData, array $itemData, bool $includeLinks = TRUE ): string
{
if( $indexData['index_class'] == Item::class )
{
return Member::loggedIn()->language()->addToStack( "album_user_own_activity_item", FALSE, array( 'sprintf' => array( $articles['indefinite'] ), 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'front' )->userLinkFromData( $authorData['member_id'], $authorData['name'], $authorData['members_seo_name'], $authorData['member_group_id'] ?? Settings::i()->guest_group ) ) ) );
}
return parent::searchResultSummaryLanguage( $authorData, $articles, $indexData, $itemData, $includeLinks );
}
/**
* Get snippet HTML for search result display
*
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, string $view ): string
{
$images = ( isset( $itemData['extra'] ) AND count( $itemData['extra'] ) ) ? $itemData['extra'] : array();
if( $indexData['index_class'] == Item::class )
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultAlbumSnippet( $indexData, $itemData, $images, static::urlFromIndexData( $indexData, $itemData ), $view == 'condensed' );
}
else
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultAlbumCommentSnippet( $indexData, $itemData, $images, static::urlFromIndexData( $indexData, $itemData ), $reviewRating, $view == 'condensed' );
}
}
/**
* Search Index Permissions
*
* @return string Comma-delimited values or '*'
* @li Number indicates a group
* @li Number prepended by "m" indicates a member
* @li Number prepended by "s" indicates a social group
*/
public function searchIndexPermissions(): string
{
if( $this->object instanceof Item )
{
return $this->object->asNode()->searchIndexPermissions();
}
return parent::searchIndexPermissions();
}
}
@@ -0,0 +1,155 @@
<?php
/**
* @brief SearchContent extension: Images
* @author <a href='https://www.invisioncommunity.com'>Invision Power Services, Inc.</a>
* @copyright (c) Invision Power Services, Inc.
* @license https://www.invisioncommunity.com/legal/standards/
* @package Invision Community
* @subpackage Gallery
* @since 10 Jul 2023
*/
namespace IPS\gallery\extensions\core\SearchContent;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\Content\Search\SearchContentAbstract;
use IPS\Content\Search\Query;
use IPS\Dispatcher;
use IPS\gallery\Album;
use IPS\gallery\Album\Item;
use IPS\gallery\Application;
use IPS\gallery\Category;
use IPS\gallery\Image;
use IPS\gallery\Image\Comment;
use IPS\gallery\Image\Review;
use IPS\Theme;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief SearchContent extension: Images
*/
class Images extends SearchContentAbstract
{
/**
* Return all searchable classes in your application,
* including comments and/or reviews
*
* @return array
*/
public static function supportedClasses() : array
{
return array(
Image::class,
Comment::class,
Review::class
);
}
/**
* Give class a chance to inspect and manipulate search engine filters for streams
*
* @param array $filters Filters to be used for activity stream
* @param Query $query Search query object
* @return void
*/
public static function searchEngineFiltering( array &$filters, Query &$query ): void
{
/* Make sure our CSS is output */
if( Dispatcher::hasInstance() )
{
Application::outputCss();
}
/* Loop through and see if we are also including albums */
$includingAlbums = FALSE;
if( !count( $filters ) )
{
$includingAlbums = TRUE;
}
else
{
foreach( $filters as $filter )
{
if( $filter->itemClass == Item::class )
{
$includingAlbums = TRUE;
}
}
}
if( $includingAlbums === TRUE )
{
if( count( $filters ) )
{
foreach( $filters as $k => $filter )
{
if( $filter->itemClass == Image::class )
{
/* container class can be category or album */
$filter->containerClasses = array( Category::class );
$filter->containerClassExclusions = array( Comment::class, Review::class );
}
}
}
else
{
$query->filterByContainerClasses( array( Album::class ), array( Comment::class, Review::class ) );
}
}
}
/**
* Search Index Permissions
*
* @return string Comma-delimited values or '*'
* @li Number indicates a group
* @li Number prepended by "m" indicates a member
* @li Number prepended by "s" indicates a social group
*/
public function searchIndexPermissions(): string
{
/* If this is a private album, only the author can view in search */
if ( method_exists( $this->object, 'directContainer' ) and $this->object->directContainer() instanceof Album and $this->object->directContainer()->type != Album::AUTH_TYPE_PUBLIC )
{
if ( $this->object->member_id )
{
return "m{$this->object->member_id}";
}
return '';
}
return parent::searchIndexPermissions();
}
/**
* Get snippet HTML for search result display
*
* @param array $indexData Data from the search index
* @param array $authorData Basic data about the author. Only includes columns returned by \IPS\Member::columnsForPhoto()
* @param array $itemData Basic data about the item. Only includes columns returned by item::basicDataColumns()
* @param array|NULL $containerData Basic data about the container. Only includes columns returned by container::basicDataColumns()
* @param array $reputationData Array of people who have given reputation and the reputation they gave
* @param int|NULL $reviewRating If this is a review, the rating
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array|null $containerData, array $reputationData, int|null $reviewRating, string $view ): string
{
if( $indexData['index_class'] == Image::class )
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultImageSnippet( $indexData, $itemData, ($itemData['extra'] ?? NULL), $itemData['image_small_file_name'], static::urlFromIndexData( $indexData, $itemData ), $view == 'condensed' );
}
else
{
return Theme::i()->getTemplate( 'global', 'gallery', 'front' )->searchResultCommentSnippet( $indexData, $itemData, $itemData['image_small_file_name'], static::urlFromIndexData( $indexData, $itemData ), $reviewRating, $view == 'condensed' );
}
}
}
@@ -12,28 +12,46 @@
namespace IPS\gallery\extensions\core\Sitemap;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Filter;
use IPS\Content\Item;
use IPS\core\extensions\core\Sitemap\Content;
use IPS\DateTime;
use IPS\Db;
use IPS\Extensions\SitemapAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Settings;
use IPS\Sitemap;
use UnderflowException;
use function defined;
use function intval;
use function is_array;
use const IPS\SITEMAP_MAX_PER_FILE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Support Images in sitemaps
*/
class _Images
class Images extends SitemapAbstract
{
/**
* @brief Recommended Settings
*/
public $recommendedSettings = array();
public array $recommendedSettings = array();
/**
* Add settings for ACP configuration to the form
*
* @return array
*/
public function settings()
public function settings(): array
{
return array();
}
@@ -43,9 +61,9 @@ class _Images
*
* @return array
*/
public function getFilenames()
public function getFilenames(): array
{
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$limit = ( isset( $settings["sitemap_{$class::$title}_count"] ) ) ? $settings["sitemap_{$class::$title}_count"] : -1;
@@ -54,10 +72,10 @@ class _Images
return array();
}
$count = \IPS\gallery\Image::getItemsWithPermission( array( 'image_media=?', 0 ), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE );
$count = Image::getItemsWithPermission( array( 'image_media=?', 0 ), NULL, 10, 'read', Filter::FILTER_AUTOMATIC, 0, new Member, FALSE, FALSE, FALSE, TRUE );
$files = array();
$count = ceil( $count / \IPS\SITEMAP_MAX_PER_FILE );
$count = ceil( $count / SITEMAP_MAX_PER_FILE );
for( $i=1; $i <= $count; $i++ )
{
@@ -71,21 +89,21 @@ class _Images
* Generate the sitemap
*
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param \IPS\Sitemap $sitemap Sitemap object reference
* @return void
* @param Sitemap $sitemap Sitemap object reference
* @return int|null
*/
public function generateSitemap( $filename, $sitemap )
public function generateSitemap( string $filename, Sitemap $sitemap ) : ?int
{
$entries = array();
$lastId = 0;
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$exploded = explode( '_', $filename );
$block = (int) array_pop( $exploded );
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
$limit = \IPS\SITEMAP_MAX_PER_FILE;
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * SITEMAP_MAX_PER_FILE;
$limit = SITEMAP_MAX_PER_FILE;
if ( ! $totalLimit )
{
@@ -106,7 +124,7 @@ class _Images
/* Try to fetch the highest ID built in the last sitemap, if it exists */
try
{
$lastId = \IPS\Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
$lastId = Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
if( $lastId > 0 )
{
@@ -114,12 +132,12 @@ class _Images
$limitClause = $limit;
}
}
catch( \UnderflowException $e ){}
catch( UnderflowException ){}
$idColumn = $class::$databaseColumnId;
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, \IPS\Content\Item::SELECT_IDS_FIRST, new \IPS\Member, TRUE ) as $item )
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', Filter::FILTER_PUBLIC_ONLY, Item::SELECT_IDS_FIRST, new Member, TRUE ) as $item )
{
if( !$item->canView( new \IPS\Member ) )
if( !$item->canView( new Member ) )
{
continue;
}
@@ -130,16 +148,16 @@ class _Images
if ( isset( $item::$databaseColumnMap['last_comment'] ) )
{
$lastCommentField = $item::$databaseColumnMap['last_comment'];
if ( \is_array( $lastCommentField ) )
if ( is_array( $lastCommentField ) )
{
foreach ( $lastCommentField as $column )
{
$lastMod = \IPS\DateTime::ts( $item->$column );
$lastMod = DateTime::ts( $item->$column );
}
}
else
{
$lastMod = \IPS\DateTime::ts( $item->$lastCommentField );
$lastMod = DateTime::ts( $item->$lastCommentField );
}
}
@@ -150,11 +168,11 @@ class _Images
/* Image sitemap data */
$data['image:image'] = array(
'image:loc' => (string) \IPS\File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'image:loc' => (string) File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'image:title' => $item->mapped('title')
);
$priority = ( $item->sitemapPriority() ?: ( \intval( isset( $settings["sitemap_{$class::$title}_priority"] ) ? $settings["sitemap_{$class::$title}_priority"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_PRIORITY ) ) );
$priority = ( $item->sitemapPriority() ?: ( intval($settings["sitemap_{$class::$title}_priority"] ?? Content::RECOMMENDED_ITEM_PRIORITY) ) );
if ( $priority !== -1 )
{
$data['priority'] = $priority;
@@ -165,7 +183,18 @@ class _Images
$lastId = $item->$idColumn;
}
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'image' => 'http://www.google.com/schemas/sitemap-image/1.1' ) );
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'image' => 'https://www.google.com/schemas/sitemap-image/1.1' ) );
return $lastId;
}
/**
* Save settings for ACP configuration
*
* @param array $values Values
* @return void
*/
public function saveSettings( array $values ): void
{
}
}
@@ -12,28 +12,46 @@
namespace IPS\gallery\extensions\core\Sitemap;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\Content\Filter;
use IPS\Content\Item;
use IPS\core\extensions\core\Sitemap\Content;
use IPS\DateTime;
use IPS\Db;
use IPS\Extensions\SitemapAbstract;
use IPS\File;
use IPS\gallery\Image;
use IPS\Member;
use IPS\Settings;
use IPS\Sitemap;
use UnderflowException;
use function defined;
use function intval;
use function is_array;
use const IPS\SITEMAP_MAX_PER_FILE;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Support Videos in sitemaps
*/
class _Videos
class Videos extends SitemapAbstract
{
/**
* @brief Recommended Settings
*/
public $recommendedSettings = array();
public array $recommendedSettings = array();
/**
* Add settings for ACP configuration to the form
*
* @return array
*/
public function settings()
public function settings(): array
{
return array();
}
@@ -43,9 +61,9 @@ class _Videos
*
* @return array
*/
public function getFilenames()
public function getFilenames(): array
{
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$limit = ( isset( $settings["sitemap_{$class::$title}_count"] ) ) ? $settings["sitemap_{$class::$title}_count"] : -1;
@@ -54,10 +72,10 @@ class _Videos
return array();
}
$count = \IPS\gallery\Image::getItemsWithPermission( array( 'image_media=?', 1 ), NULL, 10, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, new \IPS\Member, FALSE, FALSE, FALSE, TRUE );
$count = Image::getItemsWithPermission( array( 'image_media=?', 1 ), NULL, 10, 'read', Filter::FILTER_AUTOMATIC, 0, new Member, FALSE, FALSE, FALSE, TRUE );
$files = array();
$count = ceil( $count / \IPS\SITEMAP_MAX_PER_FILE );
$count = ceil( $count / SITEMAP_MAX_PER_FILE );
for( $i=1; $i <= $count; $i++ )
{
@@ -71,21 +89,21 @@ class _Videos
* Generate the sitemap
*
* @param string $filename The sitemap file to build (should be one returned from getFilenames())
* @param \IPS\Sitemap $sitemap Sitemap object reference
* @return void
* @param Sitemap $sitemap Sitemap object reference
* @return int|null
*/
public function generateSitemap( $filename, $sitemap )
public function generateSitemap( string $filename, Sitemap $sitemap ) : ?int
{
$entries = array();
$lastId = 0;
$settings = \IPS\Settings::i()->sitemap_content_settings ? json_decode( \IPS\Settings::i()->sitemap_content_settings, TRUE ) : array();
$settings = Settings::i()->sitemap_content_settings ? json_decode( Settings::i()->sitemap_content_settings, TRUE ) : array();
$class = 'IPS\\gallery\\Image';
$exploded = explode( '_', $filename );
$block = (int) array_pop( $exploded );
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * \IPS\SITEMAP_MAX_PER_FILE;
$limit = \IPS\SITEMAP_MAX_PER_FILE;
$totalLimit = ( isset( $settings["sitemap_{$class::$title}_count"] ) AND $settings["sitemap_{$class::$title}_count"] ) ? $settings["sitemap_{$class::$title}_count"] : Content::RECOMMENDED_ITEM_LIMIT;
$offset = ( $block - 1 ) * SITEMAP_MAX_PER_FILE;
$limit = SITEMAP_MAX_PER_FILE;
if ( ! $totalLimit )
{
@@ -106,7 +124,7 @@ class _Videos
/* Try to fetch the highest ID built in the last sitemap, if it exists */
try
{
$lastId = \IPS\Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
$lastId = Db::i()->select( 'last_id', 'core_sitemap', array( array( 'sitemap=?', implode( '_', $exploded ) . '_' . ( $block - 1 ) ) ) )->first();
if( $lastId > 0 )
{
@@ -114,12 +132,12 @@ class _Videos
$limitClause = $limit;
}
}
catch( \UnderflowException $e ){}
catch( UnderflowException ){}
$idColumn = $class::$databaseColumnId;
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', \IPS\Content\Hideable::FILTER_PUBLIC_ONLY, \IPS\Content\Item::SELECT_IDS_FIRST, new \IPS\Member, TRUE ) as $item )
foreach ( $class::getItemsWithPermission( $where, $class::$databasePrefix . $class::$databaseColumnId .' ASC', $limitClause, 'read', Filter::FILTER_PUBLIC_ONLY, Item::SELECT_IDS_FIRST, new Member, TRUE ) as $item )
{
if( !$item->canView( new \IPS\Member ) )
if( !$item->canView( new Member ) )
{
continue;
}
@@ -130,16 +148,16 @@ class _Videos
if ( isset( $item::$databaseColumnMap['last_comment'] ) )
{
$lastCommentField = $item::$databaseColumnMap['last_comment'];
if ( \is_array( $lastCommentField ) )
if ( is_array( $lastCommentField ) )
{
foreach ( $lastCommentField as $column )
{
$lastMod = \IPS\DateTime::ts( $item->$column );
$lastMod = DateTime::ts( $item->$column );
}
}
else
{
$lastMod = \IPS\DateTime::ts( $item->$lastCommentField );
$lastMod = DateTime::ts( $item->$lastCommentField );
}
}
@@ -150,21 +168,21 @@ class _Videos
/* Video sitemap data */
$data['video:video'] = array(
'video:content_loc' => (string) \IPS\File::get( 'gallery_Images', $item->original_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'video:content_loc' => (string) File::get( 'gallery_Images', $item->original_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' ),
'video:description' => $item->mapped('content'),
'video:title' => $item->mapped('title'),
'video:rating' => $item->mapped('rating_average'),
'video:view_count' => $item->mapped('views'),
'video:publication_date' => \IPS\DateTime::ts( $item->date )->rfc3339(),
'video:publication_date' => DateTime::ts( $item->date )->rfc3339(),
'video:uploader' => array( 0 => $item->author()->name, 'info' => (string) $item->author()->url() ),
);
if( $item->masked_file_name )
{
$data['video:video']['video:thumbnail_loc'] = (string) \IPS\File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( \IPS\Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' );
$data['video:video']['video:thumbnail_loc'] = (string) File::get( 'gallery_Images', $item->masked_file_name )->url->setScheme( ( mb_substr( Settings::i()->base_url, 0, 5 ) === 'https' ) ? 'https' : 'http' );
}
$priority = ( $item->sitemapPriority() ?: ( \intval( isset( $settings["sitemap_{$class::$title}_priority"] ) ? $settings["sitemap_{$class::$title}_priority"] : \IPS\core\extensions\core\Sitemap\Content::RECOMMENDED_ITEM_PRIORITY ) ) );
$priority = ( $item->sitemapPriority() ?: ( intval($settings["sitemap_{$class::$title}_priority"] ?? Content::RECOMMENDED_ITEM_PRIORITY) ) );
if ( $priority !== -1 )
{
$data['priority'] = $priority;
@@ -175,7 +193,18 @@ class _Videos
$lastId = $item->$idColumn;
}
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'video' => 'http://www.google.com/schemas/sitemap-video/1.1' ) );
$sitemap->buildSitemapFile( $filename, $entries, $lastId, array( 'video' => 'https://www.google.com/schemas/sitemap-video/1.1' ) );
return $lastId;
}
/**
* Save settings for ACP configuration
*
* @param array $values Values
* @return void
*/
public function saveSettings( array $values ): void
{
}
}
@@ -11,31 +11,43 @@
namespace IPS\gallery\extensions\core\Statistics;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
use IPS\DateTime;
use IPS\gallery\Image;
use IPS\Helpers\Chart;
use IPS\Helpers\Chart\Database;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output\Plugin\Filesize;
use IPS\Theme;
use OutOfRangeException;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Statistics Chart Extension
*/
class _Bandwidth extends \IPS\core\Statistics\Chart
class Bandwidth extends \IPS\core\Statistics\Chart
{
/**
* @brief Controller
*/
public $controller = 'gallery_stats_bandwidth';
public ?string $controller = 'gallery_stats_bandwidth';
/**
* Render Chart
*
* @param \IPS\Http\Url $url URL the chart is being shown on.
* @return \IPS\Helpers\Chart
* @param Url $url URL the chart is being shown on.
* @return Chart
*/
public function getChart( \IPS\Http\Url $url ): \IPS\Helpers\Chart
public function getChart( Url $url ): Chart
{
$chart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=gallery&module=stats&controller=bandwidth" ), 'gallery_bandwidth', 'bdate', '', array(
$chart = new Database( Url::internal( "app=gallery&module=stats&controller=bandwidth" ), 'gallery_bandwidth', 'bdate', '', array(
'backgroundColor' => '#ffffff',
'colors' => array( '#10967e' ),
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
@@ -43,47 +55,47 @@ class _Bandwidth extends \IPS\core\Statistics\Chart
'areaOpacity' => 0.4,
'chartArea' => array( 'left' => 120, 'width' => '75%' ),
'vAxis' => array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' )
'title' => Member::loggedIn()->language()->addToStack( 'filesize_raw_k' )
)
), 'AreaChart', 'daily', array( 'start' => 0, 'end' => 0 ), array( 'member_id', 'image_id', 'bdate', 'bsize' ) );
$chart->setExtension( $this );
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
$chart->addSeries( Member::loggedIn()->language()->addToStack('bandwidth'), 'number', 'ROUND((SUM(bsize)/1024),2)', FALSE );
$chart->tableParsers = array(
'member_id' => function( $val )
{
$member = \IPS\Member::load( $val );
$member = Member::load( $val );
if( $member->member_id )
{
$url = \IPS\Http\Url::internal( "app=gallery&module=stats&controller=member&do=images&id={$member->member_id}" );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $url, FALSE, $member->name );
$url = Url::internal( "app=gallery&module=stats&controller=member&do=images&id={$member->member_id}" );
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $url, FALSE, $member->name );
}
else
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
return Member::loggedIn()->language()->addToStack('deleted_member');
}
},
'image_id' => function( $val )
{
try
{
$image = \IPS\gallery\Image::load( $val );
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $image->url(), TRUE, $image->caption );
$image = Image::load( $val );
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $image->url(), TRUE, $image->caption );
}
catch ( \OutOfRangeException $e )
catch ( OutOfRangeException )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_image');
return Member::loggedIn()->language()->addToStack('deleted_image');
}
},
'bdate' => function( $val )
{
return (string) \IPS\DateTime::ts( $val );
return (string) DateTime::ts( $val );
},
'bsize' => function( $val )
{
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
return Filesize::humanReadableFilesize( $val );
}
);