Version 4.5.0

This commit is contained in:
Neo committed 2025-12-19 05:51:58 -08:00
1 parent 1a0c7fd3c2
commit f79dcf067a
3791 files changed
+248032 -76372

No files matched your search

@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _categories extends \IPS\Node\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* Node Class
*/
@@ -46,7 +51,8 @@ class _categories extends \IPS\Node\Controller
*/
protected function recountDownloads()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_recount_downloads' );
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_recount_downloads' );
\IPS\Session::i()->csrfCheck();
try
{
@@ -63,6 +69,11 @@ class _categories extends \IPS\Node\Controller
}
}
/**
* Show the add/edit form
*
* @return void
*/
protected function form()
{
parent::form();
@@ -76,4 +87,18 @@ class _categories extends \IPS\Node\Controller
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('add_category');
}
}
/**
* Rebuild the Downloads Files Topics
*
* @return void
*/
public function rebuildTopicContent()
{
\IPS\Session::i()->csrfCheck();
$class = $this->nodeClass;
\IPS\Task::queue( 'core', 'ResyncTopicContent', array( 'class' => $class, 'categoryId' => \IPS\Request::i()->id ), 3, array( 'categoryId' ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=categories&do=form&id=' . \IPS\Request::i()->id ), \IPS\Member::loggedIn()->language()->addToStack('rebuilding_stuff', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'category_forums_integration' ) ) ) ) );
}
}
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _fields extends \IPS\Node\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* Node Class
*/
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _settings extends \IPS\Dispatcher\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* Manage Settings
*
@@ -32,11 +37,11 @@ class _settings extends \IPS\Dispatcher\Controller
{
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
$form = $this->getForm();
$form = $this->_getForm();
if ( $values = $form->values( TRUE ) )
{
$this->saveSettingsForm( $form, $values );
$this->_saveSettingsForm( $form, $values );
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
@@ -54,7 +59,7 @@ class _settings extends \IPS\Dispatcher\Controller
* @note Abstracted to allow third party devs to extend easier
* @return \IPS\Helpers\Form
*/
protected function getForm()
protected function _getForm()
{
$form = new \IPS\Helpers\Form;
@@ -98,12 +103,13 @@ class _settings extends \IPS\Dispatcher\Controller
if ( \IPS\Application::appIsEnabled( 'nexus' ) )
{
$form->addTab( 'paid_file_settings' );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_nexus_on', \IPS\Settings::i()->idm_nexus_on, FALSE, array( 'togglesOn' => array( 'idm_nexus_tax', 'idm_nexus_percent', 'idm_nexus_transfee' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_nexus_on', \IPS\Settings::i()->idm_nexus_on, FALSE, array( 'togglesOn' => array( 'idm_nexus_tax', 'idm_nexus_percent', 'idm_nexus_transfee', 'idm_nexus_mincost', 'idm_nexus_gateways', 'idm_nexus_display' ) ) ) );
$form->add( new \IPS\Helpers\Form\Node( 'idm_nexus_tax', \IPS\Settings::i()->idm_nexus_tax ?:0, FALSE, array( 'class' => '\IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ), NULL, NULL, NULL, 'idm_nexus_tax' ) );
$form->add( new \IPS\Helpers\Form\Number( 'idm_nexus_percent', \IPS\Settings::i()->idm_nexus_percent, FALSE, array( 'min' => 0, 'max' => 100 ), NULL, NULL, '%', 'idm_nexus_percent' ) );
$form->add( new \IPS\nexus\Form\Money( 'idm_nexus_transfee', json_decode( \IPS\Settings::i()->idm_nexus_transfee, TRUE ), FALSE, array(), NULL, NULL, NULL, 'idm_nexus_transfee' ) );
$form->add( new \IPS\nexus\Form\Money( 'idm_nexus_mincost', json_decode( \IPS\Settings::i()->idm_nexus_mincost, TRUE ), FALSE, array(), NULL, NULL, NULL, 'idm_nexus_mincost' ) );
$form->add( new \IPS\Helpers\Form\Node( 'idm_nexus_gateways', ( \IPS\Settings::i()->idm_nexus_gateways ) ? explode( ',', \IPS\Settings::i()->idm_nexus_gateways ) : 0, FALSE, array( 'class' => '\IPS\nexus\Gateway', 'zeroVal' => 'no_restriction', 'multiple' => TRUE ), NULL, NULL, NULL, 'idm_nexus_gateways' ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'idm_nexus_display', explode( ',', \IPS\Settings::i()->idm_nexus_display ), FALSE, array( 'options' => array( 'purchases' => 'idm_purchases', 'downloads' => 'downloads' ) ) ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'idm_nexus_display', explode( ',', \IPS\Settings::i()->idm_nexus_display ), FALSE, array( 'options' => array( 'purchases' => 'idm_purchases', 'downloads' => 'downloads' ) ), NULL, NULL, NULL, 'idm_nexus_display' ) );
}
return $form;
@@ -115,7 +121,7 @@ class _settings extends \IPS\Dispatcher\Controller
* @param \IPS\Helpers\Form $form The Form Object
* @param array $values Values
*/
protected function saveSettingsForm( \IPS\Helpers\Form $form, array $values )
protected function _saveSettingsForm( \IPS\Helpers\Form $form, array $values )
{
/* We can't store '' for idm_nexus_display as it will fall back to the default */
if ( \IPS\Application::appIsEnabled( 'nexus' ) and !$values['idm_nexus_display'] )
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,14 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _downloaders extends \IPS\Dispatcher\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* @brief Number of results per page
*/
const PER_PAGE = 25;
/**
@@ -43,72 +51,99 @@ class _downloaders extends \IPS\Dispatcher\Controller
*/
protected function manage()
{
$values = NULL;
$where = array( array( 'dmid>0' ) );
if ( isset( \IPS\Request::i()->form ) )
{
$form = new \IPS\Helpers\Form( 'form', 'go' );
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range' ), NULL, FALSE, array( 'start' => array( 'max' => new \IPS\DateTime() ), 'end' => array( 'max' => new \IPS\DateTime() ) ));
if ( $values = $form->values() )
{
if ( $values['stats_date_range']['start'] )
{
$where[] = array( 'dtime>?', $values['stats_date_range']['start']->getTimestamp() );
}
if ( $values['stats_date_range']['end'] )
{
$where[] = array( 'dtime<?', $values['stats_date_range']['end']->getTimestamp() );
}
}
else
$default = array(
'start' => \IPS\Request::i()->start ? \IPS\DateTime::ts( \IPS\Request::i()->start ) : NULL,
'end' => \IPS\Request::i()->end ? \IPS\DateTime::ts( \IPS\Request::i()->end ) : NULL
);
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range', $default, FALSE, array( 'start' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 0, 0, 0 ), 'time' => FALSE ), 'end' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 23, 59, 59 ), 'time' => FALSE ) ) ) );
if ( !$values = $form->values() )
{
\IPS\Output::i()->output = $form;
return;
}
}
/* Figure out start and end parameters for links */
$params = array(
'start' => !empty( $values['stats_date_range']['start'] ) ? $values['stats_date_range']['start']->getTimestamp() : \IPS\Request::i()->start,
'end' => !empty( $values['stats_date_range']['end'] ) ? $values['stats_date_range']['end']->getTimestamp() : \IPS\Request::i()->end
);
if( $params['start'] )
{
$where[] = array( 'dtime>?', $params['start'] );
}
if( $params['end'] )
{
$where[] = array( 'dtime<?', $params['end'] );
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$select = \IPS\Db::i()->select( 'dmid, COUNT(*) as downloads', 'downloads_downloads', $where, 'downloads DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'dmid', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
$mids = array();
foreach( $select as $row )
try
{
$mids[] = $row['dmid'];
$total = \IPS\Db::i()->select( 'COUNT(DISTINCT(dmid))', 'downloads_downloads', $where )->first();
}
$members = array();
if ( count( $mids ) )
catch ( \UnderflowException $e )
{
$members = iterator_to_array( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
$total = 0;
}
if( $total )
{
$select = \IPS\Db::i()->select( 'dmid, count(*) as downloads', 'downloads_downloads', $where, 'downloads DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'dmid' );
$mids = array();
foreach( $select as $row )
{
$mids[] = $row['dmid'];
}
$members = array();
if ( \count( $mids ) )
{
$members = iterator_to_array( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders' )->setQueryString( $params ),
ceil( $total / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders&form=1' )->setQueryString( $params ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('stats')->downloadsTable( $select, $pagination, $members );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_downloaders');
}
else
{
/* Return the no results message */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_downloaders'), \IPS\Member::loggedIn()->language()->addToStack('no_results'), FALSE , 'ipsPad', NULL, TRUE );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders' )->setQueryString( $values ),
ceil( $select->count( TRUE ) / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders&form=1' )->setQueryString( $values ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('stats')->downloadsTable( $select, $pagination, $members );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_downloaders');
}
}
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,11 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _downloads extends \IPS\Dispatcher\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* Execute
*
@@ -46,7 +51,7 @@ class _downloads extends \IPS\Dispatcher\Controller
'colors' => array( '#10967e', '#ea7963', '#de6470', '#6b9dde', '#b09be4', '#eec766', '#9fc973', '#e291bf', '#55c1a6', '#5fb9da' ),
'hAxis' => array( 'gridlines' => array( 'color' => '#f5f5f5' ) ),
'lineWidth' => 1,
'areaOpacity' => 0.4,
'areaOpacity' => 0.4
), 'AreaChart', 'monthly', array( 'start' => 0, 'end' => 0 ), array( 'dmid', 'dfid', 'dtime', 'dsize', 'dua', 'dip' ) );
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -25,6 +25,16 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _member extends \IPS\Dispatcher\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal("app=core&module=members&controller=members&do=view&id=" . \IPS\Request::i()->id . "&blockKey=core_ContentStatistics&block[core_ContentStatistics]=downloads_Downloads") );
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -23,6 +23,14 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
*/
class _submitters extends \IPS\Dispatcher\Controller
{
/**
* @brief Has been CSRF-protected
*/
public static $csrfProtected = TRUE;
/**
* @brief Number of results per page
*/
const PER_PAGE = 25;
/**
@@ -43,72 +51,99 @@ class _submitters extends \IPS\Dispatcher\Controller
*/
protected function manage()
{
$values = NULL;
$where = array();
if ( isset( \IPS\Request::i()->form ) )
{
$form = new \IPS\Helpers\Form( 'form', 'go' );
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range' ), NULL, FALSE, array( 'start' => array( 'max' => new \IPS\DateTime() ), 'end' => array( 'max' => new \IPS\DateTime() ) ) );
if ( $values = $form->values() )
{
if ( $values['stats_date_range']['start'] )
{
$where[] = array( 'file_submitted>?', $values['stats_date_range']['start']->getTimestamp() );
}
if ( $values['stats_date_range']['end'] )
{
$where[] = array( 'file_submitted<?', $values['stats_date_range']['end']->getTimestamp() );
}
}
else
$default = array(
'start' => \IPS\Request::i()->start ? \IPS\DateTime::ts( \IPS\Request::i()->start ) : NULL,
'end' => \IPS\Request::i()->end ? \IPS\DateTime::ts( \IPS\Request::i()->end ) : NULL
);
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range', $default, FALSE, array( 'start' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 0, 0, 0 ), 'time' => FALSE ), 'end' => array( 'max' => \IPS\DateTime::ts( time() )->setTime( 23, 59, 59 ), 'time' => FALSE ) ) ) );
if ( !$values = $form->values() )
{
\IPS\Output::i()->output = $form;
return;
}
}
/* Figure out start and end parameters for links */
$params = array(
'start' => !empty( $values['stats_date_range']['start'] ) ? $values['stats_date_range']['start']->getTimestamp() : \IPS\Request::i()->start,
'end' => !empty( $values['stats_date_range']['end'] ) ? $values['stats_date_range']['end']->getTimestamp() : \IPS\Request::i()->end
);
if( $params['start'] )
{
$where[] = array( 'file_submitted>?', $params['start'] );
}
if( $params['end'] )
{
$where[] = array( 'file_submitted<?', $params['end'] );
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
$page = isset( \IPS\Request::i()->page ) ? \intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$select = \IPS\Db::i()->select( 'file_submitter, COUNT(*) as files', 'downloads_files', $where, 'files DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'file_submitter', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )->join( 'core_members', 'core_members.member_id=downloads_files.file_submitter' );
$mids = array();
foreach( $select as $row )
try
{
$mids[] = $row['file_submitter'];
$total = \IPS\Db::i()->select( 'COUNT(DISTINCT(file_submitter))', 'downloads_files', $where )->first();
}
$members = array();
if ( count( $mids ) )
catch ( \UnderflowException $e )
{
$members = iterator_to_array( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
$total = 0;
}
if( $total > 0 )
{
$select = \IPS\Db::i()->select( 'file_submitter, count(*) as files', 'downloads_files', $where, 'files DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'file_submitter' )->join( 'core_members', 'core_members.member_id=downloads_files.file_submitter' );
$mids = array();
foreach( $select as $row )
{
$mids[] = $row['file_submitter'];
}
$members = array();
if ( \count( $mids ) )
{
$members = iterator_to_array( \IPS\Db::i()->select( '*', 'core_members', array( \IPS\Db::i()->in( 'member_id', $mids ) ) )->setKeyField('member_id') );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters' )->setQueryString( $params ),
ceil( $total / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters&form=1' )->setQueryString( $params ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'stats_include_hidden_content' ), 'info' );
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate('stats')->submittersTable( $select, $pagination, $members );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_submitters');
}
else
{
/* Return the no results message */
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->block( \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_submitters'), \IPS\Member::loggedIn()->language()->addToStack('no_results'), FALSE , 'ipsPad', NULL, TRUE );
}
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters' )->setQueryString( $values ),
ceil( $select->count( TRUE ) / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters&form=1' )->setQueryString( $values ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate( 'global', 'core' )->message( \IPS\Member::loggedIn()->language()->addToStack( 'stats_include_hidden_content' ), 'info' );
\IPS\Output::i()->output .= \IPS\Theme::i()->getTemplate('stats')->submittersTable( $select, $pagination, $members );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_submitters');
}
}
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -54,9 +54,9 @@ class _browse extends \IPS\Dispatcher\Controller
*/
protected function manage()
{
if ( isset( \IPS\Request::i()->currency ) and in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) and isset( \IPS\Request::i()->csrfKey ) and \IPS\Request::i()->csrfKey === \IPS\Session\Front::i()->csrfKey )
if ( isset( \IPS\Request::i()->currency ) and \in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) and isset( \IPS\Request::i()->csrfKey ) and \IPS\Request::i()->csrfKey === \IPS\Session\Front::i()->csrfKey )
{
$_SESSION['currency'] = \IPS\Request::i()->currency;
\IPS\Request::i()->setCookie( 'currency', \IPS\Request::i()->currency );
}
if ( isset( \IPS\Request::i()->id ) )
@@ -98,6 +98,13 @@ class _browse extends \IPS\Dispatcher\Controller
if ( \IPS\Settings::i()->idm_rss )
{
\IPS\Output::i()->rssFeeds['idm_rss_title'] = \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse&do=rss', 'front', 'downloads_rss' );
if ( \IPS\Member::loggedIn()->member_id )
{
$key = md5( ( \IPS\Member::loggedIn()->members_pass_hash ?: \IPS\Member::loggedIn()->email ) . \IPS\Member::loggedIn()->members_pass_salt );
\IPS\Output::i()->rssFeeds['idm_rss_title'] = \IPS\Output::i()->rssFeeds['idm_rss_title']->setQueryString( array( 'member' => \IPS\Member::loggedIn()->member_id , 'key' => $key ) );
}
}
/* Get stuff */
@@ -118,7 +125,7 @@ class _browse extends \IPS\Dispatcher\Controller
$new = ( \IPS\Settings::i()->idm_show_newest) ? \IPS\downloads\File::getItemsWithPermission( $newestWhere, NULL, 14, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, TRUE ) : array();
if (\IPS\Settings::i()->idm_highest_rated_categories )
if ( \IPS\Settings::i()->idm_highest_rated_categories )
{
$highestWhere = array( array( 'downloads_categories.copen=1 and ' . \IPS\Db::i()->in('file_cat', explode( ',', \IPS\Settings::i()->idm_highest_rated_categories ) ) ) );
}
@@ -165,25 +172,18 @@ class _browse extends \IPS\Dispatcher\Controller
*/
protected function _category( $category )
{
$category->clubCheckRules();
\IPS\Output::i()->sidebar['contextual'] = '';
$_count = \IPS\downloads\File::getItemsWithPermission( array( array( \IPS\downloads\File::$databasePrefix . \IPS\downloads\File::$databaseColumnMap['container'] . '=?', $category->_id ) ), NULL, 1, 'read', \IPS\Content\Hideable::FILTER_AUTOMATIC, 0, NULL, FALSE, FALSE, FALSE, TRUE );
if( !$_count )
{
/* Set breadcrumb */
/* If we're viewing a club, set the breadcrumbs appropriately */
if ( $club = $category->club() )
{
\IPS\core\FrontNavigation::$clubTabActive = TRUE;
\IPS\Output::i()->breadcrumb = array();
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), \IPS\Member::loggedIn()->language()->addToStack('module__core_clubs') );
\IPS\Output::i()->breadcrumb[] = array( $club->url(), $club->name );
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
if ( \IPS\Settings::i()->clubs_header == 'sidebar' )
{
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'clubs', 'core' )->header( $club, $category, 'sidebar' );
}
$club->setBreadcrumbs( $category );
}
else
{
@@ -255,27 +255,4 @@ class _browse extends \IPS\Dispatcher\Controller
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse&do=categories', 'front', 'downloads_categories' ), \IPS\Member::loggedIn()->language()->addToStack('download_categories') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->categories();
}
/**
* Latest Files RSS
*
* @return void
*/
protected function rss()
{
if( !\IPS\Settings::i()->idm_rss )
{
\IPS\Output::i()->error( 'rss_offline', '2D175/2', 403, 'rss_offline_admin' );
}
$document = \IPS\Xml\Rss::newDocument( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse', 'front', 'downloads' ), \IPS\Member::loggedIn()->language()->get('idm_rss_title'), \IPS\Member::loggedIn()->language()->get('idm_rss_title') );
foreach ( \IPS\downloads\File::getItemsWithPermission() as $file )
{
$document->addItem( $file->name, $file->url(), $file->desc, \IPS\DateTime::ts( $file->updated ), $file->id );
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
}
}
@@ -0,0 +1,141 @@
<?php
/**
* @brief Pending Version Controller
* @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 Apr 2020
*/
namespace IPS\downloads\modules\front\downloads;
/* 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;
}
/**
* Pending Version Controller
*/
class _pending extends \IPS\Content\Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\downloads\File\PendingVersion';
/**
* @brief Storage for loaded file
*/
protected $file = NULL;
/**
* @brief Storage for loaded version
*/
protected $version = NULL;
/**
* Execute
*
* @return void
*/
public function execute()
{
try
{
$this->file = \IPS\downloads\File::load( \IPS\Request::i()->file_id );
$this->version = \IPS\downloads\File\PendingVersion::load( \IPS\Request::i()->id );
if ( !$this->version->canUnhide() )
{
\IPS\Output::i()->error( 'node_error', '2D417/1', 404, '' );
}
}
catch ( \OutOfRangeException $e )
{
/* The version does not exist, but the file does. Redirect there instead. */
if( isset( $this->file ) )
{
\IPS\Output::i()->redirect( $this->file->url() );
}
\IPS\Output::i()->error( 'node_error', '2D417/2', 404, '' );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_view.js', 'downloads', 'front' ) );
parent::execute();
}
/**
* Execute
*
* @return void
*/
public function manage()
{
/* Display */
\IPS\Output::i()->title = $this->file->name;
$container = $this->file->container();
foreach ( $container->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $container->url(), $container->_title );
\IPS\Output::i()->breadcrumb[] = array( $this->file->url(), $this->file->name );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack('pending_version') );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->pendingView( $this->file, $this->version );
}
/**
* Download a file
*
* @return void
*/
public function download()
{
try
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_id=? AND record_file_id=?', \IPS\Request::i()->fileId, $this->file->id ) )->first();
}
catch( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2D417/3', 404, '' );
}
/* Download */
if ( $record['record_type'] === 'link' )
{
\IPS\Output::i()->redirect( $record['record_location'] );
}
else
{
$file = \IPS\File::get( 'downloads_Files', $record['record_location'] );
$file->originalFilename = $record['record_realname'] ?: $file->originalFilename;
}
/* If it's an AWS file just redirect to it */
if ( $signedUrl = $file->generateTemporaryDownloadUrl() )
{
\IPS\Output::i()->redirect( $signedUrl );
}
/* Send headers and print file */
\IPS\Output::i()->sendStatusCodeHeader( 200 );
\IPS\Output::i()->sendHeader( "Content-type: " . \IPS\File::getMimeType( $file->originalFilename ) . ";charset=UTF-8" );
\IPS\Output::i()->sendHeader( "Content-Security-Policy: default-src 'none'; sandbox" );
\IPS\Output::i()->sendHeader( "X-Content-Security-Policy: default-src 'none'; sandbox" );
\IPS\Output::i()->sendHeader( 'Content-Disposition: ' . \IPS\Output::getContentDisposition( 'attachment', $file->originalFilename ) );
\IPS\Output::i()->sendHeader( "Content-Length: " . $file->filesize() );
$file->printFile();
exit;
}
}
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -132,7 +132,19 @@ class _submit extends \IPS\Dispatcher\Controller
}
/* Add the fields */
$form->add( new \IPS\Helpers\Form\Upload( 'files', $files, ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => $category->maxfile !== NULL ? ( $category->maxfile / 1024 ) : NULL, 'multiple' => TRUE, 'minimize' => FALSE ) ) );
$maximums = array();
if( $category->maxfile !== NULL AND !$category->club() )
{
$maximums[] = ( $category->maxfile / 1024 );
}
if( \IPS\Member::loggedIn()->group['idm_max_size'] !== -1 )
{
$maximums[] = ( \IPS\Member::loggedIn()->group['idm_max_size'] / 1024 );
}
$form->add( new \IPS\Helpers\Form\Upload( 'files', $files, ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => ( ( \count( $maximums ) ) ? min( $maximums ) : NULL ), 'multiple' => $category->multiple_files, 'minimize' => FALSE ) ) );
if ( !isset( \IPS\Request::i()->bulk ) )
{
@@ -145,7 +157,7 @@ class _submit extends \IPS\Dispatcher\Controller
{
$form->add( new \IPS\Helpers\Form\Stack( 'import_files', array(), FALSE, array( 'placeholder' => \IPS\ROOT_PATH ), function( $val )
{
if( $val and is_array( $val ) )
if( $val and \is_array( $val ) )
{
foreach ( $val as $file )
{
@@ -190,7 +202,10 @@ class _submit extends \IPS\Dispatcher\Controller
}
/* Version field (we only show this on create */
$form->add( new \IPS\Helpers\Form\Text( 'file_version', '1.0.0', FALSE, array( 'maxLength' => 32 ) ) );
if( $category->version_numbers )
{
$form->add( new \IPS\Helpers\Form\Text( 'file_version', '1.0.0', ( $category->version_numbers == 2 ) ? TRUE : FALSE, array( 'maxLength' => 32 ) ) );
}
}
if ( $values = $form->values() )
@@ -199,12 +214,17 @@ class _submit extends \IPS\Dispatcher\Controller
if ( empty( $values['files'] ) and empty( $values['url_files'] ) and empty( $values['import_files'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_files');
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
return \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), TRUE, ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
}
elseif ( !$category->multiple_files AND \is_array( $values['files'] ) AND ( \count( $values['files'] ?? [] ) + \count( $values['url_files'] ?? [] ) + \count( $values['import_files'] ?? [] ) > 1 ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_too_many_files');
return \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), TRUE, ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
}
if ( !isset( \IPS\Request::i()->bulk ) && $category->bitoptions['reqss'] and empty( $values['screenshots'] ) and empty( $values['url_screenshots'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_screenshots');
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
return \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), TRUE, ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
}
/* Get any records we had before in case we need to delete them */
@@ -216,6 +236,13 @@ class _submit extends \IPS\Dispatcher\Controller
$linkedFiles = array();
$screenshots = array();
$linkedScreenshots = array();
/* Files may not be an array since we have an option to limit to a single upload */
if( !\is_array( $values['files'] ) )
{
$values['files'] = [ $values['files'] ];
}
foreach ( $values['files'] as $file )
{
$files[ $k ] = (string) $file;
@@ -369,12 +396,18 @@ class _submit extends \IPS\Dispatcher\Controller
if ( !isset( \IPS\Request::i()->bulk ) )
{
$file = \IPS\downloads\File::createFromForm( array_merge( $data, $values, array( 'postKey' => \IPS\Request::i()->postKey ) ), $category );
$file->markRead();
/* Redirect */
if( $file->author()->member_id OR $file->canView() )
if ( isset( $values['guest_email'] ) )
{
$url = \IPS\Http\Url::internal( 'app=core&module=system&controller=register', 'front', 'register' );
$message = NULL;
}
elseif( $file->author()->member_id OR $file->canView() )
{
$url = $file->url();
$message = ( isset( $values['import_files'] ) AND count( $values['import_files'] ) ) ? \IPS\Member::loggedIn()->language()->addToStack('file_imported_removed') : NULL;
$message = ( isset( $values['import_files'] ) AND \count( $values['import_files'] ) ) ? \IPS\Member::loggedIn()->language()->addToStack('file_imported_removed') : NULL;
}
else
{
@@ -397,8 +430,19 @@ class _submit extends \IPS\Dispatcher\Controller
return array( 'category' => $category->_id, 'postKey' => \IPS\Request::i()->postKey, 'files' => $files, 'url_files' => $linkedFiles, 'screenshots' => $screenshots, 'url_screenshots' => $linkedScreenshots );
}
}
$guestPostBeforeRegister = ( !\IPS\Member::loggedIn()->member_id ) ? ( $category and !$category->can( 'add', \IPS\Member::loggedIn(), FALSE ) ) : NULL;
$modQueued = \IPS\downloads\File::moderateNewItems( \IPS\Member::loggedIn(), $category, $guestPostBeforeRegister );
if ( $guestPostBeforeRegister or $modQueued )
{
$postingInformation = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->postingInformation( $guestPostBeforeRegister, $modQueued, TRUE );
}
else
{
$postingInformation = NULL;
}
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
return \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), TRUE, ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ), $postingInformation );
};
/**
@@ -437,37 +481,13 @@ class _submit extends \IPS\Dispatcher\Controller
$form->addHeader( $displayName );
/* Form Elements */
foreach ( \IPS\downloads\File::formElements( NULL, $category ) as $input )
foreach ( \IPS\downloads\File::formElements( NULL, $category, "filedata_{$key}_" ) as $input )
{
\IPS\Member::loggedIn()->language()->words[ "filedata_{$key}_{$input->name}" ] = \IPS\Member::loggedIn()->language()->addToStack( $input->name, FALSE );
if ( !$input->value and in_array( $input->name, array( 'file_title', 'file_desc' ) ) )
\IPS\Member::loggedIn()->language()->words[ $input->name ] = \IPS\Member::loggedIn()->language()->addToStack( mb_substr( $input->name, mb_strlen( "filedata_{$key}_" ) ), FALSE );
if ( !$input->value and \in_array( $input->name, array( "filedata_{$key}_file_title", "filedata_{$key}_file_desc" ) ) )
{
$input->value = $displayName;
}
$input->name = "filedata_{$key}_{$input->name}";
if ( $input instanceof \IPS\Helpers\Form\Editor )
{
$input->options['autoSaveKey'] .= $key;
}
if ( isset( $input->options['toggles'] ) )
{
foreach ( $input->options['toggles'] as $trigger => $toggles )
{
foreach ( $toggles as $k => $v )
{
$input->options['toggles'][ $trigger ][ $k ] = "{$v}_{$key}";
}
}
}
if ( $input->htmlId )
{
$input->htmlId = "{$input->htmlId}_{$key}";
}
$form->add( $input );
}
@@ -486,9 +506,12 @@ class _submit extends \IPS\Dispatcher\Controller
}
/* Version field (we only show this on create */
$form->add( new \IPS\Helpers\Form\Text( "filedata_{$key}_file_version", '1.0.0', FALSE, array( 'maxLength' => 32 ) ) );
\IPS\Member::loggedIn()->language()->words[ "filedata_{$key}_file_version" ] = \IPS\Member::loggedIn()->language()->addToStack( 'file_version', FALSE );
/* Version field */
if( $category->version_numbers )
{
$form->add( new \IPS\Helpers\Form\Text( "filedata_{$key}_file_version", '1.0.0', ( $category->version_numbers == 2 ) ? TRUE : FALSE, array( 'maxLength' => 32 ) ) );
\IPS\Member::loggedIn()->language()->words[ "filedata_{$key}_file_version" ] = \IPS\Member::loggedIn()->language()->addToStack( 'file_version', FALSE );
}
}
@@ -553,6 +576,7 @@ class _submit extends \IPS\Dispatcher\Controller
{
/* $values isn't going to work as is here */
$save = array( 'postKey' => md5( "{$data['postKey']}-{$key}" ) );
$customFields = [];
$len = mb_strlen( "filedata_{$key}_" );
foreach ( $values as $k => $v )
{
@@ -560,10 +584,22 @@ class _submit extends \IPS\Dispatcher\Controller
{
$save[ mb_substr( $k, $len ) ] = $v;
}
elseif ( mb_substr( $k, 0, $len + 16 ) == "downloads_field_filedata_{$key}_" ) // That's a custom field, because the underscore after the language prefix is hardcoded
{
$customFields[] = mb_substr( $k, $len + 16 );
$save[ 'downloads_field_' . mb_substr( $k, $len + 16 ) ] = $v;
}
}
\IPS\downloads\File::createFromForm( $save, $category, FALSE );
$file = \IPS\downloads\File::createFromForm( $save, $category, FALSE );
\IPS\File::claimAttachments( "filedata_{$key}_downloads-new-file", $file->id, NULL, 'desc' );
foreach ( $customFields as $k )
{
\IPS\File::claimAttachments( md5( 'IPS\downloads\Field-filedata_' . $key . '_' . $k . '-new' ), $file->id, $k, 'fields' );
}
$file->markRead();
}
if ( \IPS\Member::loggedIn()->moderateNewContent() OR \IPS\downloads\File::moderateNewItems( \IPS\Member::loggedIn(), $category ) )
{
\IPS\downloads\File::_sendUnapprovedNotifications( $category );
@@ -615,12 +651,9 @@ class _submit extends \IPS\Dispatcher\Controller
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/plupload.full.min.js', 'core', 'interface' ) );
}
if ( \IPS\downloads\File::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$wizard = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $wizard;
}
\IPS\Output::i()->output = $wizard;
$category = NULL;
\IPS\Output::i()->sidebar['enabled'] = FALSE;
if ( isset( \IPS\Request::i()->category ) )
{
try
@@ -633,16 +666,13 @@ class _submit extends \IPS\Dispatcher\Controller
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), \IPS\Member::loggedIn()->language()->addToStack('module__core_clubs') );
\IPS\Output::i()->breadcrumb[] = array( $club->url(), $club->name );
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
if ( \IPS\Settings::i()->clubs_header == 'sidebar' )
{
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'clubs', 'core' )->header( $club, $category, 'sidebar' );
}
}
}
catch ( \OutOfRangeException $e ) { }
}
\IPS\Output::i()->output = (string) $wizard;
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'submit_a_file' ) );
}
}
@@ -12,7 +12,7 @@
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
@@ -38,7 +38,9 @@ class _view extends \IPS\Content\Controller
try
{
$this->file = \IPS\downloads\File::load( \IPS\Request::i()->id );
$this->file->container()->clubCheckRules();
/* Downloading and viewing the embed does not need to check the permission, as there is a separate download permission already and embed method need to return it's own error */
if ( !$this->file->canView( \IPS\Member::loggedIn() ) and \IPS\Request::i()->do != 'download' and \IPS\Request::i()->do != 'embed' )
{
@@ -69,13 +71,13 @@ class _view extends \IPS\Content\Controller
{
/* Init */
parent::manage();
/* Sort out comments and reviews */
$tabs = $this->file->commentReviewTabs();
$_tabs = array_keys( $tabs );
$tab = isset( \IPS\Request::i()->tab ) ? \IPS\Request::i()->tab : array_shift( $_tabs );
$activeTabContents = $this->file->commentReviews( $tab );
$commentsAndReviews = count( $tabs ) ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->commentsAndReviewsTabs( \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $this->file->url(), 'tab', FALSE, TRUE ), md5( $this->file->url() ) ) : NULL;
$commentsAndReviews = \count( $tabs ) ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->commentsAndReviewsTabs( \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $this->file->url(), 'tab', FALSE, TRUE ), md5( $this->file->url() ) ) : NULL;
if ( \IPS\Request::i()->isAjax() and !isset( \IPS\Request::i()->changelog ) )
{
\IPS\Output::i()->output = $activeTabContents;
@@ -113,7 +115,19 @@ class _view extends \IPS\Content\Controller
{
if ( $fields[ 'field_' . $field->id ] !== null AND $fields[ 'field_' . $field->id ] !== '' )
{
$cfields[ 'field_' . $field->id ] = $field->displayValue( $fields[ 'field_' . $field->id ] );
/* Check for download permission, this is also used to determine if the file has been purchased by the viewer
If this is flagged as a paid field, and download is not available, do not show it */
if( $field->paid_field AND !$this->file->canDownload( NULL, \IPS\Member::loggedIn() ) )
{
continue;
}
$cfields[ 'field_' . $field->id ] = array(
'type' => $field->type,
'key' => 'field_' . $field->id,
'value' => $field->displayValue( $fields[ 'field_' . $field->id ] ),
'location' => $field->display_location
);
}
}
}
@@ -125,12 +139,12 @@ class _view extends \IPS\Content\Controller
"operatingSystem" => "N/A",
'url' => (string) $this->file->url(),
'name' => $this->file->mapped('title'),
'description' => strip_tags( $this->file->truncated() ),
'description' => $this->file->truncated( TRUE, NULL ),
'applicationCategory' => $this->file->container()->_title,
'downloadUrl' => (string) $this->file->url( 'download' ),
'dateCreated' => \IPS\DateTime::ts( $this->file->submitted )->format( \IPS\DateTime::ISO8601 ),
'fileSize' => \IPS\Output\Plugin\Filesize::humanReadableFilesize( $this->file->filesize() ),
'softwareVersion' => $this->file->version,
'softwareVersion' => $this->file->version ?: '1.0',
'author' => array(
'@type' => 'Person',
'name' => \IPS\Member::load( $this->file->submitter )->name,
@@ -171,7 +185,7 @@ class _view extends \IPS\Content\Controller
);
}
if( $this->file->screenshots()->getInnerIterator()->count( true ) )
if( $this->file->screenshots()->getInnerIterator()->count() )
{
\IPS\Output::i()->jsonLd['download']['screenshot'] = array();
@@ -274,6 +288,8 @@ class _view extends \IPS\Content\Controller
$this->file->purchasable = (bool) \IPS\Request::i()->value;
$this->file->save();
\IPS\Session::i()->modLog( 'modlog__action_purchasestatus', array( (string) $this->file->url() => FALSE, $this->file->name => FALSE ), $this->file );
\IPS\Output::i()->redirect( $this->file->url(), 'saved' );
}
@@ -296,19 +312,26 @@ class _view extends \IPS\Content\Controller
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/K', 403, '' );
}
/* Have we accepted the terms? */
if ( $downloadTerms = $this->file->container()->message('disclaimer') and \in_array( $this->file->container()->disclaimer_location, [ 'purchase', 'both'] ) and !isset( \IPS\Request::i()->confirm ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->purchaseTerms( $this->file, $downloadTerms, $this->file->url('buy')->csrf()->setQueryString( 'confirm', 1 ) );
return;
}
/* Is it associated with a Nexus product? */
if ( $this->file->nexus )
{
$productIds = explode( ',', $this->file->nexus );
if ( count( $productIds ) === 1 )
if ( \count( $productIds ) === 1 )
{
try
{
\IPS\Output::i()->redirect( \IPS\nexus\Package::load( array_pop( $productIds ) )->url() );
}
catch ( \OutOfRangeExcpetion $e )
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/F', 404, '' );
}
@@ -361,7 +384,7 @@ class _view extends \IPS\Content\Controller
/* Generate the invoice */
$invoice = new \IPS\nexus\Invoice;
$invoice->currency = ( isset( $_SESSION['currency'] ) and in_array( $_SESSION['currency'], \IPS\nexus\Money::currencies() ) ) ? $_SESSION['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
$invoice->currency = ( isset( \IPS\Request::i()->cookie['currency'] ) and \in_array( \IPS\Request::i()->cookie['currency'], \IPS\nexus\Money::currencies() ) ) ? \IPS\Request::i()->cookie['currency'] : \IPS\nexus\Customer::loggedIn()->defaultCurrency();
$invoice->member = \IPS\nexus\Customer::loggedIn();
$invoice->addItem( $item );
$invoice->return_uri = "app=downloads&module=downloads&controller=view&id={$this->file->id}";
@@ -430,14 +453,14 @@ class _view extends \IPS\Content\Controller
$files = $this->file->files( isset( \IPS\Request::i()->version ) ? \IPS\Request::i()->version : NULL );
/* Have we accepted the terms? */
if ( $downloadTerms = $category->message('disclaimer') and !isset( \IPS\Request::i()->confirm ) )
if ( $downloadTerms = $category->message('disclaimer') and \in_array( $this->file->container()->disclaimer_location, [ 'download', 'both'] ) and !isset( \IPS\Request::i()->confirm ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, $downloadTerms, null, $confirmUrl, count( $files ) > 1 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, $downloadTerms, null, $confirmUrl, \count( $files ) > 1 );
return;
}
/* File Selected? */
if ( count( $files ) === 1 or ( isset( \IPS\Request::i()->r ) ) )
if ( \count( $files ) === 1 or ( isset( \IPS\Request::i()->r ) ) )
{
/* Which file? */
foreach ( $files as $k => $file )
@@ -460,15 +483,20 @@ class _view extends \IPS\Content\Controller
}
/* Time Delay */
if ( \IPS\Member::loggedIn()->group['idm_wait_period'] )
if ( \IPS\Member::loggedIn()->group['idm_wait_period'] AND ( !$this->file->isPaid() OR \IPS\Member::loggedIn()->group['idm_paid_restrictions'] ) )
{
if ( isset( \IPS\Request::i()->t ) )
{
$timerKey = "downloads_delay_" . md5( (string) $file );
if ( !isset( $_SESSION[ $timerKey ] ) )
$cookieDelay = 0;
if ( !isset( \IPS\Request::i()->cookie[ $timerKey ] ) )
{
$_SESSION[ $timerKey ] = time();
\IPS\Request::i()->setCookie( $timerKey, time() );
}
else
{
$cookieDelay = \IPS\Request::i()->cookie[ $timerKey ];
}
if ( \IPS\Request::i()->isAjax() )
@@ -476,19 +504,19 @@ class _view extends \IPS\Content\Controller
\IPS\Output::i()->json( array( 'download' => time() + \IPS\Member::loggedIn()->group['idm_wait_period'], 'currentTime' => time() ) );
}
if ( $_SESSION[ $timerKey ] > ( time() - \IPS\Member::loggedIn()->group['idm_wait_period'] ) )
if ( $cookieDelay > ( time() - \IPS\Member::loggedIn()->group['idm_wait_period'] ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1, $data['record_id'], ( $_SESSION[ $timerKey ] + \IPS\Member::loggedIn()->group['idm_wait_period'] ) - time() );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, \count( $files ) > 1, $data['record_id'], ( $cookieDelay + \IPS\Member::loggedIn()->group['idm_wait_period'] ) - time() );
return;
}
else
{
unset( $_SESSION[ $timerKey ] );
\IPS\Request::i()->setCookie( $timerKey, -1 );
}
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, \count( $files ) > 1 );
return;
}
}
@@ -533,7 +561,7 @@ class _view extends \IPS\Content\Controller
}
else
{
$file = \IPS\File::get( 'downloads_Files', $data['record_location'] );
$file = \IPS\File::get( 'downloads_Files', $data['record_location'], $data['record_size'] );
$file->originalFilename = $data['record_realname'] ?: $file->originalFilename;
$this->_download( $file );
}
@@ -542,7 +570,7 @@ class _view extends \IPS\Content\Controller
/* Nope - choose one */
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, \count( $files ) > 1 );
}
}
@@ -580,15 +608,22 @@ class _view extends \IPS\Content\Controller
} );
/* If it's an AWS file just redirect to it */
if ( $file instanceof \IPS\File\Amazon )
if ( $signedUrl = $file->generateTemporaryDownloadUrl() )
{
\IPS\Output::i()->redirect( $file->generateTemporaryDownloadUrl() );
\IPS\Output::i()->redirect( $signedUrl );
}
/* Print the file, honoring ranges */
try
{
$ranges = new \IPS\Http\Ranges( $file, (int) \IPS\Member::loggedIn()->group['idm_throttling'] );
if ( \IPS\Member::loggedIn()->group['idm_throttling'] AND ( !$this->file->isPaid() OR \IPS\Member::loggedIn()->group['idm_paid_restrictions'] ) )
{
$ranges = new \IPS\Http\Ranges( $file, (int) \IPS\Member::loggedIn()->group['idm_throttling'] );
}
else
{
$ranges = new \IPS\Http\Ranges( $file );
}
}
catch( \RuntimeException $e )
{
@@ -599,7 +634,7 @@ class _view extends \IPS\Content\Controller
/* If using PHP-FPM, close the request so that __destruct tasks are run after data is flushed to the browser
@see http://www.php.net/manual/en/function.fastcgi-finish-request.php */
if( function_exists( 'fastcgi_finish_request' ) )
if( \function_exists( 'fastcgi_finish_request' ) )
{
fastcgi_finish_request();
}
@@ -825,34 +860,68 @@ class _view extends \IPS\Content\Controller
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_submit.js', 'downloads', 'front' ) );
/* Permission check */
if ( !$this->file->canEdit() )
if ( !$this->file->canEdit() OR $this->file->hasPendingVersion() )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/C', 403, '' );
}
$category = $this->file->container();
\IPS\Output::i()->sidebar['enabled'] = FALSE;
/* Club */
try
{
if ( $club = $category->club() )
{
\IPS\core\FrontNavigation::$clubTabActive = TRUE;
\IPS\Output::i()->breadcrumb = array();
\IPS\Output::i()->breadcrumb[] = array( \IPS\Http\Url::internal( 'app=core&module=clubs&controller=directory', 'front', 'clubs_list' ), \IPS\Member::loggedIn()->language()->addToStack('module__core_clubs') );
\IPS\Output::i()->breadcrumb[] = array( $club->url(), $club->name );
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
}
}
catch ( \OutOfRangeException $e ) { }
/* Require approval */
$requireApproval = FALSE;
if( $category->bitoptions['moderation'] and $category->bitoptions['moderation_edits'] and !$this->file->canUnhide() )
{
$requireApproval = TRUE;
}
$postingInformation = ( $requireApproval ) ? \IPS\Theme::i()->getTemplate( 'forms', 'core' )->postingInformation( NULL, TRUE, TRUE ) : NULL;
/* Build form */
$form = new \IPS\Helpers\Form;
$form->addHeader( 'new_version_details' );
if ( $category->versioning !== 0 and \IPS\Member::loggedIn()->group['idm_bypass_revision'] )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'file_save_revision', TRUE ) );
}
$form->add( new \IPS\Helpers\Form\Text( 'file_version', $this->file->version, ( $category->versioning !== 0 ), array( 'maxLength' => 32 ) ) );
$form->add( new \IPS\Helpers\Form\Editor( 'file_changelog', $this->file->changelog, FALSE, array( 'app' => 'downloads', 'key' => 'Downloads', 'autoSaveKey' => "downloads-{$this->file->id}-changelog") ) );
$form->addHeader( 'upload_files' );
$form->add( new \IPS\Helpers\Form\Upload( 'files', iterator_to_array( $this->file->files( NULL, FALSE ) ), ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => $category->maxfile ? ( $category->maxfile / 1024 ) : NULL, 'multiple' => TRUE, 'retainDeleted' => TRUE ) ) );
if( $category->version_numbers )
{
$form->add( new \IPS\Helpers\Form\Text( 'file_version', $this->file->version, ( $category->version_numbers == 2 ) ? TRUE : FALSE, array( 'maxLength' => 32 ) ) );
}
$form->add( new \IPS\Helpers\Form\Editor( 'file_changelog', NULL, FALSE, array( 'app' => 'downloads', 'key' => 'Downloads', 'autoSaveKey' => "downloads-{$this->file->id}-changelog", 'allowAttachments' => FALSE ) ) );
$linkedFiles = iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'link' ) ) );
$defaultFiles = iterator_to_array( $this->file->files( NULL, FALSE ) );
if( !$category->multiple_files )
{
$defaultFiles = array_pop( $defaultFiles );
}
$fileField = new \IPS\Helpers\Form\Upload( 'files', $defaultFiles, ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => $category->maxfile ? ( $category->maxfile / 1024 ) : NULL, 'multiple' => $category->multiple_files, 'retainDeleted' => TRUE ) );
$fileField->label = \IPS\Member::loggedIn()->language()->addToStack('downloads_file');
$form->add( $fileField );
$linkedFiles = iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0 AND record_hidden=0', $this->file->id, 'link' ) ) );
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'url_files', $linkedFiles, FALSE, array( 'stackFieldType' => 'Url' ), array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
else if ( count( $linkedFiles ) > 0 )
else if ( \count( $linkedFiles ) > 0 )
{
$form->addMessage( 'url_files_no_perm' );
}
@@ -861,7 +930,7 @@ class _view extends \IPS\Content\Controller
{
$form->add( new \IPS\Helpers\Form\Stack( 'import_files', array(), FALSE, array( 'placeholder' => \IPS\ROOT_PATH ), function( $val )
{
if( is_array( $val ) )
if( \is_array( $val ) )
{
foreach ( $val as $file )
{
@@ -894,52 +963,76 @@ class _view extends \IPS\Content\Controller
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
//iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'sslink' ) ) )
//
$form->add( new \IPS\downloads\Form\LinkedScreenshots( 'url_screenshots', array(
'values' => iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'sslink' ) )->setKeyField('record_id')->setValueField('record_location') ),
'values' => iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0 AND record_hidden=0', $this->file->id, 'sslink' ) )->setKeyField('record_id')->setValueField('record_location') ),
'default' => $this->file->_primary_screenshot
), FALSE, array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
}
/* Check for any extra form elements */
$this->file->newVersionFormElements( $form );
/* Output */
\IPS\Output::i()->title = $this->file->name;
/* Handle submissions */
if ( $values = $form->values() )
{
{
/* Check */
if ( empty( $values['files'] ) and empty( $values['url_files'] ) and empty( $values['import_files'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_files');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), FALSE, 0, $postingInformation, $category->versioning !== 0 );
return (string) $form;
}
elseif ( !$category->multiple_files AND \is_array( $values['files'] ) AND ( \count( $values['files'] ?? [] ) + \count( $values['url_files'] ?? [] ) + \count( $values['import_files'] ?? [] ) > 1 ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_too_many_files');
return \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), FALSE, 0, $postingInformation, $category->versioning !== 0 );
}
if ( $category->bitoptions['reqss'] and empty( $values['screenshots'] ) and empty( $values['url_screenshots'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_screenshots');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $category, $category->message('subterms'), FALSE, 0, $postingInformation, $category->versioning !== 0 );
return (string) $form;
}
/* Versioning */
if( $requireApproval )
{
$fileObj = new \IPS\downloads\File\PendingVersion;
$fileObj->file_id = $this->file->id;
$fileObj->member_id = \IPS\Member::loggedIn()->member_id;
$fileObj->form_values = $values;
}
else
{
$fileObj = $this->file;
}
$existingRecords = array();
$existingScreenshots = array();
$existingLinks = array();
$existingScreenshotLinks = array();
if ( $category->versioning !== 0 and ( !\IPS\Member::loggedIn()->group['idm_bypass_revision'] or $values['file_save_revision'] ) )
{
$this->file->saveVersion();
$fileObj->saveVersion();
}
else
{
$existingRecords = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'upload', 0 ) ) ) );
$existingScreenshots = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'ssupload', 0 ) ) ) );
$existingRecords = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'upload', 0 ) )->setKeyField('record_id')->setValueField('record_location') ) );
$existingScreenshots = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'ssupload', 0 ) )->setKeyField('record_id')->setValueField('record_location') ) );
$existingLinks = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'link', 0 ) )->setKeyField('record_id')->setValueField('record_location') ) );
$existingScreenshotLinks = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=?', $this->file->id, 'sslink', 0 ) )->setKeyField('record_id')->setValueField('record_location') ) );
}
/* Files may not be an array since we have an option to limit to a single upload */
if( !\is_array( $values['files'] ) )
{
$values['files'] = [ $values['files'] ];
}
/* Insert the new records */
foreach ( $values['files'] as $file )
{
@@ -958,6 +1051,7 @@ class _view extends \IPS\Content\Controller
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
'record_hidden' => $requireApproval
) );
}
}
@@ -982,6 +1076,7 @@ class _view extends \IPS\Content\Controller
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
'record_hidden' => $requireApproval
) );
}
}
@@ -1005,6 +1100,7 @@ class _view extends \IPS\Content\Controller
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
'record_hidden' => $requireApproval
) );
}
}
@@ -1015,7 +1111,7 @@ class _view extends \IPS\Content\Controller
foreach ( $values['screenshots'] as $_key => $file )
{
/* If this was the primary screenshot, convert back */
if( is_array( $file ) )
if( \is_array( $file ) )
{
$file = $file['fileurl'];
}
@@ -1071,7 +1167,8 @@ class _view extends \IPS\Content\Controller
'record_size' => $file->filesize(),
'record_time' => time(),
'record_no_watermark' => $noWatermark,
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0,
'record_hidden' => $requireApproval
) );
}
}
@@ -1098,72 +1195,82 @@ class _view extends \IPS\Content\Controller
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0,
'record_hidden' => $requireApproval
) );
}
}
}
$deletions = array( 'records' => array(), 'links' => array() );
/* Delete any we're not using anymore */
foreach ( $existingRecords as $url )
foreach ( $existingRecords as $recordId => $url )
{
$deletions['records'][ $recordId ] = array( 'handler' => 'downloads_Files', 'url' => $url );
}
foreach ( $existingScreenshots as $recordId => $url )
{
$deletions['records'][ $recordId ] = array( 'handler' => 'downloads_Screenshots', 'url' => $url );
}
foreach ( array_merge( $existingLinks, $existingScreenshotLinks ) as $id => $url )
{
$deletions['links'][ $id ] = $id;
}
if( $requireApproval )
{
$fileObj->record_deletions = $deletions;
}
else
{
array_walk( $deletions['records'], function( $arr, $key ) use( $fileObj ) {
$fileObj->deleteRecords( $key, $arr['url'], $arr['handler'] );
});
$fileObj->deleteRecords( $deletions['links'] );
/* Set the new details */
$fileObj->version = ( isset( $values['file_version'] ) ) ? $values['file_version'] : NULL;
$fileObj->changelog = $values['file_changelog'];
}
/* These are specific to unapproved updates */
if ( !$requireApproval )
{
$fileObj->size = \floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'upload' ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first() );
/* Work out the new primary screenshot */
try
{
$file = \IPS\File::get( 'downloads_Files', $url )->delete();
$this->file->primary_screenshot = \IPS\Db::i()->select( 'record_id', 'downloads_files_records', array( 'record_file_id=? AND ( record_type=? OR record_type=? ) AND record_backup=0 AND record_hidden=0', $this->file->id, 'ssupload', 'sslink' ), 'record_default DESC, record_id ASC', NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_location=?', $url ) );
}
foreach ( $existingScreenshots as $url )
{
try
{
$file = \IPS\File::get( 'downloads_Screenshots', $url )->delete();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_location=?', $url ) );
}
foreach ( $existingLinks as $id => $url )
{
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_id=?', $id ) );
}
foreach ( $existingScreenshotLinks as $id => $url )
{
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_id=?', $id ) );
}
/* Set the new details */
$this->file->version = $values['file_version'];
$this->file->changelog = $values['file_changelog'];
$this->file->size = floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'upload' ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first() );
/* Work out the new primary screenshot */
try
{
$this->file->primary_screenshot = \IPS\Db::i()->select( 'record_id', 'downloads_files_records', array( 'record_file_id=? AND ( record_type=? OR record_type=? ) AND record_backup=0', $this->file->id, 'ssupload', 'sslink' ), 'record_default DESC, record_id ASC', NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
}
catch ( \UnderflowException $e ) { }
/* Does it have to be reapproved? */
if ( $category->bitoptions['moderation'] and $category->bitoptions['moderation_edits'] and !$this->file->canUnhide() )
{
$this->file->open = 0;
catch ( \UnderflowException $e ) { }
}
/* Save */
$this->file->updated = time();
$this->file->save();
/* Send notifications */
if ( $this->file->open )
$fileObj->updated = time();
$fileObj->save();
if( $requireApproval )
{
$this->file->sendUpdateNotifications();
$this->file->save();
$fileObj->sendUnapprovedNotification();
}
$this->file->processAfterNewVersion( $values );
else
{
/* Send notifications */
if ( $this->file->open )
{
$this->file->sendUpdateNotifications();
}
else
{
$this->file->sendUnapprovedNotification();
}
$this->file->processAfterNewVersion( $values );
}
/* Boink */
\IPS\Output::i()->redirect( $this->file->url() );
}
@@ -1180,7 +1287,7 @@ class _view extends \IPS\Content\Controller
catch ( \Exception $e ) { }
\IPS\Output::i()->breadcrumb[] = array( $this->file->url(), $this->file->name );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->submissionForm( $form, $this->file->container(), $this->file->container()->message('subterms'), FALSE, 0, $postingInformation, $category->versioning !== 0 );
}
/**
@@ -1209,6 +1316,60 @@ class _view extends \IPS\Content\Controller
}
/* Display form */
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );;
\IPS\Output::i()->output = $form->customTemplate( array( \IPS\Theme::i()->getTemplate( 'forms', 'core' ), 'popupTemplate' ) );
}
/**
* Subscribe
*
* @return void
*/
function toggleSubscription()
{
\IPS\Session::i()->csrfCheck();
if( $this->file->subscribed() )
{
\IPS\Db::i()->delete( 'downloads_files_notify', array( 'notify_member_id=? and notify_file_id=?', \IPS\Member::loggedIn()->member_id, $this->file->id ) );
$subscribed = FALSE;
}
else
{
\IPS\Db::i()->replace( 'downloads_files_notify', array( 'notify_member_id' => \IPS\Member::loggedIn()->member_id, 'notify_file_id' => $this->file->id ) );
$subscribed = TRUE;
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( $subscribed ? 'subscribed' : 'unsubscribed' );
}
else
{
\IPS\Output::i()->redirect( $this->file->url(), $subscribed ? 'file_subscribed' : 'file_unsubscribed' );
}
}
/**
* Subscribe Hover
*
* @return void
*/
function subscribeBlurb()
{
$notificationConfiguration = \IPS\Member::loggedIn()->notificationsConfiguration();
$notificationConfiguration = isset( $notificationConfiguration[ 'new_file_version' ] ) ? $notificationConfiguration[ 'new_file_version' ] : array();
$options = NULL;
if( \count( $notificationConfiguration ) )
{
foreach( $notificationConfiguration as $option )
{
$methods[] = \IPS\Member::loggedIn()->language()->addToStack( 'member_notifications_' . $option );
}
$options = \IPS\Member::loggedIn()->language()->formatList( $methods );
}
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->notifyBlurb( $this->file, $options );
}
}