Version 5.0.6

This commit is contained in:
Neo committed 2025-12-19 18:55:49 -08:00
1 parent a3a4a9ccbd
commit b89858b2ff
1214 files changed
+92828 -14859

No files matched your search

+9 -1
View File
@@ -72,7 +72,7 @@ class files extends ItemController
* @apiparam int hidden If 1, only files which are hidden are returned, if 0 only not hidden
* @apiparam int pinned If 1, only files which are pinned are returned, if 0 only not pinned
* @apiparam int featured If 1, only files which are featured are returned, if 0 only not featured
* @apiparam string sortBy What to sort by. Can be 'date' for creation date, 'title', 'updated', 'popular' or leave unspecified for ID
* @apiparam string sortBy What to sort by. Can be 'date' for creation date, 'title', 'updated', 'popular', 'downloads' or leave unspecified for ID
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
* @apiparam int page Page number
* @apiparam int perPage Number of results per page - defaults to 25
@@ -92,6 +92,14 @@ class files extends ItemController
$sortBy = 'file_rating ' . $sortDirection . ', file_reviews';
$where = array( array( 'file_rating>?', 0 ) );
}
elseif( Request::i()->sortBy == 'downloads' )
{
$sortBy = 'file_downloads';
if( !isset( Request::i()->sortDir ) )
{
Request::i()->sortDir = 'desc';
}
}
/* Return */
return $this->_list( $where, 'categories', FALSE, $sortBy );
+10 -11
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="downloads">
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/downloads" javascript_name="ips.downloads.browse.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000200">/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/downloads" javascript_name="ips.downloads.browse.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000200">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -59,7 +59,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/pending" javascript_name="ips.pending.buttons.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000250">/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/pending" javascript_name="ips.pending.buttons.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000250">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -87,7 +87,7 @@
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.settings.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000050">/**
<file javascript_app="downloads" javascript_location="admin" javascript_path="controllers/settings" javascript_name="ips.settings.settings.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000050">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -140,7 +140,7 @@
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.linkedScreenshots.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100">/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.linkedScreenshots.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -211,7 +211,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.main.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000100"><![CDATA[/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.main.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -648,7 +648,7 @@
}
});
}(jQuery, _));]]></file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.changeLog.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000150"><![CDATA[/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.changeLog.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000150"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -770,7 +770,7 @@
});
}(jQuery, _));]]></file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.download.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000150">/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.download.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000150">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -898,7 +898,7 @@
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.subscribe.js" javascript_type="controller" javascript_version="5000049" javascript_position="1000150">/**
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.subscribe.js" javascript_type="controller" javascript_version="5000074" javascript_position="1000150">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -961,7 +961,7 @@
}
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.submit.js" javascript_type="template" javascript_version="5000049" javascript_position="1000050"><![CDATA[/* VIEW TEMPLATES */
<file javascript_app="downloads" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.submit.js" javascript_type="template" javascript_version="5000074" javascript_position="1000050"><![CDATA[/* VIEW TEMPLATES */
ips.templates.set('downloads.submit.screenshot', " \
<div class='ipsUploader__row ipsUploader__row--image ipsAttach {{#done}}ipsAttach_done{{/done}}' id='{{id}}' data-role='file' data-fileid='{{id}}' data-filesize='{{sizeRaw}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-fileType='image'>\
<div class='ipsUploader__rowPreview' data-role='preview'>\
@@ -1030,8 +1030,7 @@ mustache
Debug.js
app.js</order>
<order app="global" path="/dev/js//library//jquery">jquery.js
jquery-migrate.js
jquery.transform.js</order>
jquery-migrate.js</order>
<order app="global" path="/dev/js//library//linkify">linkify.min.js
linkify-jquery.min.js</order>
</javascript>
+6 -1
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="downloads" version="5000049">
<app key="downloads" version="5000074">
<word key="__app_downloads" js="0">Downloads</word>
<word key="frontnavigation_downloads" js="0">Downloads</word>
<word key="__indefart_downloads_file_comment" js="0">a comment on a file</word>
@@ -43,6 +43,7 @@
<word key="modlog__action_purchasestatus_stats" js="0">Toggled purchase status of a file</word>
<word key="modlog__action_newversion_reject_stats" js="0">Rejected a new version of a file</word>
<word key="modlog__action_newversion_approved_stats" js="0">Approved a new version of a file</word>
<word key="modlog__linkedfile_edit_title" js="0"><![CDATA[Renamed <a href='%s'>%s</a> from %s]]></word>
<word key="mark_category_read" js="0">Mark category read</word>
<word key="mark_category_read_title" js="0">Mark this category as read</word>
<word key="editor__downloads_Categories" js="0">Download Categories</word>
@@ -196,6 +197,10 @@
<word key="downloads_field_paid" js="0">Purchase Required?</word>
<word key="downloads_field_paid_desc" js="0">If enabled, this field's contents will only be shown to members's who have purchased the file. This setting has no effect on free files.</word>
<word key="ccfields_sg" js="0">Field</word>
<word key="perm_cfield_perm__view" js="0">View Field Content</word>
<word key="perm_cfield_perm__edit" js="0">Edit Field Content</word>
<word key="perm_cfield_perm__add" js="0">Add Content to Field</word>
<word key="perm_cfield_perm__label" js="0">Groups</word>
<word key="menu__downloads_downloads_settings" js="0">Settings</word>
<word key="acplogs__downloads_settings" js="0">Updated downloads settings</word>
<word key="group__downloads_Downloads" js="0">Downloads</word>
+142 -221
View File
@@ -9,7 +9,7 @@
<h2 class='ipsBox__header'>{lang="categories"}</h2>
<i-data>
<ol class="ipsData {{if $layout === 'grid'}}ipsData--grid{{else}}ipsData--table ipsData--category{{endif}} ipsData--download-category" data-ips-hook="categories">
{template="categoryRow" group="browse" params="NULL, NULL, \IPS\downloads\Category::roots()"}
{template="categoryRow" group="browse" params="NULL, NULL, \IPS\downloads\Category::roots(), $layout"}
</ol>
</i-data>
</div>
@@ -19,7 +19,7 @@
<h2 class='ipsBox__header'><a href="{url="app=downloads&module=downloads&controller=browse&id=clubs" seoTemplate="downloads_clubs"}">{lang="club_node_downloads"}</a></h2>
<i-data>
<ol class="ipsData {{if $layout === 'grid'}}ipsData--grid{{else}}ipsData--table ipsData--category{{endif}} ipsData--download-category" data-ips-hook="clubNodes">
{template="categoryRow" group="browse" params="NULL, NULL, $clubNodes"}
{template="categoryRow" group="browse" params="NULL, NULL, $clubNodes, $layout"}
</ol>
</i-data>
</div>
@@ -181,43 +181,57 @@
{{endforeach}}
</ul>
]]></template>
<template template_group="browse" template_name="categoryRow" template_data="$table, $headers, $categories" template_location="front" template_app="downloads"><![CDATA[{{foreach $categories as $category}}
<template template_group="browse" template_name="categoryRow" template_data="$table, $headers, $categories, $layout='table'" template_location="front" template_app="downloads"><![CDATA[{{foreach $categories as $category}}
{{if $category->can('view') AND ( $category->open OR \IPS\Member::loggedIn()->isAdmin() )}}
{{$club = $category->club();}}
<li class="ipsData__item {$category->ui( 'css' )}" {{if !\IPS\downloads\File::containerUnread( $category )}}data-ips-read{{else}}data-ips-unread{{endif}} {$category->ui( 'dataAttributes' )}>
<a href="{$category->url()}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{{if $club}}{lang="club_node" sprintf="$club->name, $category->_title"}{{else}}{$category->_title}{{endif}}</span></a>
<figure class='ipsData__image'>
{{if $category->card_image}}
<img src='{file="$category->card_image" extension="downloads_Cards"}' alt='' loading='lazy'>
{{elseif $club}}
{{$coverPhoto = $club->coverPhoto( FALSE );}}
{{$cfObject = $coverPhoto->object;}}
{{if $coverPhoto->file}}
<img src="{$coverPhoto->file->url}" alt='' loading='lazy'>
{{elseif $club->profile_photo}}
<img src='{file="$club->profile_photo" extension="core_Clubs"}' alt='' loading='lazy'>
{{elseif ! empty( $cfObject::$coverPhotoDefault )}}
<div class="ipsFallbackImage" style="--i-empty-image-random--ba-co: {$coverPhoto->object->coverPhotoBackgroundColor()};"></div>
{{else}}
<i></i>
{{endif}}
{{else}}
{{if $layout==="table"}}
{{if $icon = $category->getIcon()}}
{$icon|raw}
{{else}}
<i></i>
<span class='ipsIcon ipsIcon--fa' aria-hidden="true"><i class="fa-ips"></i></span>
{{endif}}
{{else}}
{{if $category->card_image}}
<img src='{file="$category->card_image" extension="downloads_Cards"}' alt='' loading='lazy'>
{{elseif $club}}
{{$coverPhoto = $club->coverPhoto( FALSE );}}
{{$cfObject = $coverPhoto->object;}}
{{if $coverPhoto->file}}
<img src="{$coverPhoto->file->url}" alt='' loading='lazy'>
{{elseif $club->profile_photo}}
<img src='{file="$club->profile_photo" extension="core_Clubs"}' alt='' loading='lazy'>
{{elseif ! empty( $cfObject::$coverPhotoDefault )}}
<div class="ipsFallbackImage" style="--i-empty-image-random--ba-co: {$coverPhoto->object->coverPhotoBackgroundColor()};"></div>
{{else}}
<span class='ipsIcon ipsIcon--fa' aria-hidden="true"><i class="fa-ips"></i></span>
{{endif}}
{{else}}
{{if $icon = $category->getIcon()}}
{$icon|raw}
{{else}}
<span class='ipsIcon ipsIcon--fa' aria-hidden="true"><i class="fa-ips"></i></span>
{{endif}}
{{endif}}
{{endif}}
</figure>
<div class="ipsData__content">
<div class="ipsData__main">
<div class='ipsData__title'>
<h4>
<a href="{$category->url()}">{{if $club}}{lang="club_node" sprintf="$club->name, $category->_title"}{{else}}{$category->_title}{{endif}}</a>
</h4>
{{if \IPS\downloads\File::containerUnread( $category )}}
<span class="ipsIndicator" title='{lang="unread"}' data-ipstooltip></span>
{{endif}}
<h4><a href="{$category->url()}">{$category->_title}</a></h4>
</div>
{{if $club}}<div class="ipsData__club"><a href="{$club->url()}">{$club->name}</a></div>{{endif}}
{{if $category->description}}
<div class="ipsData__desc">
{template="richText" group="global" app="core" location="global" params="$category->description, array('')"}
@@ -421,7 +435,7 @@
<div data-ips-hook="header" class='ipsPageHeader__primary'>
<h1 data-ips-hook="title" class='ipsPageHeader__title'>{lang="downloads"}</h1>
</div>
<ul data-ips-hook="buttons" data-ips-hook="buttons" class='ipsButtons ipsButtons--main'>
<ul data-ips-hook="buttons" class='ipsButtons ipsButtons--main'>
{{if !\IPS\downloads\Category::theOnlyNode()}}
<li class='ipsResponsive_showPhone'>
<a href='#elDownloadsCategories_menu' data-ipsMenu id='elDownloadsCategories' class='ipsButton ipsButton--inherit'><span>{lang="downloads_category_select"}</span><span>{lang="all"}</span><i class='fa-solid fa-caret-down'></i></a>
@@ -979,7 +993,6 @@
{{endif}}
</div>
</div>]]></template>
<template template_group="global" template_name="link" template_data="$file" template_location="global" template_app="downloads"><![CDATA[<div data-ips-hook="link" class=''><a data-ips-hook="url" href="{$file->url( "getPrefComment" )}" class="i-color_inherit" target="_blank" rel='noopener'>{$file->name}</a></div>]]></template>
<template template_group="global" template_name="manageFollowRow" template_data="$table, $headers, $rows, $includeFirstCommentInCommentCount=TRUE" template_location="front" template_app="downloads"><![CDATA[{{if \count( $rows )}}
{{foreach $rows as $row}}
{{$idField = $row::$databaseColumnId;}}
@@ -1203,6 +1216,7 @@
<table class="ipsTable ipsTable_zebra">
<thead>
<tr>
<th width="60"></th>
<th>{lang="member"}</th>
<th>{lang="downloads"}</th>
</tr>
@@ -1211,7 +1225,8 @@
{{foreach $select as $row}}
{{$member = \IPS\Member::constructFromData( $members[ $row['dmid'] ] );}}
<tr>
<td>{template="userPhoto" app="core" group="global" params="$member"} {$member->name}</td>
<td>{template="userPhoto" app="core" group="global" params="$member"}</td>
<td>{$member->name}</td>
<td><a href='{url="app=downloads&module=stats&controller=member&do=downloads&id={$member->member_id}&tab=downloads&&type%5Bd74394%5D=Table"}'>{$row['downloads']}</a></td>
</tr>
{{endforeach}}
@@ -1238,6 +1253,7 @@
<table class="ipsTable ipsTable_zebra">
<thead>
<tr>
<th width="60"></th>
<th>{lang="member"}</th>
<th>{lang="files"}</th>
</tr>
@@ -1250,7 +1266,8 @@
{{$member = new \IPS\Member;}}
{{endif}}
<tr>
<td>{template="userPhoto" app="core" group="global" params="$member"} {$member->link()|raw}</td>
<td>{template="userPhoto" app="core" group="global" params="$member"}</td>
<td>{$member->link()|raw}</td>
<td>
{{if $member->member_id}}
<a href='{$member->url()->setQueryString( array( 'do' => 'content', 'type' => 'downloads_file' ) )}' target='_blank' rel='noopener'>{$row['files']}</a>
@@ -1611,7 +1628,7 @@
</ul>
</div>
</form>]]></template>
<template template_group="view" template_name="comments" template_data="$file" template_location="front" template_app="downloads"><![CDATA[<div data-controller='core.front.core.commentFeed, core.front.core.ignoredComments' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-commentsType='comments' data-baseURL='{$file->url()}' {{if $file->isLastPage()}}data-lastPage{{endif}} data-feedID='{$file->feedId}' id='comments' class='ipsEntries ipsEntries--comments ipsEntries--download-comments'>
<template template_group="view" template_name="comments" template_data="$file" template_location="front" template_app="downloads"><![CDATA[<div data-controller='core.front.core.commentFeed, core.front.core.ignoredComments' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-commentsType='comments' data-baseURL='{$file->url()}' {{if $file->isLastPage()}}data-lastPage{{endif}} data-feedID='{$file->feedId}' id='comments' class='ipsEntries ipsEntries--comments ipsEntries--download-comments' data-follow-area-id="file-{$file->id}">
{template="featuredComments" group="global" app="core" params="$file->featuredComments(), $file->url()->setQueryString( 'tab', 'comments' )->setQueryString( 'recommended', 'comments' )"}
{{if $file->commentPageCount() > 1}}
@@ -1763,7 +1780,7 @@
{{$data = $files->data();}}
<li class='ipsData__item'>
<div class='ipsData__main'>
<h4 class='ipsData__title'><span class=''>{{if $data['record_realname']}}{$data['record_realname']}{{else}}{{$pathBits = array_filter( explode( '/', \IPS\Http\Url::external( $data['record_location'] )->data[ \IPS\Http\Url::COMPONENT_PATH ] ) );}}{expression="\count( $pathBits ) ? array_pop( $pathBits ) : $data['record_location']"}{{endif}}</span></h4>
<h4 {{if $fileObject->canEdit()}}data-controller="core.front.core.moderation"{{endif}} class='ipsData__title'><span {{if $fileObject->canEdit()}}data-role="editableTitle" data-params='{"do":"ajaxEditLinkRecordRealName","record_id":{$data['record_id']}}' title='{lang="click_hold_edit"}'{{endif}} class=''>{{if $data['record_realname']}}{$data['record_realname']}{{else}}{{$pathBits = array_filter( explode( '/', \IPS\Http\Url::external( $data['record_location'] )->data[ \IPS\Http\Url::COMPONENT_PATH ] ) );}}{expression="\count( $pathBits ) ? array_pop( $pathBits ) : $data['record_location']"}{{endif}}</span></h4>
{{if $data['record_size']}}<p class='ipsData__meta'>{filesize="$data['record_size']"}</p>{{endif}}
</div>
<div>
@@ -1975,7 +1992,7 @@
</ul>
</div>]]></template>
<template template_group="view" template_name="reviews" template_data="$file" template_location="front" template_app="downloads"><![CDATA[
<div data-controller='core.front.core.commentFeed' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-commentsType='reviews' data-baseURL='{$file->url()}' {{if $file->isLastPage('reviews')}}data-lastPage{{endif}} data-feedID='{$file->reviewFeedId}' id='reviews' class='ipsEntries ipsEntries--reviews ipsEntries--download-reviews'>
<div data-controller='core.front.core.commentFeed' {{if settings.auto_polling_enabled}}data-autoPoll{{endif}} data-commentsType='reviews' data-baseURL='{$file->url()}' {{if $file->isLastPage('reviews')}}data-lastPage{{endif}} data-feedID='{$file->reviewFeedId}' id='reviews' class='ipsEntries ipsEntries--reviews ipsEntries--download-reviews' data-follow-area-id="file-{$file->id}">
{{if $file->reviewForm()}}
{{if $file->locked()}}
<strong class='i-color_warning'><i class='fa-solid fa-circle-info'></i> {lang="item_locked_can_review"}</strong>
@@ -2052,7 +2069,7 @@
<div id='elClubContainer'>
{{endif}}
<div class='ipsBlockSpacer'>
<div class='ipsBlockSpacer' data-ips-hook="main">
<div class='ipsBox ipsPull'>
<header class='ipsPageHeader'>
<div class="ipsPageHeader__row">
@@ -2103,7 +2120,7 @@
<div class="ipsPageHeader__primary">
<div class='ipsPhotoPanel ipsPhotoPanel--inline'>
{template="userPhoto" app="core" group="global" params="$file->author(), 'tiny', $file->warningRef()"}
<div class='ipsPhotoPanel__text'>
<div class='ipsPhotoPanel__text' data-ips-hook="author">
<p class="ipsPhotoPanel__primary">
{lang="byline_nodate_itemprop" htmlsprintf="$file->author()->link( $file->warningRef(), NULL, $file->isAnonymous() )"}{{if member.group['idm_view_approvers'] and $file->approver}} {lang="file_approved_by" sprintf="\IPS\Member::load( $file->approver )->name" htmlsprintf="\IPS\DateTime::ts( $file->approvedon )->html( false )"}{{endif}}
{{if $file->isAnonymous() and \IPS\Member::loggedIn()->modPermission('can_view_anonymous_posters')}}
@@ -2166,18 +2183,17 @@
<section class='i-basis_100p'>
<h2 class='ipsBox__header ipsHide'>{lang="screenshots_ct" pluralize="$file->screenshots()->getInnerIterator()->count()"}</h2>
<div class=''>
<ul class='ipsCarousel ipsCarousel--images ipsCarousel--downloads-file-screenshots' id='downloads-file-screenshots' tabindex="0">
<ul class='ipsCarousel ipsCarousel--padding ipsCarousel--images ipsCarousel--downloads-file-screenshots' id='downloads-file-screenshots' tabindex="0">
{{$fullScreenshots = iterator_to_array( $file->screenshots() );}}
{{foreach $file->screenshots( 1 ) as $id => $screenshot}}
<li>
{{ $dimensions = $screenshot->getImageDimensions(); }}
<a href="{$fullScreenshots[ $id ]->url}" class="ipsThumb" data-ipsLightbox data-ipsLightbox-group="download_{$file->id}">
<img src="{$screenshot->url}" alt="" width='{expression="$dimensions[0]"}' height='{expression="$dimensions[1]"}' loading="lazy">
<img src="{$screenshot->url}" alt="">
</a>
</li>
{{endforeach}}
</ul>
{template="carouselNavigation" group="global" app="core" params="'downloads-file-screenshots'"}
{template="carouselNavigation" group="global" app="core" params="'downloads-file-screenshots', 'i-margin-bottom_2'"}
</div>
</section>
{{endif}}
@@ -2390,7 +2406,7 @@
<div class='ipsPageActions ipsBox i-padding_2 ipsPull ipsResponsive_showPhone'>
{template="notify" app="downloads" group="view" params="$file"}
{{if \count( $file->shareLinks() )}}
{template="shareButton" app="core" group="sharelinks" params="$file, 'verySmall', 'light'"}
{template="shareButton" app="core" group="sharelinks" params="$file"}
{{endif}}
{{if \IPS\Application::appIsEnabled('cloud')}}
{template="spam" app="cloud" group="spam" params="$file"}
@@ -2430,203 +2446,111 @@
</div>
{{endif}}]]></template>
<template template_group="widgets" template_name="downloadsCommentFeed" template_data="$comments, $title, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[{{if !empty( $comments ) }}
<h3 class='ipsWidget__header'>{$title}</h3>
{{if isset($orientation) and $orientation == 'vertical'}}
<div class='ipsWidget__content'>
<i-data>
<ul class='ipsData ipsData--table ipsData--downloads-comment-feed'>
{{foreach $comments as $comment}}
<li class='ipsData__item'>
<a href="{$comment->url()}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$comment->item()->name}</span></a>
<div class='ipsData__icon'>
{template="userPhoto" group="global" app="core" params="$comment->author(), 'fluid'"}
</div>
<div class='ipsData__main'>
<h4 class='ipsData__title'><a href="{$comment->url()}">{$comment->item()->name}</a></h4>
<div class='ipsData__meta'>{lang="byline_nodate" htmlsprintf="$comment->author()->link( NULL, NULL, $comment->isAnonymous() )"} &middot; <a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' class='i-color_inherit'>{$comment->dateLine()|raw}</a></div>
<div class='ipsData__desc ipsRichText i-margin-top_2 ipsTruncate_4'>
{$comment->truncated( true )|raw}
</div>
</div>
</li>
{{endforeach}}
</ul>
</i-data>
</div>
{{else}}
<div class='ipsWidget__content'>
{{foreach $comments as $comment}}
<section class='ipsEntry ipsEntry--simple'>
<div class='ipsEntry__content'>
<header class='ipsEntry__header'>
<div class='ipsEntry__header-align'>
<div class='ipsPhotoPanel'>
{template="userPhoto" app="core" group="global" params="$comment->author(), 'mini', $comment->warningRef()"}
<div class='ipsPhotoPanel__text'>
<h3 class='ipsPhotoPanel__primary i-color_hard'>
{template="userLink" app="core" group="global" params="$comment->author(), $comment->warningRef(), NULL, $comment->isAnonymous()"}
</h3>
<p class='ipsPhotoPanel__secondary'>
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}' class='i-color_inherit'>{$comment->dateLine()|raw}</a>
{{if $comment->editLine()}}
({lang="edited_lc"})
{{endif}}
{{if $comment->hidden()}}
&middot; {$comment->hiddenBlurb()}
{{endif}}
</p>
</div>
</div>
</div>
</header>
<div class='ipsEntry__post'>
{{if member.modPermission('mod_see_warn') and $comment->warning}}
{template="commentWarned" group="global" app="core" params="$comment"}
{{endif}}
{{if \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\Reactable' ) and $comment->isHighlighted()}}
<ul class='ipsBadges'>
<li><span class='ipsBadge ipsBadge--popular'>{lang="this_is_a_popular_comment"}</span></li>
</ul>
{{endif}}
<div class='i-margin-bottom_2 i-font-weight_500 i-font-size_2'><a href="{$comment->url()}" class='i-color_hard'>{$comment->item()->name}</a></div>
<div data-role='commentContent' class='ipsRichText ' data-controller='core.front.core.lightboxedImages'>
{{if $comment->hidden() === 1 && $comment->author()->member_id == \IPS\Member::loggedIn()->member_id}}
<strong class='i-color_warning'><i class='fa-solid fa-circle-info'></i> {lang="comment_awaiting_approval"}</strong>
{{endif}}
{$comment->content()|raw}
{{if $comment->editLine()}}
{$comment->editLine()|raw}
{{endif}}
</div>
</div>
<div class='ipsEntry__footer'>
<menu class='ipsEntry__controls' data-role="commentControls">
{{if $comment->canReportOrRevoke() === TRUE}}
<li><a href='{$comment->url('report')}' {{if member.member_id or \IPS\Helpers\Form\Captcha::supportsModal()}}data-ipsDialog data-ipsDialog-remoteSubmit data-ipsDialog-size='medium' data-ipsDialog-flashMessage='{lang="report_submit_success"}' data-ipsDialog-title="{lang="report"}"{{endif}} data-action='reportComment' title='{lang="report_content"}'>{lang="report"}</a></li>
{{endif}}
</menu>
{{if $comment->hidden() !== 1 && \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\Reactable' ) and settings.reputation_enabled}}
{template="reputation" group="global" app="core" params="$comment"}
{{endif}}
</div>
</div>
</section>
{{endforeach}}
</div>
{{endif}}
{{endif}}
]]></template>
<template template_group="widgets" template_name="downloadsReviewFeed" template_data="$comments, $title, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[{{if !empty( $comments ) }}
<h3 class='ipsWidget__header'>{$title}</h3>
{{if isset($orientation) and $orientation == 'vertical'}}
<div class='ipsWidget__content'>
<i-data>
<ul class='ipsData ipsData--table ipsData--downloads-review-feed'>
{{foreach $comments as $comment}}
<li class='ipsData__item'>
<a href="{$comment->url()}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$comment->item()->name}</span></a>
<div class='ipsData__icon'>
{template="userPhoto" group="global" app="core" params="$comment->author(), 'fluid'"}
</div>
<div class='ipsData__main'>
<h4 class='ipsData__title'><a href="{$comment->url()}">{$comment->item()->name}</a></h4>
<div class='ipsData__meta'>{lang="byline_nodate" htmlsprintf="$comment->author()->link()"} &middot; <a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findReview', 'review' => $comment->id ) )}'>{$comment->dateLine()|raw}</a></div>
{template="rating" group="global" location="front" app="core" params="'small', $comment->rating, \IPS\Settings::i()->reviews_rating_out_of"}
<div class='ipsData__desc ipsRichText i-margin-top_2 ipsTruncate_4'>
{$comment->truncated( true )|raw}
</div>
</div>
</li>
{{endforeach}}
</ul>
</i-data>
</div>
{{else}}
<div class='ipsWidget__content'>
<ul>
<header class='ipsWidget__header'>
<h3>{$title}</h3>
{{if $isCarousel}}
{{$carouselID = 'widget-topic-feed_' . mt_rand();}}
{template="carouselNavigation" group="global" app="core" params="$carouselID"}
{{endif}}
</header>
<div class='ipsWidget__content'>
<i-data>
<ul class='ipsData ipsData--{$layout} {{if $isCarousel}}ipsData--carousel{{endif}} ipsData--widget-downloads-commentFeed' {{if $isCarousel}}id='{$carouselID}' tabindex="0"{{endif}}>
{{foreach $comments as $comment}}
<li class='ipsEntry ipsEntry--simple'>
<div class='ipsEntry__header'>
<div class="ipsEntry__header-align">
<div class="ipsPhotoPanel">
{template="userPhoto" app="core" group="global" params="$comment->author(), 'mini', $comment->warningRef()"}
<div class="ipsPhotoPanel__text">
<h3 class='ipsPhotoPanel__primary'>
<strong>{template="userLink" app="core" group="global" params="$comment->author(), $comment->warningRef()"}</strong>
{template="reputationBadge" group="global" app="core" params="$comment->author()"}
</h3>
<p class='ipsPhotoPanel__secondary'>
<a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findReview', 'review' => $comment->id ) )}' class='i-color_inherit'>{$comment->dateLine()|raw}</a>
{{if $comment->editLine()}}
({lang="edited_lc"})
{{endif}}
{{if $comment->hidden()}}
&middot; {$comment->hiddenBlurb()}
{{endif}}
</p>
</div>
<li class='ipsData__item'>
<a href='{$comment->url()}' class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$comment->item()->mapped('title')}</span></a>
{{if in_array($layout, array("wallpaper", "featured", "grid"))}}
<figure class='ipsData__image'>
{{if $image = $comment->item()->primaryImage()}}
<img src="{$image->url}" alt="{$comment->item()->mapped('title')}" loading="lazy">
{{else}}
<i></i>
{{endif}}
</figure>
{{else}}
<figure class='ipsData__icon'>
{template="userPhoto" app="core" group="global" params="$comment->author(), 'fluid'"}
</figure>
{{endif}}
<div class="ipsData__content">
<div class='ipsData__main'>
<div class='ipsData__title'>
<h4><a href="{$comment->url()}" title='{lang="view_this_file" sprintf="$comment->item()->mapped('title')"}'>{$comment->item()->mapped('title')}</a></h4>
</div>
<div class='ipsData__desc ipsRichText' data-controller='core.front.core.lightboxedImages'>{$comment->truncated()|raw}</div>
<p class='ipsData__meta'>{lang="byline" htmlsprintf="$comment->author()->link( NULL, NULL, $comment->isAnonymous() )"} &middot; <a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findComment', 'comment' => $comment->id ) )}'>{$comment->dateLine()|raw}</a></p>
</div>
</div>
<div class='ipsEntry__post'>
{{if member.modPermission('mod_see_warn') and $comment->warning}}
{template="commentWarned" group="global" app="core" params="$comment"}
{{endif}}
{{if \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\Reactable' ) and $comment->isHighlighted()}}
<strong class='ipsEntry__popularFlag' data-ipsTooltip title='{lang="this_is_a_popular_comment"}'><i class='fa-solid fa-star'></i></strong>
{{endif}}
<div class=''><a href="{$comment->url()}" class='ipsData__title ipsTruncate_1'>{$comment->item()->name}</a></div>
<div data-role='commentContent' class='ipsRichText ' data-controller='core.front.core.lightboxedImages'>
{{if $comment->hidden() === 1 && $comment->author()->member_id == \IPS\Member::loggedIn()->member_id}}
<strong class='i-color_warning'><i class='fa-solid fa-circle-info'></i> {lang="comment_awaiting_approval"}</strong>
{{endif}}
{$comment->content()|raw}
{{if $comment->editLine()}}
{$comment->editLine()|raw}
{{endif}}
</div>
</div>
<div class='ipsEntry__footer'>
<menu class='ipsEntry__controls' data-role="commentControls">
{{if $comment->canReportOrRevoke() === TRUE}}
<li><a href='{$comment->url('report')}' {{if member.member_id or \IPS\Helpers\Form\Captcha::supportsModal()}}data-ipsDialog data-ipsDialog-remoteSubmit data-ipsDialog-size='medium' data-ipsDialog-flashMessage='{lang="report_submit_success"}' data-ipsDialog-title="{lang="report"}"{{endif}} data-action='reportComment' title='{lang="report_content"}'>{lang="report"}</a></li>
{{endif}}
{{if ! \IPS\Output::i()->reduceLinks()}}
<li><a href='{$comment->item()->url()->setQueryString( array( 'do' => 'findReview', 'review' => $comment->id ) )}' data-ipsMenu data-ipsMenu-closeOnClick='false' id='elShareComment_{$comment->id}'>{lang="share_this_comment"}</a></li>
{{endif}}
</menu>
{{if $comment->hidden() !== 1 && \IPS\IPS::classUsesTrait( $comment, 'IPS\Content\Reactable' ) and settings.reputation_enabled}}
{template="reputation" group="global" app="core" params="$comment"}
{{endif}}
</div>
</li>
{{endforeach}}
</ul>
</div>
{{endif}}
</i-data>
</div>
{{endif}}
]]></template>
<template template_group="widgets" template_name="downloadsReviewFeed" template_data="$reviews, $title, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[<header class='ipsWidget__header'>
<h3>{$title}</h3>
{{if $isCarousel}}
{{$carouselID = 'widget-downloads-reviews_' . mt_rand();}}
{template="carouselNavigation" group="global" app="core" params="$carouselID"}
{{endif}}
</header>
<div class='ipsWidget__content'>
{{if !empty( $reviews ) }}
<i-data>
<ul class='ipsData ipsData--{$layout} {{if $isCarousel}}ipsData--carousel{{endif}} ipsData--widget-downloads-reviews' {{if $isCarousel}}id='{$carouselID}' tabindex="0"{{endif}}>
{{foreach $reviews as $review}}
<li class='ipsData__item'>
<a href="{$review->item()->url( "getPrefComment" )}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$review->item()->mapped('title')}</span></a>
{{if \in_array( $layout, array("grid", "wallpaper", "featured"))}}
<figure class="ipsData__image">
{{if $image = $review->item()->primaryImage()}}
<img src="{$image->url}" alt="{$review->item()->mapped('title')}" loading="lazy">
{{else}}
<i></i>
{{endif}}
</figure>
{{else}}
<div class='ipsData__icon'>
{template="userPhoto" app="core" group="global" params="$review->author(), 'fluid'"}
</div>
{{endif}}
<div class='ipsData__content'>
<div class='ipsData__main'>
<h4 class='ipsData__title'>
<a href="{$review->item()->url( "getPrefComment" )}" title='{lang="view_this_file" sprintf="$review->item()->mapped('title')"}'>{$review->item()->mapped('title')}</a>
{template="rating" group="global" location="front" app="core" params="'small', $review->rating, \IPS\Settings::i()->reviews_rating_out_of"}
</h4>
<p class='ipsData__meta'>
{lang="byline_nodate" htmlsprintf="$review->author()->link()"}, <time datetime='{datetime="$review->mapped('date' )" norelative="true"}'>{datetime="$review->mapped('date')" norelative="true"}</time>
</p>
<p class='ipsData__desc'>{$review->truncated()|raw}</p>
</div>
</div>
</li>
{{endforeach}}
</ul>
</i-data>
{{else}}
<p class='ipsEmptyMessage'>{lang="no_recent_reviews"}</p>
{{endif}}
</div>]]></template>
<template template_group="widgets" template_name="downloadStats" template_data="$stats, $latestFile, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[<h3 class='ipsWidget__header'>{lang="block_downloadStats"}</h3>
<div class='ipsWidget__content'>
<ul class='ipsList ipsList--stats ipsList--stats ipsList--stacked ipsList--border ipsList--fill'>
<li>
<span class='ipsList__value'>{number="$stats['totalFiles']"}</span><br>
<span class='ipsList__value'>{number="$stats['totalFiles']"}</span>
<span class='ipsList__label'>{lang="total_files_front"}</span>
</li>
{{if $stats['totalComments']}}
<li>
<span class='ipsList__value'>{number="$stats['totalComments']"}</span><br>
<span class='ipsList__value'>{number="$stats['totalComments']"}</span>
<span class='ipsList__label'>{lang="total_comments"}</span>
</li>
{{endif}}
{{if $stats['totalReviews']}}
<li>
<span class='ipsList__value'>{number="$stats['totalReviews']"}</span><br>
<span class='ipsList__value'>{number="$stats['totalReviews']"}</span>
<span class='ipsList__label'>{lang="total_reviews"}</span>
</li>
{{endif}}
@@ -2876,15 +2800,6 @@
--icon: "\f019";
}
/* Add padding to screenshot carousel */
.ipsCarousel--downloads-file-screenshots{
--i-carousel--pa: 2em;
--i-column-gap: 1em;
}
.ipsCarousel--downloads-file-screenshots + .ipsCarouselNav{
margin-bottom: 1em;
}
.cFilePrice {
color: var(--i-color_secondary);
text-transform: uppercase;
@@ -2920,6 +2835,12 @@
#elURLFiles, #elImportFiles, #elURLScreenshots {
position: relative;
}
/* Rename title */
[data-controller="downloads.front.view.download"] .ipsData__title [data-role="editableTitle"]:hover{
background: var(--i-background_selected);
color: var(--i-color_hard);
}]]></css>
<css css_location="front" css_app="downloads" css_attributes="" css_path="." css_name="embed.css">.cFilePrice {
color: var(--i-color_secondary);
+33 -1
View File
@@ -267,6 +267,13 @@
"107785": "4.7.19",
"107786": "4.7.19",
"107787": "4.7.19",
"107795": "4.7.20 Beta 1",
"107796": "4.7.20 Beta 2",
"107797": "4.7.20 Beta 3",
"107798": "4.7.20 Beta 4",
"107799": "4.7.20 Beta 5",
"107800": "4.7.20",
"107801": "4.7.20",
"500001": "5.0.0 Alpha 1",
"500002": "5.0.0 Alpha 2",
"5000003": "5.0.0 Alpha 3",
@@ -315,5 +322,30 @@
"5000046": "5.0.0 Beta 14",
"5000047": "5.0.0 Beta 14.1",
"5000048": "5.0.0 Beta 14.2",
"5000049": "5.0.0"
"5000049": "5.0.0",
"5000050": "5.0.0",
"5000051": "5.0.0",
"5000052": "5.0.1",
"5000053": "5.0.1",
"5000054": "5.0.2",
"5000055": "5.0.2",
"5000056": "5.0.2",
"5000057": "5.0.3",
"5000058": "5.0.3",
"5000059": "5.0.3",
"5000060": "5.0.3",
"5000061": "5.0.4 Beta 1",
"5000062": "5.0.4 Beta 1",
"5000063": "5.0.4 Beta 1",
"5000064": "5.0.4 Beta 2",
"5000065": "5.0.4 Beta 3",
"5000066": "5.0.4",
"5000067": "5.0.5 Beta 1",
"5000068": "5.0.5 Beta 2",
"5000069": "5.0.5",
"5000070": "5.0.6 Beta 1",
"5000071": "5.0.6 Beta 2",
"5000072": "5.0.6 Beta 3",
"5000073": "5.0.6 Beta 4",
"5000074": "5.0.6"
}
@@ -16,8 +16,11 @@ namespace IPS\downloads\modules\front\downloads;
use DateTimeInterface;
use DomainException;
use Exception;
use InvalidArgumentException;
use IPS\Application;
use IPS\Content\Controller;
use IPS\Content\Search\Index;
use IPS\Content\Search\SearchContent;
use IPS\core\DataLayer;
use IPS\core\FrontNavigation;
use IPS\DateTime;
@@ -25,6 +28,7 @@ use IPS\Db;
use IPS\downloads\File as FileClass;
use IPS\downloads\File\PendingVersion;
use IPS\downloads\Form\LinkedScreenshots;
use IPS\Events\Event;
use IPS\File;
use IPS\File\Iterator;
use IPS\Helpers\Form;
@@ -55,6 +59,8 @@ use IPS\Session;
use IPS\Settings;
use IPS\Theme;
use IPS\Widget;
use LengthException;
use LogicException;
use OutOfRangeException;
use RuntimeException;
use UnderflowException;
@@ -65,6 +71,7 @@ use function floatval;
use function function_exists;
use function in_array;
use function is_array;
use function trim;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
@@ -170,6 +177,12 @@ class view extends Controller
foreach ( new ActiveRecordIterator( Db::i()->select( 'pfd.*', array( 'downloads_cfields', 'pfd' ), NULL, 'pfd.cf_position' ), 'IPS\downloads\Field' ) as $field )
{
/* Check if the user can view this field */
if( !$field->can( 'view' ) )
{
continue;
}
if( array_key_exists( 'field_' . $field->id, $this->file->customFields() ) )
{
if ( $fields[ 'field_' . $field->id ] !== null AND $fields[ 'field_' . $field->id ] !== '' )
@@ -700,6 +713,9 @@ class view extends Controller
Output::i()->error( 'generic_error', '3D161/M', 500, '' );
}
/* Trigger an event listener */
Event::fire( 'onDownload', $file, [ $this->file ] );
/* Print the file, honoring ranges */
try
{
@@ -1246,6 +1262,7 @@ class view extends Controller
else
{
$noWatermark = NULL;
$watermarked = FALSE;
if ( Settings::i()->idm_watermarkpath )
{
try
@@ -1255,15 +1272,32 @@ class view extends Controller
$image = Image::create( $file->contents() );
$image->watermark( $watermark );
$file = File::create( 'downloads_Screenshots', $file->originalFilename, $image );
$watermarked = TRUE;
}
catch ( Exception $e ) { }
}
/**
* We only need to generate a new thumbnail if we are using watermarking.
* If we are not, then we can simply use the previous thumbnail, if this existed previously, rather than generating a new one every time we upload a new version, which is unnecessary extra processing as well as disk usage.
* If we are, then it is impossible to know if the watermark has since changed, so we need to go ahead and do it anyway.
*/
$existing = NULL;
if ( $watermarked !== TRUE )
{
try
{
/* @note SELECT_FROM_WRITE_SERVER added in c96a0b88e7386e01a6eed39427f2312bc746874f */
$existing = Db::i()->select( '*', 'downloads_files_records', array( "record_location=? AND record_file_id=?", (string) $file, $this->file->id ), NULL, NULL, NULL, NULL, \IPS\Db::SELECT_FROM_WRITE_SERVER )->first();
}
catch( \UnderflowException $e ) {}
}
Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'ssupload',
'record_location' => (string) $file,
'record_thumb' => (string) $file->thumbnail( 'downloads_Screenshots' ),
'record_thumb' => ( $watermarked OR !$existing ) ? (string) $file->thumbnail( 'downloads_Screenshots' ) : $existing['record_thumb'],
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
@@ -1464,6 +1498,78 @@ class view extends Controller
}
}
/**
* Quick edit the record's real name
*
* @return void
*/
public function ajaxEditLinkRecordRealName(): void
{
try
{
Session::i()->csrfCheck();
if ( ! $this->file->canEdit() )
{
throw new RuntimeException;
}
try
{
$record = Db::i()->select( '*', 'downloads_files_records', array( 'record_type=? and record_id=?', 'link', Request::i()->record_id ) )->first();
}
catch ( UnderflowException $e )
{
throw new RuntimeException;
}
if ( ! $record['record_file_id'] == $this->file->id )
{
throw new RuntimeException;
}
$oldTitle = $record['record_realname'];
$maxLength = Settings::i()->max_title_length ?: 255;
if( mb_strlen( Request::i()->newTitle ) > $maxLength )
{
throw new LengthException( Member::loggedIn()->language()->addToStack( 'form_maxlength', FALSE, array( 'pluralize' => array( $maxLength ) ) ) );
}
elseif( !trim( Request::i()->newTitle ) )
{
throw new InvalidArgumentException('form_required');
}
$newTitle = new Text( 'newTitle', Request::i()->newTitle );
if( $newTitle->validate() !== TRUE )
{
throw new InvalidArgumentException( Member::loggedIn()->language()->addToStack( 'form_tags_not_allowed', FALSE, array( 'sprintf' => array( Request::i()->newTitle ) ) ) );
}
/* Stop doing anything if the title wasn't changed */
if( $oldTitle == $newTitle->value )
{
Output::i()->json( $oldTitle );
}
/* Update */
Db::i()->update( 'downloads_files_records', array( 'record_realname' => $newTitle->value ), array( 'record_id=?', Request::i()->record_id ) );
Session::i()->modLog( 'modlog__linkedfile_edit_title', array( (string) $this->file->url() => FALSE, $newTitle->value => FALSE, $oldTitle => FALSE ), $this->file );
Output::i()->json( $newTitle->value );
}
catch( LogicException $e )
{
Output::i()->error( $e->getMessage(), '2D161/N', 403, '' );
}
catch ( Exception $e )
{
Output::i()->error( 'node_error', '2D161/2', 404, '' );
}
}
/**
* Subscribe Hover
*
@@ -0,0 +1,23 @@
{
"id": 107795,
"name": "4.7.20 Beta 1",
"steps": {
"queries": false,
"lang": true,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"normal": {
"added": [
"perm_cfield_perm__view",
"perm_cfield_perm__edit",
"perm_cfield_perm__add",
"perm_cfield_perm__label"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,23 @@
{
"id": 107796,
"name": "4.7.20 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107797,
"name": "4.7.20 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107798,
"name": "4.7.20 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107799,
"name": "4.7.20 Beta 5",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107800,
"name": "4.7.20",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,23 @@
{
"id": 107801,
"name": "4.7.20",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeSettings": false,
"javascript": false,
"emailTemplates": false,
"hooks": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,22 @@
{
"id": 5000050,
"name": "5.0.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000051,
"name": "5.0.0",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000052,
"name": "5.0.1",
"steps": {
"queries": false,
"lang": true,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": true
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,17 @@
{
"normal": {
"added": [
"perm_cfield_perm__view",
"perm_cfield_perm__edit",
"perm_cfield_perm__add",
"perm_cfield_perm__label"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,25 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categories",
"front\/browse\/categoryRow",
"front\/view\/view"
],
"removed": [
"global\/global\/link"
]
},
"css": {
"added": [],
"edited": [
"front\/downloads.css"
],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,75 @@
<?php
/**
* @brief 5.0.1 Upgrade Code
* @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 04 Feb 2025
*/
namespace IPS\downloads\setup\upg_5000052;
use IPS\Db;
use IPS\downloads\Field;
use IPS\Patterns\ActiveRecordIterator;
use UnderflowException;
use function defined;
/* 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;
}
/**
* 5.0.1 Upgrade Code
*/
class Upgrade
{
/**
* Set default permissions for Downloads Custom Fields.
*
* @return bool|array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1() : bool|array
{
/* Set default permissions on custom fields */
$fields = iterator_to_array(
new ActiveRecordIterator(
Db::i()->select( '*', 'downloads_cfields' ),
Field::class
)
);
/* Set up recommended permissions */
$perms = [];
foreach ( Field::$permissionMap as $k => $v )
{
$perms[ "perm_{$v}" ] = '*';
}
foreach( $fields as $field )
{
/* @var Field $field */
try
{
/* If we already have permissions (maybe from v4), don't touch them */
$current = Db::i()->select( '*', 'core_permission_index', array( 'app=? AND perm_type=? AND perm_type_id=?', 'downloads', 'fields', $field->_id ) )->first();
}
catch( UnderflowException $e )
{
/* Recommended permissions */
$insert = array_merge( $perms, [ 'app' => 'downloads', 'perm_type' => 'fields', 'perm_type_id' => $field->_id ] );
Db::i()->insert( 'core_permission_index', $insert );
}
}
return TRUE;
}
// You can create as many additional methods (step2, step3, etc.) as is necessary.
// Each step will be executed in a new HTTP request
}
@@ -0,0 +1,22 @@
{
"id": 5000053,
"name": "5.0.1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000054,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,19 @@
{
"html": {
"added": [],
"edited": [
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000055,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000056,
"name": "5.0.2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000057,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000058,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000059,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000060,
"name": "5.0.3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000061,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": true,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"normal": {
"added": [
"modlog__linkedfile_edit_title"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,27 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categoryRow",
"admin\/stats\/downloadsTable",
"admin\/stats\/submittersTable",
"front\/view\/comments",
"front\/view\/multipleFiles",
"front\/view\/reviews",
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [
"front\/downloads.css"
],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000062,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000063,
"name": "5.0.4 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000064,
"name": "5.0.4 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,19 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/index"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000065,
"name": "5.0.4 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000066,
"name": "5.0.4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000067,
"name": "5.0.5 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,20 @@
{
"html": {
"added": [],
"edited": [
"front\/widgets\/downloadsCommentFeed",
"front\/widgets\/downloadsReviewFeed"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000068,
"name": "5.0.5 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,19 @@
{
"html": {
"added": [],
"edited": [
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000069,
"name": "5.0.5",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000070,
"name": "5.0.6 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": true,
"javascript": true,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": true,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"files": {
"added": [],
"edited": [],
"removed": []
},
"orders": {
"added": [],
"edited": [
"global\/\/dev\/js\/\/library\/\/jquery"
],
"removed": []
}
}
@@ -0,0 +1,20 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categoryRow",
"front\/widgets\/downloadStats"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000071,
"name": "5.0.6 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000072,
"name": "5.0.6 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000073,
"name": "5.0.6 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000074,
"name": "5.0.6",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": true,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,14 @@
{
"categories": {
"added": [],
"edited": [],
"removed": []
},
"settings": {
"added": [],
"edited": [
"layout_downloads_categories"
],
"removed": []
}
}
@@ -958,7 +958,7 @@ class Category extends Model implements Permissions
* @param Club $club
* @return void
*/
public function clubForm( Form $form, Club $club ) : void
public function _clubForm( Form $form, Club $club ) : void
{
/* @var File $itemClass */
$itemClass = static::$contentItemClass;
+60 -1
View File
@@ -19,7 +19,9 @@ use IPS\Helpers\Form;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\TextArea;
use IPS\Helpers\Form\YesNo;
use IPS\Lang;
use IPS\Member;
use IPS\Node\Permissions;
use IPS\Settings;
use function defined;
@@ -32,7 +34,7 @@ if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
/**
* Field Node
*/
class Field extends CustomField
class Field extends CustomField implements Permissions
{
/**
* @brief [ActiveRecord] Multiton Store
@@ -85,6 +87,30 @@ class Field extends CustomField
* @brief [CustomField] Set to TRUE if uploads fields are capable of holding the submitted content for moderation
*/
public static bool $uploadsCanBeModerated = TRUE;
/**
* @brief The map of permission columns
*/
public static array $permissionMap = array(
'view' => 'view',
'edit' => 2,
'add' => 3
);
/**
* @brief [Node] App for permission index
*/
public static ?string $permApp = 'downloads';
/**
* @brief [Node] Type for permission index
*/
public static ?string $permType = 'fields';
/**
* @brief [Node] Prefix string that is automatically prepended to permission matrix language strings
*/
public static string $permissionLangPrefix = 'perm_cfield_';
/**
* @brief [Node] ACP Restrictions
@@ -121,6 +147,17 @@ class Field extends CustomField
return $this->format;
}
/**
*
* [Node] Does the currently logged-in user have permission to edit permissions for this node?
*
* @return bool
*/
public function canManagePermissions() : bool
{
return true;
}
/**
* [Node] Add/Edit Form
*
@@ -178,4 +215,26 @@ class Field extends CustomField
return parent::formatFormValues( $values );
}
/**
* Get output for API
*
* @param Member|NULL $authorizedMember The member making the API request or NULL for API Key / client_credentials
* @param array $fieldValues Current values for a specific file
* @return array
* @apiresponse int id ID number
* @apiresponse string name Name
* @apiresponse string description Description
* @apiresponse string value Current value for this file
*/
public function apiOutput( ?Member $authorizedMember = NULL, array $fieldValues=array() ): array
{
$lang = $authorizedMember ? $authorizedMember->language() : Lang::load( Lang::defaultLanguage() );
return [
'id' => $this->id,
'name' => $lang->addToStack( 'downloads_field_' . $this->id ),
'description' => $lang->addToStack( 'downloads_field_' . $this->id . '_desc' ),
'value' => $fieldValues[ 'field_' . $this->id ] ?? null
];
}
}
+69 -12
View File
@@ -1036,7 +1036,7 @@ Filter
* @param array $where Where clause
* @param string|null $order MySQL ORDER BY clause (NULL to order by date)
* @param int|array|null $limit Limit clause
* @param string $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index or NULL to ignore permissions
* @param string|null $permissionKey A key which has a value in the permission map (either of the container or of this class) matching a column ID in core_permission_index or NULL to ignore permissions
* @param int|bool|null $includeHiddenItems Include hidden items? NULL to detect if currently logged in member has permission, -1 to return public content only, TRUE to return unapproved content and FALSE to only return unapproved content the viewing member submitted
* @param int $queryFlags Select bitwise flags
* @param Member|null $member The member (NULL to use currently logged in member)
@@ -1053,7 +1053,7 @@ Filter
* @param array|null $location Array of item lat and long
* @return ActiveRecordIterator|int
*/
public static function getItemsWithPermission( array $where=array(), string $order=null, int|array|null $limit=10, string $permissionKey='read', int|bool|null $includeHiddenItems= Filter::FILTER_AUTOMATIC, int $queryFlags=0, Member $member=null, bool $joinContainer=FALSE, bool $joinComments=FALSE, bool $joinReviews=FALSE, bool $countOnly=FALSE, array|null $joins=null, bool|Model $skipPermission=FALSE, bool $joinTags=TRUE, bool $joinAuthor=TRUE, bool $joinLastCommenter=TRUE, bool $showMovedLinks=FALSE, array|null $location=null ): ActiveRecordIterator|int
public static function getItemsWithPermission( array $where=array(), string $order=null, int|array|null $limit=10, ?string $permissionKey='read', int|bool|null $includeHiddenItems= Filter::FILTER_AUTOMATIC, int $queryFlags=0, Member $member=null, bool $joinContainer=FALSE, bool $joinComments=FALSE, bool $joinReviews=FALSE, bool $countOnly=FALSE, array|null $joins=null, bool|Model $skipPermission=FALSE, bool $joinTags=TRUE, bool $joinAuthor=TRUE, bool $joinLastCommenter=TRUE, bool $showMovedLinks=FALSE, array|null $location=null ): ActiveRecordIterator|int
{
$member = $member ?: Member::loggedIn();
if ( !$member->isAdmin() )
@@ -1625,7 +1625,7 @@ Filter
Member::loggedIn()->language()->words['file_cost_desc'] = $commissionBlurb;
$return['file_cost'] = new FormMoney( "{$bulkKey}file_cost", $item ? json_decode( $item->cost, TRUE ) : array(), NULL, array(), function( $val ) use ( $minimums, $bulkKey ) {
$return['file_cost'] = new FormMoney( "{$bulkKey}file_cost", ( $item and $item->cost )? json_decode( $item->cost, TRUE ) : array(), NULL, array(), function( $val ) use ( $minimums, $bulkKey ) {
foreach( $val as $currency => $money )
{
if( isset( $minimums[ $currency ]['amount'] ) AND $money->amount->compare( new Number( $minimums[ $currency ]['amount'] ) ) === -1 )
@@ -1663,6 +1663,13 @@ Filter
{
foreach ( $container->cfields as $k => $field )
{
/* Does the user have permission to enter data into this field? */
$perm = $item ? 'edit' : 'add';
if( !$field->can( $perm ) )
{
continue;
}
$_id = $field->id;
$field->id = "{$bulkKey}{$field->id}";
if ( $field->type === 'Editor' )
@@ -1724,6 +1731,11 @@ Filter
}
foreach ( $this->container()->cfields as $field )
{
if( !array_key_exists( "downloads_field_{$field->id}", $values ) )
{
continue;
}
$helper = $field->buildHelper( NULL, NULL, $new ? NULL : $this );
if ( $helper instanceof Upload )
{
@@ -1797,6 +1809,11 @@ Filter
$cfields = array();
foreach ( $this->container()->cfields as $field )
{
if( !array_key_exists( "downloads_field_{$field->id}", $values ) )
{
continue;
}
$helper = $field->buildHelper( NULL, NULL, $new ? NULL : $this );
if ( $helper instanceof Upload )
{
@@ -2136,7 +2153,7 @@ Filter
{
if ( !in_array( $file['record_location'], $locations ) )
{
$file = SystemFile::get( $file['record_type'] == 'upload' ? 'downloads_Files' : 'downloads_Screenshots', $file['record_location'] )->delete();
SystemFile::get( $file['record_type'] == 'upload' ? 'downloads_Files' : 'downloads_Screenshots', $file['record_location'] )->delete();
}
}
catch ( Exception $e ) { }
@@ -2149,7 +2166,7 @@ Filter
{
if ( !in_array( $file['record_thumb'], $thumbs ) )
{
$file = SystemFile::get( 'downloads_Screenshots', $file['record_thumb'] )->delete();
SystemFile::get( 'downloads_Screenshots', $file['record_thumb'] )->delete();
}
}
catch ( Exception $e ) { }
@@ -2161,7 +2178,7 @@ Filter
{
if ( !in_array( $file['record_no_watermark'], $watermarks ) )
{
$file = SystemFile::get( 'downloads_Screenshots', $file['record_no_watermark'] )->delete();
SystemFile::get( 'downloads_Screenshots', $file['record_no_watermark'] )->delete();
}
}
catch ( Exception $e ) { }
@@ -2494,9 +2511,29 @@ Filter
* @apiresponse int purchases Number of purchases
* @apiresponse array renewalTerm File renewal term
* @apiresponse bool hasPendingVersion Whether file has a new version pending. Will be NULL for client requests where the authorized member cannot upload new versions.
* @apiresponse [\IPS\downloads\Field] customFields Custom field values for this file
*/
public function apiOutput( ?Member $authorizedMember = NULL, ?array $backup=NULL ) : array
{
/* Figure out custom fields if any */
$fields = array();
try
{
$fieldValues = Db::i()->select( '*', 'downloads_ccontent', [ 'file_id=?', $this->id ] )->first();
foreach( new ActiveRecordIterator(
Db::i()->select( '*', 'downloads_cfields', null, 'cf_position' ),
Field::class
) as $field )
{
if( !$authorizedMember or $field->canView( $authorizedMember ) )
{
$fields[ $field->id ] = $field->apiOutput( $authorizedMember, $fieldValues );
}
}
}
catch( UnderflowException $e ) { }
return array(
'id' => $this->id,
'title' => $backup ? $backup['b_filetitle'] : $this->name,
@@ -2536,7 +2573,8 @@ Filter
'rating' => $this->averageReviewRating(),
'purchases' => $this->purchaseCount(),
'renewalTerm' => $this->isPaid() ? $this->renewalTerm() : NULL,
'hasPendingVersion' => ( !$authorizedMember OR $this->canEdit( $authorizedMember ) ) ? $this->hasPendingVersion() : NULL
'hasPendingVersion' => ( !$authorizedMember OR $this->canEdit( $authorizedMember ) ) ? $this->hasPendingVersion() : NULL,
'customFields' => $fields
);
}
@@ -2660,6 +2698,12 @@ Filter
/* Run the parent so that we are sure everything is properly synched */
$this->_syncTopic();
/* Stop here if we're not including screenshots */
if( !$this->container()->bitoptions['topic_screenshot'] )
{
return;
}
if( $screenshot = $this->primary_screenshot_thumb )
{
/* Now we need to copy the primary screenshot as an attachment to the first post */
@@ -2676,9 +2720,24 @@ Filter
{
try
{
SystemFile::get( 'forums_Forums', $row['attach_location'] )->delete();
/* Due to an older bug in 5.0.0 B9, attachment files can match the exact filename of a downloads record, so we won't want to delete if there's a match there */
$existsAlready = Db::i()->select( '*', 'downloads_files_records', [ 'record_location=? or record_thumb=?', $row['attach_location'], $row['attach_location'] ] )->first();
}
catch( \UnderflowException )
{
$existsAlready = false;
}
if ( $existsAlready === false )
{
/* Nothing found so proceed */
try
{
SystemFile::get( 'forums_Forums', $row['attach_location'] )->delete();
}
catch( Exception ){}
}
catch( Exception ){}
$delete[] = $row['attach_id'];
}
@@ -2695,9 +2754,7 @@ Filter
{
/* Copy the screenshot and generate an attachment */
/* @var SystemFile $screenshot */
$settings = json_decode( Settings::i()->upload_settings, true );
$storageConfiguration = $settings['filestorage__core_Attachment'];
$copy = $screenshot->copy( $storageConfiguration );
$copy = $screenshot->duplicate();
$attachment = $copy->makeAttachment( md5( uniqid() ), $topic->author() );