Version 5.0.0 beta 1
This commit is contained in:
1 parent
25ddeb65d6
commit
15c7beabc5
6736 files changed
+627902
-497943
No files matched your search
@@ -11,41 +11,57 @@
|
||||
namespace IPS\downloads\extensions\core\AchievementAction;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Achievements\Actions\AchievementActionAbstract;
|
||||
use IPS\core\Achievements\Rule;
|
||||
use IPS\Db;
|
||||
use IPS\downloads\Category;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Helpers\Form\Node;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Member;
|
||||
use IPS\Theme;
|
||||
use OutOfRangeException;
|
||||
use function count;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Achievement Action Extension
|
||||
*/
|
||||
class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAction
|
||||
class DownloadFile extends AchievementActionAbstract
|
||||
{
|
||||
/**
|
||||
* Get filter form elements
|
||||
*
|
||||
* @param array|NULL $filters Current filter values (if editing)
|
||||
* @param \IPS\Http\Url $url The URL the form is being shown on
|
||||
* @param Url $url The URL the form is being shown on
|
||||
* @return array
|
||||
*/
|
||||
public function filters( ?array $filters, \IPS\Http\Url $url ): array
|
||||
public function filters( ?array $filters, Url $url ): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
$return['nodes'] = new \IPS\Helpers\Form\Node( 'achievement_filter_DownloadFile_nodes', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
|
||||
$return['nodes'] = new Node( 'achievement_filter_DownloadFile_nodes', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
|
||||
'url' => $url,
|
||||
'class' => 'IPS\downloads\Category',
|
||||
'showAllNodes' => TRUE,
|
||||
'multiple' => TRUE,
|
||||
], NULL, \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node_prefix', FALSE, [ 'sprintf' => [
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'downloads_file_sg_lc', FALSE ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'categories_sg_lc', FALSE )
|
||||
], NULL, Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node_prefix', FALSE, [ 'sprintf' => [
|
||||
Member::loggedIn()->language()->addToStack( 'downloads_file_sg_lc', FALSE ),
|
||||
Member::loggedIn()->language()->addToStack( 'categories_sg_lc', FALSE )
|
||||
] ] ) );
|
||||
$return['nodes']->label = \IPS\Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node', FALSE, [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack( 'downloads_file_sg_lc', FALSE, [ 'strtolower' => TRUE ] ) ] ] );
|
||||
$return['nodes']->label = Member::loggedIn()->language()->addToStack( 'achievement_filter_NewContentItem_node', FALSE, [ 'sprintf' => [ Member::loggedIn()->language()->addToStack( 'downloads_file_sg_lc', FALSE, [ 'strtolower' => TRUE ] ) ] ] );
|
||||
|
||||
$return['milestone'] = new \IPS\Helpers\Form\Number( 'achievement_filter_DownloadFile_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_DownloadFile_nth_suffix') );
|
||||
$return['milestone']->label = \IPS\Member::loggedIn()->language()->addToStack('achievement_filter_NewContentItem_nth');
|
||||
$return['milestone'] = new Number( 'achievement_filter_DownloadFile_nth', ( $filters and isset( $filters['milestone'] ) and $filters['milestone'] ) ? $filters['milestone'] : 0, FALSE, [], NULL, Member::loggedIn()->language()->addToStack('achievement_filter_nth_their'), Member::loggedIn()->language()->addToStack('achievement_filter_DownloadFile_nth_suffix') );
|
||||
$return['milestone']->label = Member::loggedIn()->language()->addToStack('achievement_filter_NewContentItem_nth');
|
||||
|
||||
return $return;
|
||||
}
|
||||
@@ -77,16 +93,16 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* calls that BEFORE making its change in the database (or there is read/write separation), you will need to add
|
||||
* 1 to the value being considered for milestones
|
||||
*
|
||||
* @param \IPS\Member $subject The subject member
|
||||
* @param Member $subject The subject member
|
||||
* @param array $filters The value returned by formatFilterValues()
|
||||
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
|
||||
* @return bool
|
||||
*/
|
||||
public function filtersMatch( \IPS\Member $subject, array $filters, $extra = NULL ): bool
|
||||
public function filtersMatch( Member $subject, array $filters, mixed $extra = NULL ): bool
|
||||
{
|
||||
if ( isset( $filters['nodes'] ) )
|
||||
{
|
||||
if ( !\in_array( $extra['file']->container()->_id, $filters['nodes'] ) )
|
||||
if ( !in_array( $extra['file']->container()->_id, $filters['nodes'] ) )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -94,7 +110,7 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
|
||||
if ( isset( $filters['milestone'] ) )
|
||||
{
|
||||
if ( \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', [ 'dmid=?', $subject->member_id ] )->first() < $filters['milestone'] )
|
||||
if ( Db::i()->select( 'COUNT(*)', 'downloads_downloads', [ 'dmid=?', $subject->member_id ] )->first() < $filters['milestone'] )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -125,7 +141,7 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* @param array|NULL $filters Current filter values
|
||||
* @return array
|
||||
*/
|
||||
public function awardOther( $extra = NULL, ?array $filters = NULL ): array
|
||||
public function awardOther( mixed $extra = NULL, ?array $filters = NULL ): array
|
||||
{
|
||||
return [ $extra['downloader'] ];
|
||||
}
|
||||
@@ -134,13 +150,13 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* Get identifier to prevent the member being awarded points for the same action twice
|
||||
* Must be unique within within of this domain, must not exceed 32 chars.
|
||||
*
|
||||
* @param \IPS\Member $subject The subject member
|
||||
* @param Member $subject The subject member
|
||||
* @param mixed $extra Any additional information about what is happening (e.g. if a post is being made: the post object)
|
||||
* @return string
|
||||
*/
|
||||
public function identifier( \IPS\Member $subject, $extra = NULL ): string
|
||||
public function identifier( Member $subject, mixed $extra = NULL ): string
|
||||
{
|
||||
return (string) $extra['file']->id . '.' . $extra['downloader']->member_id;
|
||||
return $extra['file']->id . '.' . $extra['downloader']->member_id;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -156,35 +172,35 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
|
||||
try
|
||||
{
|
||||
$item = \IPS\downloads\File::load( $fileId );
|
||||
$item = File::load( $fileId );
|
||||
$sprintf = [ 'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $item->url(), TRUE, $item->mapped('title') ?: $item->indefiniteArticle(), FALSE )
|
||||
Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $item->url(), TRUE, $item->mapped('title') ?: $item->indefiniteArticle(), FALSE )
|
||||
] ];
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
$sprintf = [ 'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
$sprintf = [ 'sprintf' => [ Member::loggedIn()->language()->addToStack('modcp_deleted') ] ];
|
||||
}
|
||||
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__DownloadFile_log', FALSE, $sprintf );
|
||||
return Member::loggedIn()->language()->addToStack( 'AchievementAction__DownloadFile_log', FALSE, $sprintf );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get "description" for rule
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
public function ruleDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
public function ruleDescription( Rule $rule ): ?string
|
||||
{
|
||||
$conditions = [];
|
||||
if ( isset( $rule->filters['milestone'] ) )
|
||||
{
|
||||
$conditions[] = \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
|
||||
$conditions[] = Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
|
||||
],
|
||||
'sprintf' => [ \IPS\Member::loggedIn()->language()->addToStack('AchievementAction__DownloadFile_title_generic') ]
|
||||
'sprintf' => [ Member::loggedIn()->language()->addToStack('AchievementAction__DownloadFile_title_generic') ]
|
||||
] );
|
||||
}
|
||||
|
||||
@@ -193,8 +209,8 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
$conditions[] = $nodeCondition;
|
||||
}
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'AchievementAction__DownloadFile_title' ),
|
||||
return Theme::i()->getTemplate( 'achievements' )->ruleDescription(
|
||||
Member::loggedIn()->language()->addToStack( 'AchievementAction__DownloadFile_title' ),
|
||||
$conditions
|
||||
);
|
||||
}
|
||||
@@ -202,10 +218,10 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
/**
|
||||
* Get "description" for rule (usually a description of the rule's filters)
|
||||
*
|
||||
* @param \IPS\core\Achievements\Rule $rule The rule
|
||||
* @param Rule $rule The rule
|
||||
* @return string|NULL
|
||||
*/
|
||||
protected function _nodeFilterDescription( \IPS\core\Achievements\Rule $rule ): ?string
|
||||
protected function _nodeFilterDescription( Rule $rule ): ?string
|
||||
{
|
||||
if ( isset( $rule->filters['nodes'] ) )
|
||||
{
|
||||
@@ -214,20 +230,20 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
{
|
||||
try
|
||||
{
|
||||
$nodeNames[] = \IPS\downloads\Category::load( $id )->_title;
|
||||
$nodeNames[] = Category::load( $id )->_title;
|
||||
}
|
||||
catch ( \OutOfRangeException $e ) {}
|
||||
catch ( OutOfRangeException $e ) {}
|
||||
}
|
||||
if ( $nodeNames )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
|
||||
return Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
|
||||
'htmlsprintf' => [
|
||||
\IPS\Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
|
||||
\count( $nodeNames ) === 1 ? $nodeNames[0] : \IPS\Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
|
||||
\count( $nodeNames ),
|
||||
\IPS\Member::loggedIn()->language()->addToStack( 'download_categories_lc', FALSE, [ 'strtolower' => TRUE ] )
|
||||
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
|
||||
count( $nodeNames ) === 1 ? $nodeNames[0] : Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
|
||||
count( $nodeNames ),
|
||||
Member::loggedIn()->language()->addToStack( 'download_categories_lc', FALSE, [ 'strtolower' => TRUE ] )
|
||||
] ] ),
|
||||
\count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
count( $nodeNames ) === 1 ? NULL : $nodeNames
|
||||
)
|
||||
],
|
||||
] );
|
||||
@@ -242,7 +258,7 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static public function rebuildData()
|
||||
static public function rebuildData(): array
|
||||
{
|
||||
return [ [
|
||||
'table' => 'downloads_downloads',
|
||||
@@ -259,12 +275,12 @@ class _DownloadFile extends \IPS\core\Achievements\Actions\AbstractAchievementAc
|
||||
* @param array $data Data collected when starting rebuild [table, pkey...]
|
||||
* @return void
|
||||
*/
|
||||
public static function rebuildRow( $row, $data )
|
||||
public static function rebuildRow( array $row, array $data ) : void
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $row['dfid'] );
|
||||
$file = File::load( $row['dfid'] );
|
||||
$file->author()->achievementAction( 'downloads', 'DownloadFile', [
|
||||
'file' => $file,
|
||||
'downloader' => \IPS\Member::load( $row['dmid'] )
|
||||
'downloader' => Member::load( $row['dmid'] )
|
||||
] );
|
||||
}
|
||||
|
||||
|
||||
@@ -12,35 +12,42 @@
|
||||
namespace IPS\downloads\extensions\core\Announcements;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\core\Announcements\Announcement;
|
||||
use IPS\Extensions\AnnouncementsAbstract;
|
||||
use IPS\Helpers\Form\FormAbstract;
|
||||
use IPS\Helpers\Form\Node;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Announcements Extension: Download Categories
|
||||
*/
|
||||
class _Categories
|
||||
class Categories extends AnnouncementsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief ID Field
|
||||
*/
|
||||
public static $idField = "id";
|
||||
public static string $idField = "id";
|
||||
|
||||
/**
|
||||
* @brief Controller classes
|
||||
*/
|
||||
public static $controllers = array( "IPS\\downloads\\modules\\front\\downloads\\browse" );
|
||||
public static array $controllers = array( "IPS\\downloads\\modules\\front\\downloads\\browse" );
|
||||
|
||||
/**
|
||||
* Get Setting Field
|
||||
*
|
||||
* @param \IPS\core\Announcements\Announcement $announcement
|
||||
* @return Form element
|
||||
* @param Announcement|null $announcement
|
||||
* @return FormAbstract Form element
|
||||
*/
|
||||
public function getSettingField( $announcement )
|
||||
public function getSettingField( ?Announcement $announcement ): FormAbstract
|
||||
{
|
||||
return new \IPS\Helpers\Form\Node( 'announce_download_categories', ( $announcement AND $announcement->ids ) ? explode( ",", $announcement->ids ) : 0, FALSE, array( 'class' => 'IPS\downloads\Category', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_download_categories' );
|
||||
return new Node( 'announce_download_categories', ( $announcement AND $announcement->ids ) ? explode( ",", $announcement->ids ) : 0, FALSE, array( 'class' => 'IPS\downloads\Category', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_download_categories' );
|
||||
}
|
||||
}
|
||||
@@ -12,41 +12,44 @@
|
||||
namespace IPS\downloads\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\downloads\File;
|
||||
use IPS\Extensions\ContentRouterAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
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 Content Router extension: Downloads
|
||||
*/
|
||||
class _Files
|
||||
class Files extends ContentRouterAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Content Item Classes
|
||||
*/
|
||||
public $classes = array();
|
||||
|
||||
/**
|
||||
* @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
|
||||
* @param Member|Group|NULL $member If checking access, the member/group to check for, or NULL to not check access
|
||||
* @return void
|
||||
*/
|
||||
public function __construct( $member = NULL )
|
||||
public function __construct( Member|Group $member = NULL )
|
||||
{
|
||||
if ( $member === NULL or $member->canAccessModule( \IPS\Application\Module::get( 'downloads', 'downloads', 'front' ) ) )
|
||||
if ( $member === NULL or $member->canAccessModule( Module::get( 'downloads', 'downloads', 'front' ) ) )
|
||||
{
|
||||
$this->classes[] = 'IPS\downloads\File';
|
||||
}
|
||||
|
||||
if( $member !== NULL AND ( $member instanceof \IPS\Member ) AND \IPS\downloads\File::modPermission( 'unhide', $member ) )
|
||||
if( $member !== NULL AND ( $member instanceof Member ) AND File::modPermission( 'unhide', $member ) )
|
||||
{
|
||||
$this->classes[] = 'IPS\downloads\File\PendingVersion';
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief Create Menu Extension
|
||||
* @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 Downloads
|
||||
* @since 8 Oct 2013
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\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
|
||||
*/
|
||||
class _File
|
||||
{
|
||||
/**
|
||||
* Get Items
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getItems()
|
||||
{
|
||||
if ( \IPS\downloads\Category::canOnAny( 'add', NULL, \IPS\Settings::i()->club_nodes_in_apps ? array() : array( array( 'cclub_id IS NULL' ) ) ) )
|
||||
{
|
||||
if ( !\IPS\Settings::i()->club_nodes_in_apps and $theOnlyNode = \IPS\downloads\Category::theOnlyNode() AND !\IPS\Member::loggedIn()->group['idm_bulk_submit'] )
|
||||
{
|
||||
return array(
|
||||
'file_download' => array(
|
||||
'link' => \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=submit&do=submit&_new=1&category=" . $theOnlyNode->_id, 'front', 'downloads_submit' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return array(
|
||||
'file_download' => array(
|
||||
'link' => \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=submit&_new=1", 'front', 'downloads_submit' ),
|
||||
'title' => 'select_category',
|
||||
'extraData' => array( 'data-ipsDialog' => true, 'data-ipsDialog-size' => "narrow" )
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return array();
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -12,23 +12,33 @@
|
||||
namespace IPS\downloads\extensions\core\Dashboard;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use DateInterval;
|
||||
use Exception;
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\DashboardAbstract;
|
||||
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,30 +48,30 @@ class _Overview
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock()
|
||||
public function getBlock(): string
|
||||
{
|
||||
$oneMonthAgo = \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) )->getTimestamp();
|
||||
$oneMonthAgo = DateTime::create()->sub( new DateInterval( 'P1M' ) )->getTimestamp();
|
||||
|
||||
/* Basic stats */
|
||||
$data = array(
|
||||
'total_disk_spaced' => (int) \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records' )->first(),
|
||||
'total_files' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files' )->first(),
|
||||
'total_views' => (int) \IPS\Db::i()->select( 'SUM(file_views)', 'downloads_files' )->first(),
|
||||
'total_downloads' => (int) \IPS\Db::i()->select( 'SUM(file_downloads)', 'downloads_files' )->first(),
|
||||
'total_bandwidth' => (int) \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first(),
|
||||
'current_month_bandwidth' => (int) \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dtime>?', $oneMonthAgo ) )->first(),
|
||||
'total_disk_spaced' => (int) Db::i()->select( 'SUM(record_size)', 'downloads_files_records' )->first(),
|
||||
'total_files' => (int) Db::i()->select( 'COUNT(*)', 'downloads_files' )->first(),
|
||||
'total_views' => (int) Db::i()->select( 'SUM(file_views)', 'downloads_files' )->first(),
|
||||
'total_downloads' => (int) Db::i()->select( 'SUM(file_downloads)', 'downloads_files' )->first(),
|
||||
'total_bandwidth' => (int) Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first(),
|
||||
'current_month_bandwidth' => (int) Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dtime>?', $oneMonthAgo ) )->first(),
|
||||
);
|
||||
|
||||
/* Specific files (will fail if no files yet) */
|
||||
try
|
||||
{
|
||||
$data['largest_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_size DESC', 1 )->first() );
|
||||
$data['most_viewed_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_views DESC', 1 )->first() );
|
||||
$data['most_downloaded_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_downloads DESC', 1 )->first() );
|
||||
$data['largest_file'] = File::constructFromData( Db::i()->select( '*', 'downloads_files', NULL, 'file_size DESC', 1 )->first() );
|
||||
$data['most_viewed_file'] = File::constructFromData( Db::i()->select( '*', 'downloads_files', NULL, 'file_views DESC', 1 )->first() );
|
||||
$data['most_downloaded_file'] = File::constructFromData( Db::i()->select( '*', 'downloads_files', NULL, 'file_downloads DESC', 1 )->first() );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
|
||||
/* Display */
|
||||
return \IPS\Theme::i()->getTemplate( 'dashboard', 'downloads' )->overview( $data );
|
||||
return Theme::i()->getTemplate( 'dashboard', 'downloads' )->overview( $data );
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,40 @@
|
||||
namespace IPS\downloads\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\downloads\Category;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
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: Category descriptions
|
||||
*/
|
||||
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
|
||||
{
|
||||
$file = \IPS\downloads\Category::load( $id1 );
|
||||
$file = Category::load( $id1 );
|
||||
return $file->can( 'view', $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
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\downloads\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,31 +110,25 @@ 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
|
||||
*
|
||||
* @param int|null $offset Offset to start from
|
||||
* @param int|null $max Maximum to parse
|
||||
* @param bool $status Enable/Disable lazy loading
|
||||
* @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 +139,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 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'", 'word_id ASC', array( $offset, $max ) ) as $word )
|
||||
foreach( Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'", '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 +170,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 +182,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 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'" )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'" )->first();
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,40 @@
|
||||
namespace IPS\downloads\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\downloads\File;
|
||||
use IPS\downloads\File\Comment;
|
||||
use IPS\downloads\File\Review;
|
||||
use IPS\Extensions\EditorLocationsAbstract;
|
||||
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: File descriptions and comments
|
||||
*/
|
||||
class _Downloads
|
||||
class Downloads 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;
|
||||
}
|
||||
@@ -50,11 +54,11 @@ class _Downloads
|
||||
* 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
|
||||
{
|
||||
/* Uploading a new file */
|
||||
if ( preg_match( '/^(?:filedata_\d+_)?downloads\-new\-file$/', $field->options['autoSaveKey'] ) )
|
||||
@@ -86,16 +90,17 @@ class _Downloads
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -103,14 +108,14 @@ class _Downloads
|
||||
* @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
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $id1 );
|
||||
$file = File::load( $id1 );
|
||||
return $file->canView( $member );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -122,29 +127,29 @@ class _Downloads
|
||||
* @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 === 'fields' )
|
||||
{
|
||||
return \IPS\downloads\File::load( $id1 );
|
||||
return File::load( $id1 );
|
||||
}
|
||||
else if ( $id3 === 'review' )
|
||||
{
|
||||
return \IPS\downloads\File\Review::load( $id2 );
|
||||
return Review::load( $id2 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\downloads\File\Comment::load( $id2 );
|
||||
return Comment::load( $id2 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\downloads\File::load( $id1 );
|
||||
return File::load( $id1 );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,29 +12,36 @@
|
||||
namespace IPS\downloads\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\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: Files
|
||||
*/
|
||||
class _Files
|
||||
class Files 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( "record_file_id IN(?) AND record_type=? AND record_backup=0", \IPS\Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
|
||||
array( "record_file_id IN(?) AND record_type=? AND record_backup=0", Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
|
||||
);
|
||||
|
||||
if ( $search )
|
||||
@@ -42,23 +49,23 @@ class _Files
|
||||
$where[] = array( "record_realname LIKE ( CONCAT( '%', ?, '%' ) )", $search );
|
||||
}
|
||||
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', $where )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'downloads_files_records', $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( "record_file_id IN(?) AND record_type=? AND record_backup=0", \IPS\Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
|
||||
array( "record_file_id IN(?) AND record_type=? AND record_backup=0", Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
|
||||
);
|
||||
|
||||
if ( $search )
|
||||
@@ -67,10 +74,10 @@ class _Files
|
||||
}
|
||||
|
||||
$return = array();
|
||||
foreach ( \IPS\Db::i()->select( '*', 'downloads_files_records', $where, 'record_time DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
|
||||
foreach ( Db::i()->select( '*', 'downloads_files_records', $where, 'record_time DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $row['record_file_id'] );
|
||||
$obj = \IPS\File::get( 'downloads_Files', $row['record_location'], $row['record_size'] );
|
||||
$obj = File::get( 'downloads_Files', $row['record_location'], $row['record_size'] );
|
||||
$obj->contextInfo = $file->name;
|
||||
$obj->screenshot = $file->primary_screenshot;
|
||||
$obj->originalFilename = $row['record_realname'];
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Cards
|
||||
* @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 Downloads
|
||||
* @since 26 Mar 2024
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Cards
|
||||
*/
|
||||
class Cards extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return Db::i()->select( 'COUNT(cid)', 'downloads_categories', 'ccard_image is not null' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @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
|
||||
* @return void
|
||||
*/
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$row = Db::i()->select( 'cid,ccard_image', 'downloads_categories', 'ccard_image is not null', 'cid', [ 0, 1 ] )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Cards', $row['ccard_image'] )->move( $storageConfiguration );
|
||||
if( (string) $file != $row['ccard_image'] )
|
||||
{
|
||||
Db::i()->update( 'downloads_categories', [ 'ccard_image' => (string) $file ], [ 'cid=?', $row['cid'] ] );
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
return (bool) Db::i()->select( 'count(cid)', 'downloads_categories', [ 'ccard_image=?', (string) $file ] )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( Db::i()->select( 'ccard_image', 'downloads_categories', [ 'ccard_image is not null' ] ) as $card )
|
||||
{
|
||||
try
|
||||
{
|
||||
File::get( 'downloads_Cards', $card )->delete();
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,29 +12,37 @@
|
||||
namespace IPS\downloads\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 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: FileField
|
||||
*/
|
||||
class _FileField
|
||||
class FileField extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
$count = 0;
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
foreach( Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
{
|
||||
$count += \IPS\Db::i()->select( 'COUNT(*)', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) )->first();
|
||||
$count += Db::i()->select( 'COUNT(*)', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) )->first();
|
||||
}
|
||||
|
||||
return $count;
|
||||
@@ -46,79 +54,55 @@ class _FileField
|
||||
* @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 FALSE when there are no more files to move
|
||||
*/
|
||||
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
if( !\IPS\Db::i()->select( 'COUNT(*)', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) )->first() )
|
||||
if( !Db::i()->select( 'COUNT(*)', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) )->first() )
|
||||
{
|
||||
throw new \Underflowexception;
|
||||
throw new Underflowexception;
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
foreach( Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
{
|
||||
$cfield = \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ), 'file_id', array( $offset, 1 ) )->first();
|
||||
$cfield = Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ), 'file_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $cfield[ 'field_' . $field['cf_id'] ] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ), array( 'file_id=?', $cfield['file_id'] ) );
|
||||
Db::i()->update( 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ), array( 'file_id=?', $cfield['file_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
if( !\IPS\Db::i()->select( 'COUNT(*)', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) )->first() )
|
||||
{
|
||||
throw new \Underflowexception;
|
||||
}
|
||||
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
{
|
||||
$cfield = \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ), 'file_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $cfield[ 'field_' . $field['cf_id'] ] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_ccontent', array( "field_{$field['cf_id']}" => $new ), array( 'file_id=?', $cfield['file_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
|
||||
{
|
||||
$valid = FALSE;
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
foreach( Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ) )->first();
|
||||
Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ) )->first();
|
||||
|
||||
$valid = TRUE;
|
||||
break;
|
||||
}
|
||||
catch( \UnderflowException $e ) {}
|
||||
catch( UnderflowException $e ) {}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
@@ -129,18 +113,18 @@ class _FileField
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
foreach( Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
|
||||
{
|
||||
try
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) ) as $cfield )
|
||||
foreach( Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) ) as $cfield )
|
||||
{
|
||||
\IPS\File::get( 'downloads_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->delete();
|
||||
File::get( 'downloads_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->delete();
|
||||
}
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,30 +12,38 @@
|
||||
namespace IPS\downloads\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 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: Files
|
||||
*/
|
||||
class _Files
|
||||
class Files extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Some file storage engines have the facility to upload private files that need specially signed URLs to download to prevent public access of protected files.
|
||||
*/
|
||||
public static $isPrivate = true;
|
||||
public static bool $isPrivate = true;
|
||||
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'upload' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'upload' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -44,59 +52,43 @@ class _Files
|
||||
* @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
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'upload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
$record = Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'upload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Files', $record['record_location'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Files', $record['record_location'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['record_location'] )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => (string) $file ), array( 'record_id=?', $record['record_id'] ) );
|
||||
Db::i()->update( 'downloads_files_records', array( 'record_location' => (string) $file ), array( 'record_id=?', $record['record_id'] ) );
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'upload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $record['record_location'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => $new ), array( 'record_id=?', $record['record_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( '*', 'downloads_files_records', array( 'record_location=? AND record_type=?', (string) $file, 'upload' ) )->first();
|
||||
$record = Db::i()->select( '*', 'downloads_files_records', array( 'record_location=? AND record_type=?', (string) $file, 'upload' ) )->first();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -107,15 +99,15 @@ class _Files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='upload'" ) as $file )
|
||||
foreach( Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='upload'" ) as $file )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'downloads_Files', $file['record_location'] )->delete();
|
||||
File::get( 'downloads_Files', $file['record_location'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief File Storage Extension: Icons
|
||||
* @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 Downloads
|
||||
* @since 26 Mar 2024
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\extensions\core\FileStorage;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\FileStorageAbstract;
|
||||
use IPS\File;
|
||||
use OutOfRangeException;
|
||||
use UnderflowException;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* File Storage Extension: Icons
|
||||
*/
|
||||
class Icons extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count(): int
|
||||
{
|
||||
return Db::i()->select( 'COUNT(cid)', 'downloads_categories', 'cicon is not null' )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Move stored files
|
||||
*
|
||||
* @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
|
||||
* @return void
|
||||
*/
|
||||
public function move( int $offset, int $storageConfiguration, int $oldConfiguration=NULL ) : void
|
||||
{
|
||||
$row = Db::i()->select( 'cid,cicon', 'downloads_categories', 'cicon is not null', 'cid', [ 0, 1 ] )->first();
|
||||
$test = json_decode( $row['cicon'], true );
|
||||
if( !$test )
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Icons', $row['cicon'] )->move( $storageConfiguration );
|
||||
if( (string) $file != $row['cicon'] )
|
||||
{
|
||||
Db::i()->update( 'downloads_categories', [ 'cicon' => (string) $file ], [ 'cid=?', $row['cid'] ] );
|
||||
}
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file is valid
|
||||
*
|
||||
* @param File|string $file The file path to check
|
||||
* @return bool
|
||||
*/
|
||||
public function isValidFile( File|string $file ): bool
|
||||
{
|
||||
return (bool) Db::i()->select( 'count(cid)', 'downloads_categories', [ 'cicon=?', (string) $file ] )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all stored files
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( Db::i()->select( 'cicon', 'downloads_categories', [ 'cicon is not null' ] ) as $icon )
|
||||
{
|
||||
$icon = json_decode( $icon, true );
|
||||
if( !$icon )
|
||||
{
|
||||
try
|
||||
{
|
||||
File::get( 'downloads_Icons', $icon )->delete();
|
||||
}
|
||||
catch( OutOfRangeException ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,25 +12,34 @@
|
||||
namespace IPS\downloads\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: Screenshots
|
||||
*/
|
||||
class _Screenshots
|
||||
class Screenshots extends FileStorageAbstract
|
||||
{
|
||||
/**
|
||||
* Count stored files
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function count()
|
||||
public function count(): int
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'ssupload' ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'ssupload' ) )->first();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,24 +48,24 @@ class _Screenshots
|
||||
* @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
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'ssupload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
$record = Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'ssupload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
$updates = array();
|
||||
|
||||
try
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_location'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_location'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['record_location'] )
|
||||
{
|
||||
$updates['record_location'] = (string) $file;
|
||||
}
|
||||
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_thumb'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_thumb'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['record_thumb'] )
|
||||
{
|
||||
@@ -65,7 +74,7 @@ class _Screenshots
|
||||
|
||||
if( $record['record_no_watermark'] )
|
||||
{
|
||||
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_no_watermark'] )->move( $storageConfiguration );
|
||||
$file = File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_no_watermark'] )->move( $storageConfiguration );
|
||||
|
||||
if ( (string) $file != $record['record_no_watermark'] )
|
||||
{
|
||||
@@ -73,59 +82,33 @@ class _Screenshots
|
||||
}
|
||||
}
|
||||
}
|
||||
catch( \Exception $e )
|
||||
catch( Exception $e )
|
||||
{
|
||||
/* Any issues are logged */
|
||||
}
|
||||
|
||||
if( \count( $updates ) )
|
||||
if( count( $updates ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', $updates, array( 'record_id=?', $record['record_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 )
|
||||
{
|
||||
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'ssupload' ), 'record_id', array( $offset, 1 ) )->first();
|
||||
|
||||
if ( $new = \IPS\File::repairUrl( $record['record_location'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => $new ), array( 'record_id=?', $record['record_id'] ) );
|
||||
}
|
||||
|
||||
if ( $record['record_thumb'] and $new = \IPS\File::repairUrl( $record['record_thumb'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_thumb' => $new ), array( 'record_id=?', $record['record_id'] ) );
|
||||
}
|
||||
|
||||
if ( $record['record_no_watermark'] and $new = \IPS\File::repairUrl( $record['record_no_watermark'] ) )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_no_watermark' => $new ), array( 'record_id=?', $record['record_id'] ) );
|
||||
Db::i()->update( 'downloads_files_records', $updates, array( 'record_id=?', $record['record_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
|
||||
{
|
||||
$fileName = (string) $file;
|
||||
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( '( record_location=? OR record_thumb=? OR record_no_watermark=? ) AND record_type=?', $fileName, $fileName, $fileName, 'ssupload' ) )->first();
|
||||
$record = Db::i()->select( '*', 'downloads_files_records', array( '( record_location=? OR record_thumb=? OR record_no_watermark=? ) AND record_type=?', $fileName, $fileName, $fileName, 'ssupload' ) )->first();
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
catch ( UnderflowException $e )
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
@@ -137,32 +120,32 @@ class _Screenshots
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function delete()
|
||||
public function delete() : void
|
||||
{
|
||||
foreach( \IPS\Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='ssupload'" ) as $screenshot )
|
||||
foreach( Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='ssupload'" ) as $screenshot )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'downloads_Screenshots', $screenshot['record_location'] )->delete();
|
||||
File::get( 'downloads_Screenshots', $screenshot['record_location'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
|
||||
if( $screenshot['record_thumb'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'downloads_Screenshots', $screenshot['record_thumb'] )->delete();
|
||||
File::get( 'downloads_Screenshots', $screenshot['record_thumb'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
|
||||
if( $screenshot['record_no_watermark'] )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'downloads_Screenshots', $screenshot['record_no_watermark'] )->delete();
|
||||
File::get( 'downloads_Screenshots', $screenshot['record_no_watermark'] )->delete();
|
||||
}
|
||||
catch( \Exception $e ){}
|
||||
catch( Exception $e ){}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,64 +12,78 @@
|
||||
namespace IPS\downloads\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: Downloads
|
||||
*/
|
||||
class _Downloads extends \IPS\core\FrontNavigation\FrontNavigationAbstract
|
||||
class Downloads extends FrontNavigationAbstract
|
||||
{
|
||||
/**
|
||||
* @var string Default icon
|
||||
*/
|
||||
public string $defaultIcon = '\f019';
|
||||
|
||||
/**
|
||||
* 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_downloads');
|
||||
return Member::loggedIn()->language()->addToStack('frontnavigation_downloads');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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( 'downloads', 'downloads' ) );
|
||||
return Member::loggedIn()->canAccessModule( Module::get( 'downloads', 'downloads' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Title
|
||||
*
|
||||
* @return string
|
||||
* @return string
|
||||
*/
|
||||
public function title()
|
||||
public function title(): string
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_downloads');
|
||||
return Member::loggedIn()->language()->addToStack('frontnavigation_downloads');
|
||||
}
|
||||
|
||||
/**
|
||||
* 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=downloads&module=downloads&controller=browse", 'front', 'downloads' );
|
||||
return Url::internal( "app=downloads&module=downloads&controller=browse", 'front', 'downloads' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Is Active?
|
||||
*
|
||||
* @return bool
|
||||
* @return bool
|
||||
*/
|
||||
public function active()
|
||||
public function active(): bool
|
||||
{
|
||||
return !\IPS\core\FrontNavigation::$clubTabActive and \IPS\Dispatcher::i()->application->directory === 'downloads';
|
||||
return !FrontNavigation::$clubTabActive and !FrontNavigation::nodeExtensionIsActive( 'downloads' ) and Dispatcher::i()->application->directory === 'downloads';
|
||||
}
|
||||
}
|
||||
@@ -12,104 +12,117 @@
|
||||
namespace IPS\downloads\extensions\core\GroupForm;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Extensions\GroupFormAbstract;
|
||||
use IPS\Helpers\Form;
|
||||
use IPS\Helpers\Form\Interval;
|
||||
use IPS\Helpers\Form\Number;
|
||||
use IPS\Helpers\Form\YesNo;
|
||||
use IPS\Member;
|
||||
use IPS\Member\Group;
|
||||
use IPS\Settings;
|
||||
use function defined;
|
||||
use const IPS\CIC2;
|
||||
|
||||
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 _Downloads
|
||||
class Downloads 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
|
||||
{
|
||||
$restrictions = $group->idm_restrictions ? json_decode( $group->idm_restrictions, TRUE ) : array();
|
||||
|
||||
$form->addHeader( 'file_management' );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_view_downloads', $group->idm_view_downloads ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_view_approvers', $group->idm_view_approvers ) );
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
$form->add( new YesNo( 'idm_view_downloads', $group->idm_view_downloads ) );
|
||||
$form->add( new YesNo( 'idm_view_approvers', $group->idm_view_approvers ) );
|
||||
if( $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bypass_revision', $group->idm_bypass_revision ) );
|
||||
$form->add( new YesNo( 'idm_bypass_revision', $group->idm_bypass_revision ) );
|
||||
}
|
||||
|
||||
$form->addHeader( 'submission_permissions' );
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
if ( Application::appIsEnabled( 'nexus' ) and $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
if ( \IPS\Settings::i()->idm_nexus_on )
|
||||
if ( Settings::i()->idm_nexus_on )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_add_paid', $group->idm_add_paid ) );
|
||||
$form->add( new YesNo( 'idm_add_paid', $group->idm_add_paid ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
\IPS\Member::loggedIn()->language()->words['idm_add_paid_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'idm_add_paid_enable', FALSE );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_add_paid', FALSE, FALSE, array( 'disabled' => TRUE ) ) );
|
||||
Member::loggedIn()->language()->words['idm_add_paid_desc'] = Member::loggedIn()->language()->addToStack( 'idm_add_paid_enable', FALSE );
|
||||
$form->add( new YesNo( 'idm_add_paid', FALSE, FALSE, array( 'disabled' => TRUE ) ) );
|
||||
}
|
||||
}
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bulk_submit', $group->idm_bulk_submit ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_linked_files', $group->idm_linked_files ) );
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_import_files', $group->idm_import_files ) );
|
||||
$form->add( new YesNo( 'idm_bulk_submit', $group->idm_bulk_submit ) );
|
||||
$form->add( new YesNo( 'idm_linked_files', $group->idm_linked_files ) );
|
||||
$form->add( new YesNo( 'idm_import_files', $group->idm_import_files ) );
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'idm_max_size', $group->idm_max_size, FALSE, array( 'unlimited' => -1 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('idm_maxsize_suffix') ) );
|
||||
$form->add( new Number( 'idm_max_size', $group->idm_max_size, FALSE, array( 'unlimited' => -1 ), NULL, NULL, Member::loggedIn()->language()->addToStack('idm_maxsize_suffix') ) );
|
||||
|
||||
$form->addHeader( 'download_restrictions' );
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) AND \IPS\Settings::i()->idm_nexus_on )
|
||||
if ( Application::appIsEnabled( 'nexus' ) AND Settings::i()->idm_nexus_on )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_paid_restrictions', $group->idm_paid_restrictions ) );
|
||||
$form->add( new YesNo( 'idm_paid_restrictions', $group->idm_paid_restrictions ) );
|
||||
}
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
if( $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'min_posts', isset( $restrictions['min_posts'] ) ? $restrictions['min_posts'] : 0, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('approved_posts_comments') ) );
|
||||
$form->add( new Number( 'min_posts', $restrictions['min_posts'] ?? 0, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, Member::loggedIn()->language()->addToStack('approved_posts_comments') ) );
|
||||
}
|
||||
if ( !\IPS\CIC2 )
|
||||
if ( !CIC2 )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'idm_throttling', $group->idm_throttling, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('idm_throttling_suffix') ) );
|
||||
$form->add( new Number( 'idm_throttling', $group->idm_throttling, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, Member::loggedIn()->language()->addToStack('idm_throttling_suffix') ) );
|
||||
}
|
||||
|
||||
$form->add( new \IPS\Helpers\Form\Interval( 'idm_wait_period', $group->g_id ? $group->idm_wait_period : 0, FALSE, array( 'valueAs' => \IPS\Helpers\Form\Interval::SECONDS, 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ) ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'limit_sim', isset( $restrictions['limit_sim'] ) ? $restrictions['limit_sim'] : 0, FALSE, array( 'unlimited' => 0 ) ) );
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
|
||||
$form->add( new Interval( 'idm_wait_period', $group->g_id ? $group->idm_wait_period : 0, FALSE, array( 'valueAs' => Interval::SECONDS, 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ) ) );
|
||||
$form->add( new Number( 'limit_sim', $restrictions['limit_sim'] ?? 0, FALSE, array( 'unlimited' => 0 ) ) );
|
||||
if ( Application::appIsEnabled( 'nexus' ) and Settings::i()->idm_nexus_on )
|
||||
{
|
||||
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bypass_paid', $group->idm_bypass_paid ) );
|
||||
$form->add( new YesNo( 'idm_bypass_paid', $group->idm_bypass_paid ) );
|
||||
}
|
||||
|
||||
$form->addHeader( 'bandwidth_limits' );
|
||||
$form->addMessage( 'downloads_requires_log' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'daily_bw', isset( $restrictions['daily_bw'] ) ? $restrictions['daily_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_day') ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'weekly_bw', isset( $restrictions['weekly_bw'] ) ? $restrictions['weekly_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_week') ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'monthly_bw', isset( $restrictions['monthly_bw'] ) ? $restrictions['monthly_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_month') ) );
|
||||
$form->add( new Number( 'daily_bw', $restrictions['daily_bw'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('kb_per_day') ) );
|
||||
$form->add( new Number( 'weekly_bw', $restrictions['weekly_bw'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('kb_per_week') ) );
|
||||
$form->add( new Number( 'monthly_bw', $restrictions['monthly_bw'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('kb_per_month') ) );
|
||||
$form->addHeader( 'download_limits' );
|
||||
$form->addMessage( 'downloads_requires_log' );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'daily_dl', isset( $restrictions['daily_dl'] ) ? $restrictions['daily_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_day') ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'weekly_dl', isset( $restrictions['weekly_dl'] ) ? $restrictions['weekly_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_week') ) );
|
||||
$form->add( new \IPS\Helpers\Form\Number( 'monthly_dl', isset( $restrictions['monthly_dl'] ) ? $restrictions['monthly_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_month') ) );
|
||||
$form->add( new Number( 'daily_dl', $restrictions['daily_dl'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('downloads_per_day') ) );
|
||||
$form->add( new Number( 'weekly_dl', $restrictions['weekly_dl'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('downloads_per_week') ) );
|
||||
$form->add( new Number( 'monthly_dl', $restrictions['monthly_dl'] ?? 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, Member::loggedIn()->language()->addToStack('downloads_per_month') ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
$group->idm_view_approvers = $values['idm_view_approvers'];
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
if( $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
$group->idm_bypass_revision = $values['idm_bypass_revision'];
|
||||
}
|
||||
$group->idm_view_downloads = $values['idm_view_downloads'];
|
||||
if ( !\IPS\CIC2 )
|
||||
if ( !CIC2 )
|
||||
{
|
||||
$group->idm_throttling = $values['idm_throttling'];
|
||||
}
|
||||
@@ -119,9 +132,9 @@ class _Downloads
|
||||
$group->idm_bulk_submit = $values['idm_bulk_submit'];
|
||||
$group->idm_max_size = $values['idm_max_size'];
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
|
||||
if ( Application::appIsEnabled( 'nexus' ) and Settings::i()->idm_nexus_on )
|
||||
{
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
if( $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
$group->idm_add_paid = $values['idm_add_paid'];
|
||||
}
|
||||
@@ -135,7 +148,7 @@ class _Downloads
|
||||
$restrictions[ $k ] = $values[ $k ];
|
||||
}
|
||||
|
||||
if( $group->g_id != \IPS\Settings::i()->guest_group )
|
||||
if( $group->g_id != Settings::i()->guest_group )
|
||||
{
|
||||
$restrictions['min_posts'] = $values['min_posts'];
|
||||
}
|
||||
|
||||
@@ -12,9 +12,13 @@
|
||||
namespace IPS\downloads\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 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;
|
||||
}
|
||||
|
||||
@@ -23,14 +27,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 _Downloads
|
||||
class Downloads extends GroupLimitsAbstract
|
||||
{
|
||||
/**
|
||||
* Get group limits by priority
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getLimits()
|
||||
public function getLimits(): array
|
||||
{
|
||||
return array (
|
||||
'exclude' => array(),
|
||||
|
||||
@@ -12,59 +12,51 @@
|
||||
namespace IPS\downloads\extensions\core\IpAddresses;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\IpAddressesAbstract;
|
||||
use IPS\Helpers\Table\Db as TableDb;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Useragent;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* IP Address Lookup extension
|
||||
*/
|
||||
class _DownloadLog
|
||||
class DownloadLog extends IpAddressesAbstract
|
||||
{
|
||||
/**
|
||||
* Supported in the ACP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInAcp()
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Supported in the ModCP IP address lookup tool?
|
||||
*
|
||||
* @return bool
|
||||
* @note If the method does not exist in an extension, the result is presumed to be TRUE
|
||||
*/
|
||||
public function supportedInModCp(): bool
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find Records by IP
|
||||
*
|
||||
* @param string $ip The IP Address
|
||||
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return \IPS\Helpers\Table|int|null
|
||||
* @param Url|null $baseUrl URL table will be displayed on or NULL to return a count
|
||||
* @return string|int|null
|
||||
*/
|
||||
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
|
||||
public function findByIp( string $ip, ?Url $baseUrl = NULL ): string|int|null
|
||||
{
|
||||
/* Return count */
|
||||
if ( $baseUrl === NULL )
|
||||
{
|
||||
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( "dip LIKE ?", $ip ) )->first();
|
||||
return Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( "dip LIKE ?", $ip ) )->first();
|
||||
}
|
||||
|
||||
/* Init Table */
|
||||
$table = new \IPS\Helpers\Table\Db( 'downloads_downloads', $baseUrl, array( "dip LIKE ?", $ip ) );
|
||||
$table = new TableDb( 'downloads_downloads', $baseUrl, array( "dip LIKE ?", $ip ) );
|
||||
|
||||
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'table' );
|
||||
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'rows' );
|
||||
$table->tableTemplate = array( Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'table' );
|
||||
$table->rowsTemplate = array( Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'rows' );
|
||||
|
||||
$table->include = array( 'dfid', 'dtime', 'dsize', 'dua', 'dmid', 'dip' );
|
||||
$table->sortBy = $table->sortBy ?: 'dtime';
|
||||
@@ -75,30 +67,30 @@ class _DownloadLog
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $val );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
$file = File::load( $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('content_deleted');
|
||||
return Member::loggedIn()->language()->addToStack('content_deleted');
|
||||
}
|
||||
},
|
||||
'dtime' => function( $val )
|
||||
{
|
||||
return (string) \IPS\DateTime::ts( $val );
|
||||
return (string) DateTime::ts( $val );
|
||||
},
|
||||
'dsize' => function( $val )
|
||||
{
|
||||
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
|
||||
return Filesize::humanReadableFilesize( $val );
|
||||
},
|
||||
'dua' => function( $val )
|
||||
{
|
||||
return (string) \IPS\Http\Useragent::parse( $val );
|
||||
return (string) Useragent::parse( $val );
|
||||
},
|
||||
'dmid' => function( $val )
|
||||
{
|
||||
$member = \IPS\Member::load( $val );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core' )->userPhoto( $member, 'tiny' ) . ' ' . $member->link();
|
||||
$member = Member::load( $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core' )->userPhoto( $member, 'tiny' ) . ' ' . $member->link();
|
||||
},
|
||||
);
|
||||
|
||||
@@ -120,11 +112,13 @@ class _DownloadLog
|
||||
...
|
||||
);
|
||||
* @endcode
|
||||
* @param \IPS\Member $member The member
|
||||
* @param Member $member The member
|
||||
* @return array
|
||||
*/
|
||||
public function findByMember( $member )
|
||||
public function findByMember( Member $member ) : array
|
||||
{
|
||||
return \IPS\Db::i()->select( "dip AS ip, count(*) AS count, MIN(dtime) AS first, MAX(dtime) AS last", 'downloads_downloads', array( "dmid=?", $member->member_id ), NULL, NULL, 'dip' )->setKeyField( 'ip' );
|
||||
return iterator_to_array(
|
||||
Db::i()->select( "dip AS ip, count(*) AS count, MIN(dtime) AS first, MAX(dtime) AS last", 'downloads_downloads', array( "dmid=?", $member->member_id ), NULL, NULL, 'dip' )->setKeyField( 'ip' )
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,26 +12,35 @@
|
||||
namespace IPS\downloads\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\downloads\Category;
|
||||
use IPS\Extensions\LiveSearchAbstract;
|
||||
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 _downloads
|
||||
class downloads extends LiveSearchAbstract
|
||||
{
|
||||
/**
|
||||
* Check we have access
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasAccess()
|
||||
public function hasAccess(): bool
|
||||
{
|
||||
/* Check Permissions */
|
||||
return \IPS\Member::loggedIn()->hasAcpRestriction( 'downloads', 'downloads', 'categories_manage' );
|
||||
return Member::loggedIn()->hasAcpRestriction( 'downloads', 'downloads', 'categories_manage' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,7 +49,7 @@ class _downloads
|
||||
* @param string $searchTerm Search Term
|
||||
* @return array Array of results
|
||||
*/
|
||||
public function getResults( $searchTerm )
|
||||
public function getResults( string $searchTerm ): array
|
||||
{
|
||||
if( !$this->hasAccess() )
|
||||
{
|
||||
@@ -52,10 +61,10 @@ class _downloads
|
||||
$searchTerm = mb_strtolower( $searchTerm );
|
||||
|
||||
/* Perform the search */
|
||||
$categories = \IPS\Db::i()->select(
|
||||
$categories = Db::i()->select(
|
||||
"*",
|
||||
'downloads_categories',
|
||||
array( "cclub_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, \IPS\Member::loggedIn()->language()->id ),
|
||||
array( "cclub_id IS NULL AND word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, Member::loggedIn()->language()->id ),
|
||||
NULL,
|
||||
NULL
|
||||
)->join(
|
||||
@@ -66,9 +75,9 @@ class _downloads
|
||||
/* Format results */
|
||||
foreach ( $categories as $category )
|
||||
{
|
||||
$category = \IPS\downloads\Category::constructFromData( $category );
|
||||
$category = Category::constructFromData( $category );
|
||||
|
||||
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'downloads', 'admin' )->category( $category );
|
||||
$results[] = Theme::i()->getTemplate( 'livesearch', 'downloads', 'admin' )->category( $category );
|
||||
}
|
||||
|
||||
return $results;
|
||||
@@ -79,8 +88,8 @@ class _downloads
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isDefault()
|
||||
public function isDefault(): bool
|
||||
{
|
||||
return \IPS\Dispatcher::i()->application->directory == 'downloads';
|
||||
return Dispatcher::i()->application->directory == 'downloads';
|
||||
}
|
||||
}
|
||||
@@ -11,61 +11,76 @@
|
||||
namespace IPS\downloads\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\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Useragent;
|
||||
use IPS\Member;
|
||||
use IPS\Output\Plugin\Filesize;
|
||||
use IPS\Request;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Member ACP Profile - Content Statistics Tab: Downloads
|
||||
*/
|
||||
class _Downloads extends \IPS\core\MemberACPProfile\Block
|
||||
class Downloads extends Block
|
||||
{
|
||||
/**
|
||||
* Get output
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function output()
|
||||
public function output(): string
|
||||
{
|
||||
$fileCount = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first();
|
||||
$diskspaceUsed = \IPS\Db::i()->select( 'SUM(file_size)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first();
|
||||
$numberOfDownloads = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( 'dmid=?', $this->member->member_id ) )->first();
|
||||
$totalDownloads = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads' )->first();
|
||||
$bandwidthUsed = \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dmid=?', $this->member->member_id ) )->first();
|
||||
$fileCount = Db::i()->select( 'COUNT(*)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first();
|
||||
$diskspaceUsed = Db::i()->select( 'SUM(file_size)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first();
|
||||
$numberOfDownloads = Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( 'dmid=?', $this->member->member_id ) )->first();
|
||||
$totalDownloads = Db::i()->select( 'COUNT(*)', 'downloads_downloads' )->first();
|
||||
$bandwidthUsed = Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dmid=?', $this->member->member_id ) )->first();
|
||||
|
||||
$allFiles = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files' )->first();
|
||||
$totalFileSize = \IPS\Db::i()->select( 'SUM(file_size)', 'downloads_files' )->first();
|
||||
$totalDownloadSize = \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first();
|
||||
$allFiles = Db::i()->select( 'COUNT(*)', 'downloads_files' )->first();
|
||||
$totalFileSize = Db::i()->select( 'SUM(file_size)', 'downloads_files' )->first();
|
||||
$totalDownloadSize = Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first();
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'stats', 'downloads' )->information( $this->member, \IPS\Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
|
||||
return (string) Theme::i()->getTemplate( 'stats', 'downloads' )->information( $this->member, Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
|
||||
'files_submitted' =>
|
||||
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
|
||||
\IPS\Member::loggedIn()->language()->formatNumber( $fileCount ),
|
||||
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allFiles ? ( 100 / $allFiles ) : 0 ) * $fileCount ), 2 ) ) )
|
||||
Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
|
||||
Member::loggedIn()->language()->formatNumber( $fileCount ),
|
||||
Member::loggedIn()->language()->formatNumber( ( ( $allFiles ? ( 100 / $allFiles ) : 0 ) * $fileCount ), 2 ) ) )
|
||||
),
|
||||
'diskspace_used' =>
|
||||
\IPS\Member::loggedIn()->language()->addToStack('downloads_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('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
|
||||
Filesize::humanReadableFilesize( $diskspaceUsed ),
|
||||
Member::loggedIn()->language()->formatNumber( ( ( $totalFileSize ? ( 100 / $totalFileSize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
|
||||
),
|
||||
'average_filesize_downloads' =>
|
||||
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_average', FALSE, array( 'sprintf' => array(
|
||||
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(file_size)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first() ),
|
||||
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(file_size)', 'downloads_files' )->first() ) ))
|
||||
Member::loggedIn()->language()->addToStack('downloads_stat_average', FALSE, array( 'sprintf' => array(
|
||||
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(file_size)', 'downloads_files', array( 'file_submitter=?', $this->member->member_id ) )->first() ),
|
||||
Filesize::humanReadableFilesize( Db::i()->select( 'AVG(file_size)', 'downloads_files' )->first() ) ))
|
||||
),
|
||||
'number_of_downloads' =>
|
||||
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
|
||||
\IPS\Member::loggedIn()->language()->formatNumber( $numberOfDownloads ),
|
||||
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalDownloads ? ( 100 / $totalDownloads ) : 0 ) * $numberOfDownloads ), 2 ),
|
||||
\IPS\Theme::i()->getTemplate( 'stats', 'downloads' )->link( $this->member, 'downloads', 'downloads' ) ) )
|
||||
Member::loggedIn()->language()->addToStack('downloads_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
|
||||
Member::loggedIn()->language()->formatNumber( $numberOfDownloads ),
|
||||
Member::loggedIn()->language()->formatNumber( ( ( $totalDownloads ? ( 100 / $totalDownloads ) : 0 ) * $numberOfDownloads ), 2 ),
|
||||
Theme::i()->getTemplate( 'stats', 'downloads' )->link( $this->member, 'downloads', 'downloads' ) ) )
|
||||
),
|
||||
'downloads_bandwidth_used' =>
|
||||
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
|
||||
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $bandwidthUsed ),
|
||||
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalDownloadSize ? ( 100 / $totalDownloadSize ) : 0 ) * $bandwidthUsed ), 2 ),
|
||||
\IPS\Theme::i()->getTemplate( 'stats', 'downloads' )->link( $this->member, 'bandwidth', 'bandwidth_use' ) ) )
|
||||
Member::loggedIn()->language()->addToStack('downloads_stat_of_total_link', FALSE, array( 'htmlsprintf' => array(
|
||||
Filesize::humanReadableFilesize( $bandwidthUsed ),
|
||||
Member::loggedIn()->language()->formatNumber( ( ( $totalDownloadSize ? ( 100 / $totalDownloadSize ) : 0 ) * $bandwidthUsed ), 2 ),
|
||||
Theme::i()->getTemplate( 'stats', 'downloads' )->link( $this->member, 'bandwidth', 'bandwidth_use' ) ) )
|
||||
)
|
||||
) ) );
|
||||
}
|
||||
@@ -75,12 +90,12 @@ class _Downloads extends \IPS\core\MemberACPProfile\Block
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function edit()
|
||||
public function edit(): string
|
||||
{
|
||||
switch ( \IPS\Request::i()->chart )
|
||||
switch ( Request::i()->chart )
|
||||
{
|
||||
case 'downloads':
|
||||
$downloadsChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\downloads\\extensions\\core\\MemberACPProfileContentTab\\Downloads&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'downloads_downloads', 'dtime', '', array(
|
||||
$downloadsChart = new Database( Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\downloads\\extensions\\core\\MemberACPProfileContentTab\\Downloads&id={$this->member->member_id}&chart=downloads&_graph=1" ), 'downloads_downloads', 'dtime', '', array(
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
@@ -94,38 +109,38 @@ class _Downloads extends \IPS\core\MemberACPProfile\Block
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $val );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
$file = File::load( $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_file');
|
||||
return Member::loggedIn()->language()->addToStack('deleted_file');
|
||||
}
|
||||
},
|
||||
'dtime' => function( $val )
|
||||
{
|
||||
return (string) \IPS\DateTime::ts( $val );
|
||||
return (string) DateTime::ts( $val );
|
||||
},
|
||||
'dsize' => function( $val )
|
||||
{
|
||||
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
|
||||
return Filesize::humanReadableFilesize( $val );
|
||||
},
|
||||
'dua' => function( $val )
|
||||
{
|
||||
return (string) \IPS\Http\Useragent::parse( $val );
|
||||
return (string) Useragent::parse( $val );
|
||||
},
|
||||
'dip' => function( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( \IPS\Http\Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" ), FALSE, $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" ), FALSE, $val );
|
||||
}
|
||||
);
|
||||
$downloadsChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
|
||||
$output = ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $downloadsChart : \IPS\Theme::i()->getTemplate( 'stats', 'downloads' )->graphs( (string) $downloadsChart );
|
||||
$downloadsChart->addSeries( Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
|
||||
$output = ( Request::i()->isAjax() and isset( Request::i()->_graph ) ) ? (string) $downloadsChart : Theme::i()->getTemplate( 'stats', 'downloads' )->graphs( (string) $downloadsChart );
|
||||
break;
|
||||
|
||||
case 'bandwidth_use':
|
||||
$bandwidthChart = new \IPS\Helpers\Chart\Database( \IPS\Http\Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\downloads\\extensions\\core\\MemberACPProfileContentTab\\Downloads&id={$this->member->member_id}&chart=bandwidth_use&_graph=1" ), 'downloads_downloads', 'dtime', '', array(
|
||||
'vAxis' => array( 'title' => '(' . \IPS\Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) . ')' ),
|
||||
$bandwidthChart = new Database( Url::internal( "app=core&module=members&controller=members&do=editBlock&block=IPS\\downloads\\extensions\\core\\MemberACPProfileContentTab\\Downloads&id={$this->member->member_id}&chart=bandwidth_use&_graph=1" ), 'downloads_downloads', 'dtime', '', array(
|
||||
'vAxis' => array( 'title' => '(' . Member::loggedIn()->language()->addToStack( 'filesize_raw_k' ) . ')' ),
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
@@ -133,8 +148,8 @@ class _Downloads extends \IPS\core\MemberACPProfile\Block
|
||||
'areaOpacity' => 0.4
|
||||
) );
|
||||
$bandwidthChart->where[] = array( 'dmid=?', $this->member->member_id );
|
||||
$bandwidthChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth_use'), 'number', 'ROUND((SUM(dsize)/1024),2)', FALSE );
|
||||
$output = ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $bandwidthChart : \IPS\Theme::i()->getTemplate( 'stats', 'downloads' )->graphs( (string) $bandwidthChart );
|
||||
$bandwidthChart->addSeries( Member::loggedIn()->language()->addToStack('bandwidth_use'), 'number', 'ROUND((SUM(dsize)/1024),2)', FALSE );
|
||||
$output = ( Request::i()->isAjax() and isset( Request::i()->_graph ) ) ? (string) $bandwidthChart : Theme::i()->getTemplate( 'stats', 'downloads' )->graphs( (string) $bandwidthChart );
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,26 +11,34 @@
|
||||
namespace IPS\downloads\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: Downloads
|
||||
*/
|
||||
class _Downloads extends \IPS\core\MemberACPProfile\Restriction
|
||||
class Downloads 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( 'idm_block_submissions', !$this->member->idm_block_submissions ) );
|
||||
$form->add( new YesNo( 'idm_block_submissions', !$this->member->idm_block_submissions ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -39,16 +47,16 @@ class _Downloads 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();
|
||||
|
||||
|
||||
if ( $this->member->idm_block_submissions == $values['idm_block_submissions'] )
|
||||
{
|
||||
$return['idm_block_submissions'] = array( 'old' => $this->member->idm_block_submissions, 'new' => !$values['idm_block_submissions'] );
|
||||
$this->member->idm_block_submissions = !$values['idm_block_submissions'];
|
||||
$return['idm_block_submissions'] = array( 'old' => $this->member->members_bitoptions['idm_block_submissions'], 'new' => !$values['idm_block_submissions'] );
|
||||
$this->member->idm_block_submissions = !$values['idm_block_submissions'];
|
||||
}
|
||||
|
||||
|
||||
return $return;
|
||||
}
|
||||
|
||||
@@ -57,7 +65,7 @@ class _Downloads extends \IPS\core\MemberACPProfile\Restriction
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function activeRestrictions()
|
||||
public function activeRestrictions(): array
|
||||
{
|
||||
$return = array();
|
||||
|
||||
@@ -80,7 +88,7 @@ class _Downloads extends \IPS\core\MemberACPProfile\Restriction
|
||||
{
|
||||
if ( isset( $changes['idm_block_submissions'] ) )
|
||||
{
|
||||
return array( \IPS\Member::loggedIn()->language()->addToStack( 'history_restrictions_downloads_' . \intval( $changes['idm_block_submissions']['new'] ) ) );
|
||||
return array( Member::loggedIn()->language()->addToStack( 'history_restrictions_downloads_' . intval( $changes['idm_block_submissions']['new'] ) ) );
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
@@ -1,75 +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 Downloads
|
||||
* @since 26 Dec 2013
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\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 _Downloads
|
||||
{
|
||||
/**
|
||||
* 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( 'downloads_downloads', array( 'dmid' => $member->member_id ), array( 'dmid=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'downloads_files', array( 'file_approver' => $member->member_id ), array( 'file_approver=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->update( 'downloads_files_notify', array( 'notify_member_id' => $member->member_id ), array( 'notify_member_id=?', $member2->member_id ) );
|
||||
\IPS\Db::i()->delete( 'downloads_sessions', array( 'dsess_mid=?', $member2->member_id ) );
|
||||
|
||||
/* Clean up duplicate notify rows */
|
||||
$unique = array();
|
||||
$duplicate = array();
|
||||
|
||||
foreach( \IPS\Db::i()->select( 'downloads_files_notify.*, downloads_files.file_submitter', 'downloads_files_notify', array( 'notify_member_id=?', $member->member_id ) )->join( 'downloads_files', "downloads_files_notify.notify_file_id=downloads_files.file_id" ) as $notify )
|
||||
{
|
||||
if( !\in_array( $notify['notify_file_id'], $unique ) and $notify['notify_member_id'] !== $notify['file_submitter'] )
|
||||
{
|
||||
$unique[] = $notify['notify_file_id'];
|
||||
}
|
||||
else
|
||||
{
|
||||
$duplicate[] = $notify['notify_id'];
|
||||
}
|
||||
}
|
||||
|
||||
if( \count( $duplicate ) )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'downloads_files_notify', array( "notify_id IN('" . implode( "','", $duplicate ) . "')" ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Member is deleted
|
||||
*
|
||||
* @param $member \IPS\Member The member
|
||||
* @return void
|
||||
*/
|
||||
public function onDelete( $member )
|
||||
{
|
||||
\IPS\Db::i()->delete( 'downloads_downloads', array( 'dmid=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'downloads_sessions', array( 'dsess_mid=?', $member->member_id ) );
|
||||
\IPS\Db::i()->update( 'downloads_files', array( 'file_approver' => 0 ), array( 'file_approver=?', $member->member_id ) );
|
||||
\IPS\Db::i()->delete( 'downloads_files_notify', array( 'notify_member_id=?', $member->member_id ) );
|
||||
}
|
||||
}
|
||||
Whitespace-only changes.
@@ -12,20 +12,25 @@
|
||||
namespace IPS\downloads\extensions\core\ModeratorPermissions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Extensions\ModeratorPermissionsAbstract;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Moderator Permissions
|
||||
*/
|
||||
class _Files
|
||||
class Files extends ModeratorPermissionsAbstract
|
||||
{
|
||||
/**
|
||||
* Get Permissions
|
||||
*
|
||||
* @param array $toggles
|
||||
* @code
|
||||
return array(
|
||||
'key' => 'YesNo', // Can just return a string with type
|
||||
@@ -40,34 +45,11 @@ class _Files
|
||||
* @endcode
|
||||
* @return array
|
||||
*/
|
||||
public function getPermissions()
|
||||
public function getPermissions( array $toggles ): array
|
||||
{
|
||||
return array(
|
||||
'can_make_purchasable' => 'YesNo',
|
||||
'can_make_unpurchasable' => 'YesNo'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* After change
|
||||
*
|
||||
* @param array $moderator The moderator
|
||||
* @param array $changed Values that were changed
|
||||
* @return void
|
||||
*/
|
||||
public function onChange( $moderator, $changed )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* After delete
|
||||
*
|
||||
* @param array $moderator The moderator
|
||||
* @return void
|
||||
*/
|
||||
public function onDelete( $moderator )
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,33 @@
|
||||
namespace IPS\downloads\extensions\core\Notifications;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\NotificationsAbstract;
|
||||
use IPS\Lang;
|
||||
use IPS\Member;
|
||||
use IPS\Notification\Inline;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notification Options
|
||||
*/
|
||||
class _Files
|
||||
class Files extends NotificationsAbstract
|
||||
{
|
||||
/**
|
||||
* Get fields for configuration
|
||||
*
|
||||
* @param \IPS\Member|null $member The member (to take out any notification types a given member will never see) or NULL if this is for the ACP
|
||||
* @param Member|null $member The member (to take out any notification types a given member will never see) or NULL if this is for the ACP
|
||||
* @return array
|
||||
*/
|
||||
public static function configurationOptions( \IPS\Member $member = NULL ): array
|
||||
public static function configurationOptions( Member $member = NULL ): array
|
||||
{
|
||||
return array(
|
||||
'new_file_version' => array(
|
||||
@@ -47,30 +56,30 @@ class _Files
|
||||
/**
|
||||
* Parse notification: new_file_version
|
||||
*
|
||||
* @param \IPS\Notification\Inline $notification The notification
|
||||
* @param bool $htmlEscape TRUE to escape HTML in title
|
||||
* @param Inline $notification The notification
|
||||
* @param bool $htmlEscape TRUE to escape HTML in title
|
||||
* @return array
|
||||
* @code
|
||||
return array(
|
||||
'title' => "Mark has replied to A Topic", // The notification title
|
||||
'url' => \IPS\Http\Url\Friendly::internal( ... ), // The URL the notification should link to
|
||||
'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
|
||||
// explains what the notification is about - just include any appropriate content.
|
||||
// For example, if the notification is about a post, set this as the body of the post.
|
||||
'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
|
||||
);
|
||||
* return array(
|
||||
* 'title' => "Mark has replied to A Topic", // The notification title
|
||||
* 'url' => \IPS\Http\Url\Friendly::internal( ... ), // The URL the notification should link to
|
||||
* 'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
|
||||
* // explains what the notification is about - just include any appropriate content.
|
||||
* // For example, if the notification is about a post, set this as the body of the post.
|
||||
* 'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
|
||||
* );
|
||||
* @endcode
|
||||
*/
|
||||
public function parse_new_file_version( $notification, $htmlEscape=TRUE )
|
||||
public function parse_new_file_version(Inline $notification, bool $htmlEscape=TRUE ): array
|
||||
{
|
||||
$item = $notification->item;
|
||||
if ( !$item )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
return array(
|
||||
'title' => ( $item->container()->version_numbers ) ? \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_file_version_with', FALSE, array( 'sprintf' => array( $item->author()->name, $item->version, $item->mapped('title') ) ) ) : \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_file_version', FALSE, array( 'sprintf' => array( $item->author()->name, $item->mapped('title') ) ) ),
|
||||
'title' => ( $item->container()->version_numbers ) ? Member::loggedIn()->language()->addToStack( 'notification__new_file_version_with', FALSE, array( 'sprintf' => array( $item->author()->name, $item->version, $item->mapped('title') ) ) ) : Member::loggedIn()->language()->addToStack( 'notification__new_file_version', FALSE, array( 'sprintf' => array( $item->author()->name, $item->mapped('title') ) ) ),
|
||||
'url' => $notification->item->url(),
|
||||
'content' => $notification->item->content(),
|
||||
'author' => $notification->extra ?: $notification->item->author(),
|
||||
@@ -81,11 +90,11 @@ class _Files
|
||||
/**
|
||||
* Parse notification for mobile: new_file_version
|
||||
*
|
||||
* @param \IPS\Lang $language The language that the notification should be in
|
||||
* @param \IPS\downloads\File $file The file
|
||||
* @param Lang $language The language that the notification should be in
|
||||
* @param File $file The file
|
||||
* @return array
|
||||
*/
|
||||
public static function parse_mobile_new_file_version( \IPS\Lang $language, \IPS\downloads\File $file )
|
||||
public static function parse_mobile_new_file_version( Lang $language, File $file ): array
|
||||
{
|
||||
return array(
|
||||
'title' => $language->addToStack( 'notification__new_file_version_title' ),
|
||||
|
||||
@@ -12,21 +12,29 @@
|
||||
namespace IPS\downloads\extensions\core\OverviewStatistics;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\DateTime;
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\OverviewStatisticsAbstract;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
use function is_array;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Overview statistics extension: Downloads
|
||||
*/
|
||||
class _Downloads
|
||||
class Downloads extends OverviewStatisticsAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Which statistics page (activity or user)
|
||||
*/
|
||||
public $page = 'activity';
|
||||
public string $page = 'activity';
|
||||
|
||||
/**
|
||||
* Return the sub-block keys
|
||||
@@ -34,7 +42,7 @@ class _Downloads
|
||||
* @note This is designed to allow one class to support multiple blocks, for instance using the ContentRouter to generate blocks.
|
||||
* @return array
|
||||
*/
|
||||
public function getBlocks()
|
||||
public function getBlocks(): array
|
||||
{
|
||||
return array( 'downloads' );
|
||||
}
|
||||
@@ -45,7 +53,7 @@ class _Downloads
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return array
|
||||
*/
|
||||
public function getBlockDetails( $subBlock = NULL )
|
||||
public function getBlockDetails( string $subBlock = NULL ): array
|
||||
{
|
||||
/* Description can be null and will not be shown if so */
|
||||
return array( 'app' => 'downloads', 'title' => 'stats_overview_downloads', 'description' => 'stats_overview_downloads_desc', 'refresh' => 20 );
|
||||
@@ -54,18 +62,18 @@ class _Downloads
|
||||
/**
|
||||
* Return the block HTML to show
|
||||
*
|
||||
* @param array|NULL $dateRange NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param array|string|null $dateRange String for a fixed time period in days, NULL for all time, or an array with 'start' and 'end' \IPS\DateTime objects to restrict to
|
||||
* @param string|NULL $subBlock The subblock we are loading as returned by getBlocks()
|
||||
* @return string
|
||||
*/
|
||||
public function getBlock( $dateRange = NULL, $subBlock = NULL )
|
||||
public function getBlock( array|string $dateRange = NULL, string $subBlock = NULL ): string
|
||||
{
|
||||
$where = NULL;
|
||||
$previousCount = NULL;
|
||||
|
||||
if( $dateRange !== NULL )
|
||||
{
|
||||
if( \is_array( $dateRange ) )
|
||||
if( is_array( $dateRange ) )
|
||||
{
|
||||
$where = array(
|
||||
array( 'dtime > ?', $dateRange['start']->getTimestamp() ),
|
||||
@@ -74,41 +82,17 @@ class _Downloads
|
||||
}
|
||||
else
|
||||
{
|
||||
$currentDate = new \IPS\DateTime;
|
||||
$interval = NULL;
|
||||
|
||||
switch( $dateRange )
|
||||
{
|
||||
case '7':
|
||||
$interval = new \DateInterval( 'P7D' );
|
||||
break;
|
||||
|
||||
case '30':
|
||||
$interval = new \DateInterval( 'P1M' );
|
||||
break;
|
||||
|
||||
case '90':
|
||||
$interval = new \DateInterval( 'P3M' );
|
||||
break;
|
||||
|
||||
case '180':
|
||||
$interval = new \DateInterval( 'P6M' );
|
||||
break;
|
||||
|
||||
case '365':
|
||||
$interval = new \DateInterval( 'P1Y' );
|
||||
break;
|
||||
}
|
||||
|
||||
$currentDate = new DateTime;
|
||||
$interval = static::getInterval( $dateRange );
|
||||
$initialTimestamp = $currentDate->sub( $interval )->getTimestamp();
|
||||
$where = array( array( 'dtime > ?', $initialTimestamp ) );
|
||||
|
||||
$previousCount = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( array( 'dtime BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
$previousCount = Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( array( 'dtime BETWEEN ? AND ?', $currentDate->sub( $interval )->getTimestamp(), $initialTimestamp ) ) )->first();
|
||||
}
|
||||
}
|
||||
|
||||
$count = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', $where )->first();
|
||||
$count = Db::i()->select( 'COUNT(*)', 'downloads_downloads', $where )->first();
|
||||
|
||||
return \IPS\Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $count, $previousCount );
|
||||
return Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $count, $previousCount );
|
||||
}
|
||||
}
|
||||
@@ -12,36 +12,42 @@
|
||||
namespace IPS\downloads\extensions\core\Permissions;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use BadMethodCallException;
|
||||
use IPS\downloads\Category;
|
||||
use IPS\Extensions\PermissionsAbstract;
|
||||
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\downloads\Category' => function( $current, $group )
|
||||
{
|
||||
$rows = array();
|
||||
|
||||
foreach( \IPS\downloads\Category::roots( NULL ) AS $root )
|
||||
foreach( Category::roots( NULL ) AS $root )
|
||||
{
|
||||
try
|
||||
{
|
||||
\IPS\downloads\Category::populatePermissionMatrix( $rows, $root, $group, $current );
|
||||
Category::populatePermissionMatrix( $rows, $root, $group, $current );
|
||||
}
|
||||
catch( \BadMethodCallException $e ) {}
|
||||
catch( BadMethodCallException $e ) {}
|
||||
}
|
||||
|
||||
return $rows;
|
||||
|
||||
@@ -12,16 +12,25 @@
|
||||
namespace IPS\downloads\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\downloads\Category;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _Follow
|
||||
class Follow extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* Run Background Task
|
||||
@@ -31,11 +40,11 @@ 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\downloads\Category::load( $data['category_id'] );
|
||||
$member = \IPS\Member::load( $data['member_id'] );
|
||||
$newOffset = \IPS\downloads\File::_sendNotificationsBatch( $category, $member, $offset );
|
||||
$category = Category::load( $data['category_id'] );
|
||||
$member = Member::load( $data['member_id'] );
|
||||
$newOffset = File::_sendNotificationsBatch( $category, $member, $offset );
|
||||
|
||||
if( $newOffset === NULL )
|
||||
{
|
||||
@@ -51,13 +60,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
|
||||
{
|
||||
$category = \IPS\downloads\Category::load( $data['category_id'] );
|
||||
$category = Category::load( $data['category_id'] );
|
||||
$complete = $data['followerCount'] ? round( 100 / $data['followerCount'] * $offset, 2 ) : 100;
|
||||
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $category->url(), TRUE, $category->_title, FALSE ) ) ) ), 'complete' => $complete );
|
||||
}
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $category->url(), TRUE, $category->_title, FALSE ) ) ) ), 'complete' => $complete );
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
}
|
||||
@@ -12,24 +12,37 @@
|
||||
namespace IPS\downloads\extensions\core\Queue;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
|
||||
use IPS\Application;
|
||||
use IPS\Content;
|
||||
use IPS\Db;
|
||||
use IPS\downloads\File;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\Notification;
|
||||
use IPS\Task\Queue\OutOfRangeException;
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class _Notify
|
||||
class Notify extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( $data )
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
return $data;
|
||||
}
|
||||
@@ -40,33 +53,33 @@ class _Notify
|
||||
* @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
|
||||
* @throws OutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( $data, $offset )
|
||||
public function run( array &$data, int $offset ): int
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $data['file'] );
|
||||
$file = File::load( $data['file'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$notifyIds = array();
|
||||
|
||||
$recipients = iterator_to_array( \IPS\Db::i()->select( 'downloads_files_notify.*', 'downloads_files_notify', array( 'notify_file_id=?', $data['file'] ), 'notify_id ASC', array( $offset, \IPS\Downloads\File::NOTIFICATIONS_PER_BATCH ) ) );
|
||||
$recipients = iterator_to_array( Db::i()->select( 'downloads_files_notify.*', 'downloads_files_notify', array( 'notify_file_id=?', $data['file'] ), 'notify_id ASC', array( $offset, Content::NOTIFICATIONS_PER_BATCH ) ) );
|
||||
|
||||
if( !\count( $recipients ) )
|
||||
if( !count( $recipients ) )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$notification = new \IPS\Notification( \IPS\Application::load( 'downloads' ), 'new_file_version', $file, array( $file ) );
|
||||
$notification = new Notification( Application::load( 'downloads' ), 'new_file_version', $file, array( $file ) );
|
||||
|
||||
foreach( $recipients AS $recipient )
|
||||
{
|
||||
$recipientMember = \IPS\Member::load( $recipient['notify_member_id'] );
|
||||
$recipientMember = Member::load( $recipient['notify_member_id'] );
|
||||
if ( $file->container()->can( 'view', $recipientMember ) )
|
||||
{
|
||||
$notifyIds[] = $recipient['notify_id'];
|
||||
@@ -74,10 +87,10 @@ class _Notify
|
||||
}
|
||||
}
|
||||
|
||||
\IPS\Db::i()->update( 'downloads_files_notify', array( 'notify_sent' => time() ), \IPS\Db::i()->in( 'notify_id', $notifyIds ) );
|
||||
Db::i()->update( 'downloads_files_notify', array( 'notify_sent' => time() ), Db::i()->in( 'notify_id', $notifyIds ) );
|
||||
$notification->send();
|
||||
|
||||
return $offset + \IPS\downloads\File::NOTIFICATIONS_PER_BATCH;
|
||||
return $offset + Content::NOTIFICATIONS_PER_BATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,19 +101,19 @@ class _Notify
|
||||
* @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 )
|
||||
public function getProgress( mixed $data, int $offset ): array
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $data['file'] );
|
||||
$file = File::load( $data['file'] );
|
||||
}
|
||||
catch( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Task\Queue\OutOfRangeException;
|
||||
throw new OutOfRangeException;
|
||||
}
|
||||
|
||||
$complete = $data['notifyCount'] ? round( 100 / $data['notifyCount'] * $offset, 2 ) : 100;
|
||||
|
||||
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_new_version', FALSE, array( 'htmlsprintf' => array( \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name, FALSE ) ) ) ), 'complete' => $complete );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack('backgroundQueue_new_version', FALSE, array( 'htmlsprintf' => array( Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name, FALSE ) ) ) ), 'complete' => $complete );
|
||||
}
|
||||
}
|
||||
@@ -12,43 +12,55 @@
|
||||
namespace IPS\downloads\extensions\core\Queue;
|
||||
|
||||
/* 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\QueueAbstract;
|
||||
use IPS\File;
|
||||
use IPS\Image;
|
||||
use IPS\Member;
|
||||
use IPS\Settings;
|
||||
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 _RebuildScreenshotWatermarks
|
||||
class RebuildScreenshotWatermarks extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* @brief Number of 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
|
||||
{
|
||||
$watermark = \IPS\Settings::i()->idm_watermarkpath ? \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() : NULL;
|
||||
$watermark = Settings::i()->idm_watermarkpath ? File::get( 'core_Theme', Settings::i()->idm_watermarkpath )->contents() : NULL;
|
||||
$where = array( array( 'record_type=?', 'ssupload' ) );
|
||||
if ( !$watermark )
|
||||
{
|
||||
$where[] = array( 'record_no_watermark<>?', '' );
|
||||
}
|
||||
|
||||
$data['count'] = \IPS\Db::i()->select( 'MAX(record_id)', 'downloads_files_records', $where )->first();
|
||||
$data['realCount'] = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', $where )->first();
|
||||
$data['count'] = Db::i()->select( 'MAX(record_id)', 'downloads_files_records', $where )->first();
|
||||
$data['realCount'] = Db::i()->select( 'COUNT(*)', 'downloads_files_records', $where )->first();
|
||||
}
|
||||
catch( \Exception $ex )
|
||||
catch( Exception $ex )
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -71,10 +83,10 @@ class _RebuildScreenshotWatermarks
|
||||
* @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
|
||||
{
|
||||
$last = NULL;
|
||||
$watermark = \IPS\Settings::i()->idm_watermarkpath ? \IPS\Image::create( \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() ) : NULL;
|
||||
$watermark = Settings::i()->idm_watermarkpath ? Image::create( File::get( 'core_Theme', Settings::i()->idm_watermarkpath )->contents() ) : NULL;
|
||||
|
||||
$where = array( array( 'record_id>? AND record_type=?', $offset, 'ssupload' ) );
|
||||
if ( !$watermark )
|
||||
@@ -82,7 +94,7 @@ class _RebuildScreenshotWatermarks
|
||||
$where[] = array( 'record_no_watermark<>?', '' );
|
||||
}
|
||||
|
||||
$select = \IPS\Db::i()->select( '*', 'downloads_files_records', $where, 'record_id', array( 0, $this->rebuild ) );
|
||||
$select = Db::i()->select( '*', 'downloads_files_records', $where, 'record_id', array( 0, $this->rebuild ) );
|
||||
|
||||
foreach ( $select as $row )
|
||||
{
|
||||
@@ -90,18 +102,18 @@ class _RebuildScreenshotWatermarks
|
||||
{
|
||||
if ( $row['record_no_watermark'] )
|
||||
{
|
||||
$original = \IPS\File::get( 'downloads_Screenshots', $row['record_no_watermark'] );
|
||||
$original = File::get( 'downloads_Screenshots', $row['record_no_watermark'] );
|
||||
|
||||
try
|
||||
{
|
||||
\IPS\File::get( 'downloads_Screenshots', $row['record_location'] )->delete();
|
||||
\IPS\File::get( 'downloads_Screenshots', $row['record_thumb'] )->delete();
|
||||
File::get( 'downloads_Screenshots', $row['record_location'] )->delete();
|
||||
File::get( 'downloads_Screenshots', $row['record_thumb'] )->delete();
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
|
||||
if ( !$watermark )
|
||||
{
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array(
|
||||
Db::i()->update( 'downloads_files_records', array(
|
||||
'record_location' => (string) $original,
|
||||
'record_thumb' => (string) $original->thumbnail( 'downloads_Screenshots' ),
|
||||
'record_no_watermark' => NULL
|
||||
@@ -115,21 +127,21 @@ class _RebuildScreenshotWatermarks
|
||||
}
|
||||
else
|
||||
{
|
||||
$original = \IPS\File::get( 'downloads_Screenshots', $row['record_location'] );
|
||||
$original = File::get( 'downloads_Screenshots', $row['record_location'] );
|
||||
}
|
||||
|
||||
$image = \IPS\Image::create( $original->contents() );
|
||||
$image = Image::create( $original->contents() );
|
||||
$image->watermark( $watermark );
|
||||
|
||||
$newFile = \IPS\File::create( 'downloads_Screenshots', $original->originalFilename, $image );
|
||||
$newFile = File::create( 'downloads_Screenshots', $original->originalFilename, $image );
|
||||
|
||||
\IPS\Db::i()->update( 'downloads_files_records', array(
|
||||
Db::i()->update( 'downloads_files_records', array(
|
||||
'record_location' => (string) $newFile,
|
||||
'record_thumb' => (string) $newFile->thumbnail( 'downloads_Screenshots' ),
|
||||
'record_no_watermark' => (string) $original
|
||||
), array( 'record_id=?', $row['record_id'] ) );
|
||||
}
|
||||
catch ( \Exception $e ) { }
|
||||
catch ( Exception $e ) { }
|
||||
|
||||
$data['indexed']++;
|
||||
$last = $row['record_id'];
|
||||
@@ -149,10 +161,10 @@ class _RebuildScreenshotWatermarks
|
||||
* @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('downloads_rebuilding_screenshots'), 'complete' => ( $data['realCount'] * $data['indexed'] ) > 0 ? round( ( $data['realCount'] * $data['indexed'] ) * 100, 2 ) : 0 );
|
||||
return array( 'text' => Member::loggedIn()->language()->addToStack('downloads_rebuilding_screenshots'), 'complete' => ( $data['realCount'] * $data['indexed'] ) > 0 ? round( ( $data['realCount'] * $data['indexed'] ) * 100, 2 ) : 0 );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
<?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 Downloads
|
||||
* @since 08 Jul 2024
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\extensions\core\Queue;
|
||||
|
||||
use IPS\Db;
|
||||
use IPS\Extensions\QueueAbstract;
|
||||
use IPS\Member;
|
||||
use IPS\Task\Queue\OutOfRangeException as QueueOutOfRangeException;
|
||||
use OutOfRangeException;
|
||||
use function defined;
|
||||
use const IPS\REBUILD_NORMAL;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Background Task
|
||||
*/
|
||||
class StoreMemberViews extends QueueAbstract
|
||||
{
|
||||
/**
|
||||
* Parse data before queuing
|
||||
*
|
||||
* @param array $data
|
||||
* @return array|null
|
||||
*/
|
||||
public function preQueueData( array $data ): ?array
|
||||
{
|
||||
$data['count'] = (int) Db::i()->select( 'count(*)', 'downloads_view_method' )->first();
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Run Background Task
|
||||
*
|
||||
* @param array $data Data as it was passed to \IPS\Task::queue()
|
||||
* @param int $offset Offset
|
||||
* @return int New offset
|
||||
* @throws QueueOutOfRangeException Indicates offset doesn't exist and thus task is complete
|
||||
*/
|
||||
public function run( array &$data, int $offset ): int
|
||||
{
|
||||
$rows = iterator_to_array(
|
||||
Db::i()->select( '*', 'downloads_view_method', null, 'member_id', [ $offset, REBUILD_NORMAL] )
|
||||
);
|
||||
|
||||
if( !count( $rows ) )
|
||||
{
|
||||
throw new QueueOutOfRangeException;
|
||||
}
|
||||
|
||||
foreach( $rows as $row )
|
||||
{
|
||||
Member::load( $row['member_id'] )->setLayoutValue( 'downloads_categories', $row['method'] );
|
||||
}
|
||||
|
||||
$offset += REBUILD_NORMAL;
|
||||
|
||||
if( $offset >= $data['count'] )
|
||||
{
|
||||
throw new QueueOutOfRangeException;
|
||||
}
|
||||
|
||||
return $offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Progress
|
||||
*
|
||||
* @param array $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( array $data, int $offset ): array
|
||||
{
|
||||
return array(
|
||||
'text' => Member::loggedIn()->language()->addToStack( 'downloads_updating_views' ),
|
||||
'complete' => ( $offset ? round( 100 / $data['count'] * $offset, 2 ) : 0 )
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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( array $data, bool $processed = TRUE ) : void
|
||||
{
|
||||
Db::i()->dropTable( 'downloads_view_method' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
<?php
|
||||
/**
|
||||
* @brief SearchContent extension: Files
|
||||
* @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 Downloads
|
||||
* @since 10 Jul 2023
|
||||
*/
|
||||
|
||||
namespace IPS\downloads\extensions\core\SearchContent;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
|
||||
use IPS\Content\Search\SearchContentAbstract;
|
||||
use IPS\downloads\File;
|
||||
use IPS\downloads\File\Comment;
|
||||
use IPS\downloads\File\Review;
|
||||
use IPS\Theme;
|
||||
use function defined;
|
||||
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( $_SERVER['SERVER_PROTOCOL'] ?? 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief SearchContent extension: Files
|
||||
*/
|
||||
class Files extends SearchContentAbstract
|
||||
{
|
||||
/**
|
||||
* Return all searchable classes in your application,
|
||||
* including comments and/or reviews
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function supportedClasses() : array
|
||||
{
|
||||
return array(
|
||||
File::class,
|
||||
Comment::class,
|
||||
Review::class
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
{
|
||||
$screenshot = NULL;
|
||||
if ( isset( $itemData['extra'] ) )
|
||||
{
|
||||
$screenshot = $itemData['extra']['record_thumb'] ?? $itemData['extra']['record_location'];
|
||||
}
|
||||
|
||||
if( $indexData['index_class'] == File::class )
|
||||
{
|
||||
$price = File::_price( $itemData['file_cost'], $itemData['file_nexus'] );
|
||||
|
||||
return Theme::i()->getTemplate( 'global', 'downloads', 'front' )->searchResultFileSnippet( $indexData, $itemData, $screenshot, static::urlFromIndexData( $indexData, $itemData ), $price, $view == 'condensed' );
|
||||
}
|
||||
else
|
||||
{
|
||||
return Theme::i()->getTemplate( 'global', 'downloads', 'front' )->searchResultCommentSnippet( $indexData, $screenshot, static::urlFromIndexData( $indexData, $itemData ), $reviewRating, $view == 'condensed' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,31 +11,44 @@
|
||||
namespace IPS\downloads\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\downloads\File;
|
||||
use IPS\Helpers\Chart;
|
||||
use IPS\Helpers\Chart\Database;
|
||||
use IPS\Http\Url;
|
||||
use IPS\Http\Useragent;
|
||||
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 _Downloads extends \IPS\core\Statistics\Chart
|
||||
class Downloads extends \IPS\core\Statistics\Chart
|
||||
{
|
||||
/**
|
||||
* @brief Controller
|
||||
*/
|
||||
public $controller = 'downloads_stats_downloads';
|
||||
public ?string $controller = 'downloads_stats_downloads';
|
||||
|
||||
/**
|
||||
* 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( $url, 'downloads_downloads', 'dtime', '', array(
|
||||
$chart = new Database( $url, 'downloads_downloads', 'dtime', '', array(
|
||||
'backgroundColor' => '#ffffff',
|
||||
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
|
||||
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
|
||||
@@ -44,50 +57,50 @@ class _Downloads extends \IPS\core\Statistics\Chart
|
||||
), 'AreaChart', 'monthly', array( 'start' => 0, 'end' => 0 ), array( 'dmid', 'dfid', 'dtime', 'dsize', 'dua', 'dip' ) );
|
||||
$chart->setExtension( $this );
|
||||
|
||||
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->addSeries( Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
|
||||
$chart->availableTypes = array( 'AreaChart', 'ColumnChart', 'BarChart' );
|
||||
|
||||
$chart->tableParsers = array(
|
||||
'dmid' => function( $val )
|
||||
{
|
||||
$member = \IPS\Member::load( $val );
|
||||
$member = Member::load( $val );
|
||||
|
||||
if( $member->member_id )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $member->url(), TRUE, $member->name );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $member->url(), TRUE, $member->name );
|
||||
}
|
||||
else
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
return Member::loggedIn()->language()->addToStack('deleted_member');
|
||||
}
|
||||
},
|
||||
'dfid' => function( $val )
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $val );
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
$file = File::load( $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
catch ( OutOfRangeException $e )
|
||||
{
|
||||
return \IPS\Member::loggedIn()->language()->addToStack('deleted_file');
|
||||
return Member::loggedIn()->language()->addToStack('deleted_file');
|
||||
}
|
||||
},
|
||||
'dtime' => function( $val )
|
||||
{
|
||||
return (string) \IPS\DateTime::ts( $val );
|
||||
return (string) DateTime::ts( $val );
|
||||
},
|
||||
'dsize' => function( $val )
|
||||
{
|
||||
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
|
||||
return Filesize::humanReadableFilesize( $val );
|
||||
},
|
||||
'dua' => function( $val )
|
||||
{
|
||||
return (string) \IPS\Http\Useragent::parse( $val );
|
||||
return (string) Useragent::parse( $val );
|
||||
},
|
||||
'dip' => function( $val )
|
||||
{
|
||||
return \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( \IPS\Http\Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" ), FALSE, $val );
|
||||
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" ), FALSE, $val );
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
Reference in new issue
Block a user