Skip to content

Commit

Permalink
Merge pull request #2823 from CalderaWP/feature/1399
Browse files Browse the repository at this point in the history
 Limit file upload size option Fixes #1399
  • Loading branch information
Josh Pollock authored Jan 24, 2019
2 parents ce86c9e + a14b3c3 commit 6e707fd
Show file tree
Hide file tree
Showing 10 changed files with 403 additions and 127 deletions.
6 changes: 6 additions & 0 deletions cf2/Fields/Handlers/Cf1FileUploader.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ public function scheduleFileDelete($fieldId,$formId,$file)
{
return \Caldera_Forms_Files::schedule_delete($fieldId,$formId,$file);
}

/** @inheritdoc */
public function isFileTooLarge(array $field, $filePath)
{
return \Caldera_Forms_Files::is_file_too_large($field,$filePath);
}
}
268 changes: 145 additions & 123 deletions cf2/Fields/Handlers/FileUpload.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,146 +11,168 @@
class FileUpload
{

/**
* Field config
*
* @since 1.8.0
*
* @var array
*/
protected $field;
/**
* Form config
*
* @since 1.8.0
*
* @var array
*/
protected $form;

/**
* Upload handler
*
* @since 1.8.0
*
* @var UploaderContract
*/
protected $uploader;

/**
* FileUpload constructor.
*
* @since 1.8.0
*
* @param array $field Field config
* @param array $form Form config
* @param UploaderContract $uploader Upload handler to use
*/
public function __construct(array $field, array $form, UploaderContract $uploader)
{
$this->field = $field;
$this->form = $form;
$this->uploader = $uploader;
}


/**
* Process file upload
*
* @since 1.8.0
*
* @param array $files Files to process
* @param array $hashes Supplied file hashes to compare actual hashes against
* @return array
* @throws \Exception
*/
public function processFiles(array $files, array $hashes)
{
$uploads = [];
$i = 0;
foreach ($files as $file) {
if (!$this->isAllowedType($file)) {
/**
* Field config
*
* @since 1.8.0
*
* @var array
*/
protected $field;
/**
* Form config
*
* @since 1.8.0
*
* @var array
*/
protected $form;

/**
* Upload handler
*
* @since 1.8.0
*
* @var UploaderContract
*/
protected $uploader;

/**
* FileUpload constructor.
*
* @since 1.8.0
*
* @param array $field Field config
* @param array $form Form config
* @param UploaderContract $uploader Upload handler to use
*/
public function __construct(array $field, array $form, UploaderContract $uploader)
{
$this->field = $field;
$this->form = $form;
$this->uploader = $uploader;
}


/**
* Process file upload
*
* @since 1.8.0
*
* @param array $files Files to process
* @param array $hashes Supplied file hashes to compare actual hashes against
*
* @return array
* @throws \Exception
*/
public function processFiles(array $files, array $hashes)
{
$uploads = [];
$i = 0;
foreach ( $files as $file ) {
if ( !$this->isAllowedType($file) ) {
throw new Exception(__('This file type is not allowed. Please try another.', 'caldera-forms'), 415);
}

$hashFromRequest = $hashes[$i];
$actualHash = md5_file($file['tmp_name']);
if( $this->isFileTooLarge($file)){
throw new Exception(__('This file is too large. Please try another.', 'caldera-forms'), 415);
}

$hashFromRequest = $hashes[ $i ];
$actualHash = md5_file($file[ 'tmp_name' ]);

if (! hash_equals($actualHash, $hashFromRequest) ) {
throw new Exception(__( 'Content hash did not match expected.' ), 412 );
}
if ( !hash_equals($actualHash, $hashFromRequest) ) {
throw new Exception(__('Content hash did not match expected.'), 412);
}

$isPrivate = \Caldera_Forms_Files::is_private($this->field);

$this->uploader
->addFilter(
$this->field['ID'],
$this->form['ID'],
$isPrivate,
->addFilter(
$this->field[ 'ID' ],
$this->form[ 'ID' ],
$isPrivate,
$actualHash
);
);

require_once(ABSPATH . 'wp-admin/includes/file.php');
$upload = wp_handle_upload($file, array('test_form' => false, 'action' => 'foo'));
require_once(ABSPATH . 'wp-admin/includes/file.php');
$upload = wp_handle_upload($file, [ 'test_form' => false, 'action' => 'foo' ]);

$this->uploader->removeFilter();
if (\Caldera_Forms_Files::should_attach($this->field, $this->form)) {
\Caldera_Forms_Files::add_to_media_library($upload, $this->field);
}
$this->uploader->removeFilter();
if ( \Caldera_Forms_Files::should_attach($this->field, $this->form) ) {
\Caldera_Forms_Files::add_to_media_library($upload, $this->field);
}

if( $isPrivate ){
if ( $isPrivate ) {
$this->uploader->scheduleFileDelete(
$this->field['ID'],
$this->form['ID'],
$upload['file']
$this->field[ 'ID' ],
$this->form[ 'ID' ],
$upload[ 'file' ]
);
}


$uploads[] = $upload['url'];
$i++;

}

return $uploads;
}

/**
* Check if file type if allowed for this field
*
* @since 1.8.0
*
* @param $file
* @return bool
* @throws Exception
*/
public function isAllowedType($file)
{
if (empty($this->field['config']['allowed'])) {
return true;
}
$fileName = ! empty( $file[ 'name' ] ) ? $file[ 'name' ] :basename($file['tmp_name']);
$filetype = wp_check_filetype(basename($fileName), null);
return in_array(strtolower($filetype['ext']), $this->getAllowedTypes());
}

/**
* Get allowed file types for file field
*
* @since 1.8.0
*
* @return array
*/
public function getAllowedTypes()
{
$types = !empty($this->field['config']['allowed']) ? $this->field['config']['allowed'] : [];
if (!is_array($types)) {
$types = explode(',', $types);
}
if( in_array( 'jpg', $types ) && ! in_array( 'jpeg', $types ) ){
$types[] = 'jpeg';
$uploads[] = $upload[ 'url' ];
$i++;

}

return $uploads;
}

/**
* Check if file type if allowed for this field
*
* @since 1.8.0
*
* @param $file
*
* @return bool
* @throws Exception
*/
public function isAllowedType($file)
{
if ( empty($this->field[ 'config' ][ 'allowed' ]) ) {
return true;
}
$fileName = !empty($file[ 'name' ]) ? $file[ 'name' ] : basename($file[ 'tmp_name' ]);
$filetype = wp_check_filetype(basename($fileName), null);
return in_array(strtolower($filetype[ 'ext' ]), $this->getAllowedTypes());
}


/**
* Check if file is too large
*
* @since 1.8.0
*
* @param $file
*
* @return bool
*/
public function isFileTooLarge($file)
{
return $this->uploader->isFileTooLarge($this->field, $file);

}

/**
* Get allowed file types for file field
*
* @since 1.8.0
*
* @return array
*/
public function getAllowedTypes()
{
$types = !empty($this->field[ 'config' ][ 'allowed' ]) ? $this->field[ 'config' ][ 'allowed' ] : [];
if ( !is_array($types) ) {
$types = explode(',', $types);
}
if ( in_array('jpg', $types) && !in_array('jpeg', $types) ) {
$types[] = 'jpeg';
}
return $types;
}
return $types;
}

}
12 changes: 12 additions & 0 deletions cf2/Fields/Handlers/UploaderContract.php
Original file line number Diff line number Diff line change
Expand Up @@ -51,4 +51,16 @@ public function removeFilter();
* @return bool
*/
public function scheduleFileDelete($fieldId,$formId,$file);

/**
* Check if file is too large to upload
*
* @since 1.8.0
*
* @param array $field Field config
* @param string $filePath Path to file to check
*
* @return bool
*/
public function isFileTooLarge(array $field,$filePath);
}
33 changes: 33 additions & 0 deletions classes/files.php
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,39 @@ public static function is_persistent(array $field ){
return self::should_add_to_media_library($field) || ! empty( $field['config']['persistent']);
}

/**
* Get max size for file field
*
* @since 1.8.0
*
* @param array $field Field config
*
* @return int
*/
public static function get_max_upload_size( array $field)
{
return ! empty( $field[ 'config']['max_upload'] ) ? absint( $field[ 'config']['max_upload']) : 0;
}

/**
* Check if a file is too large to upload
*
* @since 1.8.0
*
* Returns false if no max upload size set.
* Returns true if max upload size option is set and file is larger than limit
*
* @param array $field Field config
* @param string $path_to_file Path to check against
*
* @return bool
*/
public static function is_file_too_large( array $field, $path_to_file )
{

return 0 !== self::get_max_upload_size($field) && self::get_max_upload_size($field) < $path_to_file['size'];

}
/**
* Check if a file field should upload to media library.
**
Expand Down
Loading

0 comments on commit 6e707fd

Please sign in to comment.