diff --git a/Resources/config/services.yml b/Resources/config/services.yml index ff8f871..e14e1ad 100644 --- a/Resources/config/services.yml +++ b/Resources/config/services.yml @@ -1,84 +1,86 @@ -parameters: - file_uploader.file_base_path: "%kernel.root_dir%/../web/uploads" - file_uploader.web_base_path: "/uploads" - file_uploader.allowed_extensions: - # Mime types are just for documentation's sake. - # BlueImp filters by supplied extension. No checking of the - # actual file contents is done. If your mime types are - # configured correctly in Apache the browser will have the - # correct expectations for each file - - gif #image/gif - - png #image/png - - jpg #image/jpeg - - jpeg #image/jpeg - - pdf #application/pdf - - mp3 #audio/mpeg - - xls #application/vnd.ms-excel - - ppt #application/vnd.ms-powerpoint - - doc #application/msword - - pptx #application/vnd.openxmlformats-officedocument.presentationml.presentation - - sldx #application/vnd.openxmlformats-officedocument.presentationml.slide - - ppsx #application/vnd.openxmlformats-officedocument.presentationml.slideshow - - potx #application/vnd.openxmlformats-officedocument.presentationml.template - - xlsx #application/vnd.openxmlformats-officedocument.spreadsheetml.sheet - - xltx #application/vnd.openxmlformats-officedocument.spreadsheetml.template - - docx #application/vnd.openxmlformats-officedocument.wordprocessingml.document - - dotx #application/vnd.openxmlformats-officedocument.wordprocessingml.template - - txt #text/plain - - rtf #text/rtf - - # Folder where originals are uploaded. This is the only folder populated for - # uploads that are not images - file_uploader.originals: - folder: originals - - # Scaled versions of images. These image sizes are pretty great for - # 1140 grid / responsive / bootstrap projects, but you can override as you see fit - # - # Width and height here are maximums to be enforced, NOT an aspect ratio to be enforced. - # UploadHandler renders the smallest size that doesn't violate one of the limits. - # - # If an original is too small it is simply copied for that particular size. In short, - # BlueImp did a good job here. - # - # You need not specify any sizes if you don't want FileUploader to scale images for you - file_uploader.sizes: - thumbnail: - folder: thumbnails - max_width: 80 - max_height: 80 - small: - folder: small - max_width: 320 - max_height: 480 - medium: - folder: medium - max_width: 640 - max_height: 960 - large: - folder: large - max_width: 1140 - max_height: 1140 - -services: - punk_ave.file_uploader: - class: PunkAve\FileUploaderBundle\Services\FileUploader - arguments: - - file_base_path: '%file_uploader.file_base_path%' - web_base_path: '%file_uploader.web_base_path%' - request: '@request' - file_manager: '@punk_ave.file_uploader_file_manager' - allowed_extensions: '%file_uploader.allowed_extensions%' - sizes: '%file_uploader.sizes%' - originals: '%file_uploader.originals%' - scope: request - - # You usually won't need this sub-service directly, - # however you can access it from a command, which is - # convenient if you need to delete files relating to - # something in a command context - punk_ave.file_uploader_file_manager: - class: PunkAve\FileUploaderBundle\Services\FileManager - arguments: - # For bc reasons we're not changing the names of the parameters - - file_base_path: '%file_uploader.file_base_path%' +parameters: + file_uploader.file_base_path: "%kernel.root_dir%/../web/uploads" + file_uploader.web_base_path: "/uploads" + file_uploader.allowed_extensions: + # Mime types are just for documentation's sake. + # BlueImp filters by supplied extension. No checking of the + # actual file contents is done. If your mime types are + # configured correctly in Apache the browser will have the + # correct expectations for each file + - gif #image/gif + - png #image/png + - jpg #image/jpeg + - jpeg #image/jpeg + - pdf #application/pdf + - mp3 #audio/mpeg + - xls #application/vnd.ms-excel + - ppt #application/vnd.ms-powerpoint + - doc #application/msword + - pptx #application/vnd.openxmlformats-officedocument.presentationml.presentation + - sldx #application/vnd.openxmlformats-officedocument.presentationml.slide + - ppsx #application/vnd.openxmlformats-officedocument.presentationml.slideshow + - potx #application/vnd.openxmlformats-officedocument.presentationml.template + - xlsx #application/vnd.openxmlformats-officedocument.spreadsheetml.sheet + - xltx #application/vnd.openxmlformats-officedocument.spreadsheetml.template + - docx #application/vnd.openxmlformats-officedocument.wordprocessingml.document + - dotx #application/vnd.openxmlformats-officedocument.wordprocessingml.template + - txt #text/plain + - rtf #text/rtf + - xml #text/xml + + # Folder where originals are uploaded. This is the only folder populated for + # uploads that are not images + file_uploader.originals: + folder: originals + + # Scaled versions of images. These image sizes are pretty great for + # 1140 grid / responsive / bootstrap projects, but you can override as you see fit + # + # Width and height here are maximums to be enforced, NOT an aspect ratio to be enforced. + # UploadHandler renders the smallest size that doesn't violate one of the limits. + # + # If an original is too small it is simply copied for that particular size. In short, + # BlueImp did a good job here. + # + # You need not specify any sizes if you don't want FileUploader to scale images for you + file_uploader.sizes: + thumbnail: + folder: thumbnails + max_width: 80 + max_height: 80 + small: + folder: small + max_width: 320 + max_height: 480 + medium: + folder: medium + max_width: 640 + max_height: 960 + large: + folder: large + max_width: 1140 + max_height: 1140 + +services: + punk_ave.file_uploader: + class: PunkAve\FileUploaderBundle\Services\FileUploader + arguments: + - file_base_path: '%file_uploader.file_base_path%' + web_base_path: '%file_uploader.web_base_path%' + request: '@request' + file_manager: '@punk_ave.file_uploader_file_manager' + allowed_extensions: '%file_uploader.allowed_extensions%' + sizes: '%file_uploader.sizes%' + originals: '%file_uploader.originals%' + scope: request + + # You usually won't need this sub-service directly, + # however you can access it from a command, which is + # convenient if you need to delete files relating to + # something in a command context + punk_ave.file_uploader_file_manager: + # class: PunkAve\FileUploaderBundle\Services\FileManagerSF2 + class: PunkAve\FileUploaderBundle\Services\FileManager + arguments: + # For bc reasons we're not changing the names of the parameters + - file_base_path: '%file_uploader.file_base_path%' diff --git a/Services/FileManager.php b/Services/FileManager.php index 4dcde21..5076c44 100644 --- a/Services/FileManager.php +++ b/Services/FileManager.php @@ -1,125 +1,125 @@ -options = $options; - } - - /** - * Get a list of files already present. The 'folder' option is required. - * If you pass consistent options to this method and handleFileUpload with - * regard to paths, then you will get consistent results. - */ - public function getFiles($options = array()) - { - $options = array_merge($this->options, $options); - - $folder = $options['file_base_path'] . '/' . $options['folder']; - if (file_exists($folder)) - { - $dirs = glob("$folder/originals/*"); - $fullPath = isset($options['full_path']) ? $options['full_path'] : false; - if ($fullPath) - { - return $dirs; - } - $result = array_map(function($s) { return basename($s); }, $dirs); - return $result; - } - else - { - return array(); - } - } - - /** - * Remove the folder specified by 'folder' and its contents. - * If you pass consistent options to this method and handleFileUpload with - * regard to paths, then you will get consistent results. - */ - public function removeFiles($options = array()) - { - $options = array_merge($this->options, $options); - - - $folder = $options['file_base_path'] . '/' . $options['folder']; - - if (!strlen(trim($options['file_base_path']))) - { - throw \Exception("file_base_path option looks empty, bailing out"); - } - - if (!strlen(trim($options['folder']))) - { - throw \Exception("folder option looks empty, bailing out"); - } - system("rm -rf " . escapeshellarg($folder)); - } - - /** - * Sync existing files from one folder to another. The 'fromFolder' and 'toFolder' - * options are required. As with the 'folder' option elsewhere, these are appended - * to the file_base_path for you, missing parent folders are created, etc. If - * 'fromFolder' does not exist no error is reported as this is common if no files - * have been uploaded. If there are files and the sync reports errors an exception - * is thrown. - * - * If you pass consistent options to this method and handleFileUpload with - * regard to paths, then you will get consistent results. - */ - public function syncFiles($options = array()) - { - $options = array_merge($this->options, $options); - - // We're syncing and potentially deleting folders, so make sure - // we were passed something - make it a little harder to accidentally - // trash your site - if (!strlen(trim($options['file_base_path']))) - { - throw \Exception("file_base_path option looks empty, bailing out"); - } - if (!strlen(trim($options['from_folder']))) - { - throw \Exception("from_folder option looks empty, bailing out"); - } - if (!strlen(trim($options['to_folder']))) - { - throw \Exception("to_folder option looks empty, bailing out"); - } - - $from = $options['file_base_path'] . '/' . $options['from_folder']; - $to = $options['file_base_path'] . '/' . $options['to_folder']; - $slashes = substr_count($from, '/'); - if (file_exists($from)) - { - if (isset($options['create_to_folder']) && $options['create_to_folder']) - { - @mkdir($to, 0777, true); - } - elseif (!file_exists($to)) - { - throw new \Exception("to_folder does not exist"); - } - system("rsync -a --delete " . escapeshellarg($from . '/') . " " . escapeshellarg($to), $result); - if ($result !== 0) - { - throw new \Exception("Sync failed"); - } - if (isset($options['remove_from_folder']) && $options['remove_from_folder']) - { - system("rm -rf " . escapeshellarg($from)); - } - } - else - { - // A missing from_folder is not an error. This is commonly the case - // when syncing from something that has nothing attached to it yet, etc. - } - } -} +options = $options; + } + + /** + * Get a list of files already present. The 'folder' option is required. + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + */ + public function getFiles($options = array()) + { + $options = array_merge($this->options, $options); + + $folder = $options['file_base_path'] . '/' . $options['folder']; + if (file_exists($folder)) + { + $dirs = glob("$folder/originals/*"); + $fullPath = isset($options['full_path']) ? $options['full_path'] : false; + if ($fullPath) + { + return $dirs; + } + $result = array_map(function($s) { return basename($s); }, $dirs); + return $result; + } + else + { + return array(); + } + } + + /** + * Remove the folder specified by 'folder' and its contents. + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + */ + public function removeFiles($options = array()) + { + $options = array_merge($this->options, $options); + + + $folder = $options['file_base_path'] . '/' . $options['folder']; + + if (!strlen(trim($options['file_base_path']))) + { + throw \Exception("file_base_path option looks empty, bailing out"); + } + + if (!strlen(trim($options['folder']))) + { + throw \Exception("folder option looks empty, bailing out"); + } + system("rm -rf " . escapeshellarg($folder)); + } + + /** + * Sync existing files from one folder to another. The 'fromFolder' and 'toFolder' + * options are required. As with the 'folder' option elsewhere, these are appended + * to the file_base_path for you, missing parent folders are created, etc. If + * 'fromFolder' does not exist no error is reported as this is common if no files + * have been uploaded. If there are files and the sync reports errors an exception + * is thrown. + * + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + */ + public function syncFiles($options = array()) + { + $options = array_merge($this->options, $options); + + // We're syncing and potentially deleting folders, so make sure + // we were passed something - make it a little harder to accidentally + // trash your site + if (!strlen(trim($options['file_base_path']))) + { + throw \Exception("file_base_path option looks empty, bailing out"); + } + if (!strlen(trim($options['from_folder']))) + { + throw \Exception("from_folder option looks empty, bailing out"); + } + if (!strlen(trim($options['to_folder']))) + { + throw \Exception("to_folder option looks empty, bailing out"); + } + + $from = $options['file_base_path'] . '/' . $options['from_folder']; + $to = $options['file_base_path'] . '/' . $options['to_folder']; + $slashes = substr_count($from, '/'); + if (file_exists($from)) + { + if (isset($options['create_to_folder']) && $options['create_to_folder']) + { + @mkdir($to, 0777, true); + } + elseif (!file_exists($to)) + { + throw new \Exception("to_folder does not exist"); + } + system("rsync -a --delete " . escapeshellarg($from . '/') . " " . escapeshellarg($to), $result); + if ($result !== 0) + { + throw new \Exception("Sync failed"); + } + if (isset($options['remove_from_folder']) && $options['remove_from_folder']) + { + system("rm -rf " . escapeshellarg($from)); + } + } + else + { + // A missing from_folder is not an error. This is commonly the case + // when syncing from something that has nothing attached to it yet, etc. + } + } +} diff --git a/Services/FileManagerSF2.php b/Services/FileManagerSF2.php new file mode 100644 index 0000000..b5ef286 --- /dev/null +++ b/Services/FileManagerSF2.php @@ -0,0 +1,96 @@ +options = $options; + } + + /** + * Get a list of files already present. The 'folder' option is required. + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + */ + public function getFiles($options = array()) + { + $options = array_merge($this->options, $options); + $ret = array(); + $folder = $options['file_base_path'] . DIRECTORY_SEPARATOR . $options['folder']; + if ($this->exists($folder)) { + $finder = new Finder(); + $finder->in($folder . DIRECTORY_SEPARATOR . 'originals'); + $fullPath = isset($options['full_path']) ? $options['full_path'] : false; + foreach ($finder as $entry) { + /** @var $entry SplFileInfo */ + array_push($ret, $fullPath ? $entry->getRealPath() : $entry->getBasename()); + } + } + return $ret; + } + + /** + * Remove the folder specified by 'folder' and its contents. + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + * @param array $options + * @throws IOException + */ + public function removeFiles($options = array()) + { + $folder = $options['folder']; + if (!strlen(trim($folder))) { + throw \Exception("folder option looks empty, bailing out"); + } + + // Remove folder, let the caller deal with an IO exception in case of error + $this->remove($this->options['file_base_path'] . DIRECTORY_SEPARATOR . $folder); + } + + /** + * Sync existing files from one folder to another. The 'fromFolder' and 'toFolder' + * options are required. As with the 'folder' option elsewhere, these are appended + * to the file_base_path for you, missing parent folders are created, etc. If + * 'fromFolder' does not exist no error is reported as this is common if no files + * have been uploaded. If there are files and the sync reports errors an exception + * is thrown. + * + * If you pass consistent options to this method and handleFileUpload with + * regard to paths, then you will get consistent results. + */ + public function syncFiles($options = array()) + { + $options = array_merge($this->options, $options); + + // We're syncing and potentially deleting folders, so make sure + // we were passed something - make it a little harder to accidentally + // trash your site + if (!strlen(trim($options['from_folder']))) { + throw \Exception("from_folder option looks empty, bailing out"); + } + if (!strlen(trim($options['to_folder']))) { + throw \Exception("to_folder option looks empty, bailing out"); + } + + $from = $options['file_base_path'] . DIRECTORY_SEPARATOR . $options['from_folder']; + $to = $options['file_base_path'] . DIRECTORY_SEPARATOR . $options['to_folder']; + if ($this->exists($from)) { + $this->mirror($from, $to, null, $options); + if (isset($options['remove_from_folder']) && $options['remove_from_folder']) { + $this->remove($from); + } + } else { + // A missing from_folder is not an error. This is commonly the case + // when syncing from something that has nothing attached to it yet, etc. + } + } +} diff --git a/Services/FileSystem.php b/Services/FileSystem.php new file mode 100644 index 0000000..55c8b56 --- /dev/null +++ b/Services/FileSystem.php @@ -0,0 +1,52 @@ +getPathname()); + if (!$this->exists($origin)) { + $this->remove($file); + } + } + } + } + parent::mirror($originDir, $targetDir, $iterator, $options); + } +}