diff --git a/.gitignore b/.gitignore index 5509140..a02f5c6 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ *.DS_Store +.idea \ No newline at end of file diff --git a/BlueImp/UploadHandler.php b/BlueImp/UploadHandler.php index 8edfb18..492846b 100644 --- a/BlueImp/UploadHandler.php +++ b/BlueImp/UploadHandler.php @@ -13,6 +13,8 @@ * http://www.opensource.org/licenses/MIT */ +use Locale; + class UploadHandler { protected $options; @@ -69,13 +71,13 @@ function __construct($options=null) { } protected function getFullUrl() { - return - (isset($_SERVER['HTTPS']) ? 'https://' : 'http://'). - (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). - (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. - (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 || - $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). - substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')); + return + (isset($_SERVER['HTTPS']) ? 'https://' : 'http://'). + (isset($_SERVER['REMOTE_USER']) ? $_SERVER['REMOTE_USER'].'@' : ''). + (isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : ($_SERVER['SERVER_NAME']. + (isset($_SERVER['HTTPS']) && $_SERVER['SERVER_PORT'] === 443 || + $_SERVER['SERVER_PORT'] === 80 ? '' : ':'.$_SERVER['SERVER_PORT']))). + substr($_SERVER['SCRIPT_NAME'],0, strrpos($_SERVER['SCRIPT_NAME'], '/')); } protected function set_file_delete_url($file) { @@ -160,14 +162,14 @@ protected function create_scaled_image($file_name, $options) { $src_img = null; } $success = $src_img && @imagecopyresampled( - $new_img, - $src_img, - 0, 0, 0, 0, - $new_width, - $new_height, - $img_width, - $img_height - ) && $write_image($new_img, $new_file_path, $image_quality); + $new_img, + $src_img, + 0, 0, 0, 0, + $new_width, + $new_height, + $img_width, + $img_height + ) && $write_image($new_img, $new_file_path, $image_quality); // Free up memory (imagedestroy does not delete files): @imagedestroy($src_img); @imagedestroy($new_img); @@ -195,7 +197,7 @@ protected function validate($uploaded_file, $file, $error, $index) { if ($this->options['max_file_size'] && ( $file_size > $this->options['max_file_size'] || $file->size > $this->options['max_file_size']) - ) { + ) { $file->error = 'maxFileSize'; return false; } @@ -206,19 +208,19 @@ protected function validate($uploaded_file, $file, $error, $index) { } if (is_int($this->options['max_number_of_files']) && ( count($this->get_file_objects()) >= $this->options['max_number_of_files']) - ) { + ) { $file->error = 'maxNumberOfFiles'; return false; } list($img_width, $img_height) = @getimagesize($uploaded_file); if (is_int($img_width)) { if ($this->options['max_width'] && $img_width > $this->options['max_width'] || - $this->options['max_height'] && $img_height > $this->options['max_height']) { + $this->options['max_height'] && $img_height > $this->options['max_height']) { $file->error = 'maxResolution'; return false; } if ($this->options['min_width'] && $img_width < $this->options['min_width'] || - $this->options['min_height'] && $img_height < $this->options['min_height']) { + $this->options['min_height'] && $img_height < $this->options['min_height']) { $file->error = 'minResolution'; return false; } @@ -241,21 +243,28 @@ protected function upcount_name($name) { ); } - protected function trim_file_name($name, $type, $index) { + protected function trim_file_name($file_name, $type, $index) { // Remove path information and dots around the filename, to prevent uploading // into different directories or replacing hidden system files. // Also remove control characters and spaces (\x00..\x20) around the filename: - $file_name = trim(basename(stripslashes($name)), ".\x00..\x20"); + + $locale = setlocale(LC_ALL, 0); + setlocale(LC_ALL, 'en_US.utf8'); + $file_name = trim(basename(stripslashes($file_name)), ".\x00..\x20"); + // Add missing file extension for known image types: if (strpos($file_name, '.') === false && preg_match('/^image\/(gif|jpe?g|png)/', $type, $matches)) { $file_name .= '.'.$matches[1]; } + if ($this->options['discard_aborted_uploads']) { - while(is_file($this->options['upload_dir'].$file_name)) { + while (is_file($this->options['upload_dir'] . $file_name)) { $file_name = $this->upcount_name($file_name); } } + setlocale(LC_ALL, $locale); + return $file_name; } @@ -264,32 +273,32 @@ protected function handle_form_data($file, $index) { } protected function orient_image($file_path) { - $exif = @exif_read_data($file_path); + $exif = @exif_read_data($file_path); if ($exif === false) { return false; } - $orientation = intval(@$exif['Orientation']); - if (!in_array($orientation, array(3, 6, 8))) { - return false; - } - $image = @imagecreatefromjpeg($file_path); - switch ($orientation) { - case 3: - $image = @imagerotate($image, 180, 0); - break; - case 6: - $image = @imagerotate($image, 270, 0); - break; - case 8: - $image = @imagerotate($image, 90, 0); - break; - default: - return false; - } - $success = imagejpeg($image, $file_path); - // Free up memory (imagedestroy does not delete files): - @imagedestroy($image); - return $success; + $orientation = intval(@$exif['Orientation']); + if (!in_array($orientation, array(3, 6, 8))) { + return false; + } + $image = @imagecreatefromjpeg($file_path); + switch ($orientation) { + case 3: + $image = @imagerotate($image, 180, 0); + break; + case 6: + $image = @imagerotate($image, 270, 0); + break; + case 8: + $image = @imagerotate($image, 90, 0); + break; + default: + return false; + } + $success = imagejpeg($image, $file_path); + // Free up memory (imagedestroy does not delete files): + @imagedestroy($image); + return $success; } protected function handle_file_upload($uploaded_file, $name, $size, $type, $error, $index) { @@ -324,9 +333,9 @@ protected function handle_file_upload($uploaded_file, $name, $size, $type, $erro } $file_size = filesize($file_path); if ($file_size === $file->size) { - if ($this->options['orient_image']) { - $this->orient_image($file_path); - } + if ($this->options['orient_image']) { + $this->orient_image($file_path); + } $file->url = $this->options['upload_url'].rawurlencode($file->name); foreach($this->options['image_versions'] as $version => $options) { if ($this->create_scaled_image($file->name, $options)) { @@ -391,13 +400,13 @@ public function post() { isset($upload['tmp_name']) ? $upload['tmp_name'] : null, isset($_SERVER['HTTP_X_FILE_NAME']) ? $_SERVER['HTTP_X_FILE_NAME'] : (isset($upload['name']) ? - $upload['name'] : null), + $upload['name'] : null), isset($_SERVER['HTTP_X_FILE_SIZE']) ? $_SERVER['HTTP_X_FILE_SIZE'] : (isset($upload['size']) ? - $upload['size'] : null), + $upload['size'] : null), isset($_SERVER['HTTP_X_FILE_TYPE']) ? $_SERVER['HTTP_X_FILE_TYPE'] : (isset($upload['type']) ? - $upload['type'] : null), + $upload['type'] : null), isset($upload['error']) ? $upload['error'] : null ); } @@ -435,4 +444,4 @@ public function delete() { echo json_encode($success); } -} \ No newline at end of file +} diff --git a/Resources/public/js/FileUploader.js b/Resources/public/js/FileUploader.js index 280e649..3ab4236 100644 --- a/Resources/public/js/FileUploader.js +++ b/Resources/public/js/FileUploader.js @@ -18,10 +18,11 @@ function PunkAveFileUploader(options) self.addExistingFiles = function(files) { _.each(files, function(file) { + var encodedFile = encodeURIComponent(file); appendEditableImage({ // cmsMediaUrl is a global variable set by the underscoreTemplates partial of MediaItems.html.twig - 'thumbnail_url': viewUrl + '/thumbnails/' + file, - 'url': viewUrl + '/originals/' + file, + 'thumbnail_url': viewUrl + '/thumbnails/' + encodedFile, + 'url': viewUrl + '/originals/' + encodedFile, 'name': file }); }); @@ -106,6 +107,11 @@ function PunkAveFileUploader(options) success: function() { file.remove(); }, + error: function ( xhr , msg, optional ) { + if ( optional == 'Locked') { + file.find(".error-image-used").show().delay(3000).fadeOut(); + } + }, dataType: 'json' }); return false; diff --git a/Services/FileManager.php b/Services/FileManager.php index 5098457..e79ca51 100644 --- a/Services/FileManager.php +++ b/Services/FileManager.php @@ -19,6 +19,8 @@ public function __construct($options) public function getFiles($options = array()) { $options = array_merge($this->options, $options); + $locale = setlocale(LC_ALL, 0); + setlocale(LC_ALL, 'en_US.utf8'); $folder = $options['file_base_path'] . '/' . $options['folder']; if (file_exists($folder)) @@ -33,12 +35,14 @@ public function getFiles($options = array()) $dirs = array(); } $result = array_map(function($s) { return basename($s); }, $dirs); - return $result; } else { - return array(); + $result = array(); } + setlocale(LC_ALL, $locale); + + return $result; } /** @@ -112,7 +116,7 @@ public function syncFiles($options = array()) system("rsync -a --delete " . escapeshellarg($from . '/') . " " . escapeshellarg($to), $result); if ($result !== 0) { - throw new \Exception("Sync failed"); + throw new \Exception("Sync failed with errorcode '$result'!"); } if (isset($options['remove_from_folder']) && $options['remove_from_folder']) { diff --git a/Test/BlueImp/UploadHandlerTest.php b/Test/BlueImp/UploadHandlerTest.php new file mode 100644 index 0000000..e43b3d9 --- /dev/null +++ b/Test/BlueImp/UploadHandlerTest.php @@ -0,0 +1,45 @@ +getMethod('trim_file_name'); + $method->setAccessible(true); + $result = $method->invokeArgs($uploadHandler, ['../Ääüö.jpg', 'jpg', null]); + $this->assertEquals('Ääüö.jpg', $result); + } + +} + +/** + * Class UploadHandlerMock + * @package PunkAve\FileUploaderBundle\BlueImp\Tests + */ +class UploadHandlerMock extends UploadHandler +{ + /** + * + */ + public function __construct(){ + + } +} + diff --git a/Test/bootstrap.php b/Test/bootstrap.php new file mode 100644 index 0000000..e4c6b4f --- /dev/null +++ b/Test/bootstrap.php @@ -0,0 +1,5 @@ +=5.3.2", - "symfony/framework-bundle": "2.*" - }, - "autoload": { - "psr-0": { "PunkAve\\FileUploaderBundle": "" } - }, - "target-dir": "PunkAve/FileUploaderBundle", - "minimum-stability": "dev", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "name": "punkave/symfony2-file-uploader-bundle", + "type": "symfony-bundle", + "description": "Multiple file uploads for Symfony2 with the BlueImp uploader. Also scales uploaded images", + "keywords": ["upload", "file", "multiple file upload", "uploader", "blueimp", "symfony", "symfony bundle", "bundle", "punkave", "image transform", "symfony-2.0", "symfony-2.1"], + "homepage": "https://github.com/punkave/symfony2-file-uploader-bundle", + "license": "MIT", + "authors": [ + { + "name": "Thomas Boutell", + "email": "tom@punkave.com" + }, + { + "name": "Wes John-Alder", + "email": "wes@punkave.com" } + ], + "require": { + "php": ">=5.3.2", + "symfony/framework-bundle": "2.*" + }, + "require-dev": { + "phpunit/phpunit": "~5.0" + }, + "autoload": { + "psr-0": { "PunkAve\\FileUploaderBundle": "" } + }, + "target-dir": "PunkAve/FileUploaderBundle", + "minimum-stability": "dev", + "prefer-stable": true, + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + } } diff --git a/phpunit.xml b/phpunit.xml new file mode 100644 index 0000000..2473189 --- /dev/null +++ b/phpunit.xml @@ -0,0 +1,27 @@ + + + + + + ./Test/BlueImp/ + + + + + + ./BlueImp/ + ./FileUpload/ + ./Services/ + + + \ No newline at end of file