Better handling of max file upload size according to PHP settings
- Allow unlimited size - Better parsing of PHP size Fixes #4896
This commit is contained in:
parent
6e84f41517
commit
b138a99ce3
|
|
@ -21,7 +21,7 @@ class ProjectFileController extends BaseController
|
||||||
|
|
||||||
$this->response->html($this->template->render('project_file/create', array(
|
$this->response->html($this->template->render('project_file/create', array(
|
||||||
'project' => $project,
|
'project' => $project,
|
||||||
'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()),
|
'max_size' => get_upload_max_size(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ class TaskFileController extends BaseController
|
||||||
|
|
||||||
$this->response->html($this->template->render('task_file/create', array(
|
$this->response->html($this->template->render('task_file/create', array(
|
||||||
'task' => $task,
|
'task' => $task,
|
||||||
'max_size' => $this->helper->text->phpToBytes(get_upload_max_size()),
|
'max_size' => get_upload_max_size(),
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,29 +71,6 @@ class TextHelper extends Base
|
||||||
return round(pow(1024, $base - floor($base)), $precision).$suffixes[(int)floor($base)];
|
return round(pow(1024, $base - floor($base)), $precision).$suffixes[(int)floor($base)];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of bytes from PHP size
|
|
||||||
*
|
|
||||||
* @param integer $val PHP size (example: 2M)
|
|
||||||
* @return integer
|
|
||||||
*/
|
|
||||||
public function phpToBytes($val)
|
|
||||||
{
|
|
||||||
$size = (int) substr($val, 0, -1);
|
|
||||||
$last = strtolower(substr($val, -1));
|
|
||||||
|
|
||||||
switch ($last) {
|
|
||||||
case 'g':
|
|
||||||
$size *= 1024;
|
|
||||||
case 'm':
|
|
||||||
$size *= 1024;
|
|
||||||
case 'k':
|
|
||||||
$size *= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $size;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true if needle is contained in the haystack
|
* Return true if needle is contained in the haystack
|
||||||
*
|
*
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
'labelDropzone' => t('Drag and drop your files here'),
|
'labelDropzone' => t('Drag and drop your files here'),
|
||||||
'labelOr' => t('or'),
|
'labelOr' => t('or'),
|
||||||
'labelChooseFiles' => t('choose files'),
|
'labelChooseFiles' => t('choose files'),
|
||||||
'labelOversize' => t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)),
|
'labelOversize' => $max_size > 0 ? t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)) : null,
|
||||||
'labelSuccess' => t('All files have been uploaded successfully.'),
|
'labelSuccess' => t('All files have been uploaded successfully.'),
|
||||||
'labelCloseSuccess' => t('Close this window'),
|
'labelCloseSuccess' => t('Close this window'),
|
||||||
'labelUploadError' => t('Unable to upload this file.'),
|
'labelUploadError' => t('Unable to upload this file.'),
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
'labelDropzone' => t('Drag and drop your files here'),
|
'labelDropzone' => t('Drag and drop your files here'),
|
||||||
'labelOr' => t('or'),
|
'labelOr' => t('or'),
|
||||||
'labelChooseFiles' => t('choose files'),
|
'labelChooseFiles' => t('choose files'),
|
||||||
'labelOversize' => t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)),
|
'labelOversize' => $max_size > 0 ? t('The maximum allowed file size is %sB.', $this->text->bytes($max_size)) : null,
|
||||||
'labelSuccess' => t('All files have been uploaded successfully.'),
|
'labelSuccess' => t('All files have been uploaded successfully.'),
|
||||||
'labelCloseSuccess' => t('Close this window'),
|
'labelCloseSuccess' => t('Close this window'),
|
||||||
'labelUploadError' => t('Unable to upload this file.'),
|
'labelUploadError' => t('Unable to upload this file.'),
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,9 @@
|
||||||
<?= $this->form->label(t('CSV File'), 'file') ?>
|
<?= $this->form->label(t('CSV File'), 'file') ?>
|
||||||
<?= $this->form->file('file', $errors) ?>
|
<?= $this->form->file('file', $errors) ?>
|
||||||
|
|
||||||
|
<?php if ($max_size > 0): ?>
|
||||||
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
|
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
<?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
|
<?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,9 @@
|
||||||
<?= $this->form->label(t('CSV File'), 'file') ?>
|
<?= $this->form->label(t('CSV File'), 'file') ?>
|
||||||
<?= $this->form->file('file', $errors) ?>
|
<?= $this->form->file('file', $errors) ?>
|
||||||
|
|
||||||
|
<?php if ($max_size > 0): ?>
|
||||||
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
|
<p class="form-help"><?= t('Maximum size: ') ?><?= is_integer($max_size) ? $this->text->bytes($max_size) : $max_size ?></p>
|
||||||
|
<?php endif ?>
|
||||||
|
|
||||||
<?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
|
<?= $this->modal->submitButtons(array('submitLabel' => t('Import'))) ?>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,44 @@ function build_app_version($ref, $commit_hash)
|
||||||
*/
|
*/
|
||||||
function get_upload_max_size()
|
function get_upload_max_size()
|
||||||
{
|
{
|
||||||
return min(ini_get('upload_max_filesize'), ini_get('post_max_size'));
|
$upload_max_filesize = convert_php_size_to_bytes(ini_get('upload_max_filesize'));
|
||||||
|
$post_max_size = convert_php_size_to_bytes(ini_get('post_max_size'));
|
||||||
|
|
||||||
|
if ($post_max_size == 0) {
|
||||||
|
return $upload_max_filesize;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($upload_max_filesize == 0) {
|
||||||
|
return $post_max_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min($post_max_size, $upload_max_filesize);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of bytes from PHP size
|
||||||
|
*
|
||||||
|
* @param integer $value PHP size (example: 2M)
|
||||||
|
* @return integer
|
||||||
|
*/
|
||||||
|
function convert_php_size_to_bytes($value)
|
||||||
|
{
|
||||||
|
// Remove the non-unit characters from the size
|
||||||
|
$unit = preg_replace('/[^bkmgtpezy]/i', '', $value);
|
||||||
|
|
||||||
|
// Remove the non-numeric characters from the size
|
||||||
|
$size = preg_replace('/[^0-9\.]/', '', $value);
|
||||||
|
|
||||||
|
switch (strtoupper($unit)) {
|
||||||
|
case 'G':
|
||||||
|
$size *= 1024;
|
||||||
|
case 'M':
|
||||||
|
$size *= 1024;
|
||||||
|
case 'K':
|
||||||
|
$size *= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $size;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,7 @@ function showFiles(){if(files.length>0){KB.trigger('modal.enable');KB.dom(dropzo
|
||||||
function buildFileInputElement(){return KB.dom('input').attr('id','file-input-element').attr('type','file').attr('name','files[]').attr('multiple',!0).on('change',onFileChange).hide().build()}
|
function buildFileInputElement(){return KB.dom('input').attr('id','file-input-element').attr('type','file').attr('name','files[]').attr('multiple',!0).on('change',onFileChange).hide().build()}
|
||||||
function buildInnerDropzoneElement(){var dropzoneLinkElement=KB.dom('a').attr('href','#').text(options.labelChooseFiles).click(onClickFileBrowser).build();return KB.dom('div').attr('id','file-dropzone-inner').text(options.labelDropzone+' '+options.labelOr+' ').add(dropzoneLinkElement).build()}
|
function buildInnerDropzoneElement(){var dropzoneLinkElement=KB.dom('a').attr('href','#').text(options.labelChooseFiles).click(onClickFileBrowser).build();return KB.dom('div').attr('id','file-dropzone-inner').text(options.labelDropzone+' '+options.labelOr+' ').add(dropzoneLinkElement).build()}
|
||||||
function buildDropzoneElement(){var dropzoneElement=KB.dom('div').attr('id','file-dropzone').add(buildInnerDropzoneElement()).build();dropzoneElement.ondragover=onDragOver;dropzoneElement.ondrop=onDrop;dropzoneElement.ondragover=onDragOver;return dropzoneElement}
|
function buildDropzoneElement(){var dropzoneElement=KB.dom('div').attr('id','file-dropzone').add(buildInnerDropzoneElement()).build();dropzoneElement.ondragover=onDragOver;dropzoneElement.ondrop=onDrop;dropzoneElement.ondragover=onDragOver;return dropzoneElement}
|
||||||
function buildFileListItem(index){var isOversize=!1;var progressElement=KB.dom('progress').attr('id','file-progress-'+index).attr('value',0).build();var percentageElement=KB.dom('span').attr('id','file-percentage-'+index).text('(0%)').build();var deleteElement=KB.dom('span').attr('id','file-delete-'+index).html('<a href="#"><i class="fa fa-trash fa-fw"></i></a>').on('click',function(){files.splice(index,1);KB.find('#file-item-'+index).remove();showFiles()}).build();var itemElement=KB.dom('li').attr('id','file-item-'+index).add(deleteElement).add(progressElement).text(' '+files[index].name+' ').add(percentageElement);if(files[index].size>options.maxSize){itemElement.add(KB.dom('div').addClass('file-error').text(options.labelOversize).build());isOversize=!0}
|
function buildFileListItem(index){var isOversize=!1;var progressElement=KB.dom('progress').attr('id','file-progress-'+index).attr('value',0).build();var percentageElement=KB.dom('span').attr('id','file-percentage-'+index).text('(0%)').build();var deleteElement=KB.dom('span').attr('id','file-delete-'+index).html('<a href="#"><i class="fa fa-trash fa-fw"></i></a>').on('click',function(){files.splice(index,1);KB.find('#file-item-'+index).remove();showFiles()}).build();var itemElement=KB.dom('li').attr('id','file-item-'+index).add(deleteElement).add(progressElement).text(' '+files[index].name+' ').add(percentageElement);if(options.maxSize>0&&files[index].size>options.maxSize){itemElement.add(KB.dom('div').addClass('file-error').text(options.labelOversize).build());isOversize=!0}
|
||||||
if(isOversize){KB.trigger('modal.disable')}
|
if(isOversize){KB.trigger('modal.disable')}
|
||||||
return itemElement.build()}
|
return itemElement.build()}
|
||||||
function buildFileListElement(){var fileListElement=KB.dom('ul').attr('id','file-list').build();for(var i=0;i<files.length;i++){fileListElement.appendChild(buildFileListItem(i))}
|
function buildFileListElement(){var fileListElement=KB.dom('ul').attr('id','file-list').build();for(var i=0;i<files.length;i++){fileListElement.appendChild(buildFileListItem(i))}
|
||||||
|
|
|
||||||
|
|
@ -179,7 +179,7 @@ KB.component('file-upload', function (containerElement, options) {
|
||||||
.text(' ' + files[index].name + ' ')
|
.text(' ' + files[index].name + ' ')
|
||||||
.add(percentageElement);
|
.add(percentageElement);
|
||||||
|
|
||||||
if (files[index].size > options.maxSize) {
|
if (options.maxSize > 0 && files[index].size > options.maxSize) {
|
||||||
itemElement.add(KB.dom('div').addClass('file-error').text(options.labelOversize).build());
|
itemElement.add(KB.dom('div').addClass('file-error').text(options.labelOversize).build());
|
||||||
isOversize = true;
|
isOversize = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,13 @@ require_once __DIR__.'/Base.php';
|
||||||
|
|
||||||
class FunctionTest extends Base
|
class FunctionTest extends Base
|
||||||
{
|
{
|
||||||
|
public function testConvertPHPSizeToBytes()
|
||||||
|
{
|
||||||
|
$this->assertEquals(2097152, convert_php_size_to_bytes('2M'));
|
||||||
|
$this->assertEquals(2048, convert_php_size_to_bytes('2 k'));
|
||||||
|
$this->assertEquals(0, convert_php_size_to_bytes('0'));
|
||||||
|
}
|
||||||
|
|
||||||
public function testArrayColumnSum()
|
public function testArrayColumnSum()
|
||||||
{
|
{
|
||||||
$input = array(
|
$input = array(
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue