Version 4.6.0

This commit is contained in:
Neo committed 2025-12-19 05:55:31 -08:00
1 parent f79dcf067a
commit 517a5e1f70
2036 files changed
+110041 -26162

No files matched your search

@@ -272,8 +272,10 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
) ) );
if ( !empty( $customFields ) )
{
$form->add( new \IPS\Helpers\Form\Select( 'ccfields', $this->id ? explode( ',', $this->_data['cfields'] ) : array(), FALSE, array( 'options' => $customFields, 'multiple' => TRUE ), NULL, NULL, NULL, 'ccfields' ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'ccfields', $this->id ? explode( ',', $this->_data['cfields'] ) : array(), FALSE, array( 'options' => $customFields, 'multiple' => TRUE ), NULL, NULL, NULL, 'ccfields' ) );
}
$form->add( new \IPS\Helpers\Form\YesNo( 'allow_anonymous', $this->id ? $this->allow_anonymous : FALSE, FALSE, array() ) );
$form->addHeader( 'category_comments_and_reviews' );
$form->add( new \IPS\Helpers\Form\YesNo( 'cbitoptions_comments', $this->id ? $this->bitoptions['comments'] : TRUE, FALSE, array( 'togglesOn' => array( 'cbitoptions_comment_moderation' ) ), NULL, NULL, NULL, 'cbitoptions_comments' ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cbitoptions_comment_moderation', $this->bitoptions['comment_moderation'], FALSE, array(), NULL, NULL, NULL, 'cbitoptions_comment_moderation' ) );
@@ -305,9 +307,10 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
$form->add( new \IPS\Helpers\Form\Translatable( 'csubmissionterms', $this->submissionterms, FALSE, array( 'app' => 'downloads', 'key' => ( $this->id ? "downloads_category_{$this->id}_subterms" : NULL ), 'editor' => array( 'app' => 'downloads', 'key' => 'Categories', 'autoSaveKey' => ( $this->id ? "downloads-cat-{$this->id}-subt" : "downloads-new-cat-subt" ), 'attachIds' => $this->id ? array( $this->id, NULL, 'subt' ) : NULL, 'minimize' => 'csubmissionterms_placeholder' ) ) ) );
$form->addHeader( 'category_versioning' );
$form->add( new \IPS\Helpers\Form\Radio( 'cversion_numbers', $this->id ? $this->version_numbers : 1, TRUE, array( 'options' => array( 0 => 'version_numbers_disabled', 1 => 'version_numbers_enabled', 2 => 'version_numbers_required' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cversioning_on', $this->versioning !== 0, FALSE, array( 'togglesOn' => array( 'cversioning' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cversioning_on', $this->versioning !== 0, FALSE, array( 'togglesOn' => array( 'cversioning', 'crequire_changelog' ) ) ) );
$form->add( new \IPS\Helpers\Form\Number( 'cversioning', $this->versioning === NULL ? -1 : $this->versioning, FALSE, array( 'unlimited' => -1 ), NULL, NULL, NULL, 'cversioning' ) );
$form->addHeader( 'category_moderation' );
$form->add( new \IPS\Helpers\Form\YesNo( 'crequire_changelog', $this->require_changelog, FALSE, array( ), NULL, NULL, NULL, 'crequire_changelog' ) );
$form->addHeader( 'category_moderation' );
$form->add( new \IPS\Helpers\Form\YesNo( 'cbitoptions_moderation', $this->bitoptions['moderation'], FALSE, array( 'togglesOn' => array( 'cbitoptions_moderation_edits' ) ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'cbitoptions_moderation_edits', $this->bitoptions['moderation_edits'], FALSE, array(), NULL, NULL, NULL, 'cbitoptions_moderation_edits' ) );
$form->addHeader( 'category_screenshots' );
@@ -682,14 +685,15 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
{
return array( \IPS\Theme::i()->getTemplate( 'browse', 'downloads' ), 'categoryRow' );
}
/**
* Get last comment time
*
* @note This should return the last comment time for this node only, not for children nodes
* @param \IPS\Member|NULL $member MemberObject
* @return \IPS\DateTime|NULL
*/
public function getLastCommentTime()
public function getLastCommentTime( \IPS\Member $member = NULL )
{
return $this->last_file_date ? \IPS\DateTime::ts( $this->last_file_date ) : NULL;
}
@@ -755,6 +759,16 @@ class _Category extends \IPS\Node\Model implements \IPS\Node\Permissions
}
}
/**
* [Node] Get the fully qualified node type (mostly for Pages because Pages is Pages)
*
* @return string
*/
public static function fullyQualifiedType()
{
return \IPS\Member::loggedIn()->language()->addToStack('__app_downloads') . ' ' . \IPS\Member::loggedIn()->language()->addToStack( static::$nodeTitle . '_sg' );
}
/* !Clubs */
/**
@@ -109,6 +109,10 @@ class _Field extends \IPS\CustomField
{
parent::form( $form );
unset( $form->elements['']['pf_search_type'] );
\IPS\Member::loggedIn()->language()->words['pfield_displayoptions'] = \IPS\Member::loggedIn()->language()->addToStack('field_displayoptions');
$form->add( new \IPS\Helpers\Form\Radio( 'downloads_field_location', $this->id ? $this->display_location : 'below', FALSE, array( 'options' => array( 'sidebar' => 'idm_cfield_sidebar', 'below' => 'idm_cfield_below', 'tab' => 'idm_cfield_tab' ) ), NULL, NULL, NULL, 'idm_field_location' ) );
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
@@ -141,13 +145,12 @@ class _Field extends \IPS\CustomField
unset( $values['cf_topic'] );
}
$values['search_type'] = ( $values['pf_search_type'] === NULL ) ? '' : $values['pf_search_type'];
$values['allow_attachments'] = $values['pf_allow_attachments'];
unset( $values['pf_search_type'] );
unset( $values['pf_allow_attachments'] );
$values['display_location'] = $values['downloads_field_location'];
$values['paid_field'] = $values['downloads_field_paid'];
$values['paid_field'] = ( isset( $values['downloads_field_paid'] ) ) ? $values['downloads_field_paid'] : 0;
unset( $values['downloads_field_location'], $values['downloads_field_paid'] );
return parent::formatFormValues( $values );
@@ -21,7 +21,7 @@ if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* File Comment Model
*/
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable, \IPS\Content\Shareable
class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory, \IPS\Content\Hideable, \IPS\Content\Searchable, \IPS\Content\Embeddable, \IPS\Content\Shareable, \IPS\Content\Anonymous
{
use \IPS\Content\Reactable, \IPS\Content\Reportable;
@@ -58,7 +58,8 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
'edit_time' => 'edit_time',
'edit_member_name' => 'edit_name',
'edit_show' => 'append_edit',
'approved' => 'open'
'approved' => 'open',
'is_anon' => 'is_anon'
);
/**
@@ -104,7 +105,7 @@ class _Comment extends \IPS\Content\Comment implements \IPS\Content\EditHistory,
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, ?array $containerData, array $reputationData, $reviewRating, $view )
{
$screenshot = NULL;
if ( isset( $itemData['extra'] ) )
+97 -27
View File
@@ -32,7 +32,8 @@ class _File extends \IPS\Content\Item implements
\IPS\Content\Searchable,
\IPS\Content\Embeddable,
\IPS\Content\MetaData,
\IPS\Content\EditHistory
\IPS\Content\EditHistory,
\IPS\Content\Anonymous
{
use \IPS\Content\Reactable, \IPS\Content\Reportable, \IPS\Content\ItemTopic
{
@@ -85,6 +86,7 @@ class _File extends \IPS\Content\Item implements
public static $databaseColumnMap = array(
'container' => 'cat',
'author' => 'submitter',
'author_name' => 'author_name',
'views' => 'views',
'title' => 'name',
'content' => 'desc',
@@ -111,6 +113,7 @@ class _File extends \IPS\Content\Item implements
'edit_member_name' => 'edit_name',
'edit_show' => 'append_edit',
'edit_reason' => 'edit_reason',
'is_anon' => 'is_anon'
);
/**
@@ -781,7 +784,7 @@ class _File extends \IPS\Content\Item implements
$this->_primaryScreenshotThumb = NULL;
return $this->_primaryScreenshotThumb;
}
/**
* @brief Custom Field Cache
*/
@@ -1117,6 +1120,48 @@ class _File extends \IPS\Content\Item implements
return $this->canDownload;
}
/**
* @brief Requires download confirmation? Used to determine if CSRF key should be included in download URL.
*/
protected $requiresDownloadConfirmation = NULL;
/**
* Can the member download this file?
*
* @param \IPS\Member|NULL $member The member to check or NULL for currently logged in member
* @return bool
*/
public function requiresDownloadConfirmation( \IPS\Member $member = NULL )
{
$member = $member ?: \IPS\Member::loggedIn();
if ( $this->requiresDownloadConfirmation === NULL )
{
$this->requiresDownloadConfirmation = FALSE;
$category = $this->container();
if( $category->message('disclaimer') and \in_array( $category->disclaimer_location, [ 'download', 'both' ] ) )
{
$this->requiresDownloadConfirmation = TRUE;
}
$files = $this->files( isset( \IPS\Request::i()->version ) ? \IPS\Request::i()->version : NULL );
if( \count( $files ) > 1 AND !isset( \IPS\Request::i()->r ) )
{
$this->requiresDownloadConfirmation = TRUE;
}
if( $member->group['idm_wait_period'] AND ( !$this->isPaid() OR $member->group['idm_paid_restrictions'] ) )
{
$this->requiresDownloadConfirmation = TRUE;
}
}
return $this->requiresDownloadConfirmation;
}
/**
* Can the member buy this file?
@@ -1408,19 +1453,6 @@ class _File extends \IPS\Content\Item implements
return $member->group['idm_view_downloads'];
}
/**
* Build form to edit
*
* @return \IPS\Helpers\Form
*/
public function buildEditForm()
{
$form = parent::buildEditForm();
$form->class = 'ipsPadding ipsForm_vertical';
return $form;
}
/**
* Get elements for add/edit form
*
@@ -1779,6 +1811,11 @@ class _File extends \IPS\Content\Item implements
{
$topic->logDelete( $member );
}
if ( $this->hasPendingVersion() )
{
\IPS\downloads\File\PendingVersion::load( $this->id, 'pending_file_id' )->delete();
}
}
/**
@@ -1841,7 +1878,13 @@ class _File extends \IPS\Content\Item implements
\IPS\Db::i()->delete( 'downloads_filebackup', array( 'b_fileid=?', $this->id ) );
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_file_id=?', $this->id ) );
\IPS\Db::i()->delete( 'downloads_files_notify', array( 'notify_file_id=?', $this->id ) );
/* Delete pending version */
if( $this->hasPendingVersion() )
{
\IPS\downloads\File\PendingVersion::load($this->id, 'pending_file_id' )->delete();
}
/* Update Category */
$this->container()->setLastFile();
$this->container()->save();
@@ -1854,7 +1897,7 @@ class _File extends \IPS\Content\Item implements
* @param string $url Record location
* @param string $handler File storage handler key
*/
public function deleteRecords( $ids, string $url=NULL, string $handler=NULL ): void
public function deleteRecords( $ids, string $url=NULL, string $handler=NULL )
{
if( $ids AND $handler AND $url )
{
@@ -1879,13 +1922,13 @@ class _File extends \IPS\Content\Item implements
}
}
/**
* URL Blacklist Check
*
* @param array $val URLs to check
* @return void
* @throws \DomainException
*/
/**
* URL Blacklist Check
*
* @param array $val URLs to check
* @return void
* @throws \DomainException
*/
public static function blacklistCheck( $val )
{
if ( \is_array( $val ) )
@@ -2295,6 +2338,7 @@ class _File extends \IPS\Content\Item implements
{
$this->sendUpdateNotifications();
}
$this->sendAuthorApprovalNotification();
}
/**
@@ -2368,7 +2412,7 @@ class _File extends \IPS\Content\Item implements
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, ?array $containerData, array $reputationData, $reviewRating, $view )
{
$screenshot = NULL;
if ( isset( $itemData['extra'] ) )
@@ -2466,7 +2510,7 @@ class _File extends \IPS\Content\Item implements
'canDownload' => $authorizedMember ? (bool) $this->canDownload( $authorizedMember ) : NULL,
'canBuy' => $authorizedMember ? (bool) $this->canBuy( $authorizedMember ) : NULL,
'canReview' => (bool) $authorizedMember ? ( $this->canReview( $authorizedMember ) AND !$this->hasReviewed( $authorizedMember ) ) : NULL,
'rating' => $this->rating,
'rating' => $this->averageReviewRating(),
'purchases' => $this->purchaseCount(),
'renewalTerm' => $this->isPaid() ? $this->renewalTerm() : NULL,
'hasPendingVersion' => ( !$authorizedMember OR $this->canEdit( $authorizedMember ) ) ? $this->hasPendingVersion() : NULL
@@ -2628,8 +2672,34 @@ class _File extends \IPS\Content\Item implements
* @param \IPS\Helpers\Form $form
* @return void
*/
public function newVersionFormElements( \IPS\Helpers\Form &$form ): void
public function newVersionFormElements( \IPS\Helpers\Form &$form )
{
}
/**
* Do Moderator Action
*
* @param string $action The action
* @param \IPS\Member|NULL $member The member doing the action (NULL for currently logged in member)
* @param string|NULL $reason Reason (for hides)
* @param bool $immediately Delete immediately
* @return void
* @throws \OutOfRangeException|\InvalidArgumentException|\RuntimeException
*/
public function modAction( $action, \IPS\Member $member = NULL, $reason = NULL, $immediately = FALSE )
{
if ( $action == 'delete' )
{
/* Delete pending version */
if( $this->hasPendingVersion() )
{
\IPS\downloads\File\PendingVersion::load($this->id, 'pending_file_id' )->delete();
$this->_pendingVersion = FALSE;
}
}
return parent::modAction( $action, $member, $reason, $immediately );
}
}
@@ -193,7 +193,7 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
*
* @return void
*/
public function saveVersion(): void
public function saveVersion()
{
$this->save_version = 1;
}
@@ -203,8 +203,26 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
*
* @param array $values
*/
public function set_form_values( array $values ): void
public function set_form_values( array $values )
{
foreach( $values as $k => $v )
{
if( $v instanceof \IPS\File )
{
$values[ $k ] = (string) $v;
}
elseif( \is_array( $v ) )
{
foreach( $v as $_key => $_value )
{
if( $_value instanceof \IPS\File )
{
$values[ $k ][ $_key ] = (string) $_value;
}
}
}
}
$this->_formValues = $values;
$this->_data['form_values'] = json_encode( $values );
}
@@ -214,7 +232,7 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
*
* @param array $ids
*/
public function set_record_deletions( array $ids ): void
public function set_record_deletions( array $ids )
{
$this->_data['record_deletions'] = json_encode( $ids );
}
@@ -224,7 +242,7 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
*
* @param $value New date
*/
public function set_updated( $value ): void
public function set_updated( $value )
{
$this->date = $value;
}
@@ -284,7 +302,16 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
{
case 'upload':
case 'ssupload':
$this->file()->deleteRecords( $record['record_id'], $record['record_location'], ( $record['record_location'] == 'ssupload' ) ? 'downloads_Screenshots' : 'downloads_Files' );
$this->file()->deleteRecords( $record['record_id'], $record['record_location'], ( $record['record_type'] == 'ssupload' ) ? 'downloads_Screenshots' : 'downloads_Files' );
if( $record['record_type'] == 'ssupload' AND !empty( $record['record_thumb'] ) )
{
try
{
\IPS\File::get( 'downloads_Screenshots', $record['record_thumb'] )->delete();
}
catch( \Exception $e ){}
}
break;
case 'link':
case 'sslink':
@@ -336,6 +363,15 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
});
$file->deleteRecords( $deletions['links'] );
foreach( $deletions['thumbs'] as $url )
{
try
{
\IPS\File::get( 'downloads_Screenshots', $url )->delete();
}
catch( \Exception $e ){}
}
$file->size = \floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $file->id, 'upload' ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first() );
/* Work out the new primary screenshot */
@@ -366,7 +402,7 @@ class _PendingVersion extends \IPS\Content\Item implements \IPS\Content\Hideable
/* Send notifications */
if ( $file->open )
{
$file->sendUpdateNotifications();
$file->sendApprovedNotification();
}
$file->processAfterNewVersion( $formValues );
@@ -112,7 +112,7 @@ class _Review extends \IPS\Content\Review implements \IPS\Content\EditHistory, \
* @param string $view 'expanded' or 'condensed'
* @return callable
*/
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, array $containerData = NULL, array $reputationData, $reviewRating, $view )
public static function searchResultSnippet( array $indexData, array $authorData, array $itemData, ?array $containerData, array $reputationData, $reviewRating, $view )
{
return \IPS\downloads\File\Comment::searchResultSnippet( $indexData, $authorData, $itemData, $containerData, $reputationData, $reviewRating, $view );
}