Version 4.0.13.1

This commit is contained in:
Neo committed 2025-12-19 04:57:54 -08:00
1 parent f9e857d255
commit c6a86f0d9b
7517 files changed
+597400 -668041

No files matched your search

+50
View File
@@ -0,0 +1,50 @@
<?php
/**
* @brief Downloads Application Class
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2013 Invision Power Services, Inc.
* @package IPS Social Suite
* @subpackage Downloads
* @since 27 Sep 2013
* @version
*/
namespace IPS\downloads;
/**
* Downloads Application Class
*/
class _Application extends \IPS\Application
{
/**
* Init
*
* @return void
*/
public function init()
{
/* If the viewing member cannot view the board (ex: guests must login first), then send a 404 Not Found header here, before the Login page shows in the dispatcher */
if ( !\IPS\Member::loggedIn()->group['g_view_board'] and ( \IPS\Request::i()->module == 'downloads' and \IPS\Request::i()->controller == 'browse' and \IPS\Request::i()->do == 'rss' ) )
{
\IPS\Output::i()->error( 'node_error', '2D220/1', 404, '' );
}
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'downloads.css' ) );
if ( \IPS\Theme::i()->settings['responsive'] )
{
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'downloads_responsive.css', 'downloads', 'front' ) );
}
}
/**
* [Node] Get Icon for tree
*
* @note Return the class for the icon (e.g. 'globe')
* @return string|null
*/
protected function get__icon()
{
return 'download';
}
}
+42
View File
@@ -0,0 +1,42 @@
{
"downloads": {
"categories": {
"tab": "community",
"controller": "categories",
"do": "",
"restriction": "categories_manage"
},
"fields": {
"tab": "community",
"controller": "fields",
"do": "",
"restriction": "fields_manage"
},
"settings": {
"tab": "community",
"controller": "settings",
"do": "",
"restriction": "settings_manage"
}
},
"stats": {
"downloads": {
"tab": "stats",
"controller": "downloads",
"do": "",
"restriction": "downloads_manage"
},
"downloaders": {
"tab": "stats",
"controller": "downloaders",
"do": "",
"restriction": "downloaders_manage"
},
"submitters": {
"tab": "stats",
"controller": "submitters",
"do": "",
"restriction": "submitters_manage"
}
}
}
@@ -0,0 +1,28 @@
{
"downloads": {
"categories": {
"categories_manage": "categories_manage",
"categories_add": "categories_add",
"categories_edit": "categories_edit",
"categories_permissions": "categories_permissions",
"categories_delete": "categories_delete",
"categories_recount_downloads": "categories_recount_downloads"
},
"fields": {
"fields_manage": "fields_manage",
"fields_add": "fields_add",
"fields_edit": "fields_edit",
"fields_delete": "fields_delete"
},
"settings": {
"settings_manage": "settings_manage"
}
},
"stats": {
"downloads": {
"downloads_manage": "downloads_manage",
"downloaders_manage": "downloaders_manage",
"submitters_manage": "submitters_manage"
}
}
}
@@ -0,0 +1 @@
{"app=downloads&module=downloads&controller=categories":{"lang_key":"menu__downloads_downloads_categories","restriction":"categories_manage","keywords":["download categories"]},"app=downloads&module=downloads&controller=fields":{"lang_key":"menu__downloads_downloads_fields","restriction":"fields_manage","keywords":["download custom fields","download fields","file fields"]},"app=downloads&module=downloads&controller=settings&searchResult=form_idm_watermarkpath":{"lang_key":"idm_watermarkpath","restriction":"settings_manage","keywords":["screenshot","watermark"]},"app=downloads&module=downloads&controller=settings&searchResult=form_idm_link_blacklist":{"lang_key":"idm_link_blacklist","restriction":"settings_manage","keywords":["blacklist","url","link"]},"app=downloads&module=downloads&controller=settings&searchResult=form_idm_antileech":{"lang_key":"idm_antileech","restriction":"settings_manage","keywords":["direct","link"]},"app=downloads&module=downloads&controller=settings&searchResult=form_idm_rss":{"lang_key":"idm_rss","restriction":"settings_manage","keywords":["rss export","files rss"]},"app=downloads&module=stats&controller=downloads":{"lang_key":"menu__downloads_stats_downloads","restriction":"downloads_manage","keywords":["download statistics"]},"app=downloads&module=stats&controller=downloaders":{"lang_key":"menu__downloads_stats_downloaders","restriction":"downloaders_manage","keywords":["download statistics","top downloaders"]},"app=downloads&module=stats&controller=submitters":{"lang_key":"menu__downloads_stats_submitters","restriction":"submitters_manage","keywords":["top submitters"]},"app=downloads&module=downloads&controller=settings&searchResult=form_idm_nexus_on":{"lang_key":"idm_nexus_on","restriction":"settings_manage","keywords":["paid files","nexus","paid downloads","downloads","marketplace"]},"app=downloads&module=downloads&controller=settings&searchResult=idm_nexus_percent":{"lang_key":"idm_nexus_percent","restriction":"settings_manage","keywords":["commission"]},"app=downloads&module=downloads&controller=settings&searchResult=idm_nexus_transfee":{"lang_key":"idm_nexus_transfee","restriction":"settings_manage","keywords":["fee"]},"app=downloads&module=downloads&controller=settings&searchResult=idm_nexus_gateways":{"lang_key":"idm_nexus_gateways","restriction":"settings_manage","keywords":["payment methods"]},"app=downloads&module=downloads&controller=settings":{"lang_key":"menu__downloads_downloads_settings","restriction":"settings_manage","keywords":["downloads settings"]}}
@@ -0,0 +1,8 @@
{
"application_title": "Downloads",
"app_author": "Invision Power Services, Inc.",
"app_directory": "downloads",
"app_protected": 0,
"app_website": null,
"app_update_check": null
}
+108
View File
@@ -0,0 +1,108 @@
<?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 width='120' align='center' valign='top'>
{{if $comment->item()->primary_screenshot_thumb}}
<img src='{$comment->item()->primary_screenshot_thumb}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{else}}
<div style='width: 100px; height: 100px; background: #f5f5f5'>&nbsp;</div>
{{endif}}
</td>
<td align='left'>
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
{$email->language->addToStack("x_commented_file", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}
</p>
<h2 style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 15px; font-weight: 500 !important; margin: 0;">
<a href='{$comment->item()->url()}' style='text-decoration: none;'>{$comment->item()->name}</a>
</h2>
<div style='font-family: "Helvetica Neue", helvetica, sans-serif; line-height: 22px; margin-top: 5px; margin-bottom: 5px; border-left: 3px solid #8c8c8c; padding-left: 15px; font-size: 14px; margin-left: 15px'>
{$email->parseTextForEmail( $comment->content() )|raw}
</div>
</td>
</tr>]]></template_content_html><template_data>$comment, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("x_commented_file", FALSE, array( 'sprintf' => array( $comment->author()->name ) ) )}: {$comment->item()->name} ({$comment->url()})
]]></template_content_plaintext></template><template><template_app>downloads</template_app><template_name>notification_new_file_version</template_name><template_content_html><![CDATA[
{{if $content->author()->member_id}}
{$email->language->addToStack("email_new_file_version", FALSE, array( 'sprintf' => array( $content->author()->url(), $content->author()->name, $content->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()}'>{$content->mapped('title')}</a>
{{else}}
{$email->language->addToStack("email_new_file_version_guest", FALSE, array( 'sprintf' => array( $content->author()->name, $content->indefiniteArticle( $email->language ) ) ) )} <a href='{$content->url()}'>{$content->mapped('title')}</a>
{{endif}}
<br />
<br />
<table width='100%' cellpadding='0' cellspacing='0' border='0'>
<tr>
<td width='40' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
<img src='{$content->author()->photo}' width='40' height='40' style='border: 1px solid #777777; vertical-align: middle;'>
</td>
<td width='30' valign='top' class='hidePhone' style='width: 0; max-height: 0; overflow: hidden; float: left;'>
<br />
<span style='display: block; width: 0px; height: 0px; border-width: 15px; border-color: transparent #f9f9f9 transparent transparent; border-style: solid'></span>
</td>
<td valign='top' style='background: #f9f9f9;'>
<table width='100%' cellpadding='10' cellspacing='0' border='0'>
<tr>
<td>
<table width='100%' cellpadding='5' cellspacing='0' border='0'>
<tr>
<td style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px; color: #8d8d8d">
{$email->language->addToStack("email_posted_in", FALSE, array( 'sprintf' => array( $content->container()->_title ) ) )}
</td>
</tr>
<tr>
<td style="font-family: 'Helvetica Neue', helvetica, sans-serif; line-height: 1.5; font-size: 14px;">
{$email->parseTextForEmail( $content->content() )|raw}
</td>
</tr>
<tr>
<td>
<a href='{$content->url()}' style="color: #ffffff; font-family: 'Helvetica Neue', helvetica, sans-serif; text-decoration: none; font-size: 14px; background: {setting="email_color"}; line-height: 32px; padding: 0 10px; display: inline-block; border-radius: 3px;">{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $content::$title, FALSE ) ) ) ) )}</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
<br /><br />
<em style='color: #8c8c8c'>&mdash; {setting="board_name"}</em>]]></template_content_html><template_data>$content, $email</template_data><template_content_plaintext><![CDATA[
{$email->language->addToStack("email_new_file_version_plain", FALSE, array( 'sprintf' => array( $content->author()->name, $content->indefiniteArticle( $email->language ) ) ) )} {$content->mapped('title')}
{$email->language->addToStack("go_to_this_x", FALSE, array( 'sprintf' => array( mb_strtolower( $email->language->addToStack( $content::$title, FALSE ) ) ) ) )}: {$content->url()}
-- {setting="board_name"}]]></template_content_plaintext></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 width='120' align='center' valign='top'>
{{if $file->primary_screenshot_thumb}}
<img src='{$file->primary_screenshot_thumb}' style='border: 1px solid #000; vertical-align: middle;' width='100' height='100'>
{{else}}
<div style='width: 100px; height: 100px; background: #f5f5f5'>&nbsp;</div>
{{endif}}
</td>
<td align='left'>
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px; font-weight: bold'>
{$email->language->addToStack("x_created_file_in", FALSE, array( 'sprintf' => array( $file->author()->name, $file->container()->_title ) ) )}
</p>
<h2 style="font-family: 'Helvetica Neue', helvetica, sans-serif; font-size: 18px; font-weight: 500 !important; margin: 0;">
<a href='{$file->url()}' style='text-decoration: none;'>{$file->name} ({$file->version})</a>
{{if $file->mapped('featured')}}&nbsp;&nbsp;<span style='color: #68a72f; font-weight: bold; font-size: 12px; text-transform: uppercase;'>{$email->language->addToStack("featured", FALSE)}</span>{{endif}}
</h2>
<div style='font-family: "Helvetica Neue", helvetica, sans-serif; line-height: 22px; margin-top: 10px; margin-bottom: 10px'>
{$email->parseTextForEmail( $file->content() )|raw}
</div>
<p style='font-family: "Helvetica Neue", helvetica, sans-serif; margin: 0; font-size: 13px;'>
{{if $file->container()->bitoptions['reviews']}}
{{foreach range( 1, 5 ) as $i}}{{if $i <= $file->averageReviewRating()}}<img src='{resource="email/rating_on.png" location="interface" app="core"}' width='14' height='13' style='vertical-align: middle; margin-right: 2px'>{{else}}<img src='{resource="email/rating_off.png" location="interface" app="core"}' width='14' height='13' style='vertical-align: middle; margin-right: 2px'>{{endif}}{{endforeach}}
&nbsp;&nbsp;
{{endif}}
<strong style='font-family: "Helvetica Neue", helvetica, sans-serif; '>
<img src='{resource="email/download.png" location="interface" app="core"}' width='13' height='12' style='vertical-align: middle'>&nbsp; {$email->language->addToStack("num_downloads", FALSE, array( 'pluralize' => array( $file->downloads ) ) )}&nbsp;&nbsp;&nbsp;&nbsp;
{{if $file->container()->bitoptions['comments']}}
<img src='{resource="email/comment.png" location="interface" app="core"}' width='13' height='12' style='vertical-align: middle'>&nbsp; {$email->language->addToStack("num_comments", FALSE, array( 'pluralize' => array( $file->comments ) ) )}
{{endif}}
</strong>
</p>
</td>
</tr>]]></template_content_html><template_data>$file, $email</template_data><template_content_plaintext><![CDATA[{$email->language->addToStack("x_created_file_in", FALSE, array( 'sprintf' => array( $file->author()->name, $file->container()->_title ) ) )}: {$file->title} ({$file->url()})
]]></template_content_plaintext></template></emails>
+54
View File
@@ -0,0 +1,54 @@
/**
* Friendly URL Structure
*
* For each value in the $furl array:
* The key should be the "SEO Template" - an identifier which you'll use when displaying a URL.
* The value should be an associative array with two or three elements: 'friendly' and 'real', and optionally 'verify':
* 'friendly'
* The friendly URL to use - encase variables in {curly braces} containing a symbol, followed by the name of the parameter that matches in the "real" URL
* The symbol should be # for numbers or @ for strings
* For example, if the "real" URL contains id=XXX, where XXX is a number, you should include {#id} somewhere in the friendly URL.
* You can also use the tag {?} for the "SEO Title" (that is, any variables that shouldn't be part of the real URL, such as the name of the topipc being viewed).
* If you want to support more than one SEO Title, you can give them zero-indexed keys like so: {?0} {?1} {?2}
* 'real'
* This should be the base of the real URL. You should not include parameters which will be parsed out from the friendly URL.
* 'verify'
* This should be the name of a class that contains a loadFromUrl() and an url() method. The dynamic URL (i.e. app=core&...) will be passed to loadFromUrl(), and the url()
* method will subsequently be called to retrieve the correct URL, ideal with ActiveRecord pattern classes.
*
* IMPORTANT: Ensure values are listed with the most specific ones first. This is to ensure that non-FURL redirects are done correctly. For example, if you have these FURLs:
* /index.php?app=myapp&module=mymodule&controller=mycontroller&do=myaction -> /myfolder/myaction
* /index.php?app=myapp&module=mymodule&controller=mycontroller -> /myfolder
* They must be provided in that order, otherwise the former will redirec to /myfolder/?do=myaction rather than /myfolder/myaction
*/
{
"topLevel": "files",
"pages": {
"downloads_submit": {
"friendly": "submit",
"real": "app=downloads&module=downloads&controller=submit"
},
"downloads_cat": {
"friendly": "category/{#id}-{?}",
"real": "app=downloads&module=downloads&controller=browse",
"verify": "\\IPS\\downloads\\Category"
},
"downloads_categories": {
"friendly": "categories",
"real": "app=downloads&module=downloads&controller=browse&do=categories"
},
"downloads_file": {
"friendly": "file/{#id}-{?}",
"real": "app=downloads&module=downloads&controller=view",
"verify": "\\IPS\\downloads\\File"
},
"downloads_rss": {
"friendly": "files.xml",
"real": "app=downloads&module=downloads&controller=browse&do=rss"
},
"downloads": {
"friendly": "",
"real": "app=downloads&module=downloads&controller=browse"
}
}
}
+1
View File
@@ -0,0 +1 @@
[]
Whitespace-only changes.
@@ -0,0 +1,4 @@
{
"downloads_category_1": "Files",
"downloads_category_1_desc": ""
}
+686
View File
@@ -0,0 +1,686 @@
<?xml version="1.0" encoding="UTF-8"?>
<javascript app="downloads">
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/submit" javascript_name="ips.submit.main.js" javascript_type="controller" javascript_version="100045" javascript_position="1000050"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
* ips.submit.main.js - Submit controller
*
* Author: Rikki Tissier
*/
;( function($, _, undefined){
"use strict";
ips.controller.register('downloads.front.submit.main', {
_progressbarTimeout: null,
_requireScreenshots: false,
_bulkUpload: false,
_ui: {},
_hiddenUploader: false,
_overriddenUploader: false,
initialize: function () {
this.on( 'uploadedCountChanged', this.uploadCounter );
this.on( 'uploadProgress', this.uploadProgress );
this.on( 'fileAdded', this.fileAdded );
this.on( 'fileDeleted', this.fileDeleted );
this.on( 'click', '[data-action="confirmUrls"]', this.confirmURLs );
this.on( 'click', '[data-action="confirmImports"]', this.confirmImports );
this.on( 'click', '[data-action="confirmScreenshotUrls"]', this.confirmScreenshots );
this.on( 'click', '[data-action="uploadMore"]', this.uploadMore );
this.setup();
},
/**
* Setup method - hides necessary sections of the form
*
* @returns {void}
*/
setup: function () {
var self = this;
if( this.scope.attr('data-screenshotsReq') ){
this._requireScreenshots = true;
}
if( this.scope.attr('data-bulkUpload') ){
this._bulkUpload = true;
}
this._ui = {
progressBar: this.scope.find('#elDownloadsSubmit_progress'),
screenshots: this.scope.find('#elDownloadsSubmit_screenshots'),
fileInfo: this.scope.find('#elDownloadsSubmit_otherinfo')
};
var hideProgressBar = function () {
if( !_.isUndefined( self._ui.progressBar.attr('data-ipsSticky') ) ){
self.on( 'stickyInit', function () {
self._ui.progressBar.hide();
});
} else {
self._ui.progressBar.hide();
}
};
// Are there any existing files?
if( !this._hasExistingFiles() ){
hideProgressBar();
this._ui.screenshots.hide();
this._ui.fileInfo.hide();
this.scope.find('[data-role="submitForm"]').prop( 'disabled', true );
} else {
if( !this.scope.find('input[name^="files_existing"]').length ){
hideProgressBar();
} else {
this.scope.find('#elDownloadsSubmit_uploader .ipsAttachment_dropZone').hide();
this.scope.find('#elDownloadsSubmit_uploader [data-action="uploadMore"]').show();
this._hiddenUploader = true;
}
if( !this._hasExistingScreenshots() && this._requireScreenshots ){
this._ui.fileInfo.hide();
this.scope.find('[data-role="submitForm"]').prop( 'disabled', true );
}
}
},
/**
* Responds to clicking Confirm in the URLs popup. If there's URLs, we show the next steps
*
* @param {event} e Event object
* @returns {void}
*/
confirmURLs: function (e) {
e.preventDefault();
var gotURLs = this._confirmMenu( 'url_files', 'elURLFiles' );
if( gotURLs ){
this._doneUploadStep();
}
},
/**
* Responds to clicking Confirm in the Import Files popup. If there's files, we show the next steps
*
* @param {event} e Event object
* @returns {void}
*/
confirmImports: function (e) {
e.preventDefault();
var gotImports = this._confirmMenu( 'import_files', 'elImportFiles' );
if( gotImports ){
this._doneUploadStep();
}
},
/**
* Responds to clicking Confirm in the Import Files popup. If there's files, we show the next steps
*
* @param {event} e Event object
* @returns {void}
*/
confirmScreenshots: function (e) {
e.preventDefault();
var gotURLs = this._confirmMenu( 'url_screenshots', 'elURLScreenshots' );
if( gotURLs ){
this._doneScreenshotStep();
}
},
/**
* Responds to clicking the 'Upload more files' button
*
* @param {event} e Event object
* @returns {void}
*/
uploadMore: function (e) {
e.preventDefault();
this.scope.find('#elDownloadsSubmit_uploader .ipsAttachment_dropZone').show();
this.scope.find('#elDownloadsSubmit_uploader [data-action="uploadMore"]').hide();
this._hiddenUploader = false;
this._overriddenUploader = true;
},
/**
* Responds to fileAdded event from the uploader to show the screenshot and/or file information sections
*
* @param {event} e Event object
* @param {object} data Event data object from the uploader
* @returns {void}
*/
fileAdded: function (e, data) {
if( !this._bulkUpload ){
if( data.uploader == 'files' ){
this._doneUploadStep();
} else if( data.uploader == 'screenshots' ){
this._doneScreenshotStep();
}
}
},
/**
* Responds to fileDeleted event from uploader
*
* @param {event} e Event object
* @param {object} data Event data object from the uploader
* @returns {void}
*/
fileDeleted: function (e, data) {
if( data.uploader != 'files' ){
return;
}
if( data.count === 0 ){
this.scope.find( '#elDownloadsSubmit_progress .ipsProgressBar_progress')
.attr('data-progress', '0%')
.css( {
width: '0%'
});
this.scope.find('#elDownloadsSubmit_uploader .ipsAttachment_dropZone').show();
this.scope.find('#elDownloadsSubmit_uploader [data-action="uploadMore"]').hide();
this._hiddenUploader = false;
this._overriddenUploader = true;
}
},
/**
* Responds to uploadCountChanged event from uploader
*
* @param {event} e Event object
* @param {object} data Event data object from the uploader
* @returns {void}
*/
uploadCounter: function (e, data) {
if( data.uploader != 'files' ){
return;
}
},
/**
* Responds to uploadProgress event from uploader, which we use to adjust the main progressbar
*
* @param {event} e Event object
* @param {object} data Event data object from the uploader
* @returns {void}
*/
uploadProgress: function (e, data) {
if( data.uploader != 'files' ){
return;
}
var self = this;
this._showProgress();
this.scope.find( '#elDownloadsSubmit_progress .ipsProgressBar_progress')
.attr('data-progress', data.percent + '%')
.css( {
width: data.percent + '%'
});
if( data.percent === 100 && !this._progressbarTimeout ){
this._progressbarTimeout = setTimeout( function () {
self._ui.progressBar.find('.ipsProgressBar').removeClass('ipsProgressBar_animated');
self._progressbarTimeout = null;
}, 300 );
// Make the continue button available
this.scope.find('[data-role="submitForm"]').prop( 'disabled', false );
}
},
/**
* Handles the menus for specifying urls or file paths. If there's values entered, we show a count balloon.
*
* @param {string} inputName Name of the form fields containing the values
* @param {string} elemID ID of the menu trigger button (no #)
* @returns {boolean} Returns true if some urls/paths have been entered
*/
_confirmMenu: function (inputName, elemID) {
// Do we have a value?
var length = 0;
var invalid = 0;
this.scope.find('input[name^="' + inputName + '"]').each( function () {
if( $.trim( $( this ).val() ) ){
length++;
}
if( !_.isUndefined( this.checkValidity ) && !this.checkValidity() ){
invalid++;
}
});
if( !invalid ){
this.scope.find( '#' + elemID ).trigger('closeMenu');
}
this.scope.find('#' + elemID + ' [data-role="fileCount"]').text( length );
if( length ){
this.scope.find('#' + elemID + ' [data-role="fileCount"]').show();
return true;
} else {
this.scope.find('#' + elemID + ' [data-role="fileCount"]').hide();
return false;
}
},
/**
* Returns true if there are existing files on the form (from upload, url or file path)
*
* @returns {boolean} Returns true if there are existing files
*/
_hasExistingFiles: function () {
if( this.scope.find('input[name^="files_existing"]').length ){
return true;
}
var hasURL = [];
var hasImport = [];
if( this.scope.find('input[name^="url_files"]').length ){
hasURL = _.filter( this.scope.find('input[name^="url_files"]'), function (item) {
if( $.trim( $( item ).val() ) != '' ){
return true;
}
return false;
});
}
if( this.scope.find('input[name^="import_files"]').length ){
hasImport = _.filter( this.scope.find('input[name^="import_files"]'), function (item) {
if( $.trim( $( item ).val() ) != '' ){
return true;
}
return false;
});
}
if( hasURL.length || hasImport.length ){
return true;
}
return false;
},
/**
* Returns true if there are existing screenshots on the form (from upload or url)
*
* @returns {boolean} Returns true if there are existing screenshots
*/
_hasExistingScreenshots: function () {
if( this.scope.find('input[name^="screenshots_existing"]').length ){
return true;
}
var hasURL = [];
if( this.scope.find('input[name^="url_screenshots"]').length ){
hasURL = _.filter( this.scope.find('input[name^="url_screenshots"]'), function (item) {
if( $.trim( $( item ).val() ) != '' ){
return true;
}
return false;
});
if( hasURL.length ){
return true;
}
}
return false;
},
/**
* Shows the next relevant steps of the upload process
*
* @returns {void}
*/
_doneUploadStep: function () {
var self = this;
// Show screenshot step
if( this._ui.screenshots.length && !this._ui.screenshots.is(':visible') ){
ips.utils.anim.go( 'fadeIn', this._ui.screenshots )
.done( function () {
$( document ).trigger('contentChange', [ self._ui.screenshots ] );
});
}
if( !this._requireScreenshots && !this._ui.fileInfo.is(':visible') ){
ips.utils.anim.go( 'fadeIn', this._ui.fileInfo )
.done( function () {
$( document ).trigger('contentChange', [ self._ui.fileInfo ] );
});
}
this.scope.find('[data-role="submitForm"]').prop( 'disabled', false );
},
/**
* Shows the next relevant steps of the upload process
*
* @returns {void}
*/
_doneScreenshotStep: function () {
ips.utils.anim.go( 'fadeIn', this._ui.fileInfo );
},
/**
* Shows the progress bar and hides the dropzone
*
* @returns {void}
*/
_showProgress: function () {
if( !this._hiddenUploader && !this._overriddenUploader ){
this._ui.progressBar.show().find('.ipsProgressBar').addClass('ipsProgressBar_animated');
this.scope.find('#elDownloadsSubmit_uploader .ipsAttachment_dropZone').hide();
this.scope.find('#elDownloadsSubmit_uploader [data-action="uploadMore"]').show();
this._hiddenUploader = true;
}
}
});
}(jQuery, _));]]></file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.changeLog.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100"><![CDATA[/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
* ips.view.changeLog.js - Changelog controller
*
* Author: Rikki Tissier
*/
;( function($, _, undefined){
"use strict";
ips.controller.register('downloads.front.view.changeLog', {
initialize: function () {
this.on( 'menuItemSelected', this.changeVersion );
this.setup();
// Primary event that watches for URL changes
History.Adapter.bind( window, 'statechange', _.bind( this.stateChange, this ) );
},
/**
* Setup method
* Sets an initial state that we can use to go back to the default state
*
* @returns {void}
*/
setup: function () {
// Update page URL
History.replaceState( {
controller: 'changelog'
}, document.title, window.location.href );
},
/**
* Updates the version changelog being shown
*
* @param {event} e Event object
* @param {object} data Event data object from the menu
* @returns {void}
*/
changeVersion: function (e, data) {
data.originalEvent.preventDefault();
var self = this;
var url = data.menuElem.find('[data-ipsMenuValue="' + data.selectedItemID + '"] > a').attr('href');
// Update page URL
History.pushState( {
controller: 'changelog',
version: data.selectedItemID
}, document.title, url );
this._loadVersion( url, data.selectedItemID );
},
/**
* Event handler for History.js
* When the state changes, we locate that menu item based on the version, and then pull
* the version string and URL and load it
*
* @returns {void}
*/
stateChange: function () {
var state = History.getState();
// Other things on the page can change the URL, so make sure this is a changelog url
if( state.data.controller != 'changelog' ){
return;
}
var item;
if( state.data.version ){
item = $('#elChangelog_menu').find('[data-ipsMenuValue="' + state.data.version + '"]');
} else {
item = $('#elChangelog_menu').find('[data-ipsMenuValue]').first();
}
this._loadVersion( item.find('a').attr('href'), item.attr('data-ipsMenuValue') );
},
/**
* Loads version information
*
* @param {string} url URL of the version to load
* @param {string} versionTitle Title of version being loaded
* @returns {void}
*/
_loadVersion: function (url, versionTitle) {
var self = this;
// Update version
this.scope.find('[data-role="versionTitle"]').text( versionTitle );
// Set height on info area and set to loading
this.scope
.find('[data-role="changeLogData"]')
.css( {
height: this.scope.find('[data-role="changeLogData"]').height() + 'px'
})
.addClass('ipsLoading')
.html('');
// Load the new data
ips.getAjax()( url )
.done( function (response) {
self.scope
.find('[data-role="changeLogData"]')
.html( response )
.removeClass('ipsLoading')
.css({
height: 'auto'
});
})
.fail( function (jqXHR, textStatus, errorThrown) {
window.location = url;
});
}
});
}(jQuery, _));]]></file>
<file javascript_app="downloads" javascript_location="front" javascript_path="controllers/view" javascript_name="ips.view.download.js" javascript_type="controller" javascript_version="100045" javascript_position="1000100">/**
* IPS Social Suite 4
* (c) 2013 Invision Power Services - http://www.invisionpower.com
*
* ips.view.download.js - Download popup controller
*
* Author: Rikki Tissier
*/
;( function($, _, undefined){
&quot;use strict&quot;;
ips.controller.register('downloads.front.view.download', {
initialize: function () {
this.on( 'click', '[data-action=&quot;dialogClose&quot;]', this.closeDialog );
this.on( 'click', '[data-action=&quot;selectFile&quot;]', this.selectFile );
this.on( 'click', '[data-action=&quot;download&quot;]', this.doDownload );
},
/**
* Agree to the terms and update the display to show the list
*
* @param {event} e Event object
* @returns {void}
*/
selectFile: function (e) {
var url = $( e.currentTarget ).attr('href');
var self = this;
e.preventDefault();
// Load the download page
this.scope
.html('')
.css({
height: '250px'
})
.addClass('ipsLoading');
ips.getAjax()( url )
.done( function (response) {
self.scope
.html( response )
.css({
height: 'auto'
})
.removeClass('ipsLoading');
})
.fail( function (jqXHR, textStatus, errorThrown) {
window.location = url;
});
},
/**
* Event handler for the 'cancel' link
*
* @param {event} e Event object
* @returns {void}
*/
closeDialog: function (e) {
e.preventDefault();
this._closeDialog( $( e.currentTarget ).attr('href') );
},
/**
* Closes the dialog
*
* @param {string} href Href to redirect to if not in a dialog
* @returns {void}
*/
_closeDialog: function (href) {
if( this.scope.closest('.ipsDialog').length ){
this.scope.closest('.ipsDialog').trigger('closeDialog');
} else {
window.location = href;
}
},
/**
* Initiate the actual download
*
* @param {event} e Event object
* @returns {void}
*/
doDownload: function (e) {
if ( $( e.currentTarget ).attr('data-wait') ) {
e.preventDefault();
ips.getAjax()( $( e.currentTarget ).attr('href') )
.done( function (response) {
var secondsRemaining = response.download - response.currentTime;
$( e.currentTarget )
.hide()
.siblings()
.find('[data-role=&quot;downloadCounter&quot;]')
.html( secondsRemaining )
.end()
.end()
.siblings('[data-role=&quot;downloadCounterContainer&quot;]')
.removeClass('ipsHide');
var interval = setInterval( function () {
secondsRemaining--;
$( e.currentTarget ).siblings().find('[data-role=&quot;downloadCounter&quot;]').html( secondsRemaining );
if ( secondsRemaining === 0 ) {
clearInterval(interval);
window.location = $( e.currentTarget ).attr('href');
}
}, 1000 );
})
.fail( function () {
window.location = $(e.currentTarget).attr('href');
})
} else {
this._closeDialog( $( e.currentTarget ).attr('href') );
}
}
});
}(jQuery, _));</file>
<file javascript_app="downloads" javascript_location="front" javascript_path="templates" javascript_name="ips.templates.submit.js" javascript_type="template" javascript_version="100045" javascript_position="1000150"><![CDATA[/* VIEW TEMPLATES */
ips.templates.set('downloads.submit.screenshot', " \
<div class='ipsGrid_span3 ipsAttach ipsImageAttach ipsPad_half ipsAreaBackground_light' id='{{id}}' data-role='file' data-fileid='{{id}}' data-fullsizeurl='{{imagesrc}}' data-thumbnailurl='{{thumbnail}}' data-isImage='1'>\
<ul class='ipsList_inline ipsImageAttach_controls'>\
<li><input type='radio' name='{{field_name}}_primary_screenshot' id='{{field_name}}_primary_screenshot_{{id}}' value='{{id}}' title='{{#lang}}makePrimaryScreenshot{{/lang}}' data-ipsTooltip {{#default}}checked{{/default}}></li>\
<li class='ipsPos_right' data-role='deleteFileWrapper'>\
<input type='hidden' name='{{field_name}}_keep[{{id}}]' value='1'>\
<a href='#' data-role='deleteFile' class='ipsButton ipsButton_verySmall ipsButton_light' data-ipsTooltip title='{{#lang}}removeScreenshot{{/lang}}'><i class='fa fa-trash-o'></i></a>\
</li>\
</ul>\
<label for='{{field_name}}_primary_screenshot_{{id}}' class='ipsCursor_pointer'>\
<div class='ipsImageAttach_thumb ipsType_center' data-role='preview' data-grid-ratio='65' data-action='insertFile' {{#thumb}}style='background-image: url( {{thumbnail}} )'{{/thumb}}>\
{{#status}}\
<span class='ipsImageAttach_status ipsType_light' data-role='status'>{{{status}}}</span>\
<span class='ipsAttachment_progress'><span data-role='progressbar'></span></span>\
{{/status}}\
{{#thumb}}\
{{{thumb}}}\
{{/thumb}}\
</div>\
</label>\
<h2 class='ipsType_reset ipsAttach_title ipsType_medium' data-role='title'>{{title}}</h2>\
<p class='ipsType_light'>{{size}} &middot; <span data-role='status'>{{statusText}}</span></p>\
</div>\
");
ips.templates.set('downloads.submit.screenshotWrapper', " \
<div class='ipsGrid ipsGrid_collapsePhone' data-ipsGrid data-ipsGrid-minItemSize='150' data-ipsGrid-maxItemSize='250'>{{{content}}}</div>\
");]]></file>
<order app="global" path="/dev/js//framework/">templates
common/ui
common/utils
common
controllers</order>
<order app="global" path="/dev/js//library/">underscore
jquery
mustache
jstz
Debug.js
app.js</order>
<order app="global" path="/dev/js//library//jquery">jquery.js
jquery.history.js
jquery.transform.js</order>
<order app="global" path="/dev/js//library//xregexp">xregexp-all.js
xregexp-lookbehind.js</order>
</javascript>
+468
View File
@@ -0,0 +1,468 @@
<?xml version="1.0" encoding="UTF-8"?>
<language>
<app key="downloads" version="100045">
<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>
<word key="__indefart_downloads_file" js="0">a file</word>
<word key="__indefart_downloads_file_review" js="0">a review on a file</word>
<word key="menu__downloads_downloads" js="0">Downloads</word>
<word key="module__downloads_downloads" js="0">Downloads</word>
<word key="menu__downloads_stats" js="0">Downloads</word>
<word key="module__downloads_stats" js="0">Statistics</word>
<word key="file_download" js="0">File Download</word>
<word key="filestorage__downloads_Files" js="0">IP.Downloads Files</word>
<word key="filestorage__downloads_Screenshots" js="0">IP.Downloads Screenshots</word>
<word key="filestorage__downloads_FileField" js="0">IP.Downloads Custom Fields</word>
<word key="downloads_files" js="0">Downloads Files</word>
<word key="modlog__action_restorebackup" js="0"><![CDATA[Restored a previous version for a file: <a href='%s'>%s</a>]]></word>
<word key="modlog__action_visibilitybackup" js="0"><![CDATA[Toggled visibility for a previous version for a file: <a href='%s'>%s</a>]]></word>
<word key="modlog__action_deletebackup" js="0"><![CDATA[Deleted a previous version for a file: <a href='%s'>%s</a>]]></word>
<word key="editor__downloads_Categories" js="0">Download Categories</word>
<word key="editor__downloads_Downloads" js="0">File Downloads</word>
<word key="editorMedia_downloads_Files" js="0">File Downloads</word>
<word key="menu__downloads_downloads_categories" js="0">Categories</word>
<word key="subcategories" js="0">Subcategories</word>
<word key="cname" js="0">Name</word>
<word key="cbitoptions_disfiles" js="0">Allow files?</word>
<word key="cbitoptions_disfiles_desc" js="0">You may want to disable to use this category as a container for other subcategories.</word>
<word key="ctypes" js="0">Allowed file extensions</word>
<word key="cparent" js="0">Parent Category</word>
<word key="any_extensions" js="0">any extensions</word>
<word key="cmaxfile" js="0">Maximum file size</word>
<word key="ccfields" js="0">Extra fields</word>
<word key="category_screenshots" js="0">Screenshots</word>
<word key="cbitoptions_allowss" js="0">Allow screenshots?</word>
<word key="cbitoptions_allowss_desc" js="0">Images can be submitted with files to provide screenshots or other accompanying images to show in the file listing.</word>
<word key="cbitoptions_reqss" js="0">Require screenshots?</word>
<word key="cmaxss" js="0">Maximum screenshot filesize</word>
<word key="cmaxdims" js="0">Maximum screenshot dimensions</word>
<word key="category_display" js="0">Category Display</word>
<word key="csortorder" js="0">Default sort order</word>
<word key="cbitoptions_comments" js="0">Allow comments?</word>
<word key="cbitoptions_reviews" js="0">Allow reviews?</word>
<word key="cbitoptions_reviews_mod" js="0">Reviews must be approved?</word>
<word key="cbitoptions_reviews_download" js="0">Users must download before reviewing?</word>
<word key="cbitoptions_reviews_download_desc" js="0">Requires download log to be on.</word>
<word key="cdisclaimer" js="0">Download Terms</word>
<word key="cdisclaimer_placeholder" js="0">Before downloading you must agree to the following terms...</word>
<word key="ctags_disabled" js="0">Allow tags?</word>
<word key="ctags_noprefixes" js="0">Allow prefixes?</word>
<word key="ctags_predefined" js="0">Defined Tags</word>
<word key="ctags_predefined_unlimited" js="0">Use default</word>
<word key="ctags_predefined_desc" js="0">If using a closed system, users will have to choose from these tags. If using an open system, tags entered here will show as suggestions.</word>
<word key="category_errors" js="0">Error Messages</word>
<word key="category_errors_blurb" js="0">You can define specific error messages to use within this category. If not provided, a generic error message will be used.</word>
<word key="noperm_view" js="0">Cannot view files</word>
<word key="noperm_view_placeholder" js="0">Add an error message...</word>
<word key="noperm_dl" js="0">Cannot download</word>
<word key="noperm_dl_placeholder" js="0">Add an error message...</word>
<word key="perm_file_perm__label" js="0"></word>
<word key="perm_file_perm__view" js="0">See Category</word>
<word key="perm_file_perm__read" js="0">View Files</word>
<word key="perm_file_perm__add" js="0">Upload Files</word>
<word key="perm_file_perm__download" js="0">Download Files</word>
<word key="perm_file_perm__comment" js="0">Comment</word>
<word key="perm_file_perm__rate" js="0">Rate Files</word>
<word key="perm_file_perm__reply" js="0">Comment</word>
<word key="perm_file_perm__review" js="0">Review Files</word>
<word key="cbitoptions_moderation" js="0">Files must be approved?</word>
<word key="cbitoptions_moderation_edits" js="0">New versions must be re-approved?</word>
<word key="cbitoptions_show_approver" js="0">Show who approved the file?</word>
<word key="cbitoptions_show_approver_desc" js="0">Other staff members are always able to see this information.</word>
<word key="cbitoptions_comment_moderation" js="0">Comments must be approved?</word>
<word key="cversioning_on" js="0">Keep previous versions?</word>
<word key="cversioning_on_desc" js="0">If enabled, when a new version of a file is uploaded, the previous version is stored and remains available.</word>
<word key="cversioning" js="0">Number of revisions to keep</word>
<word key="category_moderation" js="0">Moderation</word>
<word key="category_downloading" js="0">Downloading</word>
<word key="category_comments_and_reviews" js="0">Comments</word>
<word key="category_logs" js="0">Logs</word>
<word key="clog_on" js="0">Log downloads?</word>
<word key="clog" js="0">Keep logs for</word>
<word key="clog_recount" js="0">Recalculate Download Counts</word>
<word key="clog_recount_desc" js="0">This will reset the number of downloads for each file in this category to the number of records currently in the log. If you have updated the log settings, you will need to save them before running this tool. This action is irreversible.</word>
<word key="clog_recount_done" js="0">Counts Recalculated</word>
<word key="r__categories_recount_downloads" js="0">Can recalculate download counts?</word>
<word key="cbitoptions_submitter_log" js="0">Allow file submitter to view log?</word>
<word key="cbitoptions_submitter_log_desc" js="0">You can also control which members can view the log from the group settings.</word>
<word key="category_submissions" js="0">Submissions</word>
<word key="category_allowed_files" js="0">Allowed Files</word>
<word key="category_versioning" js="0">Versioning</word>
<word key="csubmissionterms" js="0">Submission Terms</word>
<word key="csubmissionterms_placeholder" js="0">By submitting a file you agree to the following terms:</word>
<word key="file_cat" js="0">Category</word>
<word key="log_days" js="0">The log is pruned after {# [1:day][?:days]}</word>
<word key="category_forums_integration" js="0">Forum Topics</word>
<word key="cforum_on" js="0">Post a topic when a file is submitted?</word>
<word key="cforum_id" js="0">Forum</word>
<word key="ctopic_prefix" js="0">Topic prefix</word>
<word key="ctopic_suffix" js="0">Topic suffix</word>
<word key="cbitoptions_topic_delete" js="0">Delete topic if file is deleted?</word>
<word key="cbitoptions_topic_screenshot" js="0">Include screenshot in topic?</word>
<word key="node_no_parentd" js="0">No Parent</word>
<word key="modperms__core_Content_downloads_File" js="0">Downloads</word>
<word key="download_categories" js="0">Categories</word>
<word key="can_pin_downloads_file" js="0">Can pin files?</word>
<word key="can_unpin_downloads_file" js="0">Can unpin files?</word>
<word key="can_feature_downloads_file" js="0">Can feature files?</word>
<word key="can_unfeature_downloads_file" js="0">Can unfeature files?</word>
<word key="can_move_downloads_file" js="0">Can move files?</word>
<word key="can_lock_downloads_file" js="0">Can lock files?</word>
<word key="can_unlock_downloads_file" js="0">Can unlock files?</word>
<word key="can_reply_to_locked_downloads_file" js="0">Can comment on locked files?</word>
<word key="can_edit_downloads_file" js="0">Can edit files?</word>
<word key="can_hide_downloads_file" js="0">Can hide files?</word>
<word key="can_unhide_downloads_file" js="0">Can unhide files?</word>
<word key="can_view_hidden_downloads_file" js="0">Can view hidden files?</word>
<word key="can_delete_downloads_file" js="0">Can delete files?</word>
<word key="can_edit_downloads_file_comment" js="0">Can edit comments?</word>
<word key="can_hide_downloads_file_comment" js="0">Can hide comments?</word>
<word key="can_unhide_downloads_file_comment" js="0">Can unhide comments?</word>
<word key="can_view_hidden_downloads_file_comment" js="0">Can view hidden comments?</word>
<word key="can_delete_downloads_file_comment" js="0">Can delete comments?</word>
<word key="can_edit_downloads_file_review" js="0">Can edit reviews?</word>
<word key="can_hide_downloads_file_review" js="0">Can hide reviews?</word>
<word key="can_unhide_downloads_file_review" js="0">Can unhide reviews?</word>
<word key="can_view_hidden_downloads_file_review" js="0">Can view hidden reviews?</word>
<word key="can_delete_downloads_file_review" js="0">Can delete reviews?</word>
<word key="menu__downloads_downloads_fields" js="0">Extra Fields</word>
<word key="r__fields" js="0">Extra Fields</word>
<word key="r__fields_manage" js="0">Can view extra fields?</word>
<word key="r__fields_add" js="0">Can create extra fields?</word>
<word key="r__fields_edit" js="0">Can edit extra fields?</word>
<word key="r__fields_delete" js="0">Can delete extra fields?</word>
<word key="cf_topic" js="0">Include field in topics?</word>
<word key="menu__downloads_downloads_settings" js="0">Settings</word>
<word key="acplogs__downloads_settings" js="0">Updated downloads settings</word>
<word key="group__downloads_Downloads" js="0">Downloads</word>
<word key="idm_rss" js="0">Enable Latest Files RSS feed?</word>
<word key="idm_link_blacklist" js="0">URL Submissions Blacklist</word>
<word key="idm_link_blacklist_desc" js="0">Users that are allowed to make URL submissions will not be able to use URLs from the specified domains.</word>
<word key="idm_antileech" js="0">Prevent direct linking?</word>
<word key="idm_antileech_desc" js="0">If enabled, users will not be able to obtain a URL which directly downloads a file; users will always have to go through the file's page.</word>
<word key="idm_watermarkpath" js="0">Screenshot watermark</word>
<word key="idm_watermarkpath_desc" js="0"><![CDATA[The image provided will be overlaid on all screenshot images (for example, to show a copyright message). For best results, use a small image with a transparent background.<br><br><a href='{internal.app=downloads&module=downloads&controller=settings&do=rebuildWatermarks}'>Rebuild Existing Screenshots</a>]]></word>
<word key="acplogs__downloads_recount_downloads" js="0">Recounted downloads for category: %s</word>
<word key="idm_view_approvers" js="0">Can view who approved files?</word>
<word key="idm_bypass_revision" js="0">Can manage versions?</word>
<word key="idm_view_downloads" js="0">Can view who has downloaded files?</word>
<word key="idm_view_downloads_desc" js="0">Note that the download log can be disabled per-category and cleared periodically.</word>
<word key="idm_throttling" js="0">Maximum Download Speed</word>
<word key="idm_throttling_suffix" js="0">kB/second</word>
<word key="idm_throttling_desc" js="0"><![CDATA[This will <em>throttle</em> downloads to the maximum speed set. If set too low, this may cause your server to time out and the download to fail.]]></word>
<word key="idm_throttling_unlimited" js="0">No restriction</word>
<word key="idm_wait_period" js="0">Time user must wait before download starts</word>
<word key="idm_bypass_revision_desc" js="0"><![CDATA[When an author uploads a new version of a file within a category that has versioning enabled, the previous version is stored and is available for download. When this setting is enabled, the user will be given the option to not store the previous version when uploading a new version, and will be able to restore, hide and delete their previous versions.<br>The user needs permission to edit the file.]]></word>
<word key="limit_sim" js="0">Maximum simultaneous downloads</word>
<word key="min_posts" js="0">Posts required to download</word>
<word key="download_min_posts" js="0">You may only download files after you have made {# [1:post][?:posts]}.</word>
<word key="daily_bw" js="0">Maximum bandwidth usage per day</word>
<word key="weekly_bw" js="0">Maximum bandwidth usage per week</word>
<word key="monthly_bw" js="0">Maximum bandwidth usage per month</word>
<word key="kb_per_day" js="0">kB/day</word>
<word key="kb_per_week" js="0">kB/week</word>
<word key="kb_per_month" js="0">kB/month</word>
<word key="daily_dl" js="0">Maximum downloads per day</word>
<word key="weekly_dl" js="0">Maximum downloads per week</word>
<word key="monthly_dl" js="0">Maximum downloads per month</word>
<word key="downloads_requires_log" js="0">These settings rely on the download log which can be disabled per-category and cleared periodically. If using these settings, it is recommended that you leave the log turned on and set not to clear otherwise you may experience unexpected behavior.</word>
<word key="file_management" js="0">File Management</word>
<word key="download_restrictions" js="0">Download Restrictions</word>
<word key="bandwidth_limits" js="0">Bandwidth Limits</word>
<word key="download_limits" js="0">Download Limits</word>
<word key="downloads_per_day" js="0">downloads/day</word>
<word key="downloads_per_week" js="0">downloads/week</word>
<word key="downloads_per_month" js="0">downloads/month</word>
<word key="submission_permissions" js="0">Submission Permissions</word>
<word key="idm_linked_files" js="0">Can submit URLs?</word>
<word key="idm_import_files" js="0">Can import files from the filesystem?</word>
<word key="idm_import_files_desc" js="0">When enabled, users will be able to import files located on your server. You should only enable this for staff groups where all the users are trusted.</word>
<word key="idm_bulk_submit" js="0">Can submit multiple files at once?</word>
<word key="rss_offline" js="0">This RSS feed is disabled</word>
<word key="rss_offline_admin" js="0">The IP.Downloads option &quot;Enable Latest Files RSS feed&quot; is currently disabled. Toggle this option to yes in the admin control panel to enable the latest files RSS feed.</word>
<word key="submit_a_file" js="0">Submit a file</word>
<word key="submit_single_file" js="0">Submit single file</word>
<word key="submit_multiple_files" js="0">Submit multiple files</word>
<word key="submit_first_file" js="0">Submit the first file</word>
<word key="write_review" js="0">Write a review</word>
<word key="file_auto_follow" js="0"></word>
<word key="file_auto_follow_suffix" js="0">Notify me when other comments are posted</word>
<word key="file" js="0">File</word>
<word key="upload_files" js="0">Upload Your Files</word>
<word key="dl_get_support" js="0">Get Support</word>
<word key="dl_get_support_title" js="0">Get support for this download</word>
<word key="file_information" js="0">File Information</word>
<word key="url_files" js="0">Linked Files</word>
<word key="import_files" js="0">Import Files</word>
<word key="screenshots" js="0">Screenshots</word>
<word key="screenshots_ct" js="0">{# [1:Screenshot][?:Screenshots]}</word>
<word key="url_screenshots" js="0">Linked Screenshots</word>
<word key="file_title" js="0">File name</word>
<word key="file_submitter" js="0">Submitter</word>
<word key="file_submitted" js="0">Submitted</word>
<word key="view_file" js="0">View File</word>
<word key="file_version" js="0">Version number</word>
<word key="file_tags" js="0">Tags</word>
<word key="file_changelog" js="0">What's New</word>
<word key="new_version_details" js="0">New Version Details</word>
<word key="with_version" js="0">With version %s:</word>
<word key="file_desc" js="0">About This File</word>
<word key="file_primary_screenshot" js="0">Primary Screenshot</word>
<word key="file_primary_screenshot_desc" js="0">The primary screenshot is used in category listings.</word>
<word key="download_now" js="0">Download this file</word>
<word key="downloads" js="0">Downloads</word>
<word key="x_downloads" js="0">{# [1:download][?:downloads]}</word>
<word key="idm_purchases" js="0">Purchases</word>
<word key="x_purchases" js="0">{# [1:purchase][?:purchases]}</word>
<word key="num_downloads" js="0">{# [1:download][?:downloads]}</word>
<word key="files_no_number" js="0">{!# [1:file][?:files]}</word>
<word key="downloads_file" js="0">File</word>
<word key="downloads_file_comment" js="0">File Comment</word>
<word key="downloads_file_review" js="0">File Review</word>
<word key="downloads_file_pl" js="0">Files</word>
<word key="downloads_file_pl_lc" js="0">files</word>
<word key="downloads_file_comment_pl" js="0">File Comments</word>
<word key="downloads_file_review_pl" js="0">File Reviews</word>
<word key="downloads_category_select" js="0">Category:</word>
<word key="report_file" js="0">Report this file</word>
<word key="file_review_count" js="0">{# [1:Review][?:Reviews]}</word>
<word key="file_comment_count" js="0">{# [1:Comment][?:Comments]}</word>
<word key="subcategory" js="0">Sub Category</word>
<word key="download_no_perm" js="0">You are not allowed to download that file.</word>
<word key="add_files_no_perm" js="0">You are not allowed to upload files to this category.</word>
<word key="new_version_versioning" js="0">The previous version will be archived and users will still be able to download it.</word>
<word key="file_save_revision" js="0">Save Previous Version?</word>
<word key="downloads_edit_details" js="0">Edit Details</word>
<word key="downloads_edit_details_title" js="0">Edit this file's details</word>
<word key="file__comment_placeholder" js="0">Add a comment...</word>
<word key="file_submit_comment" js="0">Submit Comment</word>
<word key="whats_new_in_version" js="0"><![CDATA[What's New in Version <span data-role='versionTitle'>%s</span>]]></word>
<word key="see_changelog" js="0">See changelog</word>
<word key="see_changelog_for" js="0">See changelog for version %s</word>
<word key="see_changelog_title" js="0">See the version history for this file</word>
<word key="view_downloader_list" js="0">View list of downloaders</word>
<word key="who_downloaded" js="0">Who downloaded this?</word>
<word key="downloaders" js="0">Downloaders</word>
<word key="download_your_files" js="0">Download your files</word>
<word key="download_terms" js="0">Download Terms</word>
<word key="download_terms_desc" js="0">Your file is ready for download. Before downloading, you must agree to the following terms:</word>
<word key="download_file_count" js="0">{# [1:file][?:files]}</word>
<word key="agree_and_download" js="0"><![CDATA[Agree &amp; Download]]></word>
<word key="cancel_downloading" js="0">Cancel download</word>
<word key="agree_and_download_full" js="0">Agree to the terms above and download file</word>
<word key="download_version" js="0">Download</word>
<word key="restore_version" js="0">Restore</word>
<word key="delete_version" js="0">Delete</word>
<word key="hide_version" js="0">Hide from members</word>
<word key="filesize" js="0">File Size</word>
<word key="file_pending_approval" js="0">This file is not yet approved and is only visible to staff.</word>
<word key="file_approved_by" js="0">(approved by %s, %s)</word>
<word key="file_requires_approval_g" js="0">The file you submitted must be approved by a staff member before it will be visible</word>
<word key="file_no_changelog" js="0">No changelog available for this version.</word>
<word key="file_version_released" js="0">Released %s</word>
<word key="restore" js="0">Restore</word>
<word key="hide_from_members" js="0">Hide from members</word>
<word key="unhide_from_members" js="0">Unhide from members</word>
<word key="version_restore_confirm" js="0">Are you sure you want to restore version %s?</word>
<word key="version_restore_confirm_desc" js="0">All versions since %1$s will be deleted and the file will be restored to the state it was at version %1$s.</word>
<word key="version_delete_confirm" js="0">Are you sure you want to delete version %s?</word>
<word key="idm_rss_title" js="0">Latest Files</word>
<word key="wait_x_seconds_noscript" js="0">Wait {# [1:second][?:seconds]}, then click Download again</word>
<word key="download_begins_in" js="0">Download begins in </word>
<word key="file_actions" js="0">File Actions</word>
<word key="max_simultaneous_downloads" js="0">You may only download {# [1:file][?:files]} at a time. Wait until {!# [1:your other download has][?:some of your other downloads have]} finished, then try again.</word>
<word key="bandwidth_limit_daily" js="0">You may only download %s per day. You will be able to download this file after %s.</word>
<word key="bandwidth_limit_week" js="0">You may only download %s per week. You will be able to download this file after %s.</word>
<word key="bandwidth_limit_month" js="0">You may only download %s per month. The file you are trying to download is %s which is above your limit.</word>
<word key="bandwidth_limit_daily_never" js="0">You may only download %s per day. The file you are trying to download is %s which is above your limit.</word>
<word key="bandwidth_limit_weekly" js="0">You may only download %s per week. The file you are trying to download is %s which is above your limit.</word>
<word key="download_limit_daily" js="0">You may only download {# [1:file][?:files]} per day. You will be able to download this file after %s.</word>
<word key="download_limit_weekly" js="0">You may only download {# [1:file][?:files]} per week. You will be able to download this file after %s.</word>
<word key="download_limit_monthly" js="0">You may only download {# [1:file][?:files]} per month. You will be able to download this file after %s.</word>
<word key="file_rating_value" js="0">Your rating</word>
<word key="file_review_text" js="0">Your review</word>
<word key="file__review_placeholder" js="0">Add a review...</word>
<word key="err_no_files" js="0">You must upload or link to at least one file.</word>
<word key="err_no_screenshots" js="0">You must upload or link to at least one screenshot.</word>
<word key="err_url_file_blacklist" js="0">URLs from %s are not allowed.</word>
<word key="err_import_files" js="0">The file %s does not exist or is not readable.</word>
<word key="err_import_files_dir" js="0">%s is a directory. You must specify the path to a file.</word>
<word key="change_author_d" js="0">Change Author</word>
<word key="change_author_title" js="0">Change the member who owns this file</word>
<word key="err_submissions_blocked" js="0">You have been blocked from submitting files.</word>
<word key="upload_new_version_title" js="0">Upload a new version of this file</word>
<word key="feature_title_file" js="0">Feature this file</word>
<word key="unfeature_title_file" js="0">Unfeature this file</word>
<word key="pin_title_file" js="0">Pin this file</word>
<word key="unpin_title_file" js="0">Unpin this file</word>
<word key="hide_title_file" js="0">Hide this file</word>
<word key="unhide_title_file" js="0">Unhide this file</word>
<word key="approve_title_file" js="0">Approve this file</word>
<word key="lock_title_file" js="0">Lock this file</word>
<word key="unlock_title_file" js="0">Unlock this file</word>
<word key="downloads_move_title" js="0">Move this file to another category</word>
<word key="downloads_delete_title" js="0">Delete this file from the community</word>
<word key="find_users_files" js="0">Find their other files</word>
<word key="file_versioning_info" js="0"></word>
<word key="file_versioning_info_text" js="0">Click here if you would like to upload a new version of the file or screenshot</word>
<word key="browse_whats_new" js="0">What's New</word>
<word key="browse_highest_rated" js="0">Highest Rated</word>
<word key="browse_most_downloaded" js="0">Most Downloaded</word>
<word key="no_new_files" js="0">There have been no uploaded files yet.</word>
<word key="no_rated_files" js="0">No files have been rated yet.</word>
<word key="no_downloaded_files__week" js="0">No files have been downloaded yet this week.</word>
<word key="no_downloaded_files__month" js="0">No files have been downloaded yet this month.</word>
<word key="no_downloaded_files__year" js="0">No files have been downloaded yet this year.</word>
<word key="no_downloaded_files" js="0">No files have been downloaded yet.</word>
<word key="no_download_review" js="0">You may only provide a review once you have downloaded the file.</word>
<word key="index_discover" js="0">Discover</word>
<word key="index_explore" js="0">Explore Categories</word>
<word key="browse_categories_d" js="0">Browse Categories</word>
<word key="no_files_in_cat" js="0">No files in this category yet.</word>
<word key="submit_form_title" js="0">Adding New File</word>
<word key="submit_form_title_bulk" js="0">Adding New Files</word>
<word key="submit_form_desc" js="0"><![CDATA[Adding a file to <em>%s</em>]]></word>
<word key="submit_form_desc_bulk" js="0"><![CDATA[Adding files to <em>%s</em>]]></word>
<word key="select_your_files" js="0">Select your files</word>
<word key="add_files_by_url" js="0">Add files by URL</word>
<word key="add_files_by_path" js="0">Add files from server path</word>
<word key="submit_menu_confirm" js="0">Confirm</word>
<word key="add_screenshots" js="0">Add screenshots</word>
<word key="add_screenshots_by_url" js="0">Add screenshots by URL</word>
<word key="submit_file_information" js="0">File Information</word>
<word key="save_and_submit_files" js="0"><![CDATA[Save &amp; Submit Files]]></word>
<word key="submit_bulk_information" js="0">Enter File Information</word>
<word key="bulk_upload_button" js="0">I want to add multiple records at once</word>
<word key="upload_more_files" js="0">Upload more files</word>
<word key="featured_downloads" js="0">Featured Downloads</word>
<word key="next_file" js="0">Next File</word>
<word key="prev_file" js="0">Previous File</word>
<word key="downloads_category_id" js="0">Category</word>
<word key="announce_download_categories" js="0">Categories</word>
<word key="view_this_file" js="0">View the file %s</word>
<word key="file_locked_can_comment" js="0">This file is locked, but your permissions allow you to add new comments.</word>
<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="block_downloads_Overview" js="0">Downloads Overview</word>
<word key="total_disk_spaced" js="0">Total Diskspace Used</word>
<word key="total_files" js="0">Total Files</word>
<word key="total_downloads" js="0">Total Downloads *</word>
<word key="total_bandwidth" js="0">Total Bandwidth Used *</word>
<word key="current_month_bandwidth" js="0">Bandwidth Used This Month *</word>
<word key="largest_file" js="0">Largest File</word>
<word key="most_viewed_file" js="0">Most Viewed File</word>
<word key="most_downloaded_file" js="0">Most Downloaded File</word>
<word key="total_files_front" js="0">Files</word>
<word key="total_authors" js="0">Authors</word>
<word key="latest_file" js="0">Latest File</word>
<word key="latest_submitter" js="0">Latest Submitter</word>
<word key="top_week" js="0">Week</word>
<word key="top_month" js="0">Month</word>
<word key="top_year" js="0">Year</word>
<word key="top_alltime" js="0">All</word>
<word key="top_avg_rating" js="0">Average file rating</word>
<word key="top_submitters_empty__week" js="0">No top submitters this week.</word>
<word key="top_submitters_empty__month" js="0">No top submitters this month.</word>
<word key="top_submitters_empty__year" js="0">No top submitters this year.</word>
<word key="top_submitters_empty__all" js="0">No top submitters.</word>
<word key="member__downloads_Downloads" js="0">Downloads</word>
<word key="idm_block_submissions" js="0">Allowed to submit files?</word>
<word key="idm_block_submissions_desc" js="0">Each category has permissions for who can submit files within it. If this is disabled, the user will not be able to submit any files. If enabled, per-category settings will be honoured.</word>
<word key="downloads_stats" js="0">View Downloads Statistics</word>
<word key="submissions" js="0">{# [1:submission][?:submissions]}</word>
<word key="deleted_file" js="0">Deleted File</word>
<word key="dmid" js="0">Member</word>
<word key="dfid" js="0">File</word>
<word key="dtime" js="0">Date/Time</word>
<word key="dsize" js="0">Filesize</word>
<word key="dua" js="0">Browser</word>
<word key="dip" js="0">IP Address</word>
<word key="member_downloads_chart" js="0">%s's Downloads</word>
<word key="bandwidth_use" js="0">Bandwidth Use</word>
<word key="files_submitted" js="0">Files Submitted</word>
<word key="diskspace_used" js="0">Diskspace Used</word>
<word key="average_filesize_downloads" js="0">Average Filesize</word>
<word key="number_of_downloads" js="0">Number of Downloads *</word>
<word key="downloads_bandwidth_used" js="0">Bandwidth Used *</word>
<word key="downloads_stat_of_total" js="0">%s (%d%% of total)</word>
<word key="downloads_stat_average" js="0">%s (average for all users: %s)</word>
<word key="downloadS_stat_average_of_total" js="0">%d% of total; average for all users: %d</word>
<word key="download_stats_disclaimer" js="0">* This statistic comes from the download log which may be disabled on a per-category basis or set to be pruned periodically.</word>
<word key="download_graph_disclaimer" js="0">This data comes from the download log which may be disabled on a per-category basis or set to be pruned periodically.</word>
<word key="menu__downloads_stats_downloads" js="0">Download Statistics</word>
<word key="menu__downloads_stats_downloaders" js="0">Top Downloaders</word>
<word key="menu__downloads_stats_submitters" js="0">Top Submitters</word>
<word key="r__downloads" js="0">Download Statistics</word>
<word key="r__downloads_manage" js="0">Can view Download Statistics?</word>
<word key="r__downloaders_manage" js="0">Can view Top Downloaders?</word>
<word key="r__submitters_manage" js="0">Can view Top Submitters?</word>
<word key="ipAddresses__downloads_DownloadLog" js="0">Downloads</word>
<word key="block_fileFeed" js="0">Files Feed</word>
<word key="block_fileFeed_desc" js="0">Create a feed of files</word>
<word key="widget_feed_container_downloads_file" js="0">Categories</word>
<word key="block_topSubmitters" js="0">Top Submitters</word>
<word key="block_topSubmitters_desc" js="0">Shows top submitters</word>
<word key="block_downloadStats" js="0">Download Statistics</word>
<word key="block_downloadStats_desc" js="0">Shows download application statistics</word>
<word key="block_topDownloads" js="0">Top Downloads</word>
<word key="block_topDownloads_desc" js="0">Shows most popular downloaded files</word>
<word key="loc_downloads_viewing_file" js="0">Viewing File: %s</word>
<word key="loc_downloads_viewing_category" js="0">Viewing Category: %s</word>
<word key="loc_downloads_browsing_categories" js="0">Browsing Downloads categories</word>
<word key="loc_downloads_adding_file" js="0">Adding a file</word>
<word key="loc_downloads_browsing" js="0">Viewing Downloads</word>
<word key="acp_search_title_downloads_Downloads" js="0">Downloads Categories</word>
<word key="task__logCleanup" js="0">Prunes the download log.</word>
<word key="task__tempFileCleanup" js="0">Removes temporary file uploads.</word>
<word key="digest_area_category" js="0">Files</word>
<word key="x_created_file_in" js="0">%s uploaded a file to %s</word>
<word key="x_commented_file" js="0">%s commented on a file</word>
<word key="paid_file_settings" js="0">Paid Files Settings</word>
<word key="idm_nexus_on" js="0">Enable Paid Files?</word>
<word key="idm_nexus_on_desc" js="0"><![CDATA[If enabled, users who have permission will be able to submit files which must be paid for in order to download.<br>You can control which groups can submit paid files from the <a href='{internal.app=core&module=members&controller=groups}'>Groups</a> page.<br>When someone purchases a paid file, the money will be added to the file submitter's account credit. You can control how users can withdraw account credit from the <a href='{internal.app=nexus&module=payments&controller=payouts&do=settings}'>Withdrawals</a> page.]]></word>
<word key="idm_nexus_tax" js="0">Tax Class for Paid Files</word>
<word key="idm_nexus_percent" js="0">Commission for Site</word>
<word key="idm_nexus_percent_desc" js="0">The percentage specified will be deducted from the amount given to the file submitter. For example, if you set this to 10% and someone buys a file for $10, the submitter will be given $9 and $1 will be kept for the site.</word>
<word key="idm_nexus_transfee" js="0">Transaction Fee for Site</word>
<word key="idm_nexus_transfee_desc" js="0">The amount specified will be deducted from the amount given to the file submitter. For example, if you set this to $1 and someone buys a file for $10, the submitter will be given $9 and $1 will be kept for the site.</word>
<word key="idm_nexus_gateways" js="0">Payment Methods</word>
<word key="idm_nexus_display" js="0">Statistics to Display</word>
<word key="idm_nexus_display_desc" js="0">Unpaid files will always show the number of downloads.</word>
<word key="idm_nexus_gateways_desc" js="0">Customers will only be able to pay for this product and renewals with the payment methods selected.</word>
<word key="idm_add_paid" js="0">Can charge for files?</word>
<word key="idm_add_paid_enable" js="0"><![CDATA[In order to allow users to charge for files you must <a href='{internal.app=downloads&module=downloads&controller=settings}'>enable paid files</a>.]]></word>
<word key="idm_bypass_paid" js="0">Can download paid files without paying?</word>
<word key="file_cost_type" js="0">Type</word>
<word key="file_free" js="0">Free</word>
<word key="file_paid" js="0">Paid</word>
<word key="file_associate_nexus" js="0">Associate with product(s)</word>
<word key="file_associate_nexus_desc" js="0">Users who have an active purchase of one of the selected products will be able to download this file.</word>
<word key="file_cost" js="0">Price</word>
<word key="file_renewals" js="0">Renewals</word>
<word key="file_renewals_off" js="0">No renewals - once a user has purchased this file they will be able to download all future versions.</word>
<word key="file_renewals_on" js="0">I will specify renewal terms. Users must have paid the renewal fee in order to download the current version.</word>
<word key="file_renewal_term" js="0">Renewal Term</word>
<word key="file_renewal_term_desc" js="0">Once the file is saved, renewal terms cannot be edited.</word>
<word key="file_nexus" js="0">Associated Products</word>
<word key="file_not_purchased" js="0">You have not purchased this file.</word>
<word key="buy_now" js="0">Buy Now</word>
<word key="file_cost_desc_both" js="0">%s%% commission, plus a %s transaction fee will be deducted.</word>
<word key="file_cost_desc_percent" js="0">%s%% commission will be deducted.</word>
<word key="file_cost_desc_fee" js="0">A %s transaction fee will be deducted.</word>
<word key="file_renewal_term_val" js="0">Renewal Term: %s</word>
<word key="choose_file_nexus_blurb" js="0">This file is available with one of the following packages. Please add one of the following packages to your cart to continue.</word>
<word key="choose_file_nexus_title" js="0">Choose A Package</word>
<word key="notifications__downloads_Files" js="0">Downloads</word>
<word key="notifications__new_file_version" js="0">A file I am following is updated with a new version</word>
<word key="email_new_file_version_plain" js="0">%s has uploaded a new version of %s,</word>
<word key="email_new_file_version" js="0"><![CDATA[<a href='%s'>%s</a> has uploaded a new version of %s,]]></word>
<word key="email_new_file_version_guest" js="0">%s (Guest) has uploaded a new version of %s,</word>
<word key="mailsub__downloads_notification_new_file_version" js="0"><![CDATA[{$content->author()->name|raw} has uploaded a new version of {$content->mapped("title")|raw}]]></word>
<word key="notification__new_file_version" js="0">%s uploaded a new version of %s</word>
<word key="emailtpl_notification_new_file_version" js="0">New File Version Notification</word>
<word key="makePrimaryScreenshot" js="1">Make this the primary screenshot</word>
<word key="removeScreenshot" js="1">Remove this screenshot</word>
</app>
</language>
+18
View File
@@ -0,0 +1,18 @@
{
"admin": {
"downloads": {
"default_controller": "",
"protected": 0
},
"stats": {
"default_controller": "downloads",
"protected": 0
}
},
"front": {
"downloads": {
"default_controller": "browse",
"protected": 0
}
}
}
File diff suppressed because it is too large. Load diff
+18
View File
@@ -0,0 +1,18 @@
[
{
"key": "idm_antileech",
"default": "1"
},
{
"key": "idm_link_blacklist",
"default": ""
},
{
"key": "idm_rss",
"default": "1"
},
{
"key": "idm_watermarkpath",
"default": ""
}
]
+1
View File
@@ -0,0 +1 @@
{"tempFileCleanup":"P0Y0M1DT0H0M0S","logCleanup":"P0Y0M1DT0H0M0S"}
File diff suppressed because it is too large. Load diff
@@ -0,0 +1 @@
{}
+82
View File
@@ -0,0 +1,82 @@
{
"21000": "2.1.0 Beta 1",
"21001": "2.1.0 Beta 2",
"21002": "2.1.0 RC 1",
"21003": "2.1.0 RC 2",
"21004": "2.1.0 RC 3",
"21005": "2.1.0",
"21006": "2.1.1",
"22000": "2.2.0 Beta 1",
"22001": "2.2.0 Beta 2",
"22002": "2.2.0 Beta 3",
"22003": "2.2.0",
"22004": "2.2.1",
"22005": "2.2.2",
"23000": "2.3.0 Beta 1",
"23001": "2.3.0 Beta 2",
"23002": "2.3.0 Beta 3",
"23003": "2.3.0 Beta 4",
"23004": "2.3.0 Beta 5",
"23005": "2.3.0 Beta 6",
"23006": "2.3.0 RC 1",
"23007": "2.3.0",
"23008": "2.3.1",
"24000": "2.4.0 Beta 1",
"24001": "2.4.0 Beta 2",
"24002": "2.4.0",
"24003": "2.4.1",
"24004": "2.4.2",
"25000": "2.5.0 Beta 1",
"25001": "2.5.0",
"25002": "2.5.1",
"25003": "2.5.2",
"25004": "2.5.3",
"25005": "2.5.4",
"40000": "4.0.0",
"100000": "4.0.0 Beta 0",
"100001": "4.0.0 Beta 1",
"100002": "4.0.0 Beta 2",
"100003": "4.0.0 Beta 3",
"100004": "4.0.0 Beta 3a",
"100005": "4.0.0 Beta 4",
"100006": "4.0.0 Beta 4a",
"100007": "4.0.0 Beta 4b",
"100008": "4.0.0 Beta 5",
"100009": "4.0.0 Beta 5a",
"100010": "4.0.0 Beta 6",
"100011": "4.0.0 Beta 7",
"100012": "4.0.0 Beta 7a",
"100013": "4.0.0 Beta 8",
"100014": "4.0.0 RC1",
"100015": "4.0.0 RC2",
"100016": "4.0.0 RC3",
"100017": "4.0.0 RC4",
"100018": "4.0.0 RC5",
"100019": "4.0.0 RC5a",
"100020": "4.0.0 RC6",
"100021": "4.0.0 RC7",
"100022": "4.0.0 RC7a",
"100023": "4.0.0",
"100024": "4.0.1",
"100025": "4.0.2",
"100026": "4.0.3",
"100027": "4.0.4",
"100028": "4.0.5",
"100029": "4.0.5.1",
"100030": "4.0.6",
"100031": "4.0.6.1",
"100032": "4.0.7",
"100033": "4.0.8",
"100034": "4.0.8.1",
"100035": "4.0.9",
"100036": "4.0.9.1",
"100037": "4.0.9.2",
"100038": "4.0.10",
"100039": "4.0.10.1",
"100040": "4.0.10.2",
"100041": "4.0.11",
"100042": "4.0.12",
"100043": "4.0.12.1",
"100044": "4.0.13",
"100045": "4.0.13.1"
}
+37
View File
@@ -0,0 +1,37 @@
{
"topSubmitters": {
"class": "\\IPS\\Widget\\StaticCache",
"restrict": [],
"default_area": "",
"allow_reuse": false,
"menu_style": "menu",
"embeddable": true
},
"downloadStats": {
"class": "\\IPS\\Widget\\StaticCache",
"restrict": [],
"default_area": "",
"allow_reuse": false,
"menu_style": "menu",
"embeddable": true
},
"topDownloads": {
"class": "\\IPS\\Widget\\PermissionCache",
"restrict": [],
"default_area": "",
"allow_reuse": false,
"menu_style": "menu",
"embeddable": true
},
"fileFeed": {
"class": "\\IPS\\Widget\\PermissionCache",
"restrict": [
"sidebar",
"cms"
],
"default_area": "",
"allow_reuse": true,
"menu_style": "modal",
"embeddable": true
}
}
@@ -0,0 +1,47 @@
<?php
/**
* @brief Announcements Extension : Download Categories
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 28 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\Announcements;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Announcements Extension: Download Categories
*/
class _Categories
{
/**
* @brief ID Field
*/
public static $idField = "id";
/**
* @brief Controller classes
*/
public static $controllers = array( "browse" );
/**
* Get Setting Field
*
* @param \IPS\core\Announcements\Announcement $announcement
* @return Form element
*/
public function getSettingField( $announcement )
{
return new \IPS\Helpers\Form\Node( 'announce_download_categories', ( $announcement AND $announcement->ids ) ? explode( ",", $announcement->ids ) : 0, FALSE, array( 'class' => 'IPS\downloads\Category', 'zeroVal' => 'any', 'multiple' => TRUE ), NULL, NULL, NULL, 'announce_download_categories' );
}
}
Whitespace-only changes.
@@ -0,0 +1,31 @@
<?php
/**
* @brief Content Router extension: Downloads
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 02 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\ContentRouter;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Content Router extension: Downloads
*/
class _Downloads
{
/**
* @brief Content Item Classes
*/
public $classes = array( 'IPS\downloads\File' );
}
Whitespace-only changes.
@@ -0,0 +1,48 @@
<?php
/**
* @brief Create Menu Extension
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 8 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\CreateMenu;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Create Menu Extension
*/
class _File
{
/**
* Get Items
*
* @return array
*/
public function getItems()
{
if ( \IPS\downloads\Category::canOnAny( 'add' ) )
{
return array(
'file_download' => array(
'link' => \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=submit&_new=1", 'front', 'downloads_submit' ),
'title' => 'select_category',
'extraData' => array( 'data-ipsDialog' => true, 'data-ipsDialog-size' => "narrow" )
)
);
}
return array();
}
}
Whitespace-only changes.
@@ -0,0 +1,68 @@
<?php
/**
* @brief Dashboard extension: Overview
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 13 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\Dashboard;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief Dashboard extension: Overview
*/
class _Overview
{
/**
* Can the current user view this dashboard item?
*
* @return bool
*/
public function canView()
{
return TRUE;
}
/**
* Return the block HTML show on the dashboard
*
* @return string
*/
public function getBlock()
{
$oneMonthAgo = \IPS\DateTime::create()->sub( new \DateInterval( 'P1M' ) )->getTimestamp();
/* Basic stats */
$data = array(
'total_disk_spaced' => (int) \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records' )->first(),
'total_files' => (int) \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files' )->first(),
'total_views' => (int) \IPS\Db::i()->select( 'SUM(file_views)', 'downloads_files' )->first(),
'total_downloads' => (int) \IPS\Db::i()->select( 'SUM(file_downloads)', 'downloads_files' )->first(),
'total_bandwidth' => (int) \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first(),
'current_month_bandwidth' => (int) \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dtime>?', $oneMonthAgo ) )->first(),
);
/* Specific files (will fail if no files yet) */
try
{
$data['largest_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_size DESC', 1 )->first() );
$data['most_viewed_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_views DESC', 1 )->first() );
$data['most_downloaded_file'] = \IPS\downloads\File::constructFromData( \IPS\Db::i()->select( '*', 'downloads_files', NULL, 'file_downloads DESC', 1 )->first() );
}
catch ( \Exception $e ) { }
/* Display */
return \IPS\Theme::i()->getTemplate( 'dashboard', 'downloads' )->overview( $data );
}
}
Whitespace-only changes.
@@ -0,0 +1,162 @@
<?php
/**
* @brief Editor Extension: Category descriptions
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 27 Sep 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: Category descriptions
*/
class _Categories
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return TRUE;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
{
return NULL;
}
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3 )
{
try
{
$file = \IPS\downloads\Category::load( $id1 );
return $file->can( 'view', $member );
}
catch ( \OutOfRangeException $e )
{
return FALSE;
}
}
/**
* Attachment lookup
*
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
{
return \IPS\downloads\Category::load( $id1 );
}
/**
* Rebuild attachment images in non-content item areas
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildAttachmentImages( $offset, $max )
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\Parser', 'rebuildAttachmentUrls' ) );
}
/**
* Rebuild content post-upgrade
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @return int Number completed
* @note This method is optional and will only be called if it exists
*/
public function rebuildContent( $offset, $max )
{
return $this->performRebuild( $offset, $max, array( 'IPS\Text\LegacyParser', 'parseStatic' ) );
}
/**
* Perform rebuild - abstracted as the call for rebuildContent() and rebuildAttachmentImages() is nearly identical
*
* @param int|null $offset Offset to start from
* @param int|null $max Maximum to parse
* @param callable $callback Method to call to rebuild content
* @return int Number completed
*/
protected function performRebuild( $offset, $max, $callback )
{
$did = 0;
/* Language bits */
foreach( \IPS\Db::i()->select( '*', 'core_sys_lang_words', "word_key LIKE 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'", 'word_id ASC', array( $offset, $max ) ) as $word )
{
$did++;
try
{
$rebuilt = call_user_func( $callback, $word['word_custom'] );
}
catch( \InvalidArgumentException $e )
{
if( $callback[1] == 'parseStatic' AND $e->getcode() == 103014 )
{
$rebuilt = preg_replace( "#\[/?([^\]]+?)\]#", '', $word['word_custom'] );
}
else
{
throw $e;
}
}
if( $rebuilt !== FALSE )
{
\IPS\Db::i()->update( 'core_sys_lang_words', array( 'word_custom' => $rebuilt ), 'word_id=' . $word['word_id'] );
}
}
return $did;
}
/**
* Total content count to be used in progress indicator
*
* @return int Total Count
*/
public function contentCount()
{
return \IPS\Db::i()->select( 'COUNT(*)', 'core_sys_lang_words', "word_key LIKE 'downloads_category_%_desc' OR word_key LIKE 'downloads_category_%_disclaimer' OR word_key LIKE 'downloads_category_%_subterms' OR word_key LIKE 'downloads_category_%_npd' OR word_key LIKE 'downloads_category_%_npv'" )->first();
}
}
@@ -0,0 +1,99 @@
<?php
/**
* @brief Editor Extension: File descriptions
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 8 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\EditorLocations;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Extension: File descriptions and comments
*/
class _Downloads
{
/**
* Can we use HTML in this editor?
*
* @param \IPS\Member $member The member
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canUseHtml( $member )
{
return NULL;
}
/**
* Can we use attachments in this editor?
*
* @param \IPS\Member $member The member
* @param \IPS\Helpers\Form\Editor $field The editor field
* @return bool|null NULL will cause the default value (based on the member's permissions) to be used, and is recommended in most cases. A boolean value will override that.
*/
public function canAttach( $member, $field )
{
return NULL;
}
/**
* Permission check for attachments
*
* @param \IPS\Member $member The member
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return bool
*/
public function attachmentPermissionCheck( $member, $id1, $id2, $id3 )
{
try
{
$file = \IPS\downloads\File::load( $id1 );
return $file->canView( $member );
}
catch ( \OutOfRangeException $e )
{
return FALSE;
}
}
/**
* Attachment lookup
*
* @param int|null $id1 Primary ID
* @param int|null $id2 Secondary ID
* @param string|null $id3 Arbitrary data
* @return \IPS\Http\Url|\IPS\Content|\IPS\Node\Model
* @throws \LogicException
*/
public function attachmentLookup( $id1, $id2, $id3 )
{
if ( $id2 )
{
if ( $id3 === 'review' )
{
return \IPS\downloads\File\Review::load( $id2 );
}
else
{
return \IPS\downloads\File\Comment::load( $id2 );
}
}
else
{
return \IPS\downloads\File::load( $id1 );
}
}
}
Whitespace-only changes.
@@ -0,0 +1,82 @@
<?php
/**
* @brief Editor Media: Files
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 26 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\EditorMedia;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Editor Media: Files
*/
class _Files
{
/**
* Get Counts
*
* @param \IPS\Member $member The member
* @param string $postKey The post key
* @param string|null $search The search term (or NULL for all)
* @return array array( 'Title' => 0 )
*/
public function count( $member, $postKey, $search=NULL )
{
$where = array(
array( "record_file_id IN(?) AND record_type=? AND record_backup=0", \IPS\Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
);
if ( $search )
{
$where[] = array( "record_realname LIKE ( CONCAT( '%', ?, '%' ) )", $search );
}
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', $where )->first();
}
/**
* Get Files
*
* @param \IPS\Member $member The member
* @param string|null $search The search term (or NULL for all)
* @param string $postKey The post key
* @param int $page Page
* @param int $limit Number to get
* @return array array( 'Title' => array( (IPS\File, \IPS\File, ... ), ... )
*/
public function get( $member, $search, $postKey, $page, $limit )
{
$where = array(
array( "record_file_id IN(?) AND record_type=? AND record_backup=0", \IPS\Db::i()->select( 'file_id', 'downloads_files', array( 'file_submitter=?', $member->member_id ) ), 'upload' ),
);
if ( $search )
{
$where[] = array( "record_realname LIKE ( CONCAT( '%', ?, '%' ) )", $search );
}
$return = array();
foreach ( \IPS\Db::i()->select( '*', 'downloads_files_records', $where, 'record_time DESC', array( ( $page - 1 ) * $limit, $limit ) ) as $row )
{
$file = \IPS\downloads\File::load( $row['record_file_id'] );
$obj = \IPS\File::get( 'downloads_Files', $row['record_location'] );
$obj->contextInfo = \IPS\Theme::i()->getTemplate( 'global', 'downloads', 'global' )->link( $file );
$obj->originalFilename = $row['record_realname'];
$return[ (string) $file->url()->setQueryString( array( 'do' => 'download', 'r' => $row['record_id'] ) ) ] = $obj;
}
return $return;
}
}
Whitespace-only changes.
@@ -0,0 +1,147 @@
<?php
/**
* @brief File Storage Extension: FileField
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 29 Aug 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File Storage Extension: FileField
*/
class _FileField
{
/**
* Count stored files
*
* @return int
*/
public function count()
{
$count = 0;
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
{
$count += \IPS\Db::i()->select( 'COUNT(*)', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) )->first();
}
return $count;
}
/**
* Move stored files
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @return void FALSE when there are no more files to move
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
{
if( !\IPS\Db::i()->select( 'COUNT(*)', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) )->first() )
{
throw new \Underflowexception;
}
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
{
$cfield = \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ), 'file_id', array( $offset, 1 ) )->first();
try
{
$file = \IPS\File::get( $oldCinfiguration ?: 'core_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->move( $storageConfiguration );
if ( (string) $file != $cfield[ 'field_' . $field['cf_id'] ] )
{
\IPS\Db::i()->update( 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ), array( 'file_id=?', $cfield['file_id'] ) );
}
}
catch( \Exception $e )
{
/* Any issues are logged */
}
}
}
/**
* Fix all URLs
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @return void
*/
public function fixUrls( $offset )
{
if( !\IPS\Db::i()->select( 'COUNT(*)', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) )->first() )
{
throw new \Underflowexception;
}
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
{
$cfield = \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ), 'file_id', array( $offset, 1 ) )->first();
if ( $new = \IPS\File::repairUrl( $cfield[ 'field_' . $field['cf_id'] ] ) )
{
\IPS\Db::i()->update( 'downloads_ccontent', array( "field_{$field['cf_id']}=?", $new ), array( 'file_id=?', $cfield['file_id'] ) );
}
}
}
/**
* Check if a file is valid
*
* @param \IPS\Http\Url $file The file to check
* @return bool
*/
public function isValidFile( $file )
{
$valid = FALSE;
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
{
try
{
\IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}=?", (string) $file ) )->first();
$valid = TRUE;
break;
}
catch( \UnderflowException $e ) {}
}
return $valid;
}
/**
* Delete all stored files
*
* @return void
*/
public function delete()
{
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields', array( 'cf_type=?', 'Upload' ) ) AS $field )
{
try
{
foreach( \IPS\Db::i()->select( '*', 'downloads_ccontent', array( "field_{$field['cf_id']}<>? OR field_{$field['cf_id']} IS NOT NULL", '' ) ) as $cfield )
{
\IPS\File::get( 'core_FileField', $cfield[ 'field_' . $field['cf_id'] ] )->delete();
}
}
catch( \Exception $e ){}
}
}
}
@@ -0,0 +1,117 @@
<?php
/**
* @brief File Storage Extension: Files
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 08 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File Storage Extension: Files
*/
class _Files
{
/**
* Count stored files
*
* @return int
*/
public function count()
{
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'upload' ) )->first();
}
/**
* Move stored files
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @return void
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'upload' ), 'record_id', array( $offset, 1 ) )->first();
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Files', $record['record_location'] )->move( $storageConfiguration );
if ( (string) $file != $record['record_location'] )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => (string) $file ), array( 'record_id=?', $record['record_id'] ) );
}
}
catch( \Exception $e )
{
/* Any issues are logged */
}
}
/**
* Fix all URLs
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @return void
*/
public function fixUrls( $offset )
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'upload' ), 'record_id', array( $offset, 1 ) )->first();
if ( $new = \IPS\File::repairUrl( $record['record_location'] ) )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => $new ), array( 'record_id=?', $record['record_id'] ) );
}
}
/**
* Check if a file is valid
*
* @param \IPS\Http\Url $file The file to check
* @return bool
*/
public function isValidFile( $file )
{
try
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_location=? AND record_type=?', (string) $file, 'upload' ) )->first();
return TRUE;
}
catch ( \UnderflowException $e )
{
return FALSE;
}
}
/**
* Delete all stored files
*
* @return void
*/
public function delete()
{
foreach( \IPS\Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='upload'" ) as $file )
{
try
{
\IPS\File::get( 'downloads_Files', $file['record_location'] )->delete();
}
catch( \Exception $e ){}
}
}
}
@@ -0,0 +1,130 @@
<?php
/**
* @brief File Storage Extension: Screenshots
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 08 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\FileStorage;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File Storage Extension: Screenshots
*/
class _Screenshots
{
/**
* Count stored files
*
* @return int
*/
public function count()
{
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files_records', array( 'record_type=?', 'ssupload' ) )->first();
}
/**
* Move stored files
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @param int $storageConfiguration New storage configuration ID
* @param int|NULL $oldConfiguration Old storage configuration ID
* @throws \Underflowexception When file record doesn't exist. Indicating there are no more files to move
* @return void
*/
public function move( $offset, $storageConfiguration, $oldConfiguration=NULL )
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'ssupload' ), 'record_id', array( $offset, 1 ) )->first();
try
{
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_location'] )->move( $storageConfiguration );
if ( (string) $file != $record['record_location'] )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => (string) $file ), array( 'record_id=?', $record['record_id'] ) );
}
$file = \IPS\File::get( $oldConfiguration ?: 'downloads_Screenshots', $record['record_thumb'] )->move( $storageConfiguration );
if ( (string) $file != $record['record_thumb'] )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_thumb' => (string) $file ), array( 'record_id=?', $record['record_id'] ) );
}
}
catch( \Exception $e )
{
/* Any issues are logged */
}
}
/**
* Fix all URLs
*
* @param int $offset This will be sent starting with 0, increasing to get all files stored by this extension
* @return void
*/
public function fixUrls( $offset )
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_type=?', 'ssupload' ), 'record_id', array( $offset, 1 ) )->first();
if ( $new = \IPS\File::repairUrl( $record['record_location'] ) )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_location' => $new ), array( 'record_id=?', $record['record_id'] ) );
}
if ( $record['record_thumb'] and $new = \IPS\File::repairUrl( $record['record_thumb'] ) )
{
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_thumb' => $new ), array( 'record_id=?', $record['record_id'] ) );
}
}
/**
* Check if a file is valid
*
* @param \IPS\Http\Url $file The file to check
* @return bool
*/
public function isValidFile( $file )
{
try
{
$record = \IPS\Db::i()->select( '*', 'downloads_files_records', array( '( record_location=? OR record_thumb=? ) AND record_type=?', (string) $file, (string) $file, 'ssupload' ) )->first();
return TRUE;
}
catch ( \UnderflowException $e )
{
return FALSE;
}
}
/**
* Delete all stored files
*
* @return void
*/
public function delete()
{
foreach( \IPS\Db::i()->select( '*', 'downloads_files_records', "record_location IS NOT NULL and record_type='ssupload'" ) as $screenshot )
{
try
{
\IPS\File::get( 'downloads_Screenshots', $screenshot['record_location'] )->delete();
}
catch( \Exception $e ){}
}
}
}
Whitespace-only changes.
@@ -0,0 +1,76 @@
<?php
/**
* @brief Front Navigation Extension: Downloads
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 8 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\FrontNavigation;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Front Navigation Extension: Downloads
*/
class _Downloads
{
/**
* Can access?
*
* @return bool
*/
public function canView()
{
return !\IPS\Application::load('downloads')->hide_tab and \IPS\Member::loggedIn()->canAccessModule( \IPS\Application\Module::get( 'downloads', 'downloads' ) );
}
/**
* Get Title
*
* @return string
*/
public function title()
{
return \IPS\Member::loggedIn()->language()->addToStack('frontnavigation_downloads');
}
/**
* Get Link
*
* @return \IPS\Http\Url
*/
public function link()
{
return \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=browse", 'front', 'downloads' );
}
/**
* Is Active?
*
* @return bool
*/
public function active()
{
return \IPS\Dispatcher::i()->application->directory === 'downloads';
}
/**
* Children
*
* @return array
*/
public function children()
{
return array();
}
}
Whitespace-only changes.
@@ -0,0 +1,123 @@
<?php
/**
* @brief Admin CP Group Form
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 19 Nov 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\GroupForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Group Form
*/
class _Downloads
{
/**
* Process Form
*
* @param \IPS\Form\Tabbed $form The form
* @param \IPS\Member\Group $group Existing Group
* @return void
*/
public function process( &$form, $group )
{
$restrictions = $group->idm_restrictions ? json_decode( $group->idm_restrictions, TRUE ) : array();
$form->addHeader( 'file_management' );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_view_downloads', $group->idm_view_downloads ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_view_approvers', $group->idm_view_approvers ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bypass_revision', $group->idm_bypass_revision ) );
$form->addHeader( 'submission_permissions' );
if ( \IPS\Application::appIsEnabled( 'nexus' ) )
{
if ( \IPS\Settings::i()->idm_nexus_on )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_add_paid', $group->idm_add_paid ) );
}
else
{
\IPS\Member::loggedIn()->language()->words['idm_add_paid_desc'] = \IPS\Member::loggedIn()->language()->addToStack( 'idm_add_paid_enable', FALSE );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_add_paid', FALSE, FALSE, array( 'disabled' => TRUE ) ) );
}
}
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bulk_submit', $group->idm_bulk_submit ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_linked_files', $group->idm_linked_files ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_import_files', $group->idm_import_files ) );
$form->addHeader( 'download_restrictions' );
if( $group->g_id != \IPS\Settings::i()->guest_group )
{
$form->add( new \IPS\Helpers\Form\Number( 'min_posts', isset( $restrictions['min_posts'] ) ? $restrictions['min_posts'] : 0, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('approved_posts_comments') ) );
}
$form->add( new \IPS\Helpers\Form\Number( 'idm_throttling', $group->idm_throttling, FALSE, array( 'unlimited' => 0, 'unlimitedLang' => 'idm_throttling_unlimited' ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('idm_throttling_suffix') ) );
$form->add( new \IPS\Helpers\Form\Number( 'idm_wait_period', $group->idm_wait_period, FALSE, array(), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('seconds') ) );
$form->add( new \IPS\Helpers\Form\Number( 'limit_sim', isset( $restrictions['limit_sim'] ) ? $restrictions['limit_sim'] : 0, FALSE, array( 'unlimited' => 0 ) ) );
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_bypass_paid', $group->idm_bypass_paid ) );
}
$form->addHeader( 'bandwidth_limits' );
$form->addMessage( 'downloads_requires_log' );
$form->add( new \IPS\Helpers\Form\Number( 'daily_bw', isset( $restrictions['daily_bw'] ) ? $restrictions['daily_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_day') ) );
$form->add( new \IPS\Helpers\Form\Number( 'weekly_bw', isset( $restrictions['weekly_bw'] ) ? $restrictions['weekly_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_week') ) );
$form->add( new \IPS\Helpers\Form\Number( 'monthly_bw', isset( $restrictions['monthly_bw'] ) ? $restrictions['monthly_bw'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('kb_per_month') ) );
$form->addHeader( 'download_limits' );
$form->addMessage( 'downloads_requires_log' );
$form->add( new \IPS\Helpers\Form\Number( 'daily_dl', isset( $restrictions['daily_dl'] ) ? $restrictions['daily_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_day') ) );
$form->add( new \IPS\Helpers\Form\Number( 'weekly_dl', isset( $restrictions['weekly_dl'] ) ? $restrictions['weekly_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_week') ) );
$form->add( new \IPS\Helpers\Form\Number( 'monthly_dl', isset( $restrictions['monthly_dl'] ) ? $restrictions['monthly_dl'] : 0, FALSE, array( 'unlimited' => 0 ), NULL, NULL, \IPS\Member::loggedIn()->language()->addToStack('downloads_per_month') ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member\Group $group The group
* @return void
*/
public function save( $values, &$group )
{
$group->idm_view_approvers = $values['idm_view_approvers'];
$group->idm_bypass_revision = $values['idm_bypass_revision'];
$group->idm_view_downloads = $values['idm_view_downloads'];
$group->idm_throttling = $values['idm_throttling'];
$group->idm_wait_period = $values['idm_wait_period'];
$group->idm_linked_files = $values['idm_linked_files'];
$group->idm_import_files = $values['idm_import_files'];
$group->idm_bulk_submit = $values['idm_bulk_submit'];
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
{
$group->idm_add_paid = $values['idm_add_paid'];
$group->idm_bypass_paid = $values['idm_bypass_paid'];
}
$restrictions = array();
foreach ( array( 'limit_sim', 'daily_bw', 'weekly_bw', 'monthly_bw', 'daily_dl', 'weekly_dl', 'monthly_dl' ) as $k )
{
$restrictions[ $k ] = $values[ $k ];
}
if( $group->g_id != \IPS\Settings::i()->guest_group )
{
$restrictions['min_posts'] = $values['min_posts'];
}
$group->idm_restrictions = json_encode( $restrictions );
}
}
Whitespace-only changes.
@@ -0,0 +1,89 @@
<?php
/**
* @brief Group Limits
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 21 Nov 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\GroupLimits;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Group Limits
*
* This extension is used to define which limit values "win" when a user has secondary groups defined
*/
class _Downloads
{
/**
* Get group limits by priority
*
* @return array
*/
public function getLimits()
{
return array (
'exclude' => array(),
'lessIsMore' => array( 'idm_throttling', 'idm_wait_period' ),
'neg1IsBest' => array(),
'zeroIsBest' => array(),
'callback' => array( 'idm_restrictions' => function( $a, $b, $k )
{
// Decode
if ( isset( $a[ $k ] ) AND $a[ $k ] )
{
$a = json_decode( $a[ $k ], TRUE );
}
else
{
if( !isset( $b[ $k ] ) )
{
return null;
}
return $b[ $k ];
}
if ( isset( $b[ $k ] ) AND $b[ $k ] )
{
$b = json_decode( $b[ $k ], TRUE );
}
else
{
if( !isset( $a[ $k ] ) )
{
return null;
}
return json_encode( $a[ $k ] );
}
$return = array();
// Lower is better
foreach ( array( 'limit_sim', 'min_posts' ) as $k )
{
$return[ $k ] = ( $a[ $k ] < $b[ $k ] ) ? $a[ $k ] : $b[ $k ];
}
// Higher is better
foreach ( array( 'daily_bw', 'weekly_bw', 'monthly_bw', 'daily_dl', 'weekly_dl', 'monthly_dl' ) as $k )
{
$return[ $k ] = ( $a[ $k ] > $b[ $k ] ) ? $a[ $k ] : $b[ $k ];
}
// Encode
return json_encode( $return );
} )
);
}
}
Whitespace-only changes.
@@ -0,0 +1,109 @@
<?php
/**
* @brief IP Address Lookup extension
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 30 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\IpAddresses;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* IP Address Lookup extension
*/
class _DownloadLog
{
/**
* Find Records by IP
*
* @param string $ip The IP Address
* @param \IPS\Http\Url $baseUrl URL table will be displayed on or NULL to return a count
* @return \IPS\Helpers\Table|int|null
*/
public function findByIp( $ip, \IPS\Http\Url $baseUrl = NULL )
{
/* Return count */
if ( $baseUrl === NULL )
{
return \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( "dip LIKE CONCAT( ?, '%' )", $ip ) )->first();
}
/* Init Table */
$table = new \IPS\Helpers\Table\Db( 'downloads_downloads', $baseUrl, array( "dip LIKE CONCAT( ?, '%' )", $ip ) );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'table' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'tables', 'core', 'admin' ), 'rows' );
$table->include = array( 'dfid', 'dtime', 'dsize', 'dua', 'dmid' );
$table->sortBy = $table->sortBy ?: 'dtime';
/* Parsers */
$table->parsers = array(
'dfid' => function( $val )
{
try
{
$file = \IPS\downloads\File::load( $val );
return "<a href='" . $file->url() . "' target='_blank'>" . htmlentities( $file->name, \IPS\HTMLENTITIES, 'UTF-8', FALSE ) . '</a>';
}
catch ( \OutOfRangeException $e )
{
return \IPS\Member::loggedIn()->language()->addToStack('content_deleted');
}
},
'dtime' => function( $val )
{
return (string) \IPS\DateTime::ts( $val );
},
'dsize' => function( $val )
{
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
},
'dua' => function( $val )
{
return (string) \IPS\Http\Useragent::parse( $val );
},
'dmid' => function( $val )
{
$member = \IPS\Member::load( $val );
return \IPS\Theme::i()->getTemplate( 'global', 'core' )->userPhoto( $member, 'tiny' ) . ' ' . $member->link();
},
);
/* Return */
return (string) $table;
}
/**
* Find IPs by Member
*
* @code
return array(
'::1' => array(
'ip' => '::1'// string (IP Address)
'count' => ... // int (number of times this member has used this IP)
'first' => ... // int (timestamp of first use)
'last' => ... // int (timestamp of most recent use)
),
...
);
* @endcode
* @param \IPS\Member $member The member
* @return array
*/
public function findByMember( $member )
{
return \IPS\Db::i()->select( "dip AS ip, COUNT(*) AS count, MIN(dtime) AS first, MAX(dtime) AS last", 'downloads_downloads', array( "dmid=?", $member->member_id ), NULL, NULL, 'dip' )->setKeyField( 'ip' );
}
}
Whitespace-only changes.
@@ -0,0 +1,77 @@
<?php
/**
* @brief ACP Live Search Extension
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 07 Feb 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\LiveSearch;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* @brief ACP Live Search Extension
*/
class _downloads
{
/**
* Check we have access
*
* @return void
*/
public function hasAccess()
{
/* Check Permissions */
return \IPS\Member::loggedIn()->hasAcpRestriction( 'downloads', 'downloads', 'categories_manage' );
}
/**
* Get the search results
*
* @param string Search Term
* @return array Array of results
*/
public function getResults( $searchTerm )
{
if( !$this->hasAccess() )
{
return array();
}
/* Init */
$results = array();
$searchTerm = mb_strtolower( $searchTerm );
/* Perform the search */
$categories = \IPS\Db::i()->select(
"*",
'downloads_categories',
array( "word_custom LIKE CONCAT( '%', ?, '%' ) AND lang_id=?", $searchTerm, \IPS\Member::loggedIn()->language()->id ),
NULL,
NULL
)->join(
'core_sys_lang_words',
"word_key=CONCAT( 'downloads_category_', cid )"
);
/* Format results */
foreach ( $categories as $category )
{
$category = \IPS\downloads\Category::constructFromData( $category );
$results[] = \IPS\Theme::i()->getTemplate( 'livesearch', 'downloads', 'admin' )->category( $category );
}
return $results;
}
}
Whitespace-only changes.
@@ -0,0 +1,51 @@
<?php
/**
* @brief Admin CP Member Form
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 13 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\MemberForm;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Admin CP Member Form
*/
class _Downloads
{
/**
* Process Form
*
* @param \IPS\Form\Tabbed $form The form
* @param \IPS\Member $member Existing Member
* @return void
*/
public function process( &$form, $member )
{
$form->addMessage( "<a href='" . \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=member&do=downloads&id=' . $member->member_id ) . "'>" . \IPS\Member::loggedIn()->language()->addToStack('downloads_stats') . '</a>', '', FALSE );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_block_submissions', !$member->idm_block_submissions ) );
}
/**
* Save
*
* @param array $values Values from form
* @param \IPS\Member $member The member
* @return void
*/
public function save( $values, &$member )
{
$member->idm_block_submissions = !$values['idm_block_submissions'];
}
}
Whitespace-only changes.
@@ -0,0 +1,53 @@
<?php
/**
* @brief Member Sync
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 26 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\MemberSync;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Sync
*/
class _Downloads
{
/**
* Member is merged with another member
*
* @param \IPS\Member $member Member being kept
* @param \IPS\Member $member2 Member being removed
* @return void
*/
public function onMerge( $member, $member2 )
{
\IPS\Db::i()->update( 'downloads_downloads', array( 'dmid' => $member->member_id ), array( 'dmid=?', $member2->member_id ) );
\IPS\Db::i()->update( 'downloads_files', array( 'file_approver' => $member->member_id ), array( 'file_approver=?', $member2->member_id ) );
\IPS\Db::i()->delete( 'downloads_sessions', array( 'dsess_mid=?', $member2->member_id ) );
}
/**
* Member is deleted
*
* @param $member \IPS\Member The member
* @return void
*/
public function onDelete( $member )
{
\IPS\Db::i()->delete( 'downloads_downloads', array( 'dmid=?', $member->member_id ) );
\IPS\Db::i()->delete( 'downloads_sessions', array( 'dsess_mid=?', $member->member_id ) );
\IPS\Db::i()->update( 'downloads_files', array( 'file_approver' => 0 ), array( 'file_approver=?', $member->member_id ) );
}
}
Whitespace-only changes.
@@ -0,0 +1,72 @@
<?php
/**
* @brief Notification Options
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 11 Dec 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\Notifications;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Notification Options
*/
class _Files
{
/**
* Get configuration
*
* @param \IPS\Member $member The member
* @return array
*/
public function getConfiguration( $member )
{
return array(
'new_file_version' => array( 'default' => array( 'email' ), 'disabled' => array() ),
);
}
/**
* Parse notification: new_content
*
* @param \IPS\Notification\Inline $notification The notification
* @return array
* @code
return array(
'title' => "Mark has replied to A Topic", // The notification title
'url' => new \IPS\Http\Url( ... ), // The URL the notification should link to
'content' => "Lorem ipsum dolar sit", // [Optional] Any appropriate content. Do not format this like an email where the text
// explains what the notification is about - just include any appropriate content.
// For example, if the notification is about a post, set this as the body of the post.
'author' => \IPS\Member::load( 1 ), // [Optional] The user whose photo should be displayed for this notification
);
* @endcode
*/
public function parse_new_file_version( $notification )
{
$item = $notification->item;
if ( !$item )
{
throw new \OutOfRangeException;
}
return array(
'title' => \IPS\Member::loggedIn()->language()->addToStack( 'notification__new_file_version', FALSE, array( 'sprintf' => array( $item->author()->name, $item->mapped('title') ) ) ),
'url' => $notification->item->url(),
'content' => $notification->item->content(),
'author' => $notification->extra ?: $notification->item->author(),
'unread' => (bool) ( $item->unread() )
);
}
}
Whitespace-only changes.
@@ -0,0 +1,52 @@
<?php
/**
* @brief Permissions
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 16 Apr 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\Permissions;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Permissions
*/
class _Permissions
{
/**
* Get node classes
*
* @return array
*/
public function getNodeClasses()
{
return array(
'IPS\downloads\Category' => function( $current, $group )
{
$rows = array();
foreach( \IPS\downloads\Category::roots( NULL ) AS $root )
{
try
{
\IPS\downloads\Category::populatePermissionMatrix( $rows, $root, $group, $current );
}
catch( \BadMethodCallException $e ) {}
}
return $rows;
}
);
}
}
Whitespace-only changes.
@@ -0,0 +1,68 @@
<?php
/**
* @brief Background Task
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage
* @since 23 Sep 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\core\Queue;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Background Task
*/
class _Follow
{
/**
* Run Background Task
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return int|null New offset or NULL if complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function run( $data, $offset )
{
$category = \IPS\downloads\Category::load( $data['category_id'] );
$member = \IPS\Member::load( $data['member_id'] );
return \IPS\downloads\File::_sendNotificationsBatch( $category, $member, $offset );
}
/**
* Get Progress
*
* @param mixed $data Data as it was passed to \IPS\Task::queue()
* @param int $offset Offset
* @return array( 'text' => 'Doing something...', 'complete' => 50 ) Text explaning task and percentage complete
* @throws \OutOfRangeException Indicates offset doesn't exist and thus task is complete
*/
public function getProgress( $data, $offset )
{
$numberOfFollowers = \IPS\downloads\File::_notificationRecipients()->count( TRUE );
if ( $numberofFollowers )
{
$complete = round( 100 / $numberOfFollowers * $offset, 2 );
}
else
{
$complete = 100;
}
$category = \IPS\downloads\Category::load( $data['category_id'] );
$title = $category->_title;
return array( 'text' => \IPS\Member::loggedIn()->language()->addToStack('backgroundQueue_follow', FALSE, array( 'sprintf' => array( "<a href='{$category->url()}' target='_blank'>{$title}</a>" ) ) ), 'complete' => $complete );
}
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,143 @@
<?php
/**
* @brief File
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Nexus
* @since 05 Aug 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\extensions\nexus\Item;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* File
*/
class _File extends \IPS\nexus\Invoice\Item\Purchase
{
/**
* @brief Application
*/
public static $application = 'downloads';
/**
* @brief Application
*/
public static $type = 'file';
/**
* @brief Icon
*/
public static $icon = 'download';
/**
* @brief Title
*/
public static $title = 'file';
/**
* Image
*
* @return |IPS\File|NULL
*/
public function image()
{
try
{
return \IPS\downloads\File::load( $this->id )->primary_screenshot;
}
catch ( \Exception $e )
{
return NULL;
}
}
/**
* Image
*
* @param \IPS\nexus\Purchase $purchase The purchase
* @return |IPS\File|NULL
*/
public static function purchaseImage( \IPS\nexus\Purchase $purchase )
{
try
{
return \IPS\downloads\File::load( $purchase->item_id )->primary_screenshot;
}
catch ( \Exception $e )
{
return NULL;
}
}
/**
* Get Client Area Page HTML
*
* @return array( 'packageInfo' => '...', 'purchaseInfo' => '...' )
*/
public static function clientAreaPage( \IPS\nexus\Purchase $purchase )
{
try
{
$file = \IPS\downloads\File::load( $purchase->item_id );
return array( 'packageInfo' => \IPS\Theme::i()->getTemplate( 'nexus', 'downloads' )->fileInfo( $file ), 'purchaseInfo' => \IPS\Theme::i()->getTemplate( 'nexus', 'downloads' )->filePurchaseInfo( $file ) );
}
catch ( \OutOfRangeException $e ) { }
return NULL;
}
/**
* Get ACP Page HTML
*
* @return string
*/
public static function acpPage( \IPS\nexus\Purchase $purchase )
{
try
{
$file = \IPS\downloads\File::load( $purchase->item_id );
return \IPS\Theme::i()->getTemplate( 'nexus', 'downloads' )->fileInfo( $file );
}
catch ( \OutOfRangeException $e ) { }
return NULL;
}
/**
* URL
*
* @return |IPS\Http\Url|NULL
*/
public function url()
{
try
{
return \IPS\downloads\File::load( $this->id )->url();
}
catch ( \OutOfRangeException $e )
{
return NULL;
}
}
/**
* ACP URL
*
* @return |IPS\Http\Url|NULL
*/
public function acpUrl()
{
return $this->url();
}
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
View File
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,39 @@
<?php
/**
* @brief Downloads screenshot handler
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 4 Dec 2014
* @version SVN_VERSION_NUMBER
*/
require_once str_replace( 'applications/downloads/interface/legacy/screenshot.php', '', str_replace( '\\', '/', __FILE__ ) ) . 'init.php';
\IPS\Session\Front::i();
try
{
/* Get file and data */
$config = \IPS\File::getClass( 'downloads_Screenshots' );
$file = \IPS\File::get( 'downloads_Screenshots', ltrim( \IPS\Request::i()->path, '/' ) );
$headers = array_merge( \IPS\Output::getCacheHeaders( time(), 360 ), array( "Content-Disposition" => \IPS\Output::getContentDisposition( 'inline', $file->originalFilename ), "X-Content-Type-Options" => "nosniff" ) );
/* Send headers and print file */
\IPS\Output::i()->sendStatusCodeHeader( 200 );
\IPS\Output::i()->sendHeader( "Content-type: " . \IPS\File::getMimeType( $file->originalFilename ) . ";charset=UTF-8" );
foreach( $headers as $key => $header )
{
\IPS\Output::i()->sendHeader( $key . ': ' . $header );
}
\IPS\Output::i()->sendHeader( "Content-Length: " . $file->filesize() );
$file->printFile();
exit;
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->sendOutput( '', 404 );
}
@@ -0,0 +1,80 @@
<?php
/**
* @brief Categories
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 27 Sep 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Categories
*/
class _categories extends \IPS\Node\Controller
{
/**
* Node Class
*/
protected $nodeClass = 'IPS\downloads\Category';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_manage' );
parent::execute();
}
/**
* Recalculate Downloads
*
* @return void
*/
protected function recountDownloads()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'categories_recount_downloads' );
try
{
$category = \IPS\downloads\Category::load( \IPS\Request::i()->id );
\IPS\Db::i()->update( 'downloads_files', array( 'file_downloads' => \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( 'dfid=file_id' ) ) ), array( 'file_cat=?', $category->id ) );
\IPS\Session::i()->log( 'acplogs__downloads_recount_downloads', array( $category->_title => FALSE ) );
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( "app=downloads&module=downloads&controller=categories&do=form&id=" . \IPS\Request::i()->id ), 'clog_recount_done' );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2D180/1', 404, '' );
}
}
protected function form()
{
parent::form();
if ( \IPS\Request::i()->id )
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('edit_category') . ': ' . \IPS\Output::i()->title;
}
else
{
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('add_category');
}
}
}
@@ -0,0 +1,42 @@
<?php
/**
* @brief fields
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 03 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* fields
*/
class _fields extends \IPS\Node\Controller
{
/**
* Node Class
*/
protected $nodeClass = 'IPS\downloads\Field';
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'fields_manage' );
parent::execute();
}
}
Whitespace-only changes.
@@ -0,0 +1,145 @@
<?php
/**
* @brief Settings
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 09 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Settings
*/
class _settings extends \IPS\Dispatcher\Controller
{
/**
* Manage Settings
*
* @return void
*/
protected function manage()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'settings_manage' );
$form = new \IPS\Helpers\Form;
$form->addTab('basic_settings');
$form->add( new \IPS\Helpers\Form\Upload( 'idm_watermarkpath', \IPS\Settings::i()->idm_watermarkpath ? \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath ) : NULL, FALSE, array( 'image' => TRUE, 'storageExtension' => 'core_Theme' ) ) );
$form->add( new \IPS\Helpers\Form\Stack( 'idm_link_blacklist', explode( ',', \IPS\Settings::i()->idm_link_blacklist ), FALSE, array( 'placeholder' => 'example.com' ) ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_antileech', \IPS\Settings::i()->idm_antileech ) );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_rss', \IPS\Settings::i()->idm_rss ) );
if ( \IPS\Application::appIsEnabled( 'nexus' ) )
{
$form->addTab( 'paid_file_settings' );
$form->add( new \IPS\Helpers\Form\YesNo( 'idm_nexus_on', \IPS\Settings::i()->idm_nexus_on, FALSE, array( 'togglesOn' => array( 'idm_nexus_tax', 'idm_nexus_percent', 'idm_nexus_transfee' ) ) ) );
$form->add( new \IPS\Helpers\Form\Node( 'idm_nexus_tax', \IPS\Settings::i()->idm_nexus_tax, FALSE, array( 'class' => '\IPS\nexus\Tax', 'zeroVal' => 'do_not_tax' ), NULL, NULL, NULL, 'idm_nexus_tax' ) );
$form->add( new \IPS\Helpers\Form\Number( 'idm_nexus_percent', \IPS\Settings::i()->idm_nexus_percent, FALSE, array( 'min' => 0, 'max' => 100 ), NULL, NULL, '%', 'idm_nexus_percent' ) );
$form->add( new \IPS\nexus\Form\Money( 'idm_nexus_transfee', json_decode( \IPS\Settings::i()->idm_nexus_transfee, TRUE ), FALSE, array(), NULL, NULL, NULL, 'idm_nexus_transfee' ) );
$form->add( new \IPS\Helpers\Form\Node( 'idm_nexus_gateways', explode( ',', \IPS\Settings::i()->idm_nexus_gateways ), FALSE, array( 'class' => '\IPS\nexus\Gateway', 'zeroVal' => 'no_restriction', 'multiple' => TRUE ), NULL, NULL, NULL, 'idm_nexus_gateways' ) );
$form->add( new \IPS\Helpers\Form\CheckboxSet( 'idm_nexus_display', explode( ',', \IPS\Settings::i()->idm_nexus_display ), FALSE, array( 'options' => array( 'purchases' => 'idm_purchases', 'downloads' => 'downloads' ) ) ) );
}
if ( $values = $form->values( TRUE ) )
{
$form->saveAsSettings( $values );
/* Clear guest page caches */
\IPS\Data\Cache::i()->clearAll();
\IPS\Session::i()->log( 'acplogs__downloads_settings' );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('settings');
\IPS\Output::i()->output = $form;
}
/**
* Rebuild Watermarks
*
* @return void
*/
protected function rebuildWatermarks()
{
$perGo = 1;
$watermark = \IPS\Settings::i()->idm_watermarkpath ? \IPS\Image::create( \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() ) : NULL;
\IPS\Output::i()->output = new \IPS\Helpers\MultipleRedirect( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=settings&do=rebuildWatermarks' ), function( $doneSoFar ) use( $watermark, $perGo )
{
$where = array( array( 'record_type=?', 'ssupload' ) );
if ( !$watermark )
{
$where[] = array( 'record_no_watermark<>?', '' );
}
$select = \IPS\Db::i()->select( '*', 'downloads_files_records', $where, 'record_id', array( $doneSoFar, $perGo ), NULL, NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS );
if ( !$select->count() )
{
return NULL;
}
foreach ( $select as $row )
{
try
{
if ( $row['record_no_watermark'] )
{
$original = \IPS\File::get( 'downloads_Screenshots', $row['record_no_watermark'] );
try
{
\IPS\File::get( 'downloads_Screenshots', $row['record_location'] )->delete();
}
catch ( \Exception $e ) { }
if ( !$watermark )
{
\IPS\Db::i()->update( 'downloads_files_records', array(
'record_location' => (string) $original,
'record_thumb' => (string) $original->thumbnail( 'downloads_Screenshots' ),
'record_no_watermark' => NULL
), array( 'record_id=?', $row['record_id'] ) );
continue;
}
}
else
{
$original = \IPS\File::get( 'downloads_Screenshots', $row['record_location'] );
}
$image = \IPS\Image::create( $original->contents() );
$image->watermark( $watermark );
$newFile = \IPS\File::create( 'downloads_Screenshots', $original->originalFilename, $image );
\IPS\Db::i()->update( 'downloads_files_records', array(
'record_location' => (string) $newFile,
'record_thumb' => (string) $newFile->thumbnail( 'downloads_Screenshots' ),
'record_no_watermark' => (string) $original
), array( 'record_id=?', $row['record_id'] ) );
}
catch ( \Exception $e ) {}
}
$doneSoFar += $perGo;
return array( $doneSoFar, \IPS\Member::loggedIn()->language()->addToStack('rebuilding'), 100 / $select->count( TRUE ) * $doneSoFar );
}, function()
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=settings' ), 'completed' );
} );
}
}
Whitespace-only changes.
@@ -0,0 +1,102 @@
<?php
/**
* @brief Top Downloaders
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 17 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Top Downloaders
*/
class _downloaders extends \IPS\Dispatcher\Controller
{
const PER_PAGE = 25;
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'downloaders_manage' );
parent::execute();
}
/**
* Top Downloaders
*
* @return void
*/
protected function manage()
{
$values = NULL;
$where = array( array( 'dmid>0' ) );
if ( isset( \IPS\Request::i()->form ) )
{
$form = new \IPS\Helpers\Form( 'form', 'go' );
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range' ) );
if ( $values = $form->values() )
{
if ( $values['stats_date_range']['start'] )
{
$where[] = array( 'dtime>?', $values['stats_date_range']['start']->getTimestamp() );
}
if ( $values['stats_date_range']['end'] )
{
$where[] = array( 'dtime<?', $values['stats_date_range']['end']->getTimestamp() );
}
}
else
{
\IPS\Output::i()->output = $form;
return;
}
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$select = \IPS\Db::i()->select( 'dmid, COUNT(*) as downloads, core_members.*', 'downloads_downloads', $where, 'downloads DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'dmid', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )->join( 'core_members', 'core_members.member_id=downloads_downloads.dmid' );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders' )->setQueryString( $values ),
ceil( $select->count( TRUE ) / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=downloaders&form=1' )->setQueryString( $values ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('stats')->downloadsTable( $select, $pagination );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_downloaders');
}
}
@@ -0,0 +1,98 @@
<?php
/**
* @brief Downloads Statistics
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 16 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* downloads
*/
class _downloads extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'downloads_manage' );
parent::execute();
}
/**
* Downloads Statistics
*
* @return void
*/
protected function manage()
{
$chart = new \IPS\Helpers\Chart\Dynamic( \IPS\Http\Url::internal( "app=downloads&module=stats&controller=downloads" ), 'downloads_downloads', 'dtime', '', array(), 'ColumnChart', 'monthly', array( 'start' => 0, 'end' => 0 ), array( 'dmid', 'dfid', 'dtime', 'dsize', 'dua', 'dip' ) );
$chart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
$chart->availableTypes = array( 'LineChart', 'ColumnChart', 'BarChart' );
$chart->tableParsers = array(
'dmid' => function( $val )
{
try
{
$member = \IPS\Member::load( $val );
return "<a href='" . \IPS\Http\Url::internal( "app=downloads&module=stats&controller=member&do=downloads&id={$member->member_id}" ) . "'>{$member->name}</a>";
}
catch ( \OutOfRangeException $e )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_member');
}
},
'dfid' => function( $val )
{
try
{
$file = \IPS\downloads\File::load( $val );
return "<a href='{$file->url()}' target='_blank'>{$file->name}</a>";
}
catch ( \OutOfRangeException $e )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_file');
}
},
'dtime' => function( $val )
{
return (string) \IPS\DateTime::ts( $val );
},
'dsize' => function( $val )
{
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
},
'dua' => function( $val )
{
return (string) \IPS\Http\Useragent::parse( $val );
},
'dip' => function( $val )
{
$url = \IPS\Http\Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" );
return "<a href='{$url}'>{$val}</a>";
}
);
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('downloads_stats');
\IPS\Output::i()->output = (string) $chart;
}
}
Whitespace-only changes.
@@ -0,0 +1,146 @@
<?php
/**
* @brief Member Stats
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 13 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Member Stats
*/
class _member extends \IPS\Dispatcher\Controller
{
/**
* Downloads
*
* @return void
*/
protected function downloads()
{
/* Get member */
try
{
$member = \IPS\Member::load( \IPS\Request::i()->id );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2D170/1', 404, '' );
}
/* Build chart */
$tabs = array( 'information' => 'information', 'downloads' => 'downloads', 'bandwidth_use' => 'bandwidth_use' );
$activeTab = \IPS\Request::i()->tab ?: 'information';
switch ( $activeTab )
{
case 'information':
$fileCount = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files', array( 'file_submitter=?', $member->member_id ) )->first();
$diskspaceUsed = \IPS\Db::i()->select( 'SUM(file_size)', 'downloads_files', array( 'file_submitter=?', $member->member_id ) )->first();
$numberOfDownloads = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_downloads', array( 'dmid=?', $member->member_id ) )->first();
$bandwidthUsed = \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads', array( 'dmid=?', $member->member_id ) )->first();
$allFiles = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files' )->first();
$totalFileSize = \IPS\Db::i()->select( 'SUM(file_size)', 'downloads_files' )->first();
$totalDownloadSize = \IPS\Db::i()->select( 'SUM(dsize)', 'downloads_downloads' )->first();
$activeTabContents = \IPS\Theme::i()->getTemplate( 'stats' )->information( \IPS\Theme::i()->getTemplate( 'global', 'core' )->definitionTable( array(
'files_submitted' =>
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $fileCount ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allFiles ? ( 100 / $allFiles ) : 0 ) * $fileCount ), 2 ) ) )
),
'diskspace_used' =>
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $diskspaceUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalFileSize ? ( 100 / $totalFileSize ) : 0 ) * $diskspaceUsed ), 2 ) ) )
),
'average_filesize_downloads' =>
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_average', FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(file_size)', 'downloads_files', array( 'file_submitter=?', $member->member_id ) )->first() ),
\IPS\Output\Plugin\Filesize::humanReadableFilesize( \IPS\Db::i()->select( 'AVG(file_size)', 'downloads_files' )->first() ) ))
),
'number_of_downloads' =>
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Member::loggedIn()->language()->formatNumber( $numberOfDownloads ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $allFiles ? ( 100 / $allFiles ) : 0 ) * $fileCount ), 2 ) ) )
),
'downloads_bandwidth_used' =>
\IPS\Member::loggedIn()->language()->addToStack('downloads_stat_of_total', FALSE, array( 'sprintf' => array(
\IPS\Output\Plugin\Filesize::humanReadableFilesize( $bandwidthUsed ),
\IPS\Member::loggedIn()->language()->formatNumber( ( ( $totalDownloadSize ? ( 100 / $totalDownloadSize ) : 0 ) * $bandwidthUsed ), 2 ) ) )
)
) ) );
break;
case 'downloads':
$downloadsChart = new \IPS\Helpers\Chart\Dynamic( \IPS\Http\Url::internal( "app=downloads&module=stats&controller=member&do=downloads&id={$member->member_id}&tab=downloads&_graph=1" ), 'downloads_downloads', 'dtime', '', array(), 'ColumnChart', 'monthly', array( 'start' => 0, 'end' => 0 ), array( 'dfid', 'dtime', 'dsize', 'dua', 'dip' ) );
$downloadsChart->where[] = array( 'dmid=?', $member->member_id );
$downloadsChart->tableParsers = array(
'dfid' => function( $val )
{
try
{
$file = \IPS\downloads\File::load( $val );
return "<a href='{$file->url()}' target='_blank'>{$file->name}</a>";
}
catch ( \OutOfRangeException $e )
{
return \IPS\Member::loggedIn()->language()->addToStack('deleted_file');
}
},
'dtime' => function( $val )
{
return (string) \IPS\DateTime::ts( $val );
},
'dsize' => function( $val )
{
return \IPS\Output\Plugin\Filesize::humanReadableFilesize( $val );
},
'dua' => function( $val )
{
return (string) \IPS\Http\Useragent::parse( $val );
},
'dip' => function( $val )
{
$url = \IPS\http\Url::internal( "app=core&module=members&controller=ip&ip={$val}&tab=downloads_DownloadLog" );
return "<a href='{$url}'>{$val}</a>";
}
);
$downloadsChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('downloads'), 'number', 'COUNT(*)', FALSE );
$activeTabContents = ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $downloadsChart : \IPS\Theme::i()->getTemplate( 'stats' )->graphs( (string) $downloadsChart );
break;
case 'bandwidth_use':
$bandwidthChart = new \IPS\Helpers\Chart\Dynamic( \IPS\Http\Url::internal( "app=downloads&module=stats&controller=member&do=downloads&id={$member->member_id}&tab=bandwidth_use&_graph=1" ), 'downloads_downloads', 'dtime', '', array( 'vAxis' => array( 'title' => '(kB)' ) ) );
$bandwidthChart->where[] = array( 'dmid=?', $member->member_id );
$bandwidthChart->addSeries( \IPS\Member::loggedIn()->language()->addToStack('bandwidth_use'), 'number', 'ROUND((SUM(dsize)/1024),2)', FALSE );
$activeTabContents = ( \IPS\Request::i()->isAjax() and isset( \IPS\Request::i()->_graph ) ) ? (string) $bandwidthChart : \IPS\Theme::i()->getTemplate( 'stats' )->graphs( (string) $bandwidthChart );
break;
}
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('member_downloads_chart', FALSE, array( 'sprintf' => array( $member->name ) ) );
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->output = $activeTabContents;
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $activeTab, $activeTabContents, \IPS\Http\Url::internal( "app=downloads&module=stats&controller=member&do=downloads&id={$member->member_id}" ) );
}
}
}
@@ -0,0 +1,102 @@
<?php
/**
* @brief Top Submitters
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 17 Dec 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\admin\stats;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Top Submitters
*/
class _submitters extends \IPS\Dispatcher\Controller
{
const PER_PAGE = 25;
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Dispatcher::i()->checkAcpPermission( 'submitters_manage' );
parent::execute();
}
/**
* Top Submitters
*
* @return void
*/
protected function manage()
{
$values = NULL;
$where = array();
if ( isset( \IPS\Request::i()->form ) )
{
$form = new \IPS\Helpers\Form( 'form', 'go' );
$form->add( new \IPS\Helpers\Form\DateRange( 'stats_date_range' ) );
if ( $values = $form->values() )
{
if ( $values['stats_date_range']['start'] )
{
$where[] = array( 'file_submitted>?', $values['stats_date_range']['start']->getTimestamp() );
}
if ( $values['stats_date_range']['end'] )
{
$where[] = array( 'file_submitted<?', $values['stats_date_range']['end']->getTimestamp() );
}
}
else
{
\IPS\Output::i()->output = $form;
return;
}
}
$page = isset( \IPS\Request::i()->page ) ? intval( \IPS\Request::i()->page ) : 1;
if( $page < 1 )
{
$page = 1;
}
$select = \IPS\Db::i()->select( 'file_submitter, COUNT(*) as files, core_members.*', 'downloads_files', $where, 'files DESC', array( ( $page - 1 ) * static::PER_PAGE, static::PER_PAGE ), 'file_submitter', NULL, \IPS\Db::SELECT_SQL_CALC_FOUND_ROWS )->join( 'core_members', 'core_members.member_id=downloads_files.file_submitter' );
$pagination = \IPS\Theme::i()->getTemplate( 'global', 'core', 'global' )->pagination(
\IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters' )->setQueryString( $values ),
ceil( $select->count( TRUE ) / static::PER_PAGE ),
$page,
static::PER_PAGE,
FALSE
);
\IPS\Output::i()->sidebar['actions'] = array(
'settings' => array(
'title' => 'stats_date_range',
'icon' => 'calendar',
'link' => \IPS\Http\Url::internal( 'app=downloads&module=stats&controller=submitters&form=1' )->setQueryString( $values ),
'data' => array( 'ipsDialog' => '', 'ipsDialog-title' => \IPS\Member::loggedIn()->language()->addToStack('stats_date_range') )
)
);
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('stats')->submittersTable( $select, $pagination );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('menu__downloads_stats_submitters');
}
}
@@ -0,0 +1,163 @@
<?php
/**
* @brief Browse Files Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 08 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Browse Files
*/
class _browse extends \IPS\Dispatcher\Controller
{
/**
* Route
*
* @return void
*/
protected function manage()
{
if ( isset( \IPS\Request::i()->currency ) and in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) and isset( \IPS\Request::i()->csrfKey ) and \IPS\Request::i()->csrfKey === \IPS\Session\Front::i()->csrfKey )
{
$_SESSION['currency'] = \IPS\Request::i()->currency;
}
if ( isset( \IPS\Request::i()->id ) )
{
try
{
$this->_category( \IPS\downloads\Category::loadAndCheckPerms( \IPS\Request::i()->id, 'read' ) );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2D175/1', 404, '' );
}
}
else
{
$this->_index();
}
}
/**
* Show Index
*
* @return void
*/
protected function _index()
{
/* Add RSS feed */
if ( \IPS\Settings::i()->idm_rss )
{
\IPS\Output::i()->rssFeeds['idm_rss_title'] = \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse&do=rss', 'front', 'downloads_rss' );
}
/* Get stuff */
$featured = iterator_to_array( \IPS\downloads\File::featured( 4, '_rand' ) );
$new = \IPS\downloads\File::getItemsWithPermission( array(), NULL, 14 );
$highestRated = \IPS\downloads\File::getItemsWithPermission( array( array( 'file_rating > ?', 0 ) ), 'file_rating DESC', 14 );
$mostDownloaded = \IPS\downloads\File::getItemsWithPermission( array( array( 'file_downloads > ?', 0 ) ), 'file_downloads DESC', 14 );
/* Online User Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=downloads', 'front', 'downloads' ), array(), 'loc_downloads_browsing' );
/* Display */
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'browse' )->indexSidebar( \IPS\downloads\Category::canOnAny('add') );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('downloads');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->index( $featured, $new, $highestRated, $mostDownloaded );
}
/**
* Show Category
*
* @param \IPS\downloads\Category $category The category to show
* @return void
*/
protected function _category( $category )
{
$_count = \IPS\downloads\File::getItemsWithPermission( array( array( \IPS\downloads\File::$databasePrefix . \IPS\downloads\File::$databaseColumnMap['container'] . '=?', $category->_id ) ), NULL, 1, 'read', NULL, 0, NULL, FALSE, FALSE, FALSE, TRUE );
if( !$_count['cnt'] )
{
/* Show a 'no files' template if there's nothing to display */
$table = \IPS\Theme::i()->getTemplate( 'browse' )->noFiles( $category );
}
else
{
/* Build table */
$table = new \IPS\Helpers\Table\Content( 'IPS\downloads\File', $category->url(), NULL, $category );
$table->classes = array( 'ipsDataList_large' );
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on )
{
$table->filters = array(
'file_free' => "( ( file_cost='' OR file_cost IS NULL ) AND ( file_nexus='' OR file_nexus IS NULL ) )",
'file_paid' => "( file_cost<>'' OR file_nexus>0 )",
);
}
$table->title = \IPS\Member::loggedIn()->language()->pluralize( \IPS\Member::loggedIn()->language()->get('download_file_count'), array( $_count['cnt'] ) );
}
/* Online User Location */
$permissions = $category->permissions();
\IPS\Session::i()->setLocation( $category->url(), explode( ",", $permissions['perm_view'] ), 'loc_downloads_viewing_category', array( "downloads_category_{$category->id}" => TRUE ) );
/* Output */
\IPS\Output::i()->title = $category->_title;
\IPS\Output::i()->contextualSearchOptions[ \IPS\Member::loggedIn()->language()->addToStack( 'search_contextual_item', FALSE, array( 'sprintf' => array( \IPS\Member::loggedIn()->language()->addToStack( 'category' ) ) ) ) ] = array( 'type' => 'downloads_file', 'nodes' => $category->_id );
\IPS\Output::i()->sidebar['contextual'] = \IPS\Theme::i()->getTemplate( 'browse' )->indexSidebar( \IPS\downloads\Category::canOnAny('add'), $category );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->category( $category, (string) $table );
}
/**
* Show a category listing
*
* @return void
*/
protected function categories()
{
/* Online User Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse&do=categories', 'front', 'downloads_categories' ), array(), 'loc_downloads_browsing_categories' );
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack('__app_downloads');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'browse' )->categories();
}
/**
* Latest Files RSS
*
* @return void
*/
protected function rss()
{
if( !\IPS\Settings::i()->idm_rss )
{
\IPS\Output::i()->error( 'rss_offline', '2D175/2', 403, 'rss_offline_admin' );
}
$document = \IPS\Xml\Rss::newDocument( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=browse', 'front', 'downloads' ), \IPS\Member::loggedIn()->language()->get('idm_rss_title'), \IPS\Member::loggedIn()->language()->get('idm_rss_title') );
foreach ( \IPS\downloads\File::getItemsWithPermission() as $file )
{
$document->addItem( $file->name, $file->url(), $file->desc, \IPS\DateTime::ts( $file->updated ), $file->id );
}
/* @note application/rss+xml is not a registered IANA mime-type so we need to stick with text/xml for RSS */
\IPS\Output::i()->sendOutput( $document->asXML(), 200, 'text/xml' );
}
}
Whitespace-only changes.
@@ -0,0 +1,572 @@
<?php
/**
* @brief Submit File Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 08 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* Submit File Controller
*/
class _submit extends \IPS\Dispatcher\Controller
{
/**
* Execute
*
* @return void
*/
public function execute()
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_submit.js', 'downloads', 'front' ) );
\IPS\downloads\File::canCreate( \IPS\Member::loggedIn(), NULL, TRUE );
\IPS\Output::i()->sidebar['enabled'] = FALSE;
parent::execute();
}
/**
* Choose category
*
* @return void
*/
protected function manage()
{
$form = new \IPS\Helpers\Form( 'select_category', 'continue' );
$form->class = 'ipsForm_vertical ipsForm_noLabels';
$form->add( new \IPS\Helpers\Form\Node( 'category', isset( $data['category'] ) ? $data['category'] : NULL, TRUE, array(
'url' => \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit', 'front', 'downloads_submit' ),
'class' => 'IPS\downloads\Category',
'permissionCheck' => 'add',
) ) );
if ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'bulk', NULL, FALSE, array( 'label' => "bulk_upload_button" ) ) );
}
if ( $values = $form->values() )
{
$url = \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit&do=submit', 'front', 'downloads_submit' )->setQueryString( 'category', $values['category']->_id );
if ( isset( $values['bulk'] ) AND $values['bulk'] )
{
$url = $url->setQueryString( 'bulk', '1' );
}
if( isset( \IPS\Request::i()->_new ) )
{
$url = $url->setQueryString(array( '_new' => '1' ) );
}
\IPS\Output::i()->redirect( $url );
}
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( 'select_category' );
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->categorySelector( $form );
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'select_category' ) );
}
/**
* Submit files
*
* @return void
*/
protected function submit()
{
$steps = array();
/**
* Step 1: Upload files
*/
$steps['upload_files'] = function( $data )
{
/* Get category data */
try
{
$category = \IPS\downloads\Category::loadAndCheckPerms( \IPS\Request::i()->category );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit&_step=select_category', 'front', 'downloads_submit' ) );
}
if( !$category->can('add') )
{
\IPS\Output::i()->error( 'add_files_no_perm', '3D286/1', 403, '' );
}
$form = new \IPS\Helpers\Form( 'upload_files', 'continue' );
$form->class = 'ipsForm_vertical';
$form->hiddenValues['category'] = $category->_id;
$form->hiddenValues['postKey'] = ( \IPS\Request::i()->postKey ) ? \IPS\Request::i()->postKey : md5( uniqid() );
/* Populate any existing records */
$files = array();
$screenshots = array();
if ( isset( $data['files'] ) )
{
foreach ( $data['files'] as $url )
{
$files[] = \IPS\File::get( 'downloads_Files', $url );
}
}
if ( isset( $data['screenshots'] ) )
{
foreach ( $data['screenshots'] as $url )
{
$screenshots[] = \IPS\File::get( 'downloads_Screenshots', $url );
}
}
/* Add the fields */
$form->add( new \IPS\Helpers\Form\Upload( 'files', $files, ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => $category->maxfile !== NULL ? ( $category->maxfile / 1024 ) : NULL, 'multiple' => TRUE, 'minimize' => FALSE ) ) );
if ( !isset( \IPS\Request::i()->bulk ) )
{
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'url_files', isset( $data['url_files'] ) ? $data['url_files'] : array(), FALSE, array( 'stackFieldType' => 'Url' ), array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
if ( \IPS\Member::loggedIn()->group['idm_import_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'import_files', array(), FALSE, array( 'placeholder' => \IPS\ROOT_PATH ), function( $val )
{
if( $val and is_array( $val ) )
{
foreach ( $val as $file )
{
if ( is_dir( $file ) )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('err_import_files_dir', FALSE, array( 'sprintf' => array( $file ) ) ) );
}
elseif ( !is_file( $file ) )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('err_import_files', FALSE, array( 'sprintf' => array( $file ) ) ) );
}
}
}
} ) );
}
if ( $category->bitoptions['allowss'] )
{
$form->add( new \IPS\Helpers\Form\Upload( 'screenshots', $screenshots, ( $category->bitoptions['reqss'] and !\IPS\Member::loggedIn()->group['idm_linked_files'] ), array(
'storageExtension' => 'downloads_Screenshots',
'image' => $category->maxssdims ? explode( 'x', $category->maxssdims ) : TRUE,
'maxFileSize' => $category->maxss ? ( $category->maxss / 1024 ) : NULL,
'multiple' => TRUE,
'template' => "downloads.submit.screenshot",
) ) );
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'url_screenshots', isset( $data['url_screenshots'] ) ? $data['url_screenshots'] : array(), FALSE, array( 'stackFieldType' => 'Url' ), array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
}
/* Form Elements */
foreach ( \IPS\downloads\File::formElements( NULL, $category ) as $input )
{
$form->add( $input );
}
/* Version field (we only show this on create */
$form->add( new \IPS\Helpers\Form\Text( 'file_version', '1.0.0', FALSE, array( 'maxLength' => 32 ) ) );
}
if ( $values = $form->values() )
{
/* Check */
if ( empty( $values['files'] ) and empty( $values['url_files'] ) and empty( $values['import_files'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_files');
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
}
if ( !isset( \IPS\Request::i()->bulk ) && $category->bitoptions['reqss'] and empty( $values['screenshots'] ) and empty( $values['url_screenshots'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_screenshots');
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
}
/* Get any records we had before in case we need to delete them */
$existing = iterator_to_array( \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_post_key=?', \IPS\Request::i()->postKey ) )->setKeyField( 'record_location' ) );
/* Loop through the values we have */
$k = 0;
$files = array();
$linkedFiles = array();
$screenshots = array();
$linkedScreenshots = array();
foreach ( $values['files'] as $file )
{
$files[ $k ] = (string) $file;
if ( !isset( $existing[ (string) $file ] ) )
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => isset( \IPS\Request::i()->bulk ) ? md5( \IPS\Request::i()->postKey . "-{$k}" ) : \IPS\Request::i()->postKey,
'record_type' => 'upload',
'record_location' => (string) $file,
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
) );
}
$k++;
unset( $existing[ (string) $file ] );
}
if ( isset( $values['import_files'] ) )
{
foreach ( $values['import_files'] as $path )
{
$file = \IPS\File::create( 'downloads_Files', mb_substr( $path, mb_strrpos( $path, DIRECTORY_SEPARATOR ) + 1 ), NULL, NULL, FALSE, $path );
$files[ $k ] = (string) $file;
if ( !isset( $existing[ (string) $file ] ) )
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => isset( \IPS\Request::i()->bulk ) ? md5( \IPS\Request::i()->postKey . "-{$k}" ) : \IPS\Request::i()->postKey,
'record_type' => 'upload',
'record_location' => (string) $file,
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
) );
}
$k++;
}
}
if ( isset( $values['url_files'] ) )
{
foreach ( $values['url_files'] as $url )
{
$linkedFiles[] = (string) $url;
if ( !isset( $existing[ (string) $url ] ) )
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => \IPS\Request::i()->postKey,
'record_type' => 'link',
'record_location' => (string) $url,
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
) );
}
unset( $existing[ (string) $url ] );
}
}
if ( isset( $values['screenshots'] ) )
{
foreach ( $values['screenshots'] as $_key => $file )
{
$screenshots[] = (string) $file;
if ( !isset( $existing[ (string) $file ] ) )
{
$noWatermark = NULL;
if ( \IPS\Settings::i()->idm_watermarkpath )
{
try
{
$noWatermark = (string) $file;
$watermark = \IPS\Image::create( \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() );
$image = \IPS\Image::create( $file->contents() );
$image->watermark( $watermark );
$file = \IPS\File::create( 'downloads_Screenshots', $file->originalFilename, $image );
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => \IPS\Request::i()->postKey,
'record_type' => 'ssupload',
'record_location' => (string) $file,
'record_thumb' => (string) $file->thumbnail( 'downloads_Screenshots' ),
'record_realname' => $file->originalFilename,
'record_size' => \strlen( $file->contents() ),
'record_time' => time(),
'record_no_watermark' => $noWatermark,
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0
) );
}
unset( $existing[ (string) $file ] );
}
}
if ( isset( $values['url_screenshots'] ) )
{
foreach ( $values['url_screenshots'] as $url )
{
$linkedScreenshots[] = (string) $url;
if ( !isset( $existing[ (string) $url ] ) )
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => \IPS\Request::i()->postKey,
'record_type' => 'sslink',
'record_location' => (string) $url,
'record_thumb' => NULL,
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
) );
}
unset( $existing[ (string) $url ] );
}
}
/* Delete any that we don't have any more */
foreach ( $existing as $location => $file )
{
try
{
\IPS\File::get( $file['record_type'] === 'upload' ? 'downloads_Files' : 'downloads_Screenshots', $location )->delete();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_id=?', $file['record_id'] ) );
}
if ( !isset( \IPS\Request::i()->bulk ) )
{
$file = \IPS\downloads\File::createFromForm( array_merge( $data, $values, array( 'postKey' => \IPS\Request::i()->postKey ) ), $category );
/* Redirect */
if( $file->author()->member_id OR $file->canView() )
{
$url = $file->url();
$message = NULL;
}
else
{
$url = $category->url();
$message = \IPS\Member::loggedIn()->language()->addToStack('file_requires_approval_g');
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'redirect' => (string) $url ) );
}
else
{
\IPS\Output::i()->redirect( $url, $message );
}
}
else
{
/* This is a bulk file, so we want to go on to the next step */
return array( 'category' => $category->_id, 'postKey' => \IPS\Request::i()->postKey, 'files' => $files, 'url_files' => $linkedFiles, 'screenshots' => $screenshots, 'url_screenshots' => $linkedScreenshots );
}
}
return \IPS\Theme::i()->getTemplate( 'submit' )->submitForm( $form, $category, $category->message('subterms'), ( \IPS\Member::loggedIn()->group['idm_bulk_submit'] && \IPS\Request::i()->bulk ) );
};
/**
* Step 2: File information (for bulk uploads only)
*/
$steps['file_information'] = function ($data)
{
/* Get Category */
try
{
$category = \IPS\downloads\Category::loadAndCheckPerms( $data['category'] );
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->redirect( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit', 'front', 'downloads_submit' ) );
}
/* Init Form */
$form = new \IPS\Helpers\Form( 'file_information', 'continue' );
$existing = array();
foreach ( $data['files'] as $key => $file )
{
/* Header */
$file = \IPS\File::get( 'downloads_Files', $file );
$form->addTab( $file->originalFilename );
$form->addHeader( $file->originalFilename );
/* Form Elements */
foreach ( \IPS\downloads\File::formElements( NULL, $category ) as $input )
{
\IPS\Member::loggedIn()->language()->words[ "filedata_{$key}_{$input->name}" ] = \IPS\Member::loggedIn()->language()->addToStack( $input->name, FALSE );
if ( !$input->value and in_array( $input->name, array( 'file_title', 'file_desc' ) ) )
{
$input->value = $file->originalFilename;
}
$input->name = "filedata_{$key}_{$input->name}";
if ( $input instanceof \IPS\Helpers\Form\Editor )
{
$input->options['autoSaveKey'] .= $key;
}
$form->add( $input );
}
/* Screenshots */
if ( $category->bitoptions['allowss'] )
{
$existing[ $key ] = iterator_to_array( new \IPS\File\Iterator( \IPS\Db::i()->select( '*', 'downloads_files_records', array( 'record_post_key=? AND record_type=?', md5( "{$data['postKey']}-{$key}" ), 'ssupload' ) )->setValueField( function( $row ) { return $row['record_no_watermark'] ?: $row['record_location']; } )->setKeyField( function( $row ) { return $row['record_no_watermark'] ?: $row['record_location']; } ), 'downloads_Screenshots' ) );
$form->add( new \IPS\Helpers\Form\Upload( "screenshots_{$key}", $existing[ $key ], ( $category->bitoptions['reqss'] and !\IPS\Member::loggedIn()->group['idm_linked_files'] ), array(
'storageExtension' => 'downloads_Screenshots',
'image' => $category->maxssdims ? explode( 'x', $category->maxssdims ) : TRUE,
'maxFileSize' => $category->maxss ? ( $category->maxss / 1024 ) : NULL,
'multiple' => TRUE
) ) );
\IPS\Member::loggedIn()->language()->words[ "screenshots_{$key}" ] = \IPS\Member::loggedIn()->language()->addToStack( 'screenshots', FALSE );
}
/* Version field (we only show this on create */
$form->add( new \IPS\Helpers\Form\Text( "filedata_{$key}_file_version", '1.0.0', FALSE, array( 'maxLength' => 32 ) ) );
\IPS\Member::loggedIn()->language()->words[ "filedata_{$key}_file_version" ] = \IPS\Member::loggedIn()->language()->addToStack( 'file_version', FALSE );
}
/* Handle Submissions */
if ( $values = $form->values() )
{
if ( $category->bitoptions['allowss'] )
{
foreach ( $data['files'] as $key => $file )
{
/* Save Screenshots */
foreach ( $values["screenshots_{$key}"] as $file )
{
$screenshots[] = (string) $file;
if ( !isset( $existing[ $key ][ (string) $file ] ) )
{
$noWatermark = NULL;
if ( \IPS\Settings::i()->idm_watermarkpath )
{
$noWatermark = (string) $file;
$watermark = \IPS\Image::create( \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() );
$image = \IPS\Image::create( $file->contents() );
$image->watermark( $watermark );
$file = \IPS\File::create( 'downloads_Screenshots', $file->originalFilename, $image );
}
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_post_key' => md5( "{$data['postKey']}-{$key}" ),
'record_type' => 'ssupload',
'record_location' => (string) $file,
'record_thumb' => (string) $file->thumbnail( 'downloads_Screenshots' ),
'record_realname' => $file->originalFilename,
'record_size' => \strlen( $file->contents() ),
'record_time' => time(),
'record_no_watermark' => $noWatermark
) );
}
else
{
unset( $existing[ $key ][ (string) $file ] );
}
}
unset( $values["screenshots_{$key}"] );
/* Delete any that we don't have any more */
foreach ( $existing[ $key ] as $location => $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_location=? OR record_no_watermark=?', (string) $file, (string) $file ) );
}
}
}
/* Create Files */
foreach ( $data['files'] as $key => $fileUrl )
{
/* $values isn't going to work as is here */
$save = array(
'file_title' => $values["filedata_{$key}_file_title"],
'file_desc' => $values["filedata_{$key}_file_desc"],
'file_tags' => $values["filedata_{$key}_file_tags"],
'file_version' => $values["filedata_{$key}_file_version"],
'postKey' => md5( "{$data['postKey']}-{$key}" )
);
\IPS\downloads\File::createFromForm( $save, $category, FALSE );
}
if ( \IPS\Member::loggedIn()->moderateNewContent() OR \IPS\downloads\File::moderateNewItems( \IPS\Member::loggedIn(), $category ) )
{
\IPS\downloads\File::_sendUnapprovedNotifications( $category );
}
else
{
\IPS\downloads\File::_sendNotifications( $category );
}
/* Redirect */
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'redirect' => (string) $category->url() ) );
}
else
{
\IPS\Output::i()->redirect( $category->url() );
}
}
return \IPS\Theme::i()->getTemplate( 'submit' )->bulkForm( $form, $category );
};
/* Build Wizard */
$url = \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit&do=submit', 'front', 'downloads_submit' );
if ( isset( \IPS\Request::i()->category ) and \IPS\Request::i()->category )
{
$url = $url->setQueryString( 'category', \IPS\Request::i()->category );
}
if ( isset( \IPS\Request::i()->bulk ) and \IPS\Request::i()->bulk )
{
$url = $url->setQueryString( 'bulk', 1 );
}
$wizard = new \IPS\Helpers\Wizard( $steps, $url );
$wizard->template = array( \IPS\Theme::i()->getTemplate( 'submit' ), 'wizardForm' );
/* Online User Location */
\IPS\Session::i()->setLocation( \IPS\Http\Url::internal( 'app=downloads&module=downloads&controller=submit', 'front', 'downloads_submit' ), array(), 'loc_downloads_adding_file' );
/* Display */
\IPS\Output::i()->title = \IPS\Member::loggedIn()->language()->addToStack( isset( \IPS\Request::i()->bulk ) ? 'submit_multiple_files' : 'submit_a_file' );
if ( \IPS\IN_DEV )
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/moxie.js', 'core', 'interface' ) );
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/plupload.dev.js', 'core', 'interface' ) );
}
else
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'plupload/plupload.full.min.js', 'core', 'interface' ) );
}
if ( \IPS\downloads\File::moderateNewItems( \IPS\Member::loggedIn() ) )
{
$wizard = \IPS\Theme::i()->getTemplate( 'forms', 'core' )->modQueueMessage( \IPS\Member::loggedIn()->warnings( 5, NULL, 'mq' ), \IPS\Member::loggedIn()->mod_posts ) . $wizard;
}
\IPS\Output::i()->output = $wizard;
\IPS\Output::i()->breadcrumb[] = array( NULL, \IPS\Member::loggedIn()->language()->addToStack( 'submit_a_file' ) );
}
}
@@ -0,0 +1,988 @@
<?php
/**
* @brief View File Controller
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 10 Oct 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\modules\front\downloads;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* View File Controller
*/
class _view extends \IPS\Content\Controller
{
/**
* [Content\Controller] Class
*/
protected static $contentModel = 'IPS\downloads\File';
/**
* Execute
*
* @return void
*/
public function execute()
{
try
{
$this->file = \IPS\downloads\File::load( \IPS\Request::i()->id );
if ( !$this->file->canView( \IPS\Member::loggedIn() ) and \IPS\Request::i()->do != 'download' )
{
\IPS\Output::i()->error( $this->file->container()->message('npv') ?: 'node_error', '2D161/2', 403, '' );
}
if ( $this->file->primary_screenshot )
{
\IPS\Output::i()->metaTags['og:image'] = \IPS\File::get( 'downloads_Screenshots', $this->file->primary_screenshot_thumb )->url;
}
}
catch ( \OutOfRangeException $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/1', 404, '' );
}
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_view.js', 'downloads', 'front' ) );
parent::execute();
}
/**
* View File
*
* @return void
*/
protected function manage()
{
/* Init */
parent::manage();
/* Sort out comments and reviews */
$tabs = $this->file->commentReviewTabs();
$_tabs = array_keys( $tabs );
$tab = isset( \IPS\Request::i()->tab ) ? \IPS\Request::i()->tab : array_shift( $_tabs );
$activeTabContents = $this->file->commentReviews( $tab );
$commentsAndReviews = count( $tabs ) ? \IPS\Theme::i()->getTemplate( 'global', 'core' )->commentsAndReviewsTabs( \IPS\Theme::i()->getTemplate( 'global', 'core' )->tabs( $tabs, $tab, $activeTabContents, $this->file->url(), 'tab', FALSE, TRUE ), md5( $this->file->url() ) ) : NULL;
if ( \IPS\Request::i()->isAjax() and !isset( \IPS\Request::i()->changelog ) )
{
\IPS\Output::i()->output = $activeTabContents;
return;
}
/* Any previous versions? */
$versionData = array( 'b_version' => $this->file->version, 'b_changelog' => $this->file->changelog, 'b_backup' => $this->file->updated );
$previousVersions = iterator_to_array( \IPS\Db::i()->select( '*', 'downloads_filebackup', array( "b_fileid=?", $this->file->id ), 'b_backup DESC' )->setKeyField( 'b_id' ) );
if ( isset( \IPS\Request::i()->changelog ) and isset( $previousVersions[ \IPS\Request::i()->changelog ] ) )
{
$versionData = $previousVersions[ \IPS\Request::i()->changelog ];
}
if( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( \IPS\Theme::i()->getTemplate( 'view' )->changeLog( $this->file, $versionData ) );
}
/* Online User Location */
\IPS\Session::i()->setLocation( $this->file->url(), $this->file->onlineListPermissions(), 'loc_downloads_viewing_file', array( $this->file->name => FALSE ) );
/* Custom Field Formatting */
$cfields = array();
$fields = $this->file->customFields();
foreach ( new \IPS\Patterns\ActiveRecordIterator( \IPS\Db::i()->select( 'pfd.*', array( 'downloads_cfields', 'pfd' ), NULL, 'pfd.cf_position' ), 'IPS\downloads\Field' ) as $field )
{
if( array_key_exists( 'field_' . $field->id, $this->file->customFields() ) )
{
if ( $fields[ 'field_' . $field->id ] !== null AND $fields[ 'field_' . $field->id ] !== '' )
{
$cfields[ 'field_' . $field->id ] = $field->displayValue( $fields[ 'field_' . $field->id ] );
}
}
}
/* Display */
\IPS\Output::i()->sidebar['sticky'] = TRUE;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->view( $this->file, $commentsAndReviews, $versionData, $previousVersions, $this->file->nextItem(), $this->file->prevItem(), $cfields );
}
/**
* Buy file
*
* @return void
*/
protected function buy()
{
\IPS\Session::i()->csrfCheck();
/* Can we buy? */
if ( !$this->file->canBuy() )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/E', 403, '' );
}
/* Is it associated with a Nexus product? */
if ( $this->file->nexus )
{
$productIds = explode( ',', $this->file->nexus );
if ( count( $productIds ) === 1 )
{
try
{
\IPS\Output::i()->redirect( \IPS\nexus\Package::load( array_pop( $productIds ) )->url() );
}
catch ( \OutOfRangeExcpetion $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/F', 404, '' );
}
}
$category = $this->file->container();
try
{
foreach ( $category->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
}
catch ( \Exception $e ) { }
\IPS\Output::i()->cssFiles = array_merge( \IPS\Output::i()->cssFiles, \IPS\Theme::i()->css( 'store.css', 'nexus' ) );
\IPS\Output::i()->bodyClasses[] = 'ipsLayout_minimal';
\IPS\Output::i()->sidebar['enabled'] = FALSE;
\IPS\Output::i()->breadcrumb[] = array( $this->file->url(), $this->file->name );
\IPS\Output::i()->title = $this->file->name;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate('nexus')->chooseProduct( \IPS\nexus\Package\Item::getItemsWithPermission( array( array( \IPS\Db::i()->in( 'p_id', $productIds ) ) ), 'p_position' ) );
return;
}
/* Create the item */
$price = $this->file->price();
$item = new \IPS\downloads\extensions\nexus\Item\File( $this->file->name, $price );
$item->id = $this->file->id;
try
{
$item->tax = \IPS\Settings::i()->idm_nexus_tax ? \IPS\nexus\Tax::load( \IPS\Settings::i()->idm_nexus_tax ) : NULL;
}
catch ( \OutOfRangeException $e ) { }
if ( \IPS\Settings::i()->idm_nexus_gateways )
{
$item->paymentMethodIds = explode( ',', \IPS\Settings::i()->idm_nexus_gateways );
}
$item->renewalTerm = $this->file->renewalTerm();
$item->payTo = $this->file->author();
$item->commission = \IPS\Settings::i()->idm_nexus_percent;
if ( $fees = json_decode( \IPS\Settings::i()->idm_nexus_transfee, TRUE ) )
{
$item->fee = new \IPS\nexus\Money( $fees[ $price->currency ]['amount'], $price->currency );
}
/* Generate the invoice */
$invoice = new \IPS\nexus\Invoice;
$invoice->member = \IPS\nexus\Customer::loggedIn();
$invoice->addItem( $item );
$invoice->return_uri = "app=downloads&module=downloads&controller=view&id={$this->file->id}";
$invoice->save();
/* Take them to it */
\IPS\Output::i()->redirect( $invoice->checkoutUrl() );
}
/**
* Download file - Show terms and file selection
*
* @return void
*/
protected function download()
{
/* No direct linking check */
if ( \IPS\Settings::i()->idm_antileech )
{
if ( !isset( \IPS\Request::i()->csrfKey ) )
{
\IPS\Output::i()->redirect( $this->file->url() );
}
\IPS\Session::i()->csrfCheck();
}
/* Can we download? */
try
{
$this->file->downloadCheck();
}
catch ( \DomainException $e )
{
\IPS\Output::i()->error( $e->getMessage(), '1D161/3', 403, '' );
}
/* What's the URL to confirm? */
$confirmUrl = $this->file->url()->setQueryString( array( 'do' => 'download', 'confirm' => 1 ) );
if ( isset( \IPS\Request::i()->version ) )
{
$confirmUrl = $confirmUrl->setQueryString( 'version', \IPS\Request::i()->version );
}
if ( \IPS\Settings::i()->idm_antileech )
{
$confirmUrl = $confirmUrl->csrf();
}
/* Set navigation */
$category = $this->file->container();
try
{
foreach ( $category->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
}
catch ( \Exception $e ) { }
\IPS\Output::i()->breadcrumb[] = array( $this->file->url(), $this->file->name );
\IPS\Output::i()->title = $this->file->name;
/* What files do we have? */
$files = $this->file->files( isset( \IPS\Request::i()->version ) ? \IPS\Request::i()->version : NULL );
/* Have we accepted the terms? */
if ( $downloadTerms = $category->message('disclaimer') and !isset( \IPS\Request::i()->confirm ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, $downloadTerms, null, $confirmUrl, count( $files ) > 1 );
return;
}
/* File Selected? */
if ( count( $files ) === 1 or ( isset( \IPS\Request::i()->r ) ) )
{
/* Which file? */
foreach ( $files as $k => $file )
{
$data = $files->data();
if ( isset( \IPS\Request::i()->r ) and \IPS\Request::i()->r == $k )
{
break;
}
}
/* Check it */
try
{
$this->file->downloadCheck( $data );
}
catch ( \DomainException $e )
{
\IPS\Output::i()->error( $e->getMessage(), '1D161/4', 403, '' );
}
/* Time Delay */
if ( \IPS\Member::loggedIn()->group['idm_wait_period'] )
{
if ( isset( \IPS\Request::i()->t ) )
{
$timerKey = "downloads_delay_" . md5( (string) $file );
if ( !isset( $_SESSION[ $timerKey ] ) )
{
$_SESSION[ $timerKey ] = time();
}
if ( \IPS\Request::i()->isAjax() )
{
\IPS\Output::i()->json( array( 'download' => time() + \IPS\Member::loggedIn()->group['idm_wait_period'], 'currentTime' => time() ) );
}
if ( $_SESSION[ $timerKey ] > ( time() - \IPS\Member::loggedIn()->group['idm_wait_period'] ) )
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1, $data['record_id'], ( $_SESSION[ $timerKey ] + \IPS\Member::loggedIn()->group['idm_wait_period'] ) - time() );
return;
}
else
{
unset( $_SESSION[ $timerKey ] );
}
}
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1 );
return;
}
}
/* Log */
if ( $category->log !== 0 )
{
$_log = true;
if( isset( $_SERVER['HTTP_RANGE'] ) )
{
if( !\IPS\Http\Ranges::isStartOfFile() )
{
$_log = false;
}
}
if( $_log )
{
\IPS\Db::i()->insert( 'downloads_downloads', array(
'dfid' => $this->file->id,
'dtime' => time(),
'dip' => \IPS\Request::i()->ipAddress(),
'dmid' => (int) \IPS\Member::loggedIn()->member_id,
'dsize' => $data['record_size'],
'dua' => \IPS\Session::i()->userAgent->useragent,
'dbrowsers' => \IPS\Session::i()->userAgent->useragentKey,
'dos' => ''
) );
$this->file->downloads++;
$this->file->save();
}
}
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on and ( $this->file->cost or $this->file->nexus ) )
{
\IPS\nexus\Customer::loggedIn()->log( 'download', array( 'type' => 'idm', 'id' => $this->file->id, 'name' => $this->file->name ) );
}
/* Download */
if ( $data['record_type'] === 'link' )
{
\IPS\Output::i()->redirect( $data['record_location'] );
}
else
{
$file = \IPS\File::get( 'downloads_Files', $data['record_location'] );
$file->originalFilename = $data['record_realname'] ?: $file->originalFilename;
$this->_download( $file );
}
}
/* Nope - choose one */
else
{
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->download( $this->file, null, $files, $confirmUrl, count( $files ) > 1 );
}
}
/**
* Actually send the file for download
*
* @param \IPS\File $file The file to download
* @return void
*/
protected function _download( \IPS\File $file )
{
if ( !$file->filesize() )
{
\IPS\Output::i()->error( 'downloads_no_file', '3D161/G', 404, '' );
}
/* Log session */
$downloadSessionId = md5( uniqid( microtime(), true ) );
\IPS\Db::i()->insert( 'downloads_sessions', array(
'dsess_id' => $downloadSessionId,
'dsess_mid' => (int) \IPS\Member::loggedIn()->member_id,
'dsess_ip' => \IPS\Request::i()->ipAddress(),
'dsess_file' => $this->file->id,
'dsess_start' => time()
) );
register_shutdown_function( function() use( $downloadSessionId ) {
\IPS\Db::i()->delete( 'downloads_sessions', array( 'dsess_id=?', $downloadSessionId ) );
} );
/* Print the file, honoring ranges */
$ranges = new \IPS\Http\Ranges( $file, (int) \IPS\Member::loggedIn()->group['idm_throttling'] );
exit;
}
/**
* Restore a previous version
*
* @return void
*/
protected function restorePreviousVersion()
{
/* Permission check */
if ( !$this->file->canEdit() or !\IPS\Member::loggedIn()->group['idm_bypass_revision'] )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/5', 403, '' );
}
/* Load the desired version */
try
{
$version = \IPS\Db::i()->select( '*', 'downloads_filebackup', array( 'b_id=?', \IPS\Request::i()->version ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/6', 404, '' );
}
/* Delete the current versions and any versions in between */
foreach ( new \IPS\File\Iterator( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_backup=0', $this->file->id ) ), 'downloads_Files' ) as $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) {}
}
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_file_id=? AND record_backup=0', $this->file->id ) );
/* Delete any versions in between */
foreach ( \IPS\Db::i()->select( 'b_records', 'downloads_filebackup', array( 'b_fileid=? AND b_backup>?', $this->file->id, $version['b_backup'] ) ) as $backup )
{
foreach ( new \IPS\File\Iterator( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( array( 'record_type=?', 'upload' ), \IPS\Db::i()->in( 'record_id', explode( ',', $backup ) ) ) ), 'downloads_Files' ) as $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) { }
}
foreach ( new \IPS\File\Iterator( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( array( 'record_type=?', 'ssupload' ), \IPS\Db::i()->in( 'record_id', explode( ',', $backup ) ) ) ), 'downloads_Files' ) as $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->delete( 'downloads_files_records', \IPS\Db::i()->in( 'record_id', explode( ',', $backup ) ) );
}
\IPS\Db::i()->delete( 'downloads_filebackup', array( 'b_fileid=? AND b_backup>=?', $this->file->id, $version['b_backup'] ) );
/* Restore the records */
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_backup' => 0 ), array( 'record_file_id=?', $this->file->id ) );
/* Update the file information */
$this->file->name = $version['b_filetitle'];
$this->file->desc = $version['b_filedesc'];
$this->file->version = $version['b_version'];
$this->file->changelog = $version['b_changelog'];
$this->file->save();
/* Moderator log */
\IPS\Session::i()->modLog( 'modlog__action_restorebackup', array( (string) $this->file->url() => FALSE, $this->file->name => FALSE ), $this->file );
/* Redirect */
\IPS\Output::i()->redirect( $this->file->url() );
}
/**
* Toggle Previous Version Visibility
*
* @return void
*/
protected function previousVersionVisibility()
{
/* Permission check */
if ( !$this->file->canEdit() or !\IPS\Member::loggedIn()->group['idm_bypass_revision'] )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/8', 403, '' );
}
/* Load the desired version */
try
{
$version = \IPS\Db::i()->select( '*', 'downloads_filebackup', array( 'b_id=?', \IPS\Request::i()->version ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/7', 404, '' );
}
/* Change visibility */
\IPS\Db::i()->update( 'downloads_filebackup', array( 'b_hidden' => !$version['b_hidden'] ), array( 'b_id=?', $version['b_id'] ) );
/* Moderator log */
\IPS\Session::i()->modLog( 'modlog__action_visibilitybackup', array( (string) $this->file->url() => FALSE, $this->file->name => FALSE ), $this->file );
/* Redirect */
\IPS\Output::i()->redirect( $this->file->url()->setQueryString( 'changelog', $version['b_id'] ) );
}
/**
* Delete Previous Version
*
* @return void
*/
protected function deletePreviousVersion()
{
/* Permission check */
if ( !$this->file->canEdit() or !\IPS\Member::loggedIn()->group['idm_bypass_revision'] )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/9', 403, '' );
}
/* Load the desired version */
try
{
$version = \IPS\Db::i()->select( '*', 'downloads_filebackup', array( 'b_id=?', \IPS\Request::i()->version ) )->first();
}
catch ( \UnderflowException $e )
{
\IPS\Output::i()->error( 'node_error', '2D161/A', 404, '' );
}
/* Delete */
foreach ( new \IPS\File\Iterator( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( array( 'record_type=?', 'upload' ), \IPS\Db::i()->in( 'record_id', explode( ',', $version['b_records'] ) ) ) ), 'downloads_Files' ) as $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) { }
}
foreach ( new \IPS\File\Iterator( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( array( 'record_type=?', 'ssupload' ), \IPS\Db::i()->in( 'record_id', explode( ',', $version['b_records'] ) ) ) ), 'downloads_Screenshots' ) as $file )
{
try
{
$file->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->delete( 'downloads_files_records', \IPS\Db::i()->in( 'record_id', explode( ',', $version['b_records'] ) ) );
\IPS\Db::i()->delete( 'downloads_filebackup', array( 'b_id=?', $version['b_id'] ) );
/* Moderator log */
\IPS\Session::i()->modLog( 'modlog__action_deletebackup', array( (string) $this->file->url() => FALSE, $this->file->name => FALSE ), $this->file );
/* Redirect */
\IPS\Output::i()->redirect( $this->file->url()->setQueryString( 'changelog', $version['b_id'] ) );
}
/**
* View download log
*
* @return void
*/
protected function log()
{
/* Permission check */
if ( !$this->file->canViewDownloaders() )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/B', 403, '' );
}
$table = new \IPS\Helpers\Table\Db( 'downloads_downloads', $this->file->url()->setQueryString( 'do', 'log' ), array( 'dfid=?', $this->file->id ) );
$table->tableTemplate = array( \IPS\Theme::i()->getTemplate( 'view' ), 'logTable' );
$table->rowsTemplate = array( \IPS\Theme::i()->getTemplate( 'view' ), 'logRows' );
$table->sortBy = 'dtime';
$table->limit = 10;
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'view' )->log( $this->file, (string) $table );
}
/**
* Upload a new version
*
* @return void
*/
protected function newVersion()
{
\IPS\Output::i()->jsFiles = array_merge( \IPS\Output::i()->jsFiles, \IPS\Output::i()->js( 'front_submit.js', 'downloads', 'front' ) );
/* Permission check */
if ( !$this->file->canEdit() )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/C', 403, '' );
}
$category = $this->file->container();
/* Build form */
$form = new \IPS\Helpers\Form;
$form->addHeader( 'new_version_details' );
if ( $category->versioning !== 0 and \IPS\Member::loggedIn()->group['idm_bypass_revision'] )
{
$form->add( new \IPS\Helpers\Form\YesNo( 'file_save_revision', TRUE ) );
}
$form->add( new \IPS\Helpers\Form\Text( 'file_version', $this->file->version, ( $category->versioning !== 0 ), array( 'maxLength' => 32 ) ) );
$form->add( new \IPS\Helpers\Form\Editor( 'file_changelog', $this->file->changelog, FALSE, array( 'app' => 'downloads', 'key' => 'Downloads', 'autoSaveKey' => "downloads-{$this->file->id}-changelog", 'attachIds' => array( $this->file->id ) ) ) );
$form->addHeader( 'upload_files' );
$form->add( new \IPS\Helpers\Form\Upload( 'files', iterator_to_array( $this->file->files( NULL, FALSE ) ), ( !\IPS\Member::loggedIn()->group['idm_linked_files'] and !\IPS\Member::loggedIn()->group['idm_import_files'] ), array( 'storageExtension' => 'downloads_Files', 'allowedFileTypes' => $category->types, 'maxFileSize' => $category->maxfile ? ( $category->maxfile / 1024 ) : NULL, 'multiple' => TRUE, 'retainDeleted' => TRUE ) ) );
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'url_files', iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'link' ) ) ), FALSE, array( 'stackFieldType' => 'Url' ), array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
if ( \IPS\Member::loggedIn()->group['idm_import_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'import_files', array(), FALSE, array( 'placeholder' => \IPS\ROOT_PATH ), function( $val )
{
if( is_array( $val ) )
{
foreach ( $val as $file )
{
if ( !is_file( $file ) )
{
throw new \DomainException( \IPS\Member::loggedIn()->language()->addToStack('err_import_files', FALSE, array( 'sprintf' => array( $file ) ) ) );
}
}
}
} ) );
}
if ( $category->bitoptions['allowss'] )
{
$screenshots = iterator_to_array( $this->file->screenshots( 2, FALSE ) );
if( $this->file->_primary_screenshot and isset( $screenshots[ $this->file->_primary_screenshot ] ) )
{
$screenshots[ $this->file->_primary_screenshot ] = array( 'fileurl' => $screenshots[ $this->file->_primary_screenshot ], 'default' => true );
}
$form->add( new \IPS\Helpers\Form\Upload( 'screenshots', $screenshots, ( $category->bitoptions['reqss'] and !\IPS\Member::loggedIn()->group['idm_linked_files'] ), array(
'storageExtension' => 'downloads_Screenshots',
'image' => $category->maxssdims ? explode( 'x', $category->maxssdims ) : TRUE,
'maxFileSize' => $category->maxss ? ( $category->maxss / 1024 ) : NULL,
'multiple' => TRUE,
'retainDeleted' => TRUE,
'template' => "downloads.submit.screenshot",
) ) );
if ( \IPS\Member::loggedIn()->group['idm_linked_files'] )
{
$form->add( new \IPS\Helpers\Form\Stack( 'url_screenshots', iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'sslink' ) ) ), FALSE, array( 'stackFieldType' => 'Url' ), array( 'IPS\downloads\File', 'blacklistCheck' ) ) );
}
}
/* Output */
\IPS\Output::i()->title = $this->file->name;
\IPS\Output::i()->breadcrumb[] = array( $this->file->url(), $this->file->name );
/* Handle submissions */
if ( $values = $form->values() )
{
/* Check */
if ( empty( $values['files'] ) and empty( $values['url_files'] ) and empty( $values['import_files'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_files');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
return (string) $form;
}
if ( $category->bitoptions['reqss'] and empty( $values['screenshots'] ) and empty( $values['url_screenshots'] ) )
{
$form->error = \IPS\Member::loggedIn()->language()->addToStack('err_no_screenshots');
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
return (string) $form;
}
/* Versioning */
$existingRecords = array();
$existingScreenshots = array();
$existingLinks = array();
$existingScreenshotLinks = array();
if ( $category->versioning !== 0 and ( !\IPS\Member::loggedIn()->group['idm_bypass_revision'] or $values['file_save_revision'] ) )
{
/* Move the old details into a backup record */
\IPS\Db::i()->insert( 'downloads_filebackup', array(
'b_fileid' => $this->file->id,
'b_filetitle' => $this->file->name,
'b_filedesc' => $this->file->desc,
'b_hidden' => FALSE,
'b_backup' => $this->file->updated,
'b_updated' => time(),
'b_records' => implode( ',', iterator_to_array( \IPS\Db::i()->select( 'record_id', 'downloads_files_records', array( 'record_file_id=? AND record_backup=0', $this->file->id ) ) ) ),
'b_version' => $this->file->version,
'b_changelog' => $this->file->changelog,
) );
/* Set the old records to be backups */
\IPS\Db::i()->update( 'downloads_files_records', array( 'record_backup' => TRUE ), array( 'record_file_id=? AND record_backup=0', $this->file->id ) );
/* Delete any old versions we no longer keep */
if ( $category->versioning !== NULL )
{
$count = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_filebackup', array( 'b_fileid=?', $this->file->id ) )->first();
if ( ( $count - $category->versioning + 1 ) > 0 )
{
foreach ( \IPS\Db::i()->select( '*', 'downloads_filebackup', array( 'b_fileid=?', $this->file->id ), 'b_backup ASC', $count - $category->versioning + 1 ) as $backUp )
{
foreach ( \IPS\Db::i()->select( '*', 'downloads_files_records', \IPS\Db::i()->in( 'record_id', explode( ',', $backUp['b_records'] ) ) ) as $k => $file )
{
try
{
$file = \IPS\File::get( $file['record_type'] == 'upload' ? 'downloads_Files' : 'downloads_Screenshots', $file['record_location'] )->delete();
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->delete( 'downloads_files_records', \IPS\Db::i()->in( 'record_id', explode( ',', $backUp['b_records'] ) ) );
\IPS\Db::i()->delete( 'downloads_filebackup', array( 'b_id=?', $backUp['b_id'] ) );
}
}
}
}
else
{
$existingRecords = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=?', $this->file->id, 'upload' ) ) ) );
$existingScreenshots = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=?', $this->file->id, 'ssupload' ) ) ) );
$existingLinks = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=?', $this->file->id, 'link' ) )->setKeyField('record_id')->setValueField('record_location') ) );
$existingScreenshotLinks = array_unique( iterator_to_array( \IPS\Db::i()->select( 'record_id, record_location', 'downloads_files_records', array( 'record_file_id=? AND record_type=?', $this->file->id, 'sslink' ) )->setKeyField('record_id')->setValueField('record_location') ) );
}
/* Insert the new records */
foreach ( $values['files'] as $file )
{
$key = array_search( (string) $file, $existingRecords );
if ( $key !== FALSE )
{
unset( $existingRecords[ $key ] );
}
else
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'upload',
'record_location' => (string) $file,
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
) );
}
}
if ( isset( $values['import_files'] ) )
{
foreach ( $values['import_files'] as $path )
{
$file = \IPS\File::create( 'downloads_Files', mb_substr( $path, mb_strrpos( $path, DIRECTORY_SEPARATOR ) + 1 ), file_get_contents( $path ) );
$key = array_search( (string) $file, $existingRecords );
if ( $key !== FALSE )
{
unset( $existingRecords[ $key ] );
}
else
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'upload',
'record_location' => (string) $file,
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
) );
}
}
}
if ( isset( $values['url_files'] ) )
{
foreach ( $values['url_files'] as $url )
{
$key = array_search( $url, $existingLinks );
if ( $key !== FALSE )
{
unset( $existingLinks[ $key ] );
}
else
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'link',
'record_location' => (string) $url,
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
) );
}
}
}
if ( isset( $values['screenshots'] ) )
{
foreach ( $values['screenshots'] as $_key => $file )
{
/* If this was the primary screenshot, convert back */
if( is_array( $file ) )
{
$file = $file['fileurl'];
}
$key = array_search( (string) $file, $existingScreenshots );
if ( $key !== FALSE )
{
unset( $existingScreenshots[ $key ] );
}
else
{
$noWatermark = NULL;
if ( \IPS\Settings::i()->idm_watermarkpath )
{
try
{
$noWatermark = (string) $file;
$watermark = \IPS\Image::create( \IPS\File::get( 'core_Theme', \IPS\Settings::i()->idm_watermarkpath )->contents() );
$image = \IPS\Image::create( $file->contents() );
$image->watermark( $watermark );
$file = \IPS\File::create( 'downloads_Screenshots', $file->originalFilename, $image );
}
catch ( \Exception $e ) { }
}
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'ssupload',
'record_location' => (string) $file,
'record_thumb' => (string) $file->thumbnail( 'downloads_Screenshots' ),
'record_realname' => $file->originalFilename,
'record_size' => $file->filesize(),
'record_time' => time(),
'record_no_watermark' => $noWatermark,
'record_default' => ( \IPS\Request::i()->screenshots_primary_screenshot AND \IPS\Request::i()->screenshots_primary_screenshot == $_key ) ? 1 : 0
) );
}
}
}
if ( isset( $values['url_screenshots'] ) )
{
foreach ( $values['url_screenshots'] as $url )
{
$key = array_search( (string) $file, $existingScreenshotLinks );
if ( $key !== FALSE )
{
unset( $existingScreenshotLinks[ $key ] );
}
else
{
\IPS\Db::i()->insert( 'downloads_files_records', array(
'record_file_id' => $this->file->id,
'record_type' => 'sslink',
'record_location' => (string) $url,
'record_realname' => NULL,
'record_size' => 0,
'record_time' => time(),
) );
}
}
}
/* Delete any we're not using anymore */
foreach ( $existingRecords as $url )
{
try
{
$file = \IPS\File::get( 'downloads_Files', $url )->delete();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_location=?', $url ) );
}
foreach ( $existingScreenshots as $url )
{
try
{
$file = \IPS\File::get( 'downloads_Screenshots', $url )->delete();
}
catch ( \Exception $e ) { }
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_location=?', $url ) );
}
foreach ( $existingLinks as $id => $url )
{
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_id=?', $id ) );
}
foreach ( $existingScreenshotLinks as $id => $url )
{
\IPS\Db::i()->delete( 'downloads_files_records', array( 'record_id=?', $id ) );
}
/* Set the new details */
$this->file->version = $values['file_version'];
$this->file->changelog = $values['file_changelog'];
$this->file->size = floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'upload' ) )->first() );
/* Work out the new primary screenshot */
try
{
$this->file->primary_screenshot = \IPS\Db::i()->select( 'record_id', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $this->file->id, 'ssupload' ), 'record_default DESC, record_id ASC' )->first();
}
catch ( \UnderflowException $e ) { }
/* Does it have to be reapproved? */
if ( $category->bitoptions['moderation'] and $category->bitoptions['moderation_edits'] and !$this->file->canUnhide() )
{
$this->file->open = 0;
}
/* Save */
$this->file->updated = time();
$this->file->save();
/* Send notifications */
if ( $this->file->open )
{
$this->file->sendUpdateNotifications();
}
/* Boink */
\IPS\Output::i()->redirect( $this->file->url() );
}
/* Set navigation */
try
{
foreach ( $category->parents() as $parent )
{
\IPS\Output::i()->breadcrumb[] = array( $parent->url(), $parent->_title );
}
\IPS\Output::i()->breadcrumb[] = array( $category->url(), $category->_title );
}
catch ( \Exception $e ) { }
\IPS\Output::i()->output = \IPS\Theme::i()->getTemplate( 'submit' )->newVersion( $form, $category->versioning !== 0 );
}
/**
* Change Author
*
* @return void
*/
public function changeAuthor()
{
/* Permission check */
if ( !$this->file->canChangeAuthor() )
{
\IPS\Output::i()->error( 'no_module_permission', '2D161/D', 403, '' );
}
/* Build form */
$form = new \IPS\Helpers\Form;
$form->add( new \IPS\Helpers\Form\Member( 'author', NULL, TRUE ) );
$form->class .= 'ipsForm_vertical';
/* Handle submissions */
if ( $values = $form->values() )
{
$this->file->changeAuthor( $values['author'] );
\IPS\Output::i()->redirect( $this->file->url() );
}
/* Display form */
\IPS\Output::i()->output = $form->customTemplate( array( call_user_func_array( array( \IPS\Theme::i(), 'getTemplate' ), array( 'forms', 'core' ) ), 'popupTemplate' ) );;
}
}
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,197 @@
{
"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": "IP.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": "IP.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",
{
"name": "idm_block_submissions",
"type": "TINYINT",
"length": 1,
"null": false,
"default": 0,
"comment": "Blocked from submitting IP.Downloads files?",
"unsigned": true
}
]
},
"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": {
"method": "insert",
"params": [
"core_permission_index",
{
"app": "downloads",
"perm_type": "category",
"perm_type_id": 1,
"perm_view": "*",
"perm_2": "*",
"perm_3": "<%NO_GUESTS%>",
"perm_4": "<%NO_GUESTS%>",
"perm_5": "<%NO_GUESTS%>",
"perm_6": "<%NO_GUESTS%>"
}
]
}
}
Whitespace-only changes.
@@ -0,0 +1,49 @@
<?php
/**
* @brief 4.0.0 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 30 Oct 2014
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\setup\upg_100002;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 Upgrade Code
*/
class _Upgrade
{
/**
* Fix SEO titles
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
\IPS\Db::i()->update( 'downloads_categories', array( 'cname_furl' => null ) );
\IPS\Db::i()->update( 'downloads_files', array( 'file_name_furl' => null ) );
return true;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Resetting downloads friendly URL titles";
}
}
Whitespace-only changes.
@@ -0,0 +1,170 @@
{
"1": {
"method": "dropIndex",
"params": [
"downloads_files",
"file_downloads"
]
},
"2": {
"method": "changeColumn",
"params": [
"downloads_cfields",
"cf_format",
{
"name": "cf_format",
"type": "TEXT",
"length": 0,
"decimals": null,
"values": [],
"allow_null": true,
"default": null,
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"3": {
"method": "dropIndex",
"params": [
"downloads_comments",
"comment_text"
]
},
"4": {
"method": "dropIndex",
"params": [
"downloads_files",
"file_name"
]
},
"5": {
"method": "dropIndex",
"params": [
"downloads_files",
"file_desc"
]
},
"6": {
"method": "dropIndex",
"params": [
"downloads_reviews",
"review_text"
]
},
"7": {
"method": "changeColumn",
"params": [
"downloads_files",
"file_cost",
{
"name": "file_cost",
"type": "TEXT",
"length": 0,
"decimals": null,
"values": [],
"allow_null": true,
"default": "",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"8": {
"method": "changeColumn",
"params": [
"downloads_files",
"file_renewal_price",
{
"name": "file_renewal_price",
"type": "TEXT",
"length": 0,
"decimals": null,
"values": [],
"allow_null": true,
"default": "",
"comment": "",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
},
"9": {
"method": "dropTable",
"params": [
"downloads_favorites",
true
]
},
"10": {
"method": "dropTable",
"params": [
"downloads_filestorage",
true
]
},
"11": {
"method": "dropTable",
"params": [
"downloads_fileviews",
true
]
},
"12": {
"method": "dropTable",
"params": [
"downloads_mime",
true
]
},
"13": {
"method": "dropTable",
"params": [
"downloads_mimemask",
true
]
},
"14": {
"method": "dropTable",
"params": [
"downloads_mods",
true
]
},
"15": {
"method": "dropTable",
"params": [
"downloads_temp_records",
true
]
},
"16": {
"method": "dropTable",
"params": [
"downloads_upgrade_history",
true
]
},
"17": {
"method": "dropTable",
"params": [
"downloads_urls",
true
]
},
"18": {
"method": "dropColumn",
"params": [
"downloads_cfields",
"cf_file_format"
]
}
}
Whitespace-only changes.
@@ -0,0 +1,262 @@
<?php
/**
* @brief 4.0.0 Alpha 1 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @since 25 Mar 2013
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\setup\upg_100005;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 Alpha 1 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Fix downloads changelog
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
$limit = 0;
$did = 0;
$perCycle = 500;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( 'b_id, b_changelog', 'downloads_filebackup', array( "b_changelog is not null and b_changelog != ''" ), 'b_id ASC', array( $limit, $perCycle ) ) as $backup )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
if( mb_strpos( $backup['b_changelog'], '<p' ) === FALSE AND mb_strpos( $backup['b_changelog'], '<ul' ) === FALSE )
{
$contents = explode( "\n", str_replace( "\r", '', $backup['b_changelog'] ) );
$newContents = "<ul><li>" . implode( "</li><li>", $contents ) . "</li></ul>";
\IPS\Db::i()->update( 'downloads_filebackup', array( 'b_changelog' => $newContents ), array( 'b_id=?', $backup['b_id'] ) );
}
}
if( $did )
{
return ( $limit + $did );
}
else
{
unset( $_SESSION['_step1Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step1Count'] ) )
{
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_filebackup', array( "b_changelog is not null and b_changelog != ''" ) )->first();
}
return "Upgrading backup changelogs (Upgraded so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
}
/**
* Step 2
* Fix downloads changelog
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step2()
{
$limit = 0;
$did = 0;
$perCycle = 500;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( 'file_id, file_changelog', 'downloads_files', array( "file_changelog is not null and file_changelog != ''" ), 'file_id ASC', array( $limit, $perCycle ) ) as $file )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
if( mb_strpos( $file['file_changelog'], '<p' ) === FALSE AND mb_strpos( $file['file_changelog'], '<ul' ) === FALSE )
{
$contents = explode( "\n", str_replace( "\r", '', $file['file_changelog'] ) );
$newContents = "<ul><li>" . implode( "</li><li>", $contents ) . "</li></ul>";
\IPS\Db::i()->update( 'downloads_files', array( 'file_changelog' => $newContents ), array( 'file_id=?', $file['file_id'] ) );
}
}
if( $did )
{
return ( $limit + $did );
}
else
{
unset( $_SESSION['_step2Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step2CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step2Count'] ) )
{
$_SESSION['_step2Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files', array( "file_changelog is not null and file_changelog != ''" ) )->first();
}
return "Upgrading file changelogs (Upgraded so far: " . ( ( $limit > $_SESSION['_step2Count'] ) ? $_SESSION['_step2Count'] : $limit ) . ' out of ' . $_SESSION['_step2Count'] . ')';
}
/**
* Step 3
* Fix currency
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step3()
{
if( !isset( \IPS\Settings::i()->nexus_currency ) or !\IPS\Application::appIsEnabled( 'nexus', TRUE ) )
{
return TRUE;
}
$limit = 0;
$did = 0;
$perCycle = 500;
if( isset( \IPS\Request::i()->extra ) )
{
$limit = (int) \IPS\Request::i()->extra;
}
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( 'file_id, file_cost, file_renewal_price', 'downloads_files', array( "file_cost is not null and file_cost != ''" ), 'file_id ASC', array( $limit, $perCycle ) ) as $file )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$update = array();
/* Base price */
$costs = @json_decode( $file['file_cost'], TRUE );
if( !is_array( $costs ) and $file['file_cost'] )
{
$costs = array();
foreach( \IPS\nexus\Money::currencies() as $currency )
{
$costs[ $currency ] = array( 'amount' => $file['file_cost'], 'currency' => $currency );
}
$update['file_cost'] = json_encode( $costs );
}
/* Renewal price */
$costs = @json_decode( $file['file_renewal_price'], TRUE );
if( !is_array( $costs ) )
{
$costs = array();
foreach( \IPS\nexus\Money::currencies() as $currency )
{
$costs[ $currency ] = array( 'amount' => $file['file_renewal_price'], 'currency' => $currency );
}
$update['file_renewal_price'] = json_encode( $costs );
}
if( count( $update ) )
{
\IPS\Db::i()->update( 'downloads_files', $update, array( 'file_id=?', $file['file_id'] ) );
}
}
if( $did )
{
return ( $limit + $did );
}
else
{
unset( $_SESSION['_step3Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step3CustomTitle()
{
if( !isset( \IPS\Settings::i()->nexus_currency ) )
{
return "No file costs to update";
}
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step3Count'] ) )
{
$_SESSION['_step3Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_files', array( "file_cost is not null and file_cost != ''" ) )->first();
}
return "Upgrading file costs (Upgraded so far: " . ( ( $limit > $_SESSION['_step3Count'] ) ? $_SESSION['_step3Count'] : $limit ) . ' out of ' . $_SESSION['_step3Count'] . ')';
}
}
Whitespace-only changes.
@@ -0,0 +1,23 @@
{
"1": {
"method": "changeColumn",
"params": [
"downloads_reviews",
"review_votes_data",
{
"name": "review_votes_data",
"type": "TEXT",
"length": 0,
"decimals": null,
"values": [],
"allow_null": true,
"default": "",
"comment": "JSON object containing data about who has voted helpful\/unhelpful ",
"unsigned": false,
"zerofill": false,
"auto_increment": false,
"binary": false
}
]
}
}
Whitespace-only changes.
@@ -0,0 +1,83 @@
<?php
/**
* @brief 4.0.0 RC 1 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 3 Feb 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\setup\upg_100011;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 RC 1 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Rebuild last poster data
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
$perCycle = 50;
$did = 0;
$limit = intval( \IPS\Request::i()->extra );
/* Try to prevent timeouts to the extent possible */
$cutOff = \IPS\core\Setup\Upgrade::determineCutoff();
foreach( \IPS\Db::i()->select( '*', 'downloads_categories', NULL, 'cid ASC', array( $limit, $perCycle ) ) as $category )
{
if( $cutOff !== null AND time() >= $cutOff )
{
return ( $limit + $did );
}
$did++;
$category = \IPS\downloads\Category::constructFromData( $category );
$category->setLastComment();
$category->save();
}
if( $did )
{
return ( $limit + $did );
}
else
{
unset( $_SESSION['_step1Count'] );
return TRUE;
}
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
$limit = isset( \IPS\Request::i()->extra ) ? \IPS\Request::i()->extra : 0;
if( !isset( $_SESSION['_step1Count'] ) )
{
$_SESSION['_step1Count'] = \IPS\Db::i()->select( 'COUNT(*)', 'downloads_categories' )->first();
}
return "Rebuilding last poster data for download categories (Upgraded so far: " . ( ( $limit > $_SESSION['_step1Count'] ) ? $_SESSION['_step1Count'] : $limit ) . ' out of ' . $_SESSION['_step1Count'] . ')';
}
}
Whitespace-only changes.
@@ -0,0 +1,81 @@
<?php
/**
* @brief 4.0.0 RC 1 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 5 Feb 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\setup\upg_100012;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 RC 1 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Fixing custom fields
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields' ) as $field )
{
$update = array();
switch( $field['cf_type'] )
{
case 'input':
$update['cf_type'] = 'Text';
break;
case 'textarea':
$update['cf_type'] = 'TextArea';
break;
case 'drop':
$update['cf_type'] = 'Select';
break;
case 'radio':
$update['cf_type'] = 'Radio';
break;
case 'cbox':
$update['cf_type'] = 'Select';
$update['cf_multiple'] = TRUE;
break;
}
if( count( $update ) )
{
\IPS\Db::i()->update( 'downloads_cfields', $update, 'cf_id=' . $field['cf_id'] );
}
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Fixing downloads custom fields";
}
}
Whitespace-only changes.
@@ -0,0 +1,66 @@
<?php
/**
* @brief 4.0.0 RC 1 Upgrade Code
* @author <a href='http://www.invisionpower.com'>Invision Power Services, Inc.</a>
* @copyright (c) 2001 - SVN_YYYY Invision Power Services, Inc.
* @license http://www.invisionpower.com/legal/standards/
* @package IPS Social Suite
* @subpackage Downloads
* @since 9 Feb 2015
* @version SVN_VERSION_NUMBER
*/
namespace IPS\downloads\setup\upg_100013;
/* To prevent PHP errors (extending class does not exist) revealing path */
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
{
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
exit;
}
/**
* 4.0.0 RC 1 Upgrade Code
*/
class _Upgrade
{
/**
* Step 1
* Fixing custom fields
*
* @return array If returns TRUE, upgrader will proceed to next step. If it returns any other value, it will set this as the value of the 'extra' GET parameter and rerun this step (useful for loops)
*/
public function step1()
{
foreach( \IPS\Db::i()->select( '*', 'downloads_cfields' ) as $field )
{
if( $field['cf_type'] == 'Select' )
{
try
{
\IPS\Db::i()->dropIndex( 'downloads_ccontent', "field_" . $field['cf_id'] );
\IPS\Db::i()->dropColumn( 'downloads_ccontent', "field_" . $field['cf_id'] );
}
catch ( \IPS\Db\Exception $e )
{
}
\IPS\Db::i()->addColumn( 'downloads_ccontent', array( 'name' => "field_" . $field['cf_id'], 'type' => 'TEXT' ) );
\IPS\Db::i()->addIndex( 'downloads_ccontent', array( 'type' => 'key', 'name' => "field_" . $field['cf_id'], 'columns' => array( "field_" . $field['cf_id'] ) ) );
}
}
return TRUE;
}
/**
* Custom title for this step
*
* @return string
*/
public function step1CustomTitle()
{
return "Fixing downloads custom fields";
}
}
Loaded 100 of 7517 files, more files were not shown because too many files have changed in this diff. Show more