Version 5.0.13

This commit is contained in:
Neo committed 2025-12-19 19:04:57 -08:00
1 parent b89858b2ff
commit 5efe744c5f
1407 files changed
+69690 -30177

No files matched your search

+6
View File
@@ -72,6 +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 int submitted_after Find files submitted after a unix timestamp
* @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
@@ -101,6 +102,11 @@ class files extends ItemController
}
}
if( isset( Request::i()->submitted_after ) )
{
$where[] = [ 'file_submitted > ?', Request::i()->submitted_after ];
}
/* Return */
return $this->_list( $where, 'categories', FALSE, $sortBy );
}
+4 -4
View File
@@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<emails><template><template_app>downloads</template_app><template_name>digests__comment</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
<td dir='{dir}' width='120' align='center' valign='top'>
{{if $comment->item()->primary_screenshot_thumb}}
<img src='{file="$comment->item()->primary_screenshot_thumb" extension="downloads_Screenshots"}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{if $screenshot = $comment->item()->primary_screenshot_thumb}}
<img src='{$screenshot->url}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{else}}
<div style='width: 100px; height: 100px; background: #f5f5f5'>&nbsp;</div>
{{endif}}
@@ -103,8 +103,8 @@
-- {setting="board_name"}]]></template_content_plaintext><template_pinned>0</template_pinned></template><template><template_app>downloads</template_app><template_name>digests__item</template_name><template_content_html><![CDATA[<tr style='border-bottom: 1px solid #eeeeee'>
<td dir='{dir}' width='120' align='center' valign='top'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb" extension="downloads_Screenshots"}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{else}}
<div style='width: 100px; height: 100px; background: #f5f5f5'>&nbsp;</div>
{{endif}}
+21 -21
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="5000074" 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="5001302" 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="5000074" 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="5001302" 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="5000074" 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="5001302" 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="5000074" 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="5001302" 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="5000074" 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="5001302" javascript_position="1000100"><![CDATA[/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -479,7 +479,7 @@
});
if( !invalid ){
this.scope.find( '#' + elemID ).trigger('closeMenu');
this.elem.querySelector(`#${elemID}_menu`)?.closest("[popover]")?.hidePopover();
}
// Update UI if we have a file limit
@@ -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="5000074" 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="5001302" javascript_position="1000150">/**
* Invision Community
* (c) Invision Power Services, Inc. - https://www.invisioncommunity.com
*
@@ -657,7 +657,7 @@
* Author: Rikki Tissier
*/
;( function($, _, undefined){
"use strict";
&quot;use strict&quot;;
ips.controller.register('downloads.front.view.changeLog', {
@@ -689,10 +689,10 @@
* @param {object} data Event data object from the menu
* @returns {void}
*/
changeVersion: function (e, data) {
changeVersion: function (e, data = e.detail) {
data.originalEvent.preventDefault();
var url = data.menuElem.find('[data-ipsMenuValue="' + data.selectedItemID + '"] > a').attr('href');
var url = $(data.menuElem).find('[data-ipsMenuValue=&quot;' + data.selectedItemID + '&quot;]').attr('href');
// Update page URL
ips.utils.history.pushState( {
@@ -700,7 +700,7 @@
version: data.selectedItemID
}, 'downloads.front.view.changeLog', url );
this._loadVersion( url, data.menuElem.find('[data-ipsMenuValue="' + data.selectedItemID + '"]').attr('data-changelogTitle') );
this._loadVersion( url, $(data.menuElem).find('[data-ipsMenuValue=&quot;' + data.selectedItemID + '&quot;]').attr('data-changelogTitle') );
},
/**
@@ -721,12 +721,12 @@
let item;
if (state.version) {
item = $('#elChangelog_menu').find('[data-ipsMenuValue="' + state.version + '"]');
item = $('#elChangelog_menu').find('[data-ipsMenuValue=&quot;' + state.version + '&quot;]');
} else {
item = $('#elChangelog_menu').find('[data-ipsMenuValue]').first();
}
this._loadVersion( item.find('a').attr('href'), item.attr('data-ipsMenuValue') );
this._loadVersion( item.attr('href'), item.attr('data-ipsMenuValue') );
},
/**
@@ -740,13 +740,13 @@
var self = this;
// Update version
this.scope.find('[data-role="versionTitle"]').text( versionTitle );
this.scope.find('[data-role=&quot;versionTitle&quot;]').text( versionTitle );
// Set height on info area and set to loading
this.scope
.find('[data-role="changeLogData"]')
.find('[data-role=&quot;changeLogData&quot;]')
.css( {
height: this.scope.find('[data-role="changeLogData"]').height() + 'px'
height: this.scope.find('[data-role=&quot;changeLogData&quot;]').height() + 'px'
})
.addClass('ipsLoading')
.html('');
@@ -756,7 +756,7 @@
ips.getAjax()( url )
.done( function (response) {
self.scope
.find('[data-role="changeLogData"]')
.find('[data-role=&quot;changeLogData&quot;]')
.html( response )
.removeClass('ipsLoading')
.css({
@@ -769,8 +769,8 @@
}
});
}(jQuery, _));]]></file>
<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">/**
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.download.js" javascript_type="controller" javascript_version="5001302" 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="5000074" 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="5001302" 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="5000074" 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="5001302" 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'>\
+4 -2
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="downloads" version="5000074">
<app key="downloads" version="5001302">
<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>
@@ -445,7 +445,7 @@
<word key="file_locked_cannot_comment" js="0">This file is now closed to further comments.</word>
<word key="file__save" js="0">Save</word>
<word key="downloads_no_file" js="0">File not found</word>
<word key="download_teaser" js="0">Create an account or sign in to download this</word>
<word key="download_teaser" js="0">Register or sign in to download</word>
<word key="download_no_permission" js="0">Sorry, you aren't permitted to download this file.</word>
<word key="download_no_permission_guest" js="0">Sorry, you aren't permitted to download this file. However, you may be able to download if you sign in.</word>
<word key="downloads_file_info" js="0">Downloads</word>
@@ -518,6 +518,8 @@
<word key="stats_overview_downloads_desc" js="0">Logging of downloads and the retention period for logs can be adjusted on a per-category basis</word>
<word key="downloads_stats_uploader_count" js="0">{# [1:member][?:members]} uploaded files.</word>
<word key="downloads_stats_downloader_count" js="0">{# [1:member][?:members]} downloaded files.</word>
<word key="downloads_file_name" js="0">File Name</word>
<word key="downloads_file_downloads" js="0">Downloads</word>
<word key="ipAddresses__downloads_DownloadLog" js="0">Downloads</word>
<word key="acplogs__downloads_resync_topics" js="0">Resynchronized topic content for %s</word>
<word key="block_fileFeed" js="0">Files Feed</word>
+226 -203
View File
@@ -5,7 +5,7 @@
</header>
{{ $layout = \IPS\Member::loggedIn()->getLayoutValue( 'downloads_categories' ); }}
{{if !$clubsOnly}}
<div class='ipsBox'>
<div class='ipsBox ipsBox--downloadCategories ipsPull'>
<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">
@@ -14,8 +14,8 @@
</i-data>
</div>
{{endif}}
{{if settings.club_nodes_in_apps and $clubNodes = \IPS\downloads\Category::clubNodes()}}
<div class='ipsBox'>
{{if settings.clubs and settings.club_nodes_in_apps and $clubNodes = \IPS\downloads\Category::clubNodes()}}
<div class='ipsBox ipsBox--downloadClubs ipsPull'>
<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">
@@ -97,7 +97,7 @@
<div id='elClubContainer'>
{{endif}}
<header class='ipsPageHeader ipsBox ipsPull'>
<header class='ipsPageHeader ipsBox ipsBox--downloadsCategoryHeader ipsPull'>
<div class="ipsPageHeader__row">
<div data-ips-hook="header" class='ipsPageHeader__primary'>
<h1 data-ips-hook="title" data-ips-hook="title" class="ipsPageHeader__title">{$category->_title}</h1>
@@ -115,16 +115,17 @@
</header>
<div data-controller='downloads.front.downloads.browse' class='ipsBlockSpacer'>
{template="categoryMenu" group="browse" params="$category->children()"}
<ul class="ipsButtons ipsButtons--main">
{{if $category->hasChildren()}}
<li class="ipsResponsive_hideDesktop"><a href='#elDownloadsCategories_menu' data-ipsMenu id='elDownloadsCategories' class='ipsButton ipsButton--inherit'><span>{lang="subcategory"}</span><i class='fa-solid fa-caret-down'></i></a></li>
<li class="ipsResponsive_hideDesktop">
<button type="button" id="elDownloadsCategories" popovertarget="elDownloadsCategories_menu" class='ipsButton ipsButton--inherit'><span>{lang="subcategory"}</span><i class='fa-solid fa-caret-down'></i></button>
</li>
{{endif}}
{template="categoryButtons" group="browse" params="$category->can('add'), $category, FALSE"}
</ul>
{template="categoryMenu" group="browse" params="$category->children()"}
<div class='ipsBox ipsPull cDownloadsCategoryTable'>
<div class='ipsBox ipsBox--downloadsCategoryTable ipsPull cDownloadsCategoryTable'>
{$table|raw}
</div>
@@ -171,23 +172,26 @@
{{endif}}
</li>
{{endif}}]]></template>
<template template_group="browse" template_name="categoryMenu" template_data="$categories" template_location="front" template_app="downloads"><![CDATA[<ul class='ipsMenu ipsMenu_auto ipsHide' id='elDownloadsCategories_menu'>
{{foreach $categories as $cat}}
{{if $cat->can('view')}}
<li class='ipsMenu_item'>
<a href='{$cat->url()}'>{$cat->_title}<span class="ipsMenu_itemCount">{number="\IPS\downloads\File::contentCount( $cat )"}</span></a>
</li>
{{endif}}
{{endforeach}}
</ul>
]]></template>
<template template_group="browse" template_name="categoryMenu" template_data="$categories" template_location="front" template_app="downloads"><![CDATA[<i-dropdown popover id="elDownloadsCategories_menu">
<div class="iDropdown">
<ul class="iDropdown__items">
{{foreach $categories as $cat}}
{{if $cat->can('view')}}
<li>
<a href='{$cat->url()}'>{$cat->_title}<span class="ipsMenu_itemCount">{number="\IPS\downloads\File::contentCount( $cat )"}</span></a>
</li>
{{endif}}
{{endforeach}}
</ul>
</div>
</i-dropdown>]]></template>
<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'>
<div class="ipsData__image" aria-hidden="true">
{{if $layout==="table"}}
{{if $icon = $category->getIcon()}}
@@ -221,7 +225,7 @@
{{endif}}
{{endif}}
</figure>
</div>
<div class="ipsData__content">
<div class="ipsData__main">
@@ -273,20 +277,20 @@
{{endforeach}}]]></template>
<template template_group="browse" template_name="featuredFile" template_data="$file" template_location="front" template_app="downloads"><![CDATA[<li class="ipsData__item {{if $file->hidden()}}ipsModerated{{endif}} {$file->ui( 'css' )}" {$file->ui( 'dataAttributes' )}>
<a href='{$file->url( "getPrefComment" )}' class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$file->name}</span></a>
<figure class='ipsData__image'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt='' loading='lazy'>
<div class="ipsData__image" aria-hidden="true" data-ips-hook='image'>
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
</figure>
</div>
<div class='ipsData__content'>
<div class="ipsData__main">
<div class='ipsData__title'>
<div class='ipsData__title' data-ips--hook='title'>
{{if $file->unread()}}
<span class='ipsIndicator' data-ipsTooltip title='{{if $file->unread() === -1}}{lang="new"}{{else}}{lang="updated"}{{endif}}'></span>
{{endif}}
<div class='ipsBadges'>
<div class='ipsBadges' data-ips-hook='badges'>
{{foreach $file->badges() as $badge}}
{{if !\in_array($badge->badgeType, ['ipsBadge--featured', 'ipsBadge--pinned'])}}
{$badge|raw}
@@ -310,7 +314,7 @@
{{endif}}
</span>
{{endif}}
<ul class='ipsButtons ipsButtons--start i-margin-block_2' hidden>
<ul class='ipsButtons ipsButtons--start i-margin-block_2' hidden data-ips-hook='buttons'>
{{if ( $file->canDownload() or ( $file->container()->message('npd') and !$file->canBuy() ) ) && !$file->canBuy()}}
<li>
<a href='{{if settings.idm_antileech AND !$file->requiresDownloadConfirmation()}}{$file->url('download')->csrf()}{{else}}{$file->url('download')}{{endif}}' class='ipsButton ipsButton--secondary' {{if $file->requiresDownloadConfirmation()}}data-ipsDialog{{endif}}><i class="fa-solid fa-download"></i><span>{lang="download"}</span></a>
@@ -323,7 +327,7 @@
</ul>
</div>
<div class="ipsData__extra">
<ul class='ipsData__stats'>
<ul class='ipsData__stats' data-ips-hook='stats'>
{{if $file->isPaid() and !$file->nexus and \in_array( 'purchases', explode( ',', settings.idm_nexus_display ) ) and $file->purchaseCount()}}
<li data-statType="purchases">
<span class='ipsData__stats-icon' data-stat-value="{$file->purchaseCount()}" aria-hidden="true" data-ipstooltip title='{lang="x_purchases" pluralize="$file->purchaseCount()"}'></span>
@@ -362,7 +366,7 @@
</div>
{{endif}}
{template="thumbImage" group="global" app="core" params="$file->primary_screenshot_thumb, $file->name, 'medium', '', 'view_this', $file->url( 'getPrefComment' ), 'downloads_Screenshots', '', true"}
<h4 class='ipsData__title'>
<h4 class='ipsData__title' data-ips-hook='title'>
{{if $file->unread()}}
<span class='ipsIndicator' data-ipsTooltip title='{{if $file->unread() === -1}}{lang="new"}{{else}}{lang="updated"}{{endif}}'></span>
{{endif}}
@@ -381,7 +385,7 @@
{lang="in"} <a href="{$file->container()->url()}">{$file->container()->_title}</a>
{{endif}}
</p>
<div class='i-basis_220'>
<div class='i-basis_220' data-ips-hook='metadata'>
<p><strong>{{if $file->updated == $file->submitted}}{lang="submitted"} {datetime="$file->submitted" lowercase="true"}{{else}}{lang="updated"} {datetime="$file->updated" lowercase="true"}{{endif}}</strong></p>
</div>
@@ -392,7 +396,7 @@
<!-- Comments -->
{{if $file->container()->bitoptions['comments']}}
<p>
<p data-ips-hook='stats'>
{{if $file->comments}}
<a href='{$file->url()->setQueryString( 'tab', 'comments' )->setFragment('replies')}'>
{{endif}}
@@ -424,13 +428,13 @@
<span {{if !$file->downloads}}class='i-color_soft'{{endif}}><i class='fa-solid fa-circle-arrow-down'></i> {lang="num_downloads" pluralize="$file->downloads"}</span>
{{endif}}
</p>
<!-- Tags -->
{{endif}}
<!-- Tags -->
{{if \count( $file->tags() )}}
{template="tags" group="global" app="core" params="$file->tags(), TRUE"}
{{endif}}
{{endif}}
</div>]]></template>
<template template_group="browse" template_name="index" template_data="$featured, $new, $rated, $downloaded" template_location="front" template_app="downloads"><![CDATA[<header class="ipsPageHeader">
<template template_group="browse" template_name="index" template_data="$featured, $new, $rated, $downloaded" template_location="front" template_app="downloads"><![CDATA[<header class="ipsPageHeader ipsPageHeader--downloadsBrowseHeader">
<div class="ipsPageHeader__row">
<div data-ips-hook="header" class='ipsPageHeader__primary'>
<h1 data-ips-hook="title" class='ipsPageHeader__title'>{lang="downloads"}</h1>
@@ -438,7 +442,7 @@
<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>
<button type="button" id="elDownloadsCategories" popovertarget="elDownloadsCategories_menu" class='ipsButton ipsButton--inherit'><span>{lang="downloads_category_select"}</span><span>{lang="all"}</span><i class='fa-solid fa-caret-down'></i></button>
{template="categoryMenu" group="browse" params="\IPS\downloads\Category::roots()"}
</li>
{{endif}}
@@ -452,7 +456,7 @@
</div>
</header>
{{if !empty( $featured )}}
<section class='ipsBox ipsPull'>
<section class='ipsBox ipsBox--downloadsFeatured ipsPull'>
<header class='ipsBox__header i-flex i-justify-content_space-between'>
<h2>{lang="featured_downloads"}</h2>
{template="carouselNavigation" group="global" app="core" params="'downloads-featured-files'"}
@@ -470,11 +474,10 @@
{{endif}}
{{if settings.idm_show_newest AND \count( $new ) }}
<section class='ipsBox ipsPull'>
<section class='ipsBox ipsBox--downloadsWhatsNew ipsPull'>
<header class='ipsBox__header i-flex i-justify-content_space-between'>
<h2>{lang="browse_whats_new"}</h2>
{template="carouselNavigation" group="global" app="core" params="'downloads-whats-new'"}
</header>
<div class='ipsBox__content'>
<i-data>
@@ -489,7 +492,7 @@
{{endif}}
{{if settings.idm_show_highest_rated AND \count( $rated )}}
<section class='ipsBox ipsPull'>
<section class='ipsBox ipsBox--downloadsHighestRated ipsPull'>
<header class='ipsBox__header i-flex i-justify-content_space-between'>
<h2>{lang="browse_highest_rated"}</h2>
{template="carouselNavigation" group="global" app="core" params="'downloads-highest-rated'"}
@@ -508,7 +511,7 @@
{{endif}}
{{if settings.idm_show_most_downloaded AND \count( $downloaded )}}
<section class='ipsBox ipsPull'>
<section class='ipsBox ipsBox--downloadsMostDownloaded ipsPull'>
<header class='ipsBox__header i-flex i-justify-content_space-between'>
<h2>{lang="browse_most_downloaded"}</h2>
{template="carouselNavigation" group="global" app="core" params="'downloads-most-downloaded'"}
@@ -533,29 +536,29 @@
{template="categoryButtons" group="browse" params="\IPS\downloads\Category::canOnAny('add'), NULL, TRUE"}
</ul>
{{endif}}]]></template>
<template template_group="browse" template_name="indexBlock" template_data="$file" template_location="front" template_app="downloads"><![CDATA[<li class="ipsData__item {{if $file->hidden()}}ipsModerated{{endif}}">
<template template_group="browse" template_name="indexBlock" template_data="$file" template_location="front" template_app="downloads"><![CDATA[<li class="ipsData__item {{if $file->hidden()}}ipsModerated{{endif}} {$file->ui('css')}" {$file->ui('dataAttributes')}>
<a href='{$file->url( "getPrefComment" )}' class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$file->name}</span></a>
<figure class='ipsData__image'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt='' loading='lazy'>
<div class="ipsData__image" aria-hidden="true" data-ips-hook='image'>
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
</figure>
</div>
<div class='ipsData__content'>
<div class="ipsData__main">
<div class='ipsData__title'>
<div class='ipsData__title' data-ips-hook='main'>
{{if $file->unread()}}
<span class='ipsIndicator' data-ipsTooltip title='{{if $file->unread() === -1}}{lang="new"}{{else}}{lang="updated"}{{endif}}'></span>
{{endif}}
<div class='ipsBadges'>
<div class='ipsBadges' data-ips-hook='badges'>
{{foreach $file->badges() as $badge}}
{{if !\in_array($badge->badgeType, ['ipsBadge--pinned'])}}
{$badge|raw}
{{endif}}
{{endforeach}}
</div>
<h3><a href='{$file->url( "getPrefComment" )}' title='{lang="view_this_file" sprintf="$file->name"}'>{$file->name}</a></h3>
<h3 data-ips-hook='title'><a href='{$file->url( "getPrefComment" )}' title='{lang="view_this_file" sprintf="$file->name"}'>{$file->name}</a></h3>
{{if $file->container()->bitoptions['reviews'] and $file->averageReviewRating()}}
{template="rating" group="global" location="front" app="core" params="'small', $file->averageReviewRating(), \IPS\Settings::i()->reviews_rating_out_of"}
{{endif}}
@@ -573,7 +576,7 @@
{{endif}}
</div>
<div class="ipsData__extra">
<ul class='ipsData__stats'>
<ul class='ipsData__stats' data-ips-hook='stats'>
{{if $file->isPaid() and !$file->nexus and \in_array( 'purchases', explode( ',', settings.idm_nexus_display ) ) and $file->purchaseCount()}}
<li data-statType="purchases">
<span class='ipsData__stats-icon' data-stat-value="{$file->purchaseCount()}" aria-hidden="true" data-ipstooltip title='{lang="x_purchases" pluralize="$file->purchaseCount()"}'></span>
@@ -627,9 +630,9 @@
{$file->ui( 'dataAttributes' )}
>
<a href="{$file->url( 'getPrefComment' )}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$file->name}</span></a>
<a href="{$file->url( 'getPrefComment' )}" class='ipsData__image'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt='' loading='lazy'>
<a href="{$file->url( 'getPrefComment' )}" class='ipsData__image' aria-hidden="true" tabindex="-1">
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
@@ -692,15 +695,15 @@
<span class='ipsData__stats-label'>{$file->comments} {lang="total_comments"}</span>
</li>
{{endif}}
{{if $table AND method_exists( $table, 'canModerate' ) AND $table->canModerate()}}
<li>
<input class='ipsInput ipsInput--toggle' type='checkbox' data-role='moderation' name="moderate[{$file->id}]" data-actions="{expression="implode( ' ', $table->multimodActions( $file ) )"}" data-state='{{if $file->tableStates()}}{$file->tableStates()}{{endif}}'>
</li>
{{endif}}
</ul>
<div class='ipsData__last'>{lang="byline_nodate" htmlsprintf="$file->author()->link( NULL, NULL, $file->isAnonymous() )"}</div>
</div>
</div>
{{if $table AND method_exists( $table, 'canModerate' ) AND $table->canModerate()}}
<div class="ipsData__mod">
<input class='ipsInput ipsInput--toggle' type='checkbox' data-role='moderation' name="moderate[{$file->id}]" data-actions="{expression="implode( ' ', $table->multimodActions( $file ) )"}" data-state='{{if $file->tableStates()}}{$file->tableStates()}{{endif}}'>
</div>
{{endif}}
</li>
{{endforeach}}
{{else}}
@@ -716,17 +719,17 @@
{$file->ui( 'dataAttributes' )}
>
<a href='{$file->url( "getPrefComment" )}' class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$file->name}</span></a>
<a href="{$file->url( 'getPrefComment' )}" class='ipsData__image'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt='' loading='lazy'>
<a href="{$file->url( 'getPrefComment' )}" class='ipsData__image' aria-hidden="true" tabindex="-1">
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
</a>
<div class='ipsData__content'>
<div class='ipsData__main'>
<div class='ipsData__title'>
<div class='ipsBadges'>
<div class='ipsData__title' data-ips-hook='main'>
<div class='ipsBadges' data-ips-hook='badges'>
{{foreach $file->badges() as $badge}}{$badge|raw}{{endforeach}}
</div>
{{if $file->prefix()}}
@@ -735,7 +738,7 @@
{{if $file->unread()}}
<span class='ipsIndicator' data-ipsTooltip title='{{if $file->unread() === -1}}{lang="new"}{{else}}{lang="updated"}{{endif}}'></span>
{{endif}}
<h4><a href='{$file->url( "getPrefComment" )}' title='{lang="view_this_file" sprintf="$file->name"} {{if $file->canEdit()}}{lang="click_hold_edit"}{{endif}}' {{if $file->canEdit()}}data-role="editableTitle"{{endif}}>{$file->name}</a></h4>
<h4 data-ips-hook='title'><a href='{$file->url( "getPrefComment" )}' title='{lang="view_this_file" sprintf="$file->name"} {{if $file->canEdit()}}{lang="click_hold_edit"}{{endif}}' {{if $file->canEdit()}}data-role="editableTitle"{{endif}}>{$file->name}</a></h4>
</div>
<div class='ipsData__desc'>{$file->truncated()|raw}</div>
<div class="i-flex i-align-items_center i-gap_2 i-flex-wrap_wrap">
@@ -748,7 +751,7 @@
</div>
</div>
<div class="ipsData__extra">
<ul class='ipsData__stats'>
<ul class='ipsData__stats' data-ips-hook='stats'>
{{if \IPS\Application::appIsEnabled( 'nexus' ) and settings.idm_nexus_on}}
<li data-stattype="price">
{{if $file->isPaid()}}
@@ -781,7 +784,7 @@
</ul>
<div class="ipsData__last">
{template="userPhoto" app="core" group="global" params="$file->author(), 'fluid'"}
<div class="ipsData__last-text">
<div class="ipsData__last-text" data-ips-hook='details'>
<div class="ipsData__last-primary">
{lang="byline_nodate" htmlsprintf="$file->author()->link( NULL, NULL, $file->isAnonymous() )"}
{{if \IPS\Request::i()->app != 'downloads'}}
@@ -839,7 +842,7 @@
<h3 class='ipsTitle ipsTitle--h3'><a href='{$file->url( "getPrefComment" )}' title='{lang="view_this_file" sprintf="$file->name"}'>{$file->mapped('title')}</a></h3>
<p class='i-color_soft i-link-color_inherit'>{lang="in"} <a href='{$file->container()->url()}'>{$file->container()->_title}</a></p>
{{if $file->container()->bitoptions['reviews']}}
{template="rating" group="global" location="front" app="core" params="'large', $file->rating, \IPS\Settings::i()->reviews_rating_out_of"} &nbsp;&nbsp;
{template="rating" group="global" location="front" app="core" params="'large', $file->averageReviewRating(), \IPS\Settings::i()->reviews_rating_out_of"} &nbsp;&nbsp;
{{endif}}
<span>{{if !$file->downloads}}<span class='i-color_soft'>{{endif}}<i class='fa-solid fa-circle-arrow-down'></i> {number="$file->downloads"}{{if !$file->downloads}}</span>{{endif}} {{if $file->container()->bitoptions['comments']}}&nbsp;&nbsp;{{if !$file->comments}}<span class='i-color_soft'>{{endif}}<i class='fa-solid fa-comment'></i> {$file->comments}{{endif}}{{if !$file->comments}}</span>{{endif}}</span>
@@ -911,9 +914,9 @@
{template="embedHeader" group="embed" app="core" params="$comment, $item->mapped('title'), $comment->mapped('date'), $url"}
<div class='ipsRichEmbed__content'>
<div class='ipsRichEmbed_originalItem'>
{{if $item->primary_screenshot_thumb}}
{{if $screenshot = $item->primary_screenshot_thumb}}
<a href='{$url}' title='{$item->mapped('title')}' class='ipsRichEmbed_masthead ipsRichEmbed_masthead--small'>
<img src='{file="$item->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt="{$item->mapped('title')}" loading="lazy">
<img src='{$screenshot->url}' alt="{$item->mapped('title')}" loading="lazy">
</a>
{{endif}}
<div class='ipsRichEmbed__content'>
@@ -962,9 +965,9 @@
<div class='ipsRichEmbed__content'>
<div class='ipsRichEmbed_originalItem'>
<div>
{{if $item->primary_screenshot_thumb}}
{{if $screenshot = $item->primary_screenshot_thumb}}
<a href='{$url}' title='{$item->mapped('title')}' class='ipsRichEmbed_masthead ipsRichEmbed_masthead--small'>
<img src='{file="$item->primary_screenshot_thumb" extension="downloads_Screenshots"}' alt="{$item->mapped('title')}" loading="lazy">
<img src='{$screenshot->url}' alt="{$item->mapped('title')}" loading="lazy">
</a>
{{else}}
<div class='ipsRichEmbed_masthead'></div>
@@ -997,13 +1000,13 @@
{{foreach $rows as $row}}
{{$idField = $row::$databaseColumnId;}}
<li class="ipsData__item {{if method_exists( $row, 'tableClass' ) && $row->tableClass()}}ipsData__item--{$row->tableClass()}{{endif}} {{if $row->hidden()}}ipsModerated{{endif}}" data-controller='core.front.system.manageFollowed' data-followID='{$row->_followData['follow_area']}-{$row->_followData['follow_rel_id']}' {{if $row->unread()}}data-ips-unread{{else}}data-ips-read{{endif}}>
<figure class='ipsData__image'>
<div class="ipsData__image" aria-hidden="true">
{{if $row->_primary_screenshot }}
<img src='{expression="str_replace( array( '(', ')' ), array( '\(', '\)' ), $row->primary_screenshot->url )"}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
</figure>
</div>
<div class='ipsData__content'>
<div class='ipsData__main'>
<div class='ipsData__title'>
@@ -1134,9 +1137,9 @@
<template template_group="nexus" template_name="fileInfo" template_data="$file" template_location="admin" template_app="downloads"><![CDATA[
<div class='i-background_2 i-padding_3 i-margin-bottom_2 i-border-radius_box'>
<div class='ipsData__item'>
<a href="$file->url()" class='ipsData__image'>
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb"}' alt='' loading='lazy'>
<a href="$file->url()" class='ipsData__image' aria-hidden="true" tabindex="-1">
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
@@ -1403,41 +1406,45 @@
<input type="hidden" name="{$k}" value="{$v}">
{{endforeach}}
<div class='ipsBox ipsPull i-margin-bottom_block'>
<div class='ipsBox ipsBox--downloadsSubmit1 ipsPull i-margin-bottom_block'>
<h3 class='ipsBox__header'>{$step}{{$step++;}}. {{if $category->multiple_files}}{lang="select_your_files"}{{else}}{lang="select_your_file"}{{endif}}</h3>
<div class='i-padding_3'>
{{if isset( $form->elements['']['import_files'] ) || isset( $form->elements['']['url_files'] )}}
<ul class='ipsButtons ipsButtons--end i-margin-bottom_2'>
{{if isset( $form->elements['']['url_files'] )}}
<li>
<button type="button" class='ipsButton ipsButton--soft ipsButton--small' id='elURLFiles' data-ipsMenu data-ipsMenu-closeOnClick='false' data-ipsMenu-appendTo='#elDownloadsSubmit'>
<button type="button" id="elURLFiles" popovertarget="elURLFiles_menu" class='ipsButton ipsButton--soft ipsButton--small'>
<i class='fa-solid fa-earth-americas'></i> {lang="add_files_by_url"} <i class='fa-solid fa-caret-down'></i>
<span class='ipsNotification {{if !\count( $form->elements['']['url_files']->value )}}ipsHide{{endif}}' data-role='fileCount'>{expression="\count( $form->elements['']['url_files']->value )"}</span>
</button>
<div id='elURLFiles_menu' class='ipsMenu ipsMenu_normal i-padding_0 ipsHide'>
<ul class='ipsForm ipsForm--fullWidth'>
{$form->elements['']['url_files']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmUrls'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
<i-dropdown popover id="elURLFiles_menu">
<div class="iDropdown">
<ul class='ipsForm ipsForm--fullWidth'>
{$form->elements['']['url_files']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmUrls'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
</i-dropdown>
</li>
{{endif}}
{{if isset( $form->elements['']['import_files'] )}}
<li>
<button type="button" class='ipsButton ipsButton--soft ipsButton--small' id='elImportFiles' data-ipsMenu data-ipsMenu-closeOnClick='false' data-ipsMenu-appendTo='#elDownloadsSubmit'>
<button type="button" id="elImportFiles" popovertarget="elImportFiles_menu" class='ipsButton ipsButton--soft ipsButton--small'>
<i class='fa-solid fa-folder'></i> {lang="add_files_by_path"} <i class='fa-solid fa-caret-down'></i>
<span class='ipsNotification {{if !\count( $form->elements['']['import_files']->value )}}ipsHide{{endif}}' data-role='fileCount'>{expression="\count( $form->elements['']['import_files']->value )"}</span>
</button>
<div id='elImportFiles_menu' class='ipsMenu ipsMenu_normal i-padding_0 ipsHide'>
<ul class='ipsForm ipsForm--fullWidth'>
{$form->elements['']['import_files']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmImports'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
<i-dropdown popover id="elImportFiles_menu">
<div class="iDropdown">
<ul class='ipsForm ipsForm--fullWidth'>
{$form->elements['']['import_files']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmImports'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
</i-dropdown>
</li>
{{endif}}
</ul>
@@ -1459,24 +1466,26 @@
{{if !$bulk }}
{{if $category->bitoptions['allowss'] }}
<div id='elDownloadsSubmit_screenshots'>
<div class='ipsBox ipsPull i-margin-bottom_block'>
<div class='ipsBox ipsBox--downloadsSubmit2 ipsPull i-margin-bottom_block'>
<h3 class='ipsBox__header'>{$step}{{$step++;}}. {lang="add_screenshots"}</h3>
<div class='i-padding_3'>
{{if isset( $form->elements['']['url_screenshots'] )}}
<ul class='ipsButtons ipsButtons--end i-margin-bottom_2'>
<li>
<button type="button" class='ipsButton ipsButton--soft ipsButton--small' id='elURLScreenshots' data-ipsMenu data-ipsMenu-closeOnClick='false' data-ipsMenu-appendTo='#elDownloadsSubmit_screenshots'>
<button type="button" id="elURLScreenshots" popovertarget="elURLScreenshots_menu" class='ipsButton ipsButton--soft ipsButton--small'>
<i class='fa-solid fa-earth-americas'></i> {lang="add_screenshots_by_url"} <i class='fa-solid fa-caret-down'></i>
<span class='ipsNotification {{if !isset( $form->elements['']['url_screenshots']->value['values'] ) OR !\count( $form->elements['']['url_screenshots']->value['values'] )}}ipsHide{{endif}}' data-role='fileCount'>{expression="\count( $form->elements['']['url_screenshots']->value['values'] ?? array() )"}</span>
</button>
<div id='elURLScreenshots_menu' class='ipsMenu ipsMenu_wide ipsHide'>
<ul class="ipsForm ipsForm--vertical">
{$form->elements['']['url_screenshots']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmScreenshotUrls'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
<i-dropdown popover id="elURLScreenshots_menu">
<div class="iDropdown">
<ul class="ipsForm ipsForm--vertical">
{$form->elements['']['url_screenshots']|raw}
<li class="ipsSubmitRow">
<button type="button" class='ipsButton ipsButton--wide ipsButton--primary' data-action='confirmScreenshotUrls'>{lang="submit_menu_confirm"}</button>
</li>
</ul>
</div>
</i-dropdown>
</li>
</ul>
{{endif}}
@@ -1491,7 +1500,7 @@
{{endif}}
<div id='elDownloadsSubmit_otherinfo'>
<div class='ipsBox ipsPull i-margin-bottom_block'>
<div class='ipsBox ipsBox--downloadsSubmit3 ipsPull i-margin-bottom_block'>
<h3 class='ipsBox__header'>{$step}{{$step++;}}. {{if $newSubmission}}{lang="submit_file_information"}{{else}}{lang="new_version_details"}{{endif}}</h3>
<ul class='ipsForm ipsForm--vertical ipsForm--submit-file'>
{{foreach $form->elements as $collection}}
@@ -1505,7 +1514,7 @@
</div>
{{if $terms}}
<div class='ipsBox ipsPull i-margin-bottom_block'>
<div class='ipsBox ipsBox--downloadsSubmit4 ipsPull i-margin-bottom_block'>
<h3 class='ipsBox__header'>{$step}{{$step++;}}. {lang="csubmissionterms_placeholder"}</h3>
<div class='i-padding_3 ipsRichText'>
{$terms|raw}
@@ -1514,7 +1523,7 @@
{{endif}}
</div>
{{elseif $terms}}
<div class='ipsBox ipsPull i-margin-bottom_block'>
<div class='ipsBox ipsBox--downloadsSubmit5 ipsPull i-margin-bottom_block'>
<h3 class='ipsBox__header'>{$step}{{$step++;}}. {lang="csubmissionterms_placeholder"}</h3>
<div class='i-padding_3 ipsRichText'>
{$terms|raw}
@@ -1522,7 +1531,7 @@
</div>
{{endif}}
<div class='ipsBox ipsPull i-padding_2 i-text-align_center'>
<div class='ipsBox ipsBox--downloadsSubmit6 ipsPull i-padding_2 i-text-align_center'>
<button type='submit' class='ipsButton ipsButton--primary' data-role='submitForm'>
{{if $bulk}}
{lang="continue"}
@@ -1559,7 +1568,7 @@
</p>
{{foreach $file->customFields( TRUE ) as $k => $v}}
<p>
<strong><span data-ips-font-size="90">{lang="downloads_{$k}"} </span></strong> {$v|raw}
{$v|raw}
</p>
{{endforeach}}
</div>
@@ -1574,7 +1583,7 @@
{{endif}}
{{endforeach}}]]></template>
<template template_group="view" template_name="changeLog" template_data="$file, $version" template_location="front" template_app="downloads"><![CDATA[{{$versionNumber = $version['b_version'] ?: (string) \IPS\DateTime::ts( $version['b_backup'] );}}
<p class='i-color_soft i-margin-bottom_2'>{lang="file_version_released" htmlsprintf="\IPS\DateTime::ts( $version['b_backup'] )->html( false )"}</p>
<p class='i-color_soft i-margin-bottom_1'>{lang="file_version_released" htmlsprintf="\IPS\DateTime::ts( $version['b_backup'] )->html( false )"}</p>
<div class='ipsRichText'>
{{if $version['b_changelog']}}
{template="richText" group="global" app="core" location="global" params="$version['b_changelog']"}
@@ -1583,8 +1592,8 @@
{{endif}}
</div>
{{if isset( $version['b_id'] ) and ( $file->canDownload() or ( $file->canEdit() and member.group['idm_bypass_revision'] ) )}}
<div class="ipsTitle ipsTitle--h5 i-margin-top_3 i-margin-bottom_1">{lang="with_version" sprintf="$versionNumber"}</div>
<ul class='ipsList ipsList--inline'>
<li><img src='{resource="subitem_stem.png" app="core"}' alt=''> <strong>{lang="with_version" sprintf="$versionNumber"}</strong></li>
{{if $file->canDownload()}}
<li><a href='{{if settings.idm_antileech AND !$file->requiresDownloadConfirmation()}}{$file->url('download')->setQueryString( array( 'version' => $version['b_id'] ) )->csrf()}{{else}}{$file->url('download')->setQueryString( array( 'version' => $version['b_id'] ) )}{{endif}}' {{if $file->requiresDownloadConfirmation()}}data-ipsDialog{{endif}}>{lang="download"}</a></li>
{{endif}}
@@ -1707,7 +1716,7 @@
]]></template>
<template template_group="view" template_name="downloadSidebar" template_data="$file" template_location="front" template_app="downloads"></template>
<template template_group="view" template_name="downloadTeaser" template_data="" template_location="front" template_app="downloads"><![CDATA[
<span class="i-color_soft ipsResponsive_hidePhone"><i class="fa-solid fa-circle-info"></i> {lang="download_teaser"}</span>
<a class='ipsButton ipsButton--inherit ipsButton--wide' href='{url="app=core&module=system&controller=login" seoTemplate="login"}' data-ipsDialog data-ipsDialog-size='medium' data-ipsDialog-title='{lang="teaser_signin_button"}'><i class="fa-solid fa-circle-info"></i> {lang="download_teaser"}</a>
]]></template>
<template template_group="view" template_name="downloadTerms" template_data="$file, $downloadTerms, $confirmUrl, $multipleFiles" template_location="front" template_app="downloads"><![CDATA[<div class='i-padding_3'>
<h1 class='ipsTitle ipsTitle--h3'>{lang="download_terms"}</h1>
@@ -1737,7 +1746,7 @@
</div>
</li>
{{endforeach}}]]></template>
<template template_group="view" template_name="logTable" template_data="$table, $headers, $rows, $quickSearch" template_location="front" template_app="downloads"><![CDATA[<div data-baseurl='{$table->baseUrl}' data-resort='{$table->resortKey}' data-controller='core.global.core.table' {{if $table->getPaginationKey() != 'page'}}data-pageParam='{$table->getPaginationKey()}'{{endif}} {{if !\IPS\Request::i()->isAjax() }}class="ipsBox"{{endif}}>
<template template_group="view" template_name="logTable" template_data="$table, $headers, $rows, $quickSearch" template_location="front" template_app="downloads"><![CDATA[<div data-baseurl='{$table->baseUrl}' data-resort='{$table->resortKey}' data-controller='core.global.core.table' {{if $table->getPaginationKey() != 'page'}}data-pageParam='{$table->getPaginationKey()}'{{endif}} {{if !\IPS\Request::i()->isAjax() }}class="ipsBox ipsBox--downloadLogTable"{{endif}}>
{{if $table->pages > 1}}
<div class="ipsButtonBar ipsButtonBar--top">
@@ -1823,7 +1832,7 @@
<div>
<div class='{{if $file->primary_screenshot}}ipsColumns{{endif}}'>
<div {{if $file->primary_screenshot_thumb}}class='ipsColumns__primary'{{endif}}>
<header class='ipsPageHeader ipsBox ipsPull ipsPageHeader--downloads-pending'>
<header class='ipsPageHeader ipsBox ipsBox--downloadsPendingHeader ipsPull ipsPageHeader--downloads-pending'>
<div class="ipsPageHeader__row">
<div class='ipsPageHeader__primary'>
<h1 class='ipsPageHeader__title'>
@@ -1885,7 +1894,7 @@
</div>
{{endif}}
<div class='ipsBox i-margin-top_block'>
<div class='ipsBox ipsBox--downloadsPending i-margin-top_block'>
{{if $file->screenshots( 0, TRUE, NULL, TRUE )->getInnerIterator()->count()}}
<h2 class='ipsBox__header ipsHide'>{lang="screenshots_ct" pluralize="$file->screenshots()->getInnerIterator()->count()"}</h2>
<div class='ipsBox__content'>
@@ -1992,31 +2001,33 @@
</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' 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>
{{endif}}
<div id='elFileReviewForm'>
{$file->reviewForm()|raw}
</div>
{{else}}
{{if $file->hasReviewed()}}
<!-- Already reviewed -->
{{elseif $file->locked()}}
{template="commentUnavailable" group="forms" location="front" app="core" params="'item_locked_cannot_review'"}
{{elseif \IPS\Member::loggedin()->restrict_post}}
{{if \IPS\Member::loggedIn()->restrict_post == -1}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'restricted_cannot_comment'"}
{{else}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'restricted_cannot_comment', \IPS\Member::loggedIn()->warnings(5,NULL,'rpa'), \IPS\Member::loggedIn()->restrict_post"}
<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' data-follow-area-id="file-{$file->id}">
<div class="ipsComposeAreaWrapper">
{{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>
{{endif}}
<div id='elFileReviewForm'>
{$file->reviewForm()|raw}
</div>
{{else}}
{{if $file->hasReviewed()}}
<!-- Already reviewed -->
{{elseif $file->locked()}}
{template="commentUnavailable" group="forms" location="front" app="core" params="'item_locked_cannot_review'"}
{{elseif \IPS\Member::loggedin()->restrict_post}}
{{if \IPS\Member::loggedIn()->restrict_post == -1}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'restricted_cannot_comment'"}
{{else}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'restricted_cannot_comment', \IPS\Member::loggedIn()->warnings(5,NULL,'rpa'), \IPS\Member::loggedIn()->restrict_post"}
{{endif}}
{{elseif $file->mustDownloadBeforeReview()}}
<p class='i-color_soft i-font-weight_600 i-text-align_center i-background_2 i-padding_2 i-border-start-start-radius_box i-border-start-end-radius_box'>{lang="no_download_review"}</p>
{{elseif \IPS\Member::loggedIn()->members_bitoptions['unacknowledged_warnings']}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'unacknowledged_warning_cannot_post', \IPS\Member::loggedIn()->warnings( 1, FALSE )"}
{{endif}}
{{elseif $file->mustDownloadBeforeReview()}}
<p class='i-color_soft i-font-weight_600 i-text-align_center i-background_2 i-padding_2 i-border-start-start-radius_box i-border-start-end-radius_box'>{lang="no_download_review"}</p>
{{elseif \IPS\Member::loggedIn()->members_bitoptions['unacknowledged_warnings']}}
{template="reviewUnavailable" group="forms" location="front" app="core" params="'unacknowledged_warning_cannot_post', \IPS\Member::loggedIn()->warnings( 1, FALSE )"}
{{endif}}
{{endif}}
</div>
{{if \count( $file->reviews( NULL, NULL, 'date', 'desc', NULL, NULL, NULL, NULL, isset( \IPS\Request::i()->showDeleted ) ) )}}
<div class='ipsButtonBar ipsButtonBar--top'>
@@ -2035,7 +2046,7 @@
{template="commentMultimodHeader" app="core" group="global" params="$file, '#reviews', 'review'"}
</div>
</div>
<div data-role='commentFeed' data-controller='core.front.core.moderation'>
<div data-role='commentFeed' data-controller='core.front.core.moderation' class='ipsEntries ipsEntries--reviews ipsEntries--download-reviews'>
<form action="{$file->url()->csrf()->setQueryString( 'do', 'multimodReview' )->setPage('page',\IPS\Request::i()->page)}" method="post" data-ipsPageAction data-role='moderationTools'>
{{$reviewCount=0; $timeLastRead = $file->timeLastRead(); $lined = FALSE;}}
{{foreach $file->reviews( NULL, NULL, 'date', 'desc', NULL, NULL, NULL, NULL, isset( \IPS\Request::i()->showDeleted ) ) as $review}}
@@ -2070,15 +2081,15 @@
{{endif}}
<div class='ipsBlockSpacer' data-ips-hook="main">
<div class='ipsBox ipsPull'>
<div class='ipsBox ipsBox--downloadsFile ipsPull'>
<header class='ipsPageHeader'>
<div class="ipsPageHeader__row">
<div data-ips-hook="header" class='ipsPageHeader__primary'>
<div data-ips-hook="title" class='ipsPageHeader__title'>
<div class='ipsPageHeader__title'>
<div data-ips-hook="badges" class='ipsBadges'>
{{foreach $file->badges() as $badge}}{$badge|raw}{{endforeach}}
</div>
<h1>
<h1 data-ips-hook="title">
{{if $file->canEdit()}}
<span data-controller="core.front.core.moderation">
<span data-role="editableTitle" title="{lang="click_hold_edit"}">{$file->name}</span>{{if $file->container()->version_numbers}} <span class="i-color_soft">{$file->version}</span>{{endif}}
@@ -2105,7 +2116,7 @@
{template="tagsWithPrefix" group="global" app="core" params="$file->tags(), $file->prefix(), FALSE, FALSE, ( $file->canEdit() AND ( \count( $file->tags() ) OR $file::canTag( NULL, $file->container() ) ) ) ? $file->url() : NULL"}
{{endif}}
</div>
<div class='ipsButtons'>
<div class='ipsButtons' data-ips-hook='fileMainButtons'>
{{if \count( $file->shareLinks() )}}
{template="shareButton" app="core" group="sharelinks" params="$file"}
{{endif}}
@@ -2177,26 +2188,25 @@
</ul>
</div>
{{endif}}
{{if $file->screenshots()->getInnerIterator()->count()}}
<section class='i-border-bottom_3'>
<h2 class='ipsBox__header ipsHide'>{lang="screenshots_ct" pluralize="$file->screenshots()->getInnerIterator()->count()"}</h2>
<div data-ips-hook='screenshots'>
<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>
<a href="{$fullScreenshots[ $id ]->url}" class="ipsThumb" data-ipsLightbox data-ipsLightbox-group="download_{$file->id}">
<img src="{$screenshot->url}" alt="">
</a>
</li>
{{endforeach}}
</ul>
{template="carouselNavigation" group="global" app="core" params="'downloads-file-screenshots', 'i-margin-bottom_2'"}
</div>
</section>
{{endif}}
<div class='ipsColumns ipsColumns--lines'>
{{if $file->screenshots()->getInnerIterator()->count()}}
<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--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>
<a href="{$fullScreenshots[ $id ]->url}" class="ipsThumb" data-ipsLightbox data-ipsLightbox-group="download_{$file->id}">
<img src="{$screenshot->url}" alt="">
</a>
</li>
{{endforeach}}
</ul>
{template="carouselNavigation" group="global" app="core" params="'downloads-file-screenshots', 'i-margin-bottom_2'"}
</div>
</section>
{{endif}}
<article class='ipsColumns__primary i-flex i-flex-direction_column'>
{{$tabs = array();}}
{{foreach $cfields as $field}}
@@ -2227,26 +2237,35 @@
{{endif}}
{{if $versionData['b_changelog'] or !empty( $previousVersions )}}
<section data-controller='downloads.front.view.changeLog' class='i-margin-top_4 i-background_2 i-padding_3 i-border-radius_box'>
<div class='i-flex i-align-items_center i-gap_1 i-flex-wrap_wrap i-justify-content_space-between i-margin-bottom_3'>
<div class='i-flex i-align-items_center i-gap_1 i-flex-wrap_wrap i-justify-content_space-between i-margin-bottom_2'>
<h2 class='ipsTitle ipsTitle--h5'>{lang="whats_new_in_version" sprintf="$versionData['b_version'] ?: (string) \IPS\DateTime::ts( $versionData['b_backup'] )"}</h2>
{{if !empty( $previousVersions )}}<a href='#' id='elChangelog' data-ipsMenu data-ipsMenu-selectable="radio" class='i-color_soft i-font-weight_500' title='{lang="see_changelog_title"}'><span>{lang="see_changelog"}</span><i class='fa-solid fa-caret-down i-margin-start_icon'></i></a>{{endif}}
{{if !empty( $previousVersions )}}
<button type="button" id="elChangelog" popovertarget="elChangelog_menu" class='i-color_soft i-font-weight_500' title='{lang="see_changelog_title"}'><span>{lang="see_changelog"}</span><i class='fa-solid fa-caret-down i-margin-start_icon'></i></button>
{{endif}}
</div>
<div data-role='changeLogData'>
{template="changeLog" group="view" params="$file, $versionData"}
</div>
<ul class='ipsMenu ipsMenu_selectable ipsMenu_auto ipsHide' id='elChangelog_menu'>
{{$versionNumber = $file->version ?: (string) \IPS\DateTime::ts( $file->published );}}
<li class='ipsMenu_item {{if !request.changelog}}ipsMenu_itemChecked{{endif}}' data-ipsMenuValue='{$versionNumber}'><a href='{$file->url()->setQuerystring( 'changelog', 0 )}' title='{lang="see_changelog_for" sprintf="$versionNumber"}'>{$versionNumber}</a></li>
{{foreach $previousVersions as $version}}
{{$versionNumber = $version['b_version'] ?: (string) \IPS\DateTime::ts( $version['b_backup'] );}}
<li class='ipsMenu_item {{if request.changelog == $version['b_id']}}ipsMenu_itemChecked{{endif}} {{if $version['b_hidden']}}ipsModerated{{endif}}' data-ipsMenuValue='{expression="md5( $versionNumber . $version['b_backup'] . mt_rand() )"}' data-changelogTitle="{$versionNumber}">
<a href='{$file->url()->setQueryString( 'changelog', $version['b_id'] )}' title='{lang="see_changelog_for" sprintf="$versionNumber"}'>
{$versionNumber}<br>
<span class='i-color_soft'>{expression="\IPS\DateTime::ts( $version['b_backup'] )->html()" raw="true"}</span>
</a>
</li>
{{endforeach}}
</ul>
<i-dropdown popover id="elChangelog_menu" data-i-dropdown-selectable="radio">
<div class="iDropdown">
<ul class="iDropdown__items">
{{$versionNumber = $file->version ?: (string) \IPS\DateTime::ts( $file->published );}}
<li><a href='{$file->url()->setQuerystring( 'changelog', 0 )}' title='{lang="see_changelog_for" sprintf="$versionNumber"}' {{if !request.changelog}}aria-selected="true"{{endif}} data-ipsMenuValue='{$versionNumber}'><i class="iDropdown__input"></i>{$versionNumber}</a></li>
{{foreach $previousVersions as $version}}
{{$versionNumber = $version['b_version'] ?: (string) \IPS\DateTime::ts( $version['b_backup'] );}}
<li class='{{if $version['b_hidden']}}ipsModerated{{endif}}'>
<a href='{$file->url()->setQueryString( 'changelog', $version['b_id'] )}' title='{lang="see_changelog_for" sprintf="$versionNumber"}' {{if request.changelog == $version['b_id']}}aria-selected="true"{{endif}} data-ipsMenuValue='{expression="md5( $versionNumber . $version['b_backup'] . mt_rand() )"}' data-changelogTitle="{$versionNumber}">
<i class="iDropdown__input"></i>
<div>
{$versionNumber}
<span class='iDropdown__minor'>{expression="\IPS\DateTime::ts( $version['b_backup'] )->html()" raw="true"}</span>
</div>
</a>
</li>
{{endforeach}}
</ul>
</div>
</i-dropdown>
</section>
{{endif}}
@@ -2283,7 +2302,7 @@
{{if $menu->hasContent() || ( \IPS\IPS::classUsesTrait( $file, 'IPS\Content\Reactable' ) and settings.reputation_enabled )}}
<div class='ipsEntry__footer'>
{{if $menu->hasContent()}}
<menu class='ipsEntry__controls'>
<menu class='ipsEntry__controls' data-ips-hook='menu'>
<li>{$menu|raw}</li>
</menu>
{{endif}}
@@ -2302,7 +2321,7 @@
{{endif}}
<li>
{{if !$file->isPurchasable( FALSE )}}
<button class="ipsButton ipsButton--inherit ipsResponsive_hidePhone" disabled type='button'><i class="fa-solid fa-circle-info"></i><span>{lang="purchasing_disabled"}</span></button>
<button class="ipsButton ipsButton--inherit" disabled type='button'><i class="fa-solid fa-circle-info"></i><span>{lang="purchasing_disabled"}</span></button>
{{else}}
<a href='{{if !$file->container()->message('disclaimer') OR !\in_array( $file->container()->disclaimer_location, [ 'purchase', 'both' ] )}}{$file->url('buy')->csrf()}{{else}}{$file->url('buy')}{{endif}}' class='ipsButton ipsButton--primary ipsButton--large i-width_100p' {{if $file->container()->message('disclaimer') AND \in_array( $file->container()->disclaimer_location, [ 'purchase', 'both'])}}data-ipsDialog{{endif}}><i class='fa-solid fa-cart-shopping'></i><span>{lang="buy_now"}{{if $price = $file->price()}} - {$price|raw}{{endif}}</span></a>
{{endif}}
@@ -2311,7 +2330,7 @@
{{if $file->canDownload() or !$file->downloadTeaser()}}
{template="downloadButton" group="view" app="downloads" params="$file"}
{{else}}
{$file->downloadTeaser()|raw}
<li>{$file->downloadTeaser()|raw}</li>
{{endif}}
{{endif}}
{{if ( isset( $purchasesToRenew ) or $purchasesToRenew = $file->purchasesToRenew() ) and \count( $purchasesToRenew )}}
@@ -2321,12 +2340,16 @@
<a href='{$purchase->url()->setQueryString('do', 'renew')->csrf()}' class='ipsButton ipsButton--primary ipsButton--large i-width_100p'><i class='fa-solid fa-arrows-rotate'></i><span>{lang="purchase_renew_now"} - {$purchase->renewals->cost}</span></a>
{{endforeach}}
{{else}}
<a href='#elFileRenew_menu' id='elFileRenew' class='ipsButton ipsButton--primary ipsButton--large i-width_100p' data-ipsMenu><i class='fa-solid fa-arrows-rotate'></i><span>{lang="purchase_renew_now"}</span><i class="fa-solid fa-caret-down"></i></a>
<ul id='elFileRenew_menu' class='ipsMenu ipsMenu_auto ipsHide'>
{{foreach $purchasesToRenew as $purchase}}
<li class='ipsMenu_item'><a href="{$purchase->url()->setQueryString('do', 'renew')->csrf()}">{$purchase->name}<br><span class='i-color_soft'>{$purchase->renewals}</span></a></li>
{{endforeach}}
</ul>
<button type="button" id="elFileRenew" popovertarget="elFileRenew_menu" class='ipsButton ipsButton--primary ipsButton--large i-width_100p'><i class='fa-solid fa-arrows-rotate'></i><span>{lang="purchase_renew_now"}</span><i class="fa-solid fa-caret-down"></i></button>
<i-dropdown popover id="elFileRenew_menu">
<div class="iDropdown">
<ul class="iDropdown__items">
{{foreach $purchasesToRenew as $purchase}}
<li><a href="{$purchase->url()->setQueryString('do', 'renew')->csrf()}">{$purchase->name}<span class='iDropdown__minor'>{$purchase->renewals}</span></a></li>
{{endforeach}}
</ul>
</div>
</i-dropdown>
{{endif}}
</li>
{{endif}}
@@ -2457,20 +2480,20 @@
<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='ipsData__item'>
<li class='ipsData__item {$comment->ui('css')}' {$comment->ui('dataAttributes')}>
<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'>
<div class="ipsData__image" aria-hidden="true">
{{if $image = $comment->item()->primaryImage()}}
<img src="{$image->url}" alt="{$comment->item()->mapped('title')}" loading="lazy">
{{else}}
<i></i>
{{endif}}
</figure>
</div>
{{else}}
<figure class='ipsData__icon'>
<div class='ipsData__icon'>
{template="userPhoto" app="core" group="global" params="$comment->author(), 'fluid'"}
</figure>
</div>
{{endif}}
<div class="ipsData__content">
<div class='ipsData__main'>
@@ -2500,16 +2523,16 @@
<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'>
<li class='ipsData__item {$review->ui('css')}' {$review->ui('dataAttributes')}>
<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">
<div class="ipsData__image" aria-hidden="true">
{{if $image = $review->item()->primaryImage()}}
<img src="{$image->url}" alt="{$review->item()->mapped('title')}" loading="lazy">
{{else}}
<i></i>
{{endif}}
</figure>
</div>
{{else}}
<div class='ipsData__icon'>
{template="userPhoto" app="core" group="global" params="$review->author(), 'fluid'"}
@@ -2594,18 +2617,18 @@
<p class='ipsEmptyMessage'>{lang="no_new_files"}</p>
{{endif}}
</div>]]></template>
<template template_group="widgets" template_name="fileRow" template_data="$file, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[<li class='ipsData__item'>
<template template_group="widgets" template_name="fileRow" template_data="$file, $layout='table', $isCarousel=false" template_location="front" template_app="downloads"><![CDATA[<li class='ipsData__item {$file->ui('css')}' {$file->ui('dataAttributes')}>
<a href="{$file->url('getPrefComment')}" class="ipsLinkPanel" aria-hidden="true" tabindex="-1"><span>{$file->name}</span></a>
<figure class="ipsData__image">
{{if $file->primary_screenshot_thumb}}
<img src='{file="$file->primary_screenshot_thumb"}' alt='' loading='lazy'>
<div class="ipsData__image" aria-hidden="true" data-ips-hook='image'>
{{if $screenshot = $file->primary_screenshot_thumb}}
<img src='{$screenshot->url}' alt='' loading='lazy'>
{{else}}
<i></i>
{{endif}}
</figure>
</div>
<div class="ipsData__content">
<div class='ipsData__main'>
<h4 class='ipsData__title'>
<h4 class='ipsData__title' data-ips-hook='title'>
<a href="{$file->url( "getPrefComment" )}" title='{lang="view_this_file" sprintf="$file->name"}'>{$file->name}</a>
</h4>
{{$price = NULL;}}
@@ -2624,13 +2647,13 @@
{{if \in_array( $layout, array("minimal"))}}
<div class="ipsData__meta">{lang="byline_nodate" htmlsprintf="$file->author()->link( NULL, NULL, $file->isAnonymous() )"} &middot; {datetime="$file->mapped('date')" lowercase="true" short="true"}</div>
{{endif}}
{{if $file->container()->bitoptions['reviews'] and $file->rating > 0}}
{template="rating" group="global" location="front" app="core" params="'small', $file->rating, \IPS\Settings::i()->reviews_rating_out_of"}
{{if $file->container()->bitoptions['reviews']}}
{template="rating" group="global" location="front" app="core" params="'small', $file->averageReviewRating(), \IPS\Settings::i()->reviews_rating_out_of"}
{{endif}}
</div>
{{if !\in_array( $layout, array("minimal"))}}
<div class="ipsData__extra">
<ul class='ipsData__stats'>
<ul class='ipsData__stats' data-ips-hook='stats'>
{{if $file->isPaid() and !$file->nexus and \in_array( 'purchases', explode( ',', settings.idm_nexus_display ) ) }}
<li data-stattype="purchases" data-v="{$file->purchaseCount()}">
<span class="ipsData__stats-icon" data-stat-value="{$file->purchaseCount()}" aria-hidden="true" data-ipstooltip title='{$file->purchaseCount()} {lang="idm_purchases"}'></span>
+51 -1
View File
@@ -235,6 +235,7 @@
"107731": "4.7.15 Beta 2",
"107732": "4.7.15",
"107733": "4.7.15",
"107734": "4.7.15",
"107740": "4.7.16 Beta 1",
"107741": "4.7.16 Beta 2",
"107742": "4.7.16 Beta 3",
@@ -347,5 +348,54 @@
"5000071": "5.0.6 Beta 2",
"5000072": "5.0.6 Beta 3",
"5000073": "5.0.6 Beta 4",
"5000074": "5.0.6"
"5000074": "5.0.6",
"5000075": "5.0.7 Beta 1",
"5000076": "5.0.7 Beta 2",
"5000077": "5.0.7 Beta 2",
"5000078": "5.0.7 Beta 3",
"5000079": "5.0.7 Beta 4",
"5000080": "5.0.7",
"5000081": "5.0.7",
"5000082": "5.0.7",
"5000800": "5.0.8 Alpha 1",
"5000801": "5.0.8 Alpha 2",
"5000802": "5.0.8 Beta 1",
"5000803": "5.0.8 Beta 2",
"5000804": "5.0.8 Beta 3",
"5000805": "5.0.8",
"5000900": "5.0.9 Beta 1",
"5000901": "5.0.9 Beta 1",
"5000902": "5.0.9 Beta 1",
"5000903": "5.0.9 Beta 2",
"5000904": "5.0.9",
"5000905": "5.0.9",
"5000906": "5.0.10 Beta 1",
"5000907": "5.0.10 Beta 1",
"5000908": "5.0.10 Beta 1",
"5000909": "5.0.10 Beta 1",
"5000910": "5.0.10 Beta 2",
"5000911": "5.0.10 Beta 3",
"5000912": "5.0.10 Beta 4",
"5000913": "5.0.10 Beta 4",
"5000914": "5.0.10",
"5000915": "5.0.10",
"5000916": "5.0.10",
"5000917": "5.0.10",
"5000918": "5.0.10",
"5000919": "5.0.10",
"5000920": "5.0.10",
"5001100": "5.0.11 Beta 1",
"5001101": "5.0.11 Beta 1",
"5001102": "5.0.11 Beta 2",
"5001103": "5.0.11",
"5001104": "5.0.11",
"5001105": "5.0.11",
"5001200": "5.0.12 Beta 1",
"5001201": "5.0.12 Beta 2",
"5001202": "5.0.12 Beta 3",
"5001203": "5.0.12",
"5001204": "5.0.12",
"5001300": "5.0.13 Beta 1",
"5001301": "5.0.13 Beta 2",
"5001302": "5.0.13"
}
@@ -47,7 +47,7 @@ class DownloadFile extends AchievementActionAbstract
*/
public function filters( ?array $filters, Url $url ): array
{
$return = array();
$return = parent::filters( $filters, $url );
$return['nodes'] = new Node( 'achievement_filter_DownloadFile_nodes', ( $filters and isset( $filters['nodes'] ) and $filters['nodes'] ) ? $filters['nodes'] : 0, FALSE, [
'url' => $url,
@@ -74,7 +74,7 @@ class DownloadFile extends AchievementActionAbstract
*/
public function formatFilterValues( array $values ): array
{
$return = [];
$return = parent::formatFilterValues( $values );
if ( isset( $values['achievement_filter_DownloadFile_nodes'] ) )
{
$return['nodes'] = array_keys( $values['achievement_filter_DownloadFile_nodes'] );
@@ -145,6 +145,38 @@ class DownloadFile extends AchievementActionAbstract
{
return [ $extra['downloader'] ];
}
/**
* Determines if the member has already completed this rule.
* Used for retroactive rule completion.
* So far, this is only used in Quests, but may be used elsewhere at a later point.
*
* @param Member $member
* @param array $filters
* @return bool
*/
public function isRuleCompleted( Member $member, array $filters ) : bool
{
$where = [
[ 'dmid=?', $member->member_id ]
];
if( !empty( $filters['nodes'] ) )
{
$where[] = [ Db::i()->in( 'file_cat', $filters['nodes'] ) ];
}
$total = Db::i()->select( 'count(*)', 'downloads_downloads', $where )
->join( 'downloads_files', 'dfid=file_id' )
->first();
if( !empty( $filters['milestone'] ) )
{
return $total >= $filters['milestone'];
}
return $total > 0;
}
/**
* Get identifier to prevent the member being awarded points for the same action twice
@@ -198,7 +230,7 @@ class DownloadFile extends AchievementActionAbstract
{
$conditions[] = Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone', FALSE, [
'htmlsprintf' => [
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'milestone', Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
Theme::i()->getTemplate( 'achievements', 'core' )->ruleDescriptionBadge( 'milestone', Member::loggedIn()->language()->addToStack( 'achievements_title_filter_milestone_nth', FALSE, [ 'pluralize' => [ $rule->filters['milestone'] ] ] ) )
],
'sprintf' => [ Member::loggedIn()->language()->addToStack('AchievementAction__DownloadFile_title_generic') ]
] );
@@ -209,7 +241,12 @@ class DownloadFile extends AchievementActionAbstract
$conditions[] = $nodeCondition;
}
return Theme::i()->getTemplate( 'achievements' )->ruleDescription(
if( $questCondition = $this->_questFilterDescription( $rule ) )
{
$conditions[] = $questCondition;
}
return Theme::i()->getTemplate( 'achievements', 'core' )->ruleDescription(
Member::loggedIn()->language()->addToStack( 'AchievementAction__DownloadFile_title' ),
$conditions
);
@@ -238,7 +275,7 @@ class DownloadFile extends AchievementActionAbstract
{
return Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location', FALSE, [
'htmlsprintf' => [
Theme::i()->getTemplate( 'achievements' )->ruleDescriptionBadge( 'location',
Theme::i()->getTemplate( 'achievements', 'core' )->ruleDescriptionBadge( 'location',
count( $nodeNames ) === 1 ? $nodeNames[0] : Member::loggedIn()->language()->addToStack( 'achievements_title_filter_location_val', FALSE, [ 'sprintf' => [
count( $nodeNames ),
Member::loggedIn()->language()->addToStack( 'download_categories_lc', FALSE, [ 'strtolower' => TRUE ] )
@@ -158,7 +158,7 @@ class Categories extends EditorLocationsAbstract
}
catch( InvalidArgumentException $e )
{
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
if( is_array( $callback ) and $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
{
$rebuilt = preg_replace( "#\[/?([^\]]+?)\]#", '', $word['word_custom'] );
}
@@ -67,6 +67,20 @@ class Downloads extends OverviewStatisticsAbstract
* @return string
*/
public function getBlock( array|string $dateRange = NULL, string $subBlock = NULL ): string
{
$numbers = $this->getBlockNumbers( $dateRange, $subBlock );
return Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $numbers['statsreports_current_count'], $numbers['statsreports_previous_count'] );
}
/**
* @param array|string $dateRange=null
* @param string $subBlock = null
*
* @return array{statsreports_current_count: number|null, statsreports_previous_count: number|null}
*/
public function getBlockNumbers( array|string $dateRange = null, string $subBlock = null ) : array
{
$where = NULL;
$previousCount = NULL;
@@ -92,7 +106,9 @@ class Downloads extends OverviewStatisticsAbstract
}
$count = Db::i()->select( 'COUNT(*)', 'downloads_downloads', $where )->first();
return Theme::i()->getTemplate( 'stats' )->overviewComparisonCount( $count, $previousCount );
return [
'statsreports_current_count' => $count,
'statsreports_previous_count' => $previousCount,
];
}
}
@@ -39,6 +39,10 @@ class StoreMemberViews extends QueueAbstract
*/
public function preQueueData( array $data ): ?array
{
if( !Db::i()->checkForTable( 'downloads_view_method'))
{
return null;
}
$data['count'] = (int) Db::i()->select( 'count(*)', 'downloads_view_method' )->first();
return $data;
}
@@ -53,6 +57,11 @@ class StoreMemberViews extends QueueAbstract
*/
public function run( array &$data, int $offset ): int
{
if( !Db::i()->checkForTable( 'downloads_view_method'))
{
throw new QueueOutOfRangeException;
}
$rows = iterator_to_array(
Db::i()->select( '*', 'downloads_view_method', null, 'member_id', [ $offset, REBUILD_NORMAL] )
);
@@ -102,6 +111,6 @@ class StoreMemberViews extends QueueAbstract
*/
public function postComplete( array $data, bool $processed = TRUE ) : void
{
Db::i()->dropTable( 'downloads_view_method' );
Db::i()->dropTable( 'downloads_view_method', true );
}
}
@@ -37,6 +37,7 @@ try
Output::i()->sendHeader( "Content-Security-Policy: default-src 'none'; sandbox" );
Output::i()->sendHeader( "X-Content-Security-Policy: default-src 'none'; sandbox" );
Output::i()->sendHeader( "Cross-Origin-Opener-Policy: same-origin" );
$file->printFile();
exit;
@@ -13,22 +13,27 @@ namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
use IPS\DateTime;
use IPS\Db;
use IPS\Dispatcher;
use IPS\Dispatcher\Controller;
use IPS\downloads\Field;
use IPS\downloads\File;
use IPS\Helpers\Form;
use IPS\Helpers\Form\DateRange;
use IPS\Helpers\Table\Db as Table;
use IPS\Http\Url;
use IPS\Member;
use IPS\Output;
use IPS\Request;
use IPS\Session;
use IPS\Theme;
use UnderflowException;
use function count;
use function defined;
use function intval;
use function file_get_contents;
use const IPS\Helpers\Table\SEARCH_BOOL;
use const IPS\Helpers\Table\SEARCH_CONTAINS_TEXT;
use const IPS\Helpers\Table\SEARCH_DATE_RANGE;
use const IPS\Helpers\Table\SEARCH_MEMBER;
use const IPS\Helpers\Table\SEARCH_NUMERIC;
use const IPS\Helpers\Table\SEARCH_SELECT;
use const IPS\TEMP_DIRECTORY;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
@@ -51,11 +56,6 @@ class topdownloads extends Controller
*/
public static bool $allowRWSeparation = TRUE;
/**
* @brief Number of results per page
*/
const PER_PAGE = 25;
/**
* Execute
*
@@ -74,102 +74,149 @@ class topdownloads extends Controller
*/
protected function manage() : void
{
$where = array();
$table = new Table( 'downloads_files', Url::internal( 'app=downloads&module=stats&controller=topdownloads' ) );
$table->langPrefix = 'downloads_';
$customFields = Field::roots();
if ( isset( Request::i()->form ) )
/* Joins */
$joinSelect = array();
foreach( $customFields as $field )
{
$form = new Form( 'form', 'go' );
$joinSelect[] = 'downloads_ccontent.field_' . $field->id;
}
$default = array(
'start' => Request::i()->start ? DateTime::ts( Request::i()->start ) : NULL,
'end' => Request::i()->end ? DateTime::ts( Request::i()->end ) : NULL
/* Columns */
if( count( $customFields ) )
{
$table->joins = array(
array( 'select' => implode(',', $joinSelect), 'from' => 'downloads_ccontent', 'where' => "downloads_ccontent.file_id=downloads_files.file_id" )
);
}
$form->add( new DateRange( 'stats_date_range', $default, FALSE, array( 'start' => array( 'max' => DateTime::ts( time() )->setTime( 0, 0, 0 ), 'time' => FALSE ), 'end' => array( 'max' => DateTime::ts( time() )->setTime( 23, 59, 59 ), 'time' => FALSE ) ) ) );
$table->include = array( 'file_name', 'file_downloads' );
$table->advancedSearch = array(
'file_downloads' => SEARCH_NUMERIC
);
if ( !$values = $form->values() )
/* Add our custom fields */
foreach ( $customFields as $field )
{
$customField = 'field_' . $field->id;
switch ( $field->type )
{
Output::i()->output = $form;
return;
case 'Checkbox':
case 'YesNo':
$table->advancedSearch[ $customField ] = SEARCH_BOOL;
break;
case 'Upload':
case 'Color':
case 'Password':
/* These fields make no sense to be searchable */
break;
case 'CheckboxSet':
case 'Select':
case 'Radio':
$options = array();
foreach ( json_decode( $field->content ) as $option )
{
$options[ $option ] = $option;
}
$table->advancedSearch[ $customField ] = array( SEARCH_SELECT, array( 'options' => array_merge(["" => "Any"], $options ), 'multiple' => $field->multiple ) );
break;
case 'Date':
$table->advancedSearch[ $customField ] = SEARCH_DATE_RANGE;
break;
case 'Member':
$table->advancedSearch[ $customField ] = array( SEARCH_MEMBER, array( 'multiple' => $field->multiple ) );
break;
case 'Number':
case 'Rating':
$table->advancedSearch[ $customField ] = SEARCH_NUMERIC;
break;
default:
$table->advancedSearch[ $customField ] = SEARCH_CONTAINS_TEXT;
break;
}
}
/* Figure out start and end parameters for links */
$params = array(
'start' => !empty( $values['stats_date_range']['start'] ) ? $values['stats_date_range']['start']->getTimestamp() : Request::i()->start,
'end' => !empty( $values['stats_date_range']['end'] ) ? $values['stats_date_range']['end']->getTimestamp() : Request::i()->end
$table->mainColumn = 'file_name';
$table->quickSearch = 'file_name';
$table->sortBy = $table->sortBy ?: 'file_downloads';
$table->sortDirection = $table->sortDirection ?: 'desc';
/* Parsers */
$table->parsers = array(
'file_name' => function( $val, $row ) {
$file = File::constructFromData( $row );
return Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name );
}
);
if ( $params['start'] )
Output::i()->sidebar['actions']['download'] = [
'icon' => 'download',
'title' => 'download',
'link' => Url::internal( "app=downloads&module=stats&controller=topdownloads&do=download" )->csrf()
];
/* Display */
Output::i()->output = (string) $table;
Output::i()->title = Member::loggedIn()->language()->addToStack('menu__downloads_stats_topdownloads');
}
/**
* @return void
*/
protected function download() : void
{
Session::i()->csrfCheck();
$headers = [ 'file_name' => 'File', 'file_downloads' => 'Downloads' ];
$customFields = Field::roots();
$customFieldNames = array();
foreach ( $customFields as $field )
{
$where[] = array( 'dtime>?', $params['start'] );
$headers['field_' . $field->id] = Member::loggedIn()->language()->get( 'downloads_field_' . $field->id );
}
if ( $params['end'] )
{
$where[] = array( 'dtime<?', $params['end'] );
}
$tmpFile = tempnam( TEMP_DIRECTORY, 'IPS' );
$fh = fopen( $tmpFile, 'w' );
$page = isset( Request::i()->page ) ? intval( Request::i()->page ) : 1;
fputcsv($fh, $headers);
if ( $page < 1 )
$files = Db::i()->select('*', 'downloads_files', null, 'file_downloads desc' )->join('downloads_ccontent', 'downloads_ccontent.file_id=downloads_files.file_id');
foreach ( $files as $file )
{
$page = 1;
}
try
{
$total = Db::i()->select( 'COUNT(DISTINCT(dfid))', 'downloads_downloads', $where )->first();
}
catch ( UnderflowException $e )
{
$total = 0;
}
/* Add date range selector */
Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => Url::internal( 'app=downloads&module=stats&controller=topdownloads&form=1' )->setQueryString( $params ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => Member::loggedIn()->language()->addToStack( 'stats_date_range' ) )
)
);
if ( $total > 0 )
{
$select = iterator_to_array( Db::i()->select( 'dfid, count(*) as downloads', 'downloads_downloads', $where, 'downloads DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'dfid' )->join( 'downloads_files', 'downloads_files.file_id=downloads_downloads.dfid' ) );
$files = iterator_to_array( Db::i()->select( '*', 'downloads_files', Db::i()->in( 'file_id', array_column( $select, 'dfid' ) ) )->setKeyField( 'file_id' ) );
$downloads = array();
if ( count( $select ) )
$row = [];
foreach ( $headers as $key => $header )
{
foreach ( $select as $row )
if( isset( $file[ $key ] ) )
{
$file = File::constructFromData( $files[ $row['dfid'] ] );
$downloads[] = array(
'dfid' => $row['dfid'],
'downloads' => $row['downloads'],
'file' => Theme::i()->getTemplate( 'global', 'core', 'global' )->basicUrl( $file->url(), TRUE, $file->name )
);
$row[] = $file[ $key ];
}
else
{
$row[] = '';
}
}
$pagination = Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
Url::internal( 'app=downloads&module=stats&controller=topdownloads' )->setQueryString( $params ),
ceil( $total / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
fputcsv($fh, $row);
}
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->message( Member::loggedIn()->language()->addToStack( 'stats_include_hidden_content' ), 'info' );
Output::i()->output .= Theme::i()->getTemplate( 'stats' )->topDownloadsTable( $downloads, $pagination );
Output::i()->title = Member::loggedIn()->language()->addToStack( 'menu__downloads_stats_topdownloads' );
}
else
{
/* Return the no results message */
Output::i()->output .= Theme::i()->getTemplate( 'global', 'core' )->block( Member::loggedIn()->language()->addToStack( 'menu__downloads_stats_topdownloads' ), Member::loggedIn()->language()->addToStack( 'no_results' ), FALSE, 'i-padding_3', NULL, TRUE );
}
fclose( $fh );
$csv = file_get_contents( $tmpFile );
$name = 'topdownloads_' . date('Y-m-d');
Member::loggedIn()->language()->parseOutputForDisplay( $name );
Member::loggedIn()->language()->parseOutputForDisplay( $csv );
Output::i()->sendOutput( $csv, 200, 'text/csv', array( 'Content-Disposition' => Output::getContentDisposition( 'attachment', "{$name}.csv" ) ), FALSE, FALSE, FALSE );
}
}
@@ -272,6 +272,7 @@ class browse extends Controller
}
/* Output */
Output::i()->bodyAttributes['contentClass'] = Category::class;
Output::i()->title = $category->_title;
Output::i()->contextualSearchOptions[ Member::loggedIn()->language()->addToStack( 'search_contextual_item_downloads_categories' ) ] = array( 'type' => 'downloads_file', 'nodes' => $category->_id );
Output::i()->sidebar['contextual'] .= Theme::i()->getTemplate( 'browse' )->indexSidebar( Category::canOnAny('add'), $category );
@@ -164,6 +164,7 @@ class pending extends Controller
Output::i()->sendHeader( "Content-type: " . File::getMimeType( $file->originalFilename ) . ";charset=UTF-8" );
Output::i()->sendHeader( "Content-Security-Policy: default-src 'none'; sandbox" );
Output::i()->sendHeader( "X-Content-Security-Policy: default-src 'none'; sandbox" );
Output::i()->sendHeader( "Cross-Origin-Opener-Policy: same-origin" );
Output::i()->sendHeader( 'Content-Disposition: ' . Output::getContentDisposition( 'attachment', $file->originalFilename ) );
Output::i()->sendHeader( "Content-Length: " . $file->filesize() );
@@ -238,6 +238,9 @@ class submit extends Controller
{
$form->add( new Text( 'file_version', '1.0.0', $category->version_numbers == 2, array( 'maxLength' => 32 ) ) );
}
/* Call UI extensions, because we bypass that in this controller */
File::extendForm( $form, null, $category );
}
if ( $values = $form->values() )
@@ -637,7 +637,7 @@ class view extends Controller
] );
/* Data Layer Event */
if ( Settings::i()->core_datalayer_enabled )
if ( DataLayer::enabled() )
{
$properties = $this->file->getDataLayerProperties();
$properties['file_name'] = $data['record_realname'] ?: $file->originalFilename;
@@ -1,123 +1,5 @@
{
"1": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_view_approvers",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can view who approved files?",
"unsigned": true
}
]
},
"2": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_bypass_revision",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can bypass revisions?",
"unsigned": true
}
]
},
"3": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_view_downloads",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can view who downloaded files?",
"unsigned": true
}
]
},
"4": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_throttling",
"type": "INT",
"length": 10,
"null": false,
"default": 0,
"comment": "Downloads Speed Throttling kb",
"unsigned": true
}
]
},
"5": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_wait_period",
"type": "INT",
"length": 10,
"null": false,
"default": 0,
"comment": "Seconds users must wait before download",
"unsigned": true
}
]
},
"6": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_restrictions",
"type": "TEXT",
"null": false,
"default": "{}",
"comment": "Downloads Restrictions"
}
]
},
"7": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_linked_files",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can submit URLs?",
"unsigned": true
}
]
},
"8": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_import_files",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can import files from a path?",
"unsigned": true
}
]
},
"9": {
"method": "addColumn",
"params": [
"core_members",
@@ -132,52 +14,7 @@
}
]
},
"10": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_bulk_submit",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can bulk upload?",
"unsigned": true
}
]
},
"11": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_add_paid",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can submit paid files?",
"unsigned": true
}
]
},
"12": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_bypass_paid",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Can download paid files without paying?",
"unsigned": true
}
]
},
"13": {
"2": {
"method": "insert",
"params": [
"core_permission_index",
@@ -193,34 +30,5 @@
"perm_6": "<%NO_GUESTS%>"
}
]
},
"14": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_paid_restrictions",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Download restrictions apply to Paid files?",
"unsigned": true
}
]
},
"15": {
"method": "addColumn",
"params": [
"core_groups",
{
"name": "idm_max_size",
"type": "INT",
"null": false,
"default": -1,
"comment": "Maximum file size allowed",
"unsigned": false
}
]
}
}
@@ -1,48 +1 @@
{
"1": {
"method": "createTable",
"params": [
{
"name": "downloads_view_method",
"columns": {
"member_id": {
"name": "member_id",
"type": "BIGINT",
"length": "20",
"decimals": null,
"values": null,
"allow_null": false,
"default": 0,
"comment": "ID Number",
"unsigned": true,
"auto_increment": false
},
"method": {
"name": "method",
"type": "VARCHAR",
"length": 16,
"decimals": null,
"values": null,
"allow_null": true,
"default": "table",
"comment": "",
"unsigned": false,
"auto_increment": false
}
},
"indexes": {
"uniquemember": {
"type": "unique",
"name": "uniquemember",
"columns": [
"member_id"
],
"length": [
null
]
}
}
}
]
}
}
[]
@@ -0,0 +1,22 @@
{
"id": 5000075,
"name": "5.0.7 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,25 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categories",
"front\/browse\/category",
"front\/browse\/index",
"front\/submit\/submissionForm",
"front\/view\/logTable",
"front\/view\/pendingView",
"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": 5000076,
"name": "5.0.7 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": 5000077,
"name": "5.0.7 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": 5000078,
"name": "5.0.7 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": 5000079,
"name": "5.0.7 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": 5000080,
"name": "5.0.7",
"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": 5000081,
"name": "5.0.7",
"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": 5000082,
"name": "5.0.7",
"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": 5000800,
"name": "5.0.8 Alpha 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": [],
"edited": [
"download_teaser"
],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,31 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categories",
"front\/browse\/categoryRow",
"front\/browse\/featuredFile",
"front\/browse\/indexBlock",
"front\/browse\/rows",
"front\/browse\/tableRow",
"front\/global\/manageFollowRow",
"admin\/nexus\/fileInfo",
"front\/view\/downloadTeaser",
"front\/view\/view",
"front\/widgets\/downloadsCommentFeed",
"front\/widgets\/downloadsReviewFeed",
"front\/widgets\/fileRow"
],
"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": 5000801,
"name": "5.0.8 Alpha 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": 5000802,
"name": "5.0.8 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": 5000803,
"name": "5.0.8 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000804,
"name": "5.0.8 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000805,
"name": "5.0.8",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000900,
"name": "5.0.9 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": false,
"javascript": false,
"emailTemplates": true,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
@@ -0,0 +1,8 @@
{
"added": [],
"edited": [
"digests__comment",
"digests__item"
],
"removed": []
}
@@ -0,0 +1,29 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/featuredFile",
"front\/browse\/indexBlock",
"front\/browse\/rows",
"front\/browse\/tableRow",
"front\/global\/commentTableHeader",
"front\/global\/embedFileComment",
"front\/global\/embedFileReview",
"admin\/nexus\/fileInfo",
"front\/submit\/topic",
"front\/view\/downloadTeaser",
"front\/widgets\/fileRow"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000901,
"name": "5.0.9 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000902,
"name": "5.0.9 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000903,
"name": "5.0.9 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000904,
"name": "5.0.9",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000905,
"name": "5.0.9",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000906,
"name": "5.0.10 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": false,
"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,25 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/categoryRow",
"front\/browse\/featuredFile",
"front\/browse\/indexBlock",
"front\/global\/manageFollowRow",
"front\/widgets\/downloadsCommentFeed",
"front\/widgets\/downloadsReviewFeed",
"front\/widgets\/fileRow"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5000907,
"name": "5.0.10 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000908,
"name": "5.0.10 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000909,
"name": "5.0.10 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000910,
"name": "5.0.10 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000911,
"name": "5.0.10 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000912,
"name": "5.0.10 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000913,
"name": "5.0.10 Beta 4",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000914,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000915,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000916,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000917,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000918,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000919,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5000920,
"name": "5.0.10",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001100,
"name": "5.0.11 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001101,
"name": "5.0.11 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": false,
"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,27 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/featuredFile",
"front\/browse\/fileGrid",
"front\/browse\/indexBlock",
"front\/browse\/rows",
"front\/browse\/tableRow",
"front\/view\/view",
"front\/widgets\/downloadsCommentFeed",
"front\/widgets\/downloadsReviewFeed",
"front\/widgets\/fileRow"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5001102,
"name": "5.0.11 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001103,
"name": "5.0.11",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001104,
"name": "5.0.11",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001105,
"name": "5.0.11",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001200,
"name": "5.0.12 Beta 1",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": false,
"javascript": true,
"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,15 @@
{
"files": {
"added": [],
"edited": [
"downloads\/front\/controllers\/submit\/ips.submit.main.js",
"downloads\/front\/controllers\/view\/ips.view.changeLog.js"
],
"removed": []
},
"orders": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,24 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/category",
"front\/browse\/categoryMenu",
"front\/browse\/index",
"front\/submit\/submissionForm",
"front\/view\/reviews",
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5001201,
"name": "5.0.12 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001202,
"name": "5.0.12 Beta 3",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001203,
"name": "5.0.12",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001204,
"name": "5.0.12",
"steps": {
"queries": false,
"lang": false,
"theme": true,
"themeeditor": false,
"javascript": true,
"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 @@
{
"files": {
"added": [],
"edited": [
"downloads\/front\/controllers\/view\/ips.view.changeLog.js"
],
"removed": []
},
"orders": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,20 @@
{
"html": {
"added": [],
"edited": [
"front\/view\/changeLog",
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5001300,
"name": "5.0.13 Beta 1",
"steps": {
"queries": false,
"lang": true,
"theme": true,
"themeeditor": false,
"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,15 @@
{
"normal": {
"added": [
"downloads_file_name",
"downloads_file_downloads"
],
"edited": [],
"removed": []
},
"js": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,23 @@
{
"html": {
"added": [],
"edited": [
"front\/browse\/category",
"front\/browse\/categoryMenu",
"front\/browse\/index",
"front\/submit\/submissionForm",
"front\/view\/view"
],
"removed": []
},
"css": {
"added": [],
"edited": [],
"removed": []
},
"resources": {
"added": [],
"edited": [],
"removed": []
}
}
@@ -0,0 +1,22 @@
{
"id": 5001301,
"name": "5.0.13 Beta 2",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"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,22 @@
{
"id": 5001302,
"name": "5.0.13",
"steps": {
"queries": false,
"lang": false,
"theme": false,
"themeeditor": false,
"javascript": false,
"emailTemplates": false,
"acpSearchKeywords": false,
"settings": false,
"tasks": false,
"modules": false,
"widgets": false,
"customOptions": false,
"customRoutines": false
},
"forceMainUpgrader": false,
"forceManualDownloadNoCiC": false,
"forceManualDownloadCiC": false
}
+53 -1
View File
@@ -15,14 +15,18 @@ namespace IPS\downloads;
use IPS\Application;
use IPS\CustomField;
use IPS\Data\Store;
use IPS\Helpers\Form;
use IPS\Helpers\Form\Radio;
use IPS\Helpers\Form\TextArea;
use IPS\Helpers\Form\YesNo;
use IPS\Lang;
use IPS\Log;
use IPS\Member;
use IPS\Node\Permissions;
use IPS\Settings;
use IPS\Theme;
use ParseError;
use function defined;
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
@@ -226,6 +230,7 @@ class Field extends CustomField implements Permissions
* @apiresponse string name Name
* @apiresponse string description Description
* @apiresponse string value Current value for this file
* @apiresponse string|int|array|boolean displayValue Parsed Field value with all field data
*/
public function apiOutput( ?Member $authorizedMember = NULL, array $fieldValues=array() ): array
{
@@ -234,7 +239,54 @@ class Field extends CustomField implements Permissions
'id' => $this->id,
'name' => $lang->addToStack( 'downloads_field_' . $this->id ),
'description' => $lang->addToStack( 'downloads_field_' . $this->id . '_desc' ),
'value' => $fieldValues[ 'field_' . $this->id ] ?? null
'value' => $fieldValues[ 'field_' . $this->id ] ?? null,
'displayValue' => $this->apiValue( $fieldValues[ 'field_' . $this->id ] )
];
}
/**
* Parse the HTML logic to format the field
*
* @param string $rawValue Raw value
* @param File $file
* @return string
*/
public function formatValue( string $rawValue, File $file ) : string
{
/* If we are using the "default" formatting, set that up now */
$template = $this->format ?: "<strong><span data-ips-font-size=\"90\">{title} </span></strong> {content}";
$template = str_replace( [ '{title}', '{content}' ], [ "{\$title}", "{\$content}" ], $template );
try
{
$functionName = 'downloadsfields_cc_' . md5( $template );
if ( ! isset( Store::i()->$functionName ) )
{
/* We need the "raw" content because HTML is typically used to format the value */
$template = str_replace( '{$processedContent}', '{$processedContent|raw}', $template );
/* If this an editor, we can safely use the |raw value as it is clean, otherwise the escaped value will display which is not what the user expects */
if ( $this->type == 'Editor' )
{
$template = str_replace( '{$content}', '{$content|raw}', $template );
$template = Theme::i()->getTemplate('global', 'core', 'global')->richText( $template );
}
/* $content is the raw content from the database, $processedContent is the parsed content ready for display */
Store::i()->$functionName = Theme::compileTemplate( $template, $functionName, '$title, $content, $processedContent, $file' );
}
Theme::runProcessFunction( Store::i()->$functionName, $functionName );
$themeFunction = 'IPS\\Theme\\'. $functionName;
return $themeFunction( Member::loggedIn()->language()->addToStack( static::$langKey . '_' . $this->id ), $rawValue, $this->displayValue( $rawValue ), $file );
}
catch ( ParseError $e )
{
@ob_end_clean();
Log::log( $e, 'pfield_error' );
return (string) $this->displayValue( $rawValue );
}
}
}
+17 -19
View File
@@ -933,20 +933,12 @@ Filter
if( $topic === TRUE )
{
$thisField = Field::constructFromData( $this->_fieldData[ $fieldId ] );
if( isset( $this->_fieldData[ $fieldId ] ) )
{
$v = str_replace( '{content}', htmlspecialchars( $v, ENT_DISALLOWED, 'UTF-8', FALSE ), $thisField->displayValue( $v ) );
$v = str_replace( '{member_id}', Member::loggedIn()->member_id, $v );
$v = str_replace( '{title}', Member::loggedIn()->language()->addToStack( 'downloads_field_' . $fieldId ), $v );
}
else
{
$v = htmlspecialchars( $v, ENT_DISALLOWED, 'UTF-8', FALSE );
}
$return[ $k ] = $thisField->formatValue( $v, $this );
}
else
{
$return[ $k ] = $v;
}
$return[ $k ] = $v;
}
}
}
@@ -2482,6 +2474,7 @@ Filter
* @apiresponse \IPS\Member author Author
* @apiresponse datetime date When the file was created
* @apiresponse datetime updated When the file was last updated
* @apiresponse datetime published When the file was published
* @apiresponse string description Description
* @apiresponse string version Current version number
* @apiresponse string changelog Description of what changed between this version and the previous one
@@ -2541,6 +2534,7 @@ Filter
'author' => $this->author()->apiOutput( $authorizedMember ),
'date' => DateTime::ts( $backup ? $backup['b_backup'] : $this->submitted )->rfc3339(),
'updated' => DateTime::ts( $this->updated )->rfc3339(),
'published' => DateTime::ts( $this->published )->rfc3339(),
'description' => $backup ? $backup['b_filedesc'] : $this->content(),
'version' => $backup ? $backup['b_version'] : $this->version,
'changelog' => $backup ? $backup['b_changelog'] : $this->changelog,
@@ -2723,7 +2717,7 @@ Filter
/* 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 )
catch( UnderflowException )
{
$existsAlready = false;
}
@@ -2754,7 +2748,8 @@ Filter
{
/* Copy the screenshot and generate an attachment */
/* @var SystemFile $screenshot */
$copy = $screenshot->duplicate();
$uploadSettings = json_decode( Settings::i()->upload_settings, true );
$copy = $screenshot->copy( $uploadSettings['filestorage__core_Attachment'] );
$attachment = $copy->makeAttachment( md5( uniqid() ), $topic->author() );
@@ -2773,7 +2768,10 @@ Filter
}
catch( RuntimeException ){}
$topic->firstComment()->post = $content;
$firstComment = $topic->firstComment();
$contentField = $firstComment::$databaseColumnMap['content'];
$topic->firstComment()->$contentField = $content;
$topic->firstComment()->save();
}
}
@@ -2924,17 +2922,17 @@ Filter
if( !$this->hasPendingVersion() AND $this->canEdit( $member ) )
{
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'newVersion' ) ), languageString: Member::loggedIn()->language()->addToStack( 'upload_new_version') ) );
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'newVersion' ) ), languageString: Member::loggedIn()->language()->addToStack( 'upload_new_version'), icon: "fa-solid fa-upload" ) );
}
if( $this->isPurchasable() AND $this->canDisablePurchases( $member ) )
{
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'purchaseStatus' , 'value' => 0 ) )->csrf(), languageString: Member::loggedIn()->language()->addToStack( 'disable_purchases') ) );
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'purchaseStatus' , 'value' => 0 ) )->csrf(), languageString: Member::loggedIn()->language()->addToStack( 'disable_purchases'), icon: "fa-solid fa-circle-xmark" ) );
}
if( !$this->isPurchasable() AND $this->canEnablePurchases() )
{
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'purchaseStatus' , 'value' => 1 ) )->csrf(), languageString: Member::loggedIn()->language()->addToStack( 'enable_purchases') ) );
$menu->add( new Menu\Link( url: $this->url()->setQueryString( array( 'do' => 'purchaseStatus' , 'value' => 1 ) )->csrf(), languageString: Member::loggedIn()->language()->addToStack( 'enable_purchases'), icon: "fa-solid fa-circle-check" ) );
}
return $menu;