Version 4.5.0
This commit is contained in:
1 parent
1a0c7fd3c2
commit
f79dcf067a
3791 files changed
+248032
-76372
No files matched your search
@@ -12,7 +12,7 @@
|
||||
namespace IPS\downloads\api;
|
||||
|
||||
/* To prevent PHP errors (extending class does not exist) revealing path */
|
||||
if ( !defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
if ( !\defined( '\IPS\SUITE_UNIQUE_KEY' ) )
|
||||
{
|
||||
header( ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' ) . ' 403 Forbidden' );
|
||||
exit;
|
||||
@@ -39,7 +39,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* @apiparam int hidden If 1, only files which are hidden are returned, if 0 only not hidden
|
||||
* @apiparam int pinned If 1, only files which are pinned are returned, if 0 only not pinned
|
||||
* @apiparam int featured If 1, only files which are featured are returned, if 0 only not featured
|
||||
* @apiparam string sortBy What to sort by. Can be 'date' for creation date, 'title' or leave unspecified for ID
|
||||
* @apiparam string sortBy What to sort by. Can be 'date' for creation date, 'title', 'updated', 'popular' or leave unspecified for ID
|
||||
* @apiparam string sortDir Sort direction. Can be 'asc' or 'desc' - defaults to 'asc'
|
||||
* @apiparam int page Page number
|
||||
* @apiparam int perPage Number of results per page - defaults to 25
|
||||
@@ -49,9 +49,18 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
{
|
||||
/* Where clause */
|
||||
$where = array();
|
||||
|
||||
$sortBy = NULL;
|
||||
|
||||
/* Sort by popular files */
|
||||
if( \IPS\Request::i()->sortBy == 'popular' )
|
||||
{
|
||||
\IPS\Request::i()->sortDir = \IPS\Request::i()->sortDir ?: 'ASC';
|
||||
$sortBy = 'file_rating ' . \IPS\Request::i()->sortDir . ', file_reviews';
|
||||
$where = array( array( 'file_rating>?', 0 ) );
|
||||
}
|
||||
|
||||
/* Return */
|
||||
return $this->_list( $where, 'categories' );
|
||||
return $this->_list( $where, 'categories', FALSE, $sortBy );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +70,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* @param int $id ID Number
|
||||
* @apiparam int version If specified, will show a previous version of a file (see GET /downloads/files/{id}/versions)
|
||||
* @throws 2S303/1 INVALID_ID The file ID does not exist or the authorized user does not have permission to view it
|
||||
* @throws 2S303/1 INVALID_VERSION The version ID does not exist
|
||||
* @throws 2S303/6 INVALID_VERSION The version ID does not exist
|
||||
* @return \IPS\downloads\File
|
||||
*/
|
||||
public function GETitem( $id )
|
||||
@@ -101,7 +110,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* POST /downloads/files
|
||||
* Upload a file
|
||||
*
|
||||
* @note For requests using an OAuth Access Token for a particular member, any parameters the user doesn't have permission to use are ignored (for example, locked will only be honoured if the authentictaed user has permission to lock files).
|
||||
* @note For requests using an OAuth Access Token for a particular member, any parameters the user doesn't have permission to use are ignored (for example, locked will only be honoured if the authenticated user has permission to lock files).
|
||||
* @reqapiparam int category The ID number of the calendar the file should be created in
|
||||
* @reqapiparam int author The ID number of the member creating the file (0 for guest). Required for requests made using an API Key or the Client Credentials Grant Type. For requests using an OAuth Access Token for a particular member, that member will always be the author
|
||||
* @reqapiparam string title The file name
|
||||
@@ -179,7 +188,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
}
|
||||
|
||||
/* Validate files */
|
||||
if ( !isset( \IPS\Request::i()->files ) or !is_array( \IPS\Request::i()->files ) or empty( \IPS\Request::i()->files ) )
|
||||
if ( !isset( \IPS\Request::i()->files ) or !\is_array( \IPS\Request::i()->files ) or empty( \IPS\Request::i()->files ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_FILES', '1L296/B', 400 );
|
||||
}
|
||||
@@ -249,7 +258,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
if ( $category->types )
|
||||
{
|
||||
$ext = mb_substr( $name, mb_strrpos( $name, '.' ) + 1 );
|
||||
if( !in_array( mb_strtolower( $ext ), array_map( 'mb_strtolower', $category->types ) ) )
|
||||
if( !\in_array( mb_strtolower( $ext ), array_map( 'mb_strtolower', $category->types ) ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'BAD_FILE_EXT', '1S303/I', 400 );
|
||||
}
|
||||
@@ -308,11 +317,11 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* @apiparam string description The description as HTML (e.g. "<p>This is an file.</p>"). Will be sanatized for requests using an OAuth Access Token for a particular member; will be saved unaltered for requests made using an API Key or the Client Credentials Grant Type.
|
||||
* @apiparam string prefix Prefix tag
|
||||
* @apiparam string tags Comma-separated list of tags (do not include prefix)
|
||||
* @apiparam datetime date The date/time that should be used for the file post date. If not provided, will use the current date/time. Ignored for requests using an OAuth Access Token for a particular member.
|
||||
* @apiparam string ip_address The IP address that should be stored for the file. If not provided, will use the IP address from the API request. Ignored for requests using an OAuth Access Token for a particular member.
|
||||
* @apiparam int locked 1/0 indicating if the file should be locked
|
||||
* @apiparam int hidden 0 = unhidden; 1 = hidden, pending moderator approval; -1 = hidden (as if hidden by a moderator)
|
||||
* @apiparam int featured 1/0 indicating if the file should be featured
|
||||
* @param int $id ID Number
|
||||
* @throws 2S303/C INVALID_ID The file ID is invalid or the authorized user does not have permission to view it
|
||||
* @throws 1S303/D NO_CATEGORY The category ID does not exist or the authorized user does not have permission to post in it
|
||||
* @throws 1S303/E NO_AUTHOR The author ID does not exist
|
||||
@@ -435,7 +444,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
protected function _recalculate( $file )
|
||||
{
|
||||
/* File size */
|
||||
$file->size = floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $file->id, 'upload' ) )->first() );
|
||||
$file->size = \floatval( \IPS\Db::i()->select( 'SUM(record_size)', 'downloads_files_records', array( 'record_file_id=? AND record_type=? AND record_backup=0', $file->id, 'upload' ) )->first() );
|
||||
|
||||
/* Work out the new primary screenshot */
|
||||
try
|
||||
@@ -471,6 +480,80 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2S303/2', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /downloads/files/{id}/download
|
||||
* Download a file, increments download counter
|
||||
*
|
||||
* @apimemberonly
|
||||
* @param int $id ID Number
|
||||
* @apiparam int version If specified, will show a previous version of a file (see GET /downloads/files/{id}/versions)
|
||||
* @return array
|
||||
* @throws 2S303/M INVALID_ID The file ID does not exist or the authorized user does not have permission to view it
|
||||
* @throws 2S303/N NO_PERMISSION The file cannot be downloaded by the authorized member
|
||||
* @throws 2S303/O INVALID_VERSION The version ID does not exist
|
||||
* @apiresponse [\IPS\File] files The files
|
||||
*/
|
||||
public function GETitem_download( $id )
|
||||
{
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $id );
|
||||
$backup = FALSE;
|
||||
if ( $this->member and !$file->can( 'read', $this->member ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
|
||||
if ( !$file->canDownload( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2S303/N', 404 );
|
||||
}
|
||||
|
||||
if ( isset( \IPS\Request::i()->version ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
$backup = \IPS\Db::i()->select( '*', 'downloads_filebackup', array( 'b_id=? AND b_fileid=?', \IPS\Request::i()->version, $file->id ) )->first();
|
||||
}
|
||||
catch ( \UnderflowException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_VERSION', '2S303/O', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $file->container()->log !== 0 )
|
||||
{
|
||||
\IPS\Db::i()->insert( 'downloads_downloads', array(
|
||||
'dfid' => $file->id,
|
||||
'dtime' => time(),
|
||||
'dip' => \IPS\Request::i()->ipAddress(),
|
||||
'dmid' => (int) $this->member->member_id,
|
||||
'dsize' => 0,
|
||||
'dua' => 'REST API',
|
||||
'dbrowsers' => '',
|
||||
'dos' => ''
|
||||
) );
|
||||
}
|
||||
|
||||
$file->downloads++;
|
||||
$file->save();
|
||||
|
||||
if ( \IPS\Application::appIsEnabled( 'nexus' ) and \IPS\Settings::i()->idm_nexus_on and ( $file->cost or $file->nexus ) )
|
||||
{
|
||||
\IPS\nexus\Customer::load( $this->member->member_id )->log( 'download', array( 'type' => 'idm', 'id' => $file->id, 'name' => $file->name ) );
|
||||
}
|
||||
|
||||
$member = $this->member;
|
||||
return new \IPS\Api\Response( 200, array( 'files' => array_values( array_map( function( $file ) use ( $member ) {
|
||||
return $file->apiOutput( $member );
|
||||
}, iterator_to_array( $file->files( $backup ? $backup['b_id'] : NULL ) ) ) ) ) );
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2S303/M', 404 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* GET /downloads/files/{id}/reviews
|
||||
@@ -506,6 +589,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* @apiresponse int id The version ID number (use to get more information about this version in GET /downloads/files/{id})
|
||||
* @apiresponse string version The version number provided by the user
|
||||
* @apiresponse string changelog What was new in this version
|
||||
* @apiresponse datetime date Datetime the backup was stored
|
||||
* @apiresponse bool hidden If this version is hidden
|
||||
*/
|
||||
public function GETitem_history( $id )
|
||||
@@ -527,6 +611,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
'version' => $backup['b_version'],
|
||||
'changelog' => $backup['b_changelog'],
|
||||
'hidden' => (bool) $backup['b_hidden'],
|
||||
'date' => \IPS\DateTime::ts( $backup['b_backup'] )->rfc3339()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -549,9 +634,11 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
* @apiparam int save If 1 this will be saved as a new version and the previous version available in the history. If 0, will simply replace the existing files/screenshots. Defaults to 1. Ignored if category does not have versioning enabled or authorized user does not have permission to disable.
|
||||
* @reqapiparam object files Files. Keys should be filename (e.g. 'file.txt') and values should be file content - will replace all current files
|
||||
* @apiparam object screenshots Screenshots. Keys should be filename (e.g. 'screenshot1.png') and values should be file content - will replace all current screenshots
|
||||
* @param int $id ID Number
|
||||
* @throws 2S303/F INVALID_ID The file ID is invalid or the authorized user does not have permission to view it
|
||||
* @throws 1S303/G NO_FILES No files were supplied
|
||||
* @throws 2S303/Q NO_PERMISSION The authorized user does not have permission to edit the file
|
||||
* @throws 2S303/P PENDING_VERSION The file already has a new version waiting for approval, this version must be deleted or approved by a moderator first.
|
||||
* @throws 1S303/I BAD_FILE_EXT One of the files has a file type that is not allowed
|
||||
* @throws 1S303/J BAD_FILE_SIZE One of the files is too big
|
||||
* @throws 1S303/K BAD_SS One of the screenshots is not a valid image
|
||||
@@ -574,10 +661,14 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_PERMISSION', '2S303/O', 403 );
|
||||
}
|
||||
if( $file->hasPendingVersion() )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'PENDING_VERSION', '2S303/P', 403 );
|
||||
}
|
||||
$category = $file->container();
|
||||
|
||||
/* Validate files */
|
||||
if ( !isset( \IPS\Request::i()->files ) or !is_array( \IPS\Request::i()->files ) or empty( \IPS\Request::i()->files ) )
|
||||
if ( !isset( \IPS\Request::i()->files ) or !\is_array( \IPS\Request::i()->files ) or empty( \IPS\Request::i()->files ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NO_FILES', '1L296/B', 400 );
|
||||
}
|
||||
@@ -607,7 +698,7 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
{
|
||||
foreach ( \IPS\Db::i()->select( 'record_location', 'downloads_files_records', array( 'record_file_id=?', $file->id ) ) as $record )
|
||||
{
|
||||
if ( in_array( $record['record_type'], array( 'upload', 'ssupload' ) ) )
|
||||
if ( \in_array( $record['record_type'], array( 'upload', 'ssupload' ) ) )
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -679,6 +770,128 @@ class _files extends \IPS\Content\Api\ItemController
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* POST /downloads/files/{id}/buy
|
||||
* Generate an invoice to buy a file
|
||||
*
|
||||
* @apimemberonly
|
||||
* @param int $id ID Number
|
||||
* @apiparam string currency Desired currency. If not specified, will use member's default
|
||||
* @apiparam string returnUri The URI to return to after payment is complete. If not specified, will redirect back to the file URI
|
||||
* @return \IPS\nexus\Invoice
|
||||
* @throws 2S303/V INVALID_ID The file ID does not exist or the authorized user does not have permission to view it
|
||||
* @throws 1S303/R CANNOT_BUY The member cannot buy the file
|
||||
* @throws 1S303/S NOT_PURCHASABLE The file is not currently purchasable
|
||||
* @throws 1S303/T BUY_PRODUCT The file cannot be bought directly - direct user to buy associated product
|
||||
* @throws 1S303/U INVALID_CURRENCY The currency specified is not available
|
||||
*/
|
||||
public function POSTitem_buy( $id )
|
||||
{
|
||||
/* Get the file */
|
||||
try
|
||||
{
|
||||
$file = \IPS\downloads\File::load( $id );
|
||||
if ( $this->member and !$file->can( 'read', $this->member ) )
|
||||
{
|
||||
throw new \OutOfRangeException;
|
||||
}
|
||||
}
|
||||
catch ( \OutOfRangeException $e )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_ID', '2S303/V', 404 );
|
||||
}
|
||||
$customer = \IPS\nexus\Customer::load( $this->member->member_id );
|
||||
|
||||
/* Can we buy? */
|
||||
if ( !$file->canBuy( $this->member ) )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'CANNOT_BUY', '2S303/R', 403 );
|
||||
}
|
||||
if ( !$file->isPurchasable() )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'NOT_PURCHASABLE', '2S303/S', 403 );
|
||||
}
|
||||
|
||||
/* Is it associated with a Nexus product? */
|
||||
if ( $file->nexus )
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'BUY_PRODUCT', '2S303/T', 400 );
|
||||
}
|
||||
|
||||
/* Work out which currency to use */
|
||||
if ( isset( \IPS\Request::i()->currency ) )
|
||||
{
|
||||
if ( \in_array( \IPS\Request::i()->currency, \IPS\nexus\Money::currencies() ) )
|
||||
{
|
||||
$currency = \IPS\Request::i()->currency;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_CURRENCY', '1S303/U', 400 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$currency = $customer->defaultCurrency();
|
||||
}
|
||||
|
||||
/* Work out the price */
|
||||
$costs = json_decode( $file->cost, TRUE );
|
||||
if ( \is_array( $costs ) )
|
||||
{
|
||||
if ( isset( $costs[ $currency ]['amount'] ) and $costs[ $currency ]['amount'] )
|
||||
{
|
||||
$price = new \IPS\nexus\Money( $costs[ $currency ]['amount'], $currency );
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new \IPS\Api\Exception( 'INVALID_CURRENCY', '1S303/U', 400 );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$price = new \IPS\nexus\Money( $cost, $currency );
|
||||
}
|
||||
|
||||
/* Create the item */
|
||||
$item = new \IPS\downloads\extensions\nexus\Item\File( $file->name, $price );
|
||||
$item->id = $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 = $file->renewalTerm();
|
||||
$item->payTo = $file->author();
|
||||
$item->commission = \IPS\Settings::i()->idm_nexus_percent;
|
||||
if ( $fees = json_decode( \IPS\Settings::i()->idm_nexus_transfee, TRUE ) and isset( $fees[ $price->currency ] ) )
|
||||
{
|
||||
$item->fee = new \IPS\nexus\Money( $fees[ $price->currency ]['amount'], $price->currency );
|
||||
}
|
||||
|
||||
/* Generate the invoice */
|
||||
$invoice = new \IPS\nexus\Invoice;
|
||||
$invoice->currency = $currency;
|
||||
$invoice->member = $customer;
|
||||
$invoice->addItem( $item );
|
||||
if ( \IPS\Request::i()->returnUri )
|
||||
{
|
||||
$invoice->return_uri = \IPS\Request::i()->returnUri;
|
||||
}
|
||||
else
|
||||
{
|
||||
$invoice->return_uri = "app=downloads&module=downloads&controller=view&id={$file->id}";
|
||||
}
|
||||
$invoice->save();
|
||||
|
||||
/* Return */
|
||||
return new \IPS\Api\Response( 200, $invoice->apiOutput( $this->member ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* DELETE /downloads/files/{id}
|
||||
* Delete a file
|
||||
|
||||
Reference in new issue
Block a user