Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit file upload size option #2823

Merged
merged 13 commits into from
Jan 24, 2019
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