Version 4.6.0

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

No files matched your search

+108 -23
View File
@@ -98,7 +98,7 @@ abstract class _File
*/
public static function getClass( $storageExtension, $tryOldFirst=FALSE )
{
static::getConfigurations();
static::getStore();
$configurationId = NULL;
if ( \is_int( $storageExtension ) )
@@ -247,17 +247,6 @@ abstract class _File
return static::$storageConfigurations;
}
/**
* Load storage configurations
*
* @return array
* @deprecated
*/
public static function getConfigurations()
{
return static::getStore();
}
/**
* @brief Copy files instead of moving them
*/
@@ -301,7 +290,7 @@ abstract class _File
/* Image-specific stuff */
$ext = mb_substr( $filename, ( mb_strrpos( $filename, '.' ) + 1 ) );
if( \in_array( mb_strtolower( $ext ), \IPS\Image::$imageExtensions ) and ( !$isSafe or \IPS\Image::exifSupported() ) )
if( \in_array( mb_strtolower( $ext ), \IPS\Image::supportedExtensions() ) and ( !$isSafe or \IPS\Image::exifSupported() ) )
{
/* Get contents */
if( $data === NULL AND $filePath !== NULL )
@@ -428,6 +417,12 @@ abstract class _File
}
}
/* Check that the filename doesn't have an invalid bytecode sequence */
if( !preg_match( '//u', $file['name'] ) )
{
throw new \DomainException( 'upload_error', 4 );
}
if( $callback !== NULL )
{
$contents = file_get_contents( $file['tmp_name'] );
@@ -583,10 +578,10 @@ abstract class _File
}
/* If it's got an image extension, check it's actually a valid image */
if ( \in_array( $ext, \IPS\Image::$imageExtensions ) AND !isset( $file['_skipUploadCheck'] ) )
if ( \in_array( $ext, \IPS\Image::supportedExtensions() ) AND !isset( $file['_skipUploadCheck'] ) )
{
$imageAttributes = getimagesize( $file['tmp_name'] );
if( !\in_array( $imageAttributes[2], array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG ) ) )
if( !\in_array( $imageAttributes[2], array( IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG, IMAGETYPE_WEBP ) ) )
{
throw new \DomainException( 'upload_error', 4 );
}
@@ -686,7 +681,7 @@ abstract class _File
if ( static::isFullyQualifiedUrl( $url ) )
{
/* Loop through all configurations and remove the baseUrl() if it matches */
static::getConfigurations();
static::getStore();
foreach( static::$storageConfigurations as $id => $data )
{
@@ -1206,6 +1201,21 @@ abstract class _File
/* Return */
return $class;
}
/**
* Create a duplicate of this file in the same storage location but with a new filename
*
* @return \IPS\File
* @throws \RuntimeException
*/
public function duplicate()
{
$copyFiles = static::$copyFiles;
static::$copyFiles = TRUE;
$return = static::create( $this->storageExtension, $this->originalFilename, $this->contents(), $this->container, $this instanceof \IPS\File\FileSystem ? ( $this->configuration['dir'] . '/' . ( $this->container ? "{$this->container}/" : '' ) . $this->filename ) : NULL );
static::$copyFiles = $copyFiles;
return $return;
}
/**
* Copy a file to a different storage location
@@ -1217,7 +1227,7 @@ abstract class _File
public function copy( $storageConfiguration )
{
/* Load class */
static::getConfigurations();
static::getStore();
$handlers = static::storageHandlers( static::$storageConfigurations[ $storageConfiguration ] );
$classname = $handlers[ static::$storageConfigurations[ $storageConfiguration ]['method'] ];
$class = new $classname( json_decode( static::$storageConfigurations[ $storageConfiguration ]['configuration'], TRUE ) );
@@ -1268,6 +1278,11 @@ abstract class _File
* @brief Attachment thumbnail URL
*/
public $attachmentThumbnailUrl = NULL;
/**
* @brief Security Key
*/
public $securityKey = NULL;
/**
* Make into an attachment
@@ -1282,6 +1297,8 @@ abstract class _File
$ext = mb_substr( $this->originalFilename, mb_strrpos($this->originalFilename, '.') + 1 );
$memberId = ( $member and $member->member_id ) ? $member->member_id : 0;
$this->securityKey = \IPS\Login::generateRandomString();
$data = array(
'attach_ext' => $ext,
@@ -1298,7 +1315,8 @@ abstract class _File
'attach_filesize' => $this->filesize(),
'attach_img_width' => 0,
'attach_img_height' => 0,
'attach_is_archived' => FALSE
'attach_is_archived' => FALSE,
'attach_security_key' => $this->securityKey
);
/* If this is an image, grab the appropriate data */
@@ -1306,14 +1324,14 @@ abstract class _File
{
try
{
$thumbDims = \IPS\Settings::i()->attachment_image_size ? explode( 'x', \IPS\Settings::i()->attachment_image_size ) : array( 1000, 750 );
$thumbDims = \IPS\Settings::i()->attachment_image_size ? explode( 'x', \IPS\Settings::i()->attachment_image_size ) : [ 0, 0 ];
$dimensions = $this->getImageDimensions();
$data['attach_is_image'] = TRUE;
$data['attach_img_width'] = $dimensions[0];
$data['attach_img_height'] = $dimensions[1];
if ( $dimensions[0] > $thumbDims[0] or $dimensions[1] > $thumbDims[1] )
if ( ( isset( $thumbDims[0] ) and $thumbDims[0] and $dimensions[0] > $thumbDims[0] ) or ( isset( $thumbDims[1] ) and $thumbDims[1] and $dimensions[1] > $thumbDims[1] ) )
{
$data['attach_thumb_location'] = (string) $this->thumbnail( 'core_Attachment', $thumbDims[0], $thumbDims[1] );
$data['attach_thumb_width'] = static::$thumbnailDimensions[0];
@@ -1338,7 +1356,7 @@ abstract class _File
{
$ext = mb_substr( $this->originalFilename, mb_strrpos( $this->originalFilename, '.' ) + 1 );
if ( \in_array( mb_strtolower( $ext ), \IPS\Image::$imageExtensions ) )
if ( \in_array( mb_strtolower( $ext ), \IPS\Image::supportedExtensions() ) )
{
return TRUE;
}
@@ -1427,7 +1445,7 @@ abstract class _File
* @note If you call this, it is your responsibility to call unclaimAttachments if/when the thing is deleted
*/
public static function claimAttachments( $autoSaveKey, $id1=NULL, $id2=NULL, $id3=NULL, $translatable=FALSE )
{
{
if ( $translatable )
{
foreach ( \IPS\Lang::languages() as $lang )
@@ -1616,7 +1634,7 @@ abstract class _File
$firstBytes = \substr( $data, 0, 1024 );
/* @see https://mimesniff.spec.whatwg.org/#identifying-a-resource-with-an-unknown-mime-type */
if( preg_match( '#(<\!DOCTYPE\s+HTML|<script|<html|<head|<iframe|<h1|<div|<font|<table|<title|<style|<body|<pre|<table|<br|<a\s+href|<img|<plaintext|<cross\-domain\-policy|<\!\-\-|<\?xml)(\s|=|>)#si', $firstBytes, $matches ) )
if( preg_match( '#(<\!DOCTYPE\s+HTML|<script|<html|<head|<iframe|<h1|<div|<font|<table|<title|<style|<body|<pre|<table|<br|<a\s+href|<img|<plaintext|<cross\-domain\-policy|<\!\-\-|<\?xml)(\s|>)#si', $firstBytes, $matches ) )
{
return TRUE;
}
@@ -1677,6 +1695,25 @@ abstract class _File
return (float) $size;
}
/**
* Returns an icon to represent the file, based on its extension
*
* @param string filename The full filename
* @return string
*/
public static function getIconFromName( $filename )
{
$ext = pathinfo( $filename, PATHINFO_EXTENSION );
if( isset( static::$fileIconMap[ $ext ] ) )
{
return static::$fileIconMap[ $ext ];
}
return 'file-o';
}
/**
* Get output for API
@@ -1696,6 +1733,54 @@ abstract class _File
);
}
/**
* @brief Maps file extensions to fontawesome icons
*/
public static $fileIconMap = array(
'txt' => 'file-text-o',
'rtf' => 'file-text-o',
'csv' => 'file-text-o',
'pdf' => 'file-pdf-o',
'doc' => 'file-word-o',
'docx' => 'file-word-o',
'xls' => 'file-excel-o',
'xlsx' => 'file-excel-o',
'xlsm' => 'file-excel-o',
'zip' => 'file-archive-o',
'tar' => 'file-archive-o',
'gz' => 'file-archive-o',
'ppt' => 'file-powerpoint-o',
'pptx' => 'file-powerpoint-o',
'ico' => 'file-image-o',
'gif' => 'file-image-o',
'jpeg' => 'file-image-o',
'jpg' => 'file-image-o',
'jpe' => 'file-image-o',
'png' => 'file-image-o',
'psd' => 'file-image-o',
'aac' => 'file-audio-o',
'mp3' => 'file-audio-o',
'ogg' => 'file-audio-o',
'ogv' => 'file-audio-o',
'wav' => 'file-audio-o',
'avi' => 'file-video-o',
'flv' => 'file-video-o',
'mkv' => 'file-video-o',
'mp4' => 'file-video-o',
'mpg' => 'file-video-o',
'mpeg' => 'file-video-o',
'3gp' => 'file-video-o',
'webm' => 'file-video-o',
'wmv' => 'file-video-o',
'avi' => 'file-video-o',
'm4v' => 'file-video-o',
'mov' => 'file-video-o',
'css' => 'file-code-o',
'html' => 'file-code-o',
'js' => 'file-code-o',
'xml' => 'file-code-o',
);
/* !Mime-Type Map */
/**