├── .gitignore ├── Resources ├── public │ ├── lib │ │ ├── jquery-file-upload │ │ │ ├── server │ │ │ │ ├── node │ │ │ │ │ ├── tmp │ │ │ │ │ │ └── .gitignore │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── public │ │ │ │ │ │ └── files │ │ │ │ │ │ │ └── .gitignore │ │ │ │ │ └── package.json │ │ │ │ ├── gae-go │ │ │ │ │ ├── static │ │ │ │ │ │ ├── robots.txt │ │ │ │ │ │ └── favicon.ico │ │ │ │ │ └── app.yaml │ │ │ │ ├── gae-python │ │ │ │ │ ├── static │ │ │ │ │ │ ├── robots.txt │ │ │ │ │ │ └── favicon.ico │ │ │ │ │ └── app.yaml │ │ │ │ └── php │ │ │ │ │ ├── files │ │ │ │ │ ├── .gitignore │ │ │ │ │ └── .htaccess │ │ │ │ │ └── index.php │ │ │ ├── .gitignore │ │ │ ├── img │ │ │ │ ├── loading.gif │ │ │ │ └── progressbar.gif │ │ │ ├── css │ │ │ │ ├── style.css │ │ │ │ ├── jquery.fileupload-ui-noscript.css │ │ │ │ ├── demo-ie8.css │ │ │ │ ├── jquery.fileupload-noscript.css │ │ │ │ ├── jquery.fileupload.css │ │ │ │ ├── jquery.fileupload-ui.css │ │ │ │ └── demo.css │ │ │ ├── cors │ │ │ │ ├── result.html │ │ │ │ └── postmessage.html │ │ │ ├── Gruntfile.js │ │ │ ├── blueimp-file-upload.jquery.json │ │ │ ├── package.json │ │ │ ├── bower.json │ │ │ ├── CONTRIBUTING.md │ │ │ └── js │ │ │ │ ├── main.js │ │ │ │ ├── cors │ │ │ │ ├── jquery.xdr-transport.js │ │ │ │ └── jquery.postmessage-transport.js │ │ │ │ ├── jquery.fileupload-audio.js │ │ │ │ ├── jquery.fileupload-video.js │ │ │ │ ├── app.js │ │ │ │ └── jquery.fileupload-validate.js │ │ └── jcrop │ │ │ ├── css │ │ │ ├── Jcrop.gif │ │ │ ├── jquery.Jcrop.min.css │ │ │ └── jquery.Jcrop.css │ │ │ ├── demos │ │ │ ├── demo_files │ │ │ │ ├── pool.jpg │ │ │ │ ├── sago.jpg │ │ │ │ ├── sagomod.jpg │ │ │ │ ├── sagomod.png │ │ │ │ └── demos.css │ │ │ ├── tutorial1.html │ │ │ ├── non-image.html │ │ │ ├── crop.php │ │ │ ├── styling.html │ │ │ ├── tutorial2.html │ │ │ └── tutorial3.html │ │ │ ├── bower.json │ │ │ ├── MIT-LICENSE.txt │ │ │ ├── README.md │ │ │ └── index.html │ ├── img │ │ ├── default.png │ │ ├── ajax-loader.gif │ │ └── ajax-loader-small.gif │ └── css │ │ └── jbfileupload.css ├── doc │ ├── img │ │ └── screenshots.png │ ├── base │ │ ├── resolvers.md │ │ ├── validation.md │ │ ├── install.md │ │ └── reference.md │ ├── advanced │ │ ├── fileowner.md │ │ └── javascript.md │ ├── file_upload │ │ ├── simple.md │ │ └── image.md │ └── index.md ├── config │ ├── routing.yml │ ├── resolver_factories.yml │ ├── form_types.yml │ ├── resolvers.yml │ ├── validators.yml │ └── services.yml └── views │ └── Form │ └── fields.html.twig ├── .scrutinizer.yml ├── Exception ├── ValidationException.php └── JbFileUploaderException.php ├── Service ├── Resolver │ ├── CdnResolver.php │ ├── ResolverInterface.php │ ├── ImagineCacheManagerResolver.php │ ├── AssetsResolver.php │ └── Aws3Resolver.php ├── Validator │ ├── Constraints │ │ ├── FileOwner.php │ │ └── FileOwnerValidator.php │ ├── CropValidator.php │ ├── ImageValidator.php │ ├── AbstractValidator.php │ └── AbstractImageValidator.php ├── FileHistoryManagerInterface.php ├── Imagine │ └── AwsS3Resolver.php ├── EndpointConfiguration.php ├── ResolverChain.php ├── ValidatorChain.php ├── ValidatorManager.php ├── CropFileManager.php ├── Croper.php └── FileHistoryManager.php ├── composer.json ├── JbFileUploaderBundle.php ├── LICENSE ├── DependencyInjection ├── ResolverFactory │ ├── ImagineResolverFactory.php │ ├── ResolverFactoryInterface.php │ ├── CdnResolverFactory.php │ ├── AssetsResolverFactory.php │ └── Aws3ResolverFactory.php ├── ResolverFactoryConfiguration.php ├── Compiler │ ├── ResolverCompilerPass.php │ └── ValidatorCompilerPass.php ├── JbFileUploaderExtension.php └── MainConfiguration.php ├── README.md ├── EventListener ├── Validation │ └── ConfiguredValidationListener.php └── Upload │ └── UploadListener.php ├── Form └── Type │ ├── ImageAjaxType.php │ ├── CropImageAjaxType.php │ ├── CropType.php │ └── FileAjaxType.php ├── Controller └── CropController.php ├── Twig └── CropExtension.php └── Entity └── FileHistory.php /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | vendor 3 | composer.lock 4 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/node/tmp/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.scrutinizer.yml: -------------------------------------------------------------------------------- 1 | filter: 2 | excluded_paths: 3 | - Resources/public/lib/* 4 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *.pyc 3 | node_modules 4 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/node/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/node/public/files/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-go/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-python/static/robots.txt: -------------------------------------------------------------------------------- 1 | User-agent: * 2 | Disallow: 3 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/php/files/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | !.htaccess 4 | -------------------------------------------------------------------------------- /Resources/public/img/default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/img/default.png -------------------------------------------------------------------------------- /Resources/doc/img/screenshots.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/doc/img/screenshots.png -------------------------------------------------------------------------------- /Resources/public/img/ajax-loader.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/img/ajax-loader.gif -------------------------------------------------------------------------------- /Resources/public/img/ajax-loader-small.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/img/ajax-loader-small.gif -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/css/Jcrop.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jcrop/css/Jcrop.gif -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/demo_files/pool.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jcrop/demos/demo_files/pool.jpg -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/demo_files/sago.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jcrop/demos/demo_files/sago.jpg -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/demo_files/sagomod.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jcrop/demos/demo_files/sagomod.jpg -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/demo_files/sagomod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jcrop/demos/demo_files/sagomod.png -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jquery-file-upload/img/loading.gif -------------------------------------------------------------------------------- /Resources/config/routing.yml: -------------------------------------------------------------------------------- 1 | jb_image_crop_endpoint: 2 | path: /_jbfileuploader/crop/{endpoint} 3 | defaults: { _controller: "JbFileUploaderBundle:Crop:filter" } 4 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/img/progressbar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jquery-file-upload/img/progressbar.gif -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-go/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jquery-file-upload/server/gae-go/static/favicon.ico -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-python/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jbouzekri/FileUploaderBundle/HEAD/Resources/public/lib/jquery-file-upload/server/gae-python/static/favicon.ico -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-go/app.yaml: -------------------------------------------------------------------------------- 1 | application: jquery-file-upload 2 | version: 2 3 | runtime: go 4 | api_version: go1 5 | 6 | handlers: 7 | - url: /(favicon\.ico|robots\.txt) 8 | static_files: static/\1 9 | upload: static/(.*) 10 | expiration: '1d' 11 | - url: /.* 12 | script: _go_app 13 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/gae-python/app.yaml: -------------------------------------------------------------------------------- 1 | application: jquery-file-upload 2 | version: 1 3 | runtime: python27 4 | api_version: 1 5 | threadsafe: true 6 | 7 | builtins: 8 | - deferred: on 9 | 10 | handlers: 11 | - url: /(favicon\.ico|robots\.txt) 12 | static_files: static/\1 13 | upload: static/(.*) 14 | expiration: '1d' 15 | - url: /.* 16 | script: main.app 17 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/css/style.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Plugin CSS Example 8.8.2 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | body { 14 | padding-top: 60px; 15 | } 16 | -------------------------------------------------------------------------------- /Resources/public/css/jbfileupload.css: -------------------------------------------------------------------------------- 1 | .fileinput-button input { 2 | font-size: 12px; 3 | } 4 | 5 | .jb_crop_upload { 6 | display: inline-block; 7 | } 8 | 9 | .fileinput-button:hover a { 10 | text-decoration: underline; 11 | } 12 | 13 | .jb_progressbar { 14 | width: 100%; 15 | height: 15px; 16 | border: 1px solid #111; 17 | margin-top: 3px; 18 | } 19 | 20 | .jb_bar { 21 | width: 0; 22 | background-color: #111; 23 | height: 15px; 24 | } -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/php/index.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Exception; 12 | 13 | /** 14 | * ValidationException 15 | * 16 | * @author jobou 17 | */ 18 | class ValidationException extends JbFileUploaderException 19 | { 20 | } 21 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Jcrop", 3 | "version": "0.9.12", 4 | "homepage": "https://github.com/tapmodo/Jcrop", 5 | "authors": [ "Tapmodo " ], 6 | "description": "Image cropping plugin for jQuery", 7 | "main": [ 8 | "js/jquery.Jcrop.js", 9 | "css/jquery.Jcrop.css" 10 | ], 11 | "keywords": [ "img", "image", "form", "crop", "cropping", "cropper" ], 12 | "license": "MIT", 13 | "ignore": [ 14 | "**/.*", 15 | "build", 16 | "demos", 17 | "node_modules", 18 | "bower_components" 19 | ] 20 | } 21 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/css/jquery.fileupload-noscript.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Plugin NoScript CSS 1.2.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileinput-button input { 14 | position: static; 15 | opacity: 1; 16 | filter: none; 17 | font-size: inherit; 18 | direction: inherit; 19 | } 20 | .fileinput-button span { 21 | display: none; 22 | } 23 | -------------------------------------------------------------------------------- /Exception/JbFileUploaderException.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Exception; 12 | 13 | /** 14 | * JbFileUploaderException 15 | * Base exception for this bundle 16 | * 17 | * @author jobou 18 | */ 19 | class JbFileUploaderException extends \Exception 20 | { 21 | } 22 | -------------------------------------------------------------------------------- /Resources/doc/base/resolvers.md: -------------------------------------------------------------------------------- 1 | Resolvers 2 | ========= 3 | 4 | * [Asset resolver](#assets-resolver) 5 | 6 | Assets resolver 7 | --------------- 8 | 9 | This type of assets is used to display an image or a link to a file when they are stored in the public folder (`web`) or its sub directories. 10 | 11 | The only configuration needed is the directory key. 12 | 13 | ``` yml 14 | jb_file_uploader: 15 | resolvers: 16 | croped: 17 | assets: 18 | directory: uploads/croped 19 | ``` 20 | 21 | This assets resolver named `croped` will generate urls `/uploads/croped/` 22 | -------------------------------------------------------------------------------- /Service/Resolver/CdnResolver.php: -------------------------------------------------------------------------------- 1 | url = $url; 26 | } 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function getUrl($key) 32 | { 33 | return $this->url . '/' . $key; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Resources/doc/advanced/fileowner.md: -------------------------------------------------------------------------------- 1 | Validate file ownership 2 | ======================= 3 | 4 | As every query are made via ajax, you could have a person fill the hidden filename input tag with the filename of another user. 5 | 6 | To prevent this from happening, a custom validation constraint has been added : 7 | 8 | ~~~ php 9 | use Jb\Bundle\FileUploaderBundle\Service\Validator\Constraints as JbAssert; 10 | 11 | /** 12 | * @JbAssert\FileOwner 13 | */ 14 | protected $picture; 15 | ~~~ 16 | 17 | With this validator, symfony will check that the submitted file is owned by the user who submitted it. 18 | 19 | For it to work, you should have your form submit route behind a firewall. 20 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/cors/result.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | jQuery Iframe Transport Plugin Redirect Page 18 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Resources/doc/advanced/javascript.md: -------------------------------------------------------------------------------- 1 | Javascript Events 2 | ================= 3 | 4 | There are a few javascript events that get fired that can help you integrate your workflow. These Are: 5 | 6 | * jb.FileUpload.success 7 | * jb.FileUpload.error 8 | * jb.FileUpload.remove 9 | 10 | The Success event provide an extra object parameter that contains: 11 | 12 | { 13 | filename: "some-image-name.jpg" 14 | filepath: "http://the.path.to.the/uploaded/image.ext" 15 | originalname: "original-image-name.ext" 16 | } 17 | 18 | The remove event provides a similar object, but with empty values. 19 | 20 | The error event provides the string error message as its additional parameter. -------------------------------------------------------------------------------- /Service/Resolver/ResolverInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Resolver; 12 | 13 | /** 14 | * ResolverInterface 15 | * 16 | * @author jobou 17 | */ 18 | interface ResolverInterface 19 | { 20 | /** 21 | * Get the url 22 | * 23 | * @param string $key 24 | * 25 | * @return string 26 | */ 27 | public function getUrl($key); 28 | } 29 | -------------------------------------------------------------------------------- /Resources/doc/file_upload/simple.md: -------------------------------------------------------------------------------- 1 | Simple file upload 2 | ================== 3 | 4 | This is the simplest upload field type. It shows an upload link and can display the uploaded filename with a download link when the upload was successful. 5 | 6 | ~~~ php 7 | 8 | use Jb\Bundle\FileUploaderBundle\Form\Type\FileAjaxType; 9 | 10 | $builder->add('file', FileAjaxType::class, array( 11 | 'endpoint' => 'my_endpoint_name' 12 | )); 13 | ~~~ 14 | 15 | The available options are : 16 | 17 | * endpoint (_mandatory_) : a oneup fileupload mapping name 18 | * download_link (_boolean_) : show the download link when the upload was successful 19 | * remove_link (_boolean_) : show a remove link allowing to empty the field 20 | * progress (_boolean_) : show a progress bar 21 | 22 | -------------------------------------------------------------------------------- /Resources/doc/file_upload/image.md: -------------------------------------------------------------------------------- 1 | Image file upload 2 | ================= 3 | 4 | This form type provides file upload optimized for image. 5 | 6 | ~~~ php 7 | use Jb\Bundle\FileUploaderBundle\Form\Type\ImageAjaxType; 8 | 9 | ... 10 | $builder->add('image', ImageAjaxType::class, array( 11 | 'endpoint' => 'my_endpoint_name' 12 | )); 13 | ~~~ 14 | 15 | The parent field type is [simple file upload](simple.md). You can use all the options of the parent field. 16 | 17 | The specific option are : 18 | 19 | * default_image : the image displayed when there is not file uploaded 20 | * img_width : the width of the preview img tag 21 | * img_height : the height of the preview img tag 22 | 23 | _Note :_ Upload file validation can be configured in [`config.yml`](../base/validation.md). 24 | 25 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/php/files/.htaccess: -------------------------------------------------------------------------------- 1 | # The following directives force the content-type application/octet-stream 2 | # and force browsers to display a download dialog for non-image files. 3 | # This prevents the execution of script files in the context of the website: 4 | ForceType application/octet-stream 5 | Header set Content-Disposition attachment 6 | 7 | ForceType none 8 | Header unset Content-Disposition 9 | 10 | 11 | # The following directive prevents browsers from MIME-sniffing the content-type. 12 | # This is an important complement to the ForceType directive above: 13 | Header set X-Content-Type-Options nosniff 14 | 15 | # Uncomment the following lines to prevent unauthorized download of files: 16 | #AuthName "Authorization required" 17 | #AuthType Basic 18 | #require valid-user 19 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/css/jquery.fileupload.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Plugin CSS 1.3.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileinput-button { 14 | position: relative; 15 | overflow: hidden; 16 | } 17 | .fileinput-button input { 18 | position: absolute; 19 | top: 0; 20 | right: 0; 21 | margin: 0; 22 | opacity: 0; 23 | -ms-filter: 'alpha(opacity=0)'; 24 | font-size: 200px; 25 | direction: ltr; 26 | cursor: pointer; 27 | } 28 | 29 | /* Fixes for IE < 8 */ 30 | @media screen\9 { 31 | .fileinput-button input { 32 | filter: alpha(opacity=0); 33 | font-size: 100%; 34 | height: 100%; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Service/Validator/Constraints/FileOwner.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator\Constraints; 12 | 13 | use Symfony\Component\Validator\Constraint; 14 | 15 | /** 16 | * FileOwner 17 | * 18 | * @author jobou 19 | * @Annotation 20 | */ 21 | class FileOwner extends Constraint 22 | { 23 | /** 24 | * @var string 25 | */ 26 | public $message = 'You do not own the submitted file "%filename%".'; 27 | 28 | /** 29 | * {@inheritdoc} 30 | */ 31 | public function validatedBy() 32 | { 33 | return 'jb_file_owner'; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jbouzekri/file-uploader-bundle", 3 | "type": "symfony-bundle", 4 | "description": "Aggregate some bundles and libraries to provide easy ajax file upload integration with functionnalities like image croping or storage on amazon", 5 | "keywords": ["Symfony", "upload", "ajax", "jcrop", "file", "upload", "S3", "resize", "crop"], 6 | "homepage": "https://github.com/jbouzekri/FileUploaderBundle", 7 | "license": "MIT", 8 | "require": { 9 | "oneup/uploader-bundle": "~1.3", 10 | "knplabs/knp-gaufrette-bundle": "~0.5.0", 11 | "liip/imagine-bundle": "~1.7.1", 12 | "symfony/symfony": "~3.0" 13 | }, 14 | "suggest": { 15 | "willdurand/js-translation-bundle": "Provide js translation in ajax", 16 | "aws/aws-sdk-php": "Store your uploads in amazon s3" 17 | }, 18 | "autoload": { 19 | "psr-0": { "Jb\\Bundle\\FileUploaderBundle": "" } 20 | }, 21 | "target-dir": "Jb/Bundle/FileUploaderBundle" 22 | } 23 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/Gruntfile.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Gruntfile 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /*global module */ 13 | 14 | module.exports = function (grunt) { 15 | 'use strict'; 16 | 17 | grunt.initConfig({ 18 | jshint: { 19 | options: { 20 | jshintrc: '.jshintrc' 21 | }, 22 | all: [ 23 | 'Gruntfile.js', 24 | 'js/cors/*.js', 25 | 'js/*.js', 26 | 'server/node/server.js', 27 | 'test/test.js' 28 | ] 29 | } 30 | }); 31 | 32 | grunt.loadNpmTasks('grunt-contrib-jshint'); 33 | grunt.loadNpmTasks('grunt-bump-build-git'); 34 | grunt.registerTask('test', ['jshint']); 35 | grunt.registerTask('default', ['test']); 36 | 37 | }; 38 | -------------------------------------------------------------------------------- /Resources/doc/index.md: -------------------------------------------------------------------------------- 1 | JbFileUploaderBundle Documentation 2 | ================================== 3 | 4 | Base documentation 5 | ------------------ 6 | 7 | * [Installation](base/install.md) 8 | * [Getting started](base/getting_started.md) 9 | * [Reference](base/reference.md) 10 | * [Validation](base/validation.md) 11 | * [Resolvers](base/resolvers.md) 12 | * [HTML Markup](base/markup.md) 13 | 14 | Form Fields 15 | ----------- 16 | 17 | * [Simple file upload](file_upload/simple.md) 18 | * [Image file upload](file_upload/image.md) 19 | * [Image file upload with crop](file_upload/crop.md) 20 | 21 | Advanced 22 | -------- 23 | 24 | * [Using amazon S3 for storage](advanced/amazons3.md) 25 | * [Validate file ownership](advanced/fileowner.md) 26 | * [Javascript Events](advanced/javascript.md) 27 | 28 | Troubleshooting 29 | --------------- 30 | 31 | * Is your HTML markup right ? [more information](base/markup.md) 32 | * Do you have a oneup endpoint configuration and jb_fileupload endpoint one with the same name ? [more information](base/getting_started.md) 33 | -------------------------------------------------------------------------------- /JbFileUploaderBundle.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/ConfigKnpMenuBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/ConfigKnpMenuBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle; 12 | 13 | use Symfony\Component\HttpKernel\Bundle\Bundle; 14 | use Symfony\Component\DependencyInjection\ContainerBuilder; 15 | 16 | /** 17 | * JbFileUploaderBundle bundle 18 | * 19 | * @author Jonathan Bouzekri 20 | */ 21 | class JbFileUploaderBundle extends Bundle 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | public function build(ContainerBuilder $container) 27 | { 28 | parent::build($container); 29 | 30 | $container->addCompilerPass(new DependencyInjection\Compiler\ResolverCompilerPass()); 31 | $container->addCompilerPass(new DependencyInjection\Compiler\ValidatorCompilerPass()); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Service/Validator/CropValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Exception\ValidationException; 14 | 15 | /** 16 | * CropValidator 17 | * 18 | * @author jobou 19 | */ 20 | class CropValidator extends AbstractImageValidator 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function extractWidthHeight($value) 26 | { 27 | if (empty($value) || !isset($value['width']) || !isset($value['height'])) { 28 | throw new ValidationException('Unable to determine size.'); 29 | } 30 | 31 | return array( 32 | 'width' => (int) $value['width'], 33 | 'height' => (int) $value['height'] 34 | ); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Service/Validator/ImageValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Exception\ValidationException; 14 | 15 | /** 16 | * ImageValidator 17 | * 18 | * @author jobou 19 | */ 20 | class ImageValidator extends AbstractImageValidator 21 | { 22 | /** 23 | * {@inheritdoc} 24 | */ 25 | protected function extractWidthHeight($value) 26 | { 27 | $size = @getimagesize($this->formatValue($value)); 28 | 29 | if (empty($size) || ($size[0] === 0) || ($size[1] === 0)) { 30 | throw new ValidationException('Unable to determine size.'); 31 | } 32 | 33 | return array( 34 | 'width' => $size[0], 35 | 'height' => $size[1] 36 | ); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Jonathan Bouzekri 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Tapmodo Interactive LLC, 2 | http://github.com/tapmodo/Jcrop 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Service/Resolver/ImagineCacheManagerResolver.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Resolver; 12 | 13 | use Liip\ImagineBundle\Imagine\Cache\CacheManager; 14 | 15 | /** 16 | * ImagineCacheManagerResolver 17 | * 18 | * @author jobou 19 | */ 20 | class ImagineCacheManagerResolver implements ResolverInterface 21 | { 22 | /** 23 | * @var \Liip\ImagineBundle\Imagine\Cache\CacheManager 24 | */ 25 | protected $imagine; 26 | 27 | /** 28 | * Constructor 29 | * 30 | * @param \Liip\ImagineBundle\Imagine\Cache\CacheManager $imagine 31 | */ 32 | public function __construct(CacheManager $imagine) 33 | { 34 | $this->imagine = $imagine; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function getUrl($key) 41 | { 42 | return $this->imagine->getBrowserPath($key, 'original'); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactory/ImagineResolverFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | /** 12 | * @namespace 13 | */ 14 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory; 15 | 16 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 17 | use Symfony\Component\DependencyInjection\ContainerBuilder; 18 | 19 | /** 20 | * ImagineResolverFactory 21 | * 22 | * @author jobou 23 | */ 24 | class ImagineResolverFactory implements ResolverFactoryInterface 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function getKey() 30 | { 31 | return 'imagine'; 32 | } 33 | 34 | /** 35 | * {@inheritdoc} 36 | */ 37 | public function addConfiguration(ArrayNodeDefinition $node) 38 | { 39 | 40 | } 41 | 42 | /** 43 | * {@inheritdoc} 44 | */ 45 | public function create(ContainerBuilder $container, $id, array $factory) 46 | { 47 | 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JbFileUploaderBundle 2 | ==================== 3 | 4 | [![SensioLabsInsight](https://insight.sensiolabs.com/projects/fc4abd08-89d9-45cd-bbae-9bda5d39ed97/mini.png)](https://insight.sensiolabs.com/projects/fc4abd08-89d9-45cd-bbae-9bda5d39ed97) 5 | [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/jbouzekri/FileUploaderBundle/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/jbouzekri/FileUploaderBundle/?branch=master) 6 | 7 | This bundle aggregates the following bundles to provides ajax file upload with crop and validation : 8 | * [OneupUploaderBundle](https://github.com/1up-lab/OneupUploaderBundle) : server implementation for file upload 9 | * [KnpGaufretteBundle](https://github.com/KnpLabs/KnpGaufretteBundle) : Filesystem abstraction to store file on different support 10 | * [LiipImagineBundle](https://github.com/liip/LiipImagineBundle) : Image resize 11 | 12 | Documentation 13 | ------------- 14 | 15 | [Documentation](https://github.com/jbouzekri/FileUploaderBundle/tree/master/Resources/doc/index.md) 16 | 17 | Preview 18 | ------- 19 | 20 | ![Preview FileUploaderBundle](Resources/doc/img/screenshots.png?raw=true) 21 | 22 | License 23 | ------- 24 | 25 | [License](https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE) 26 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/server/node/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueimp-file-upload-node", 3 | "version": "2.1.0", 4 | "title": "jQuery File Upload Node.js example", 5 | "description": "Node.js implementation example of a file upload handler for jQuery File Upload.", 6 | "keywords": [ 7 | "file", 8 | "upload", 9 | "cross-domain", 10 | "cross-site", 11 | "node" 12 | ], 13 | "homepage": "https://github.com/blueimp/jQuery-File-Upload", 14 | "author": { 15 | "name": "Sebastian Tschan", 16 | "url": "https://blueimp.net" 17 | }, 18 | "maintainers": [ 19 | { 20 | "name": "Sebastian Tschan", 21 | "url": "https://blueimp.net" 22 | } 23 | ], 24 | "repository": { 25 | "type": "git", 26 | "url": "git://github.com/blueimp/jQuery-File-Upload.git" 27 | }, 28 | "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", 29 | "licenses": [ 30 | { 31 | "type": "MIT", 32 | "url": "http://www.opensource.org/licenses/MIT" 33 | } 34 | ], 35 | "dependencies": { 36 | "formidable": ">=1.0.11", 37 | "node-static": ">=0.6.5", 38 | "imagemagick": ">=0.1.3" 39 | }, 40 | "main": "server.js" 41 | } 42 | -------------------------------------------------------------------------------- /Service/Resolver/AssetsResolver.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Resolver; 12 | 13 | use Symfony\Component\Asset\Packages; 14 | 15 | /** 16 | * AssetsResolver 17 | * 18 | * @author jobou 19 | */ 20 | class AssetsResolver implements ResolverInterface 21 | { 22 | /** 23 | * @var Packages 24 | */ 25 | protected $assetPackages; 26 | 27 | /** 28 | * @var string 29 | */ 30 | protected $directory; 31 | 32 | /** 33 | * AssetsResolver constructor. 34 | * @param Packages $assetPackages 35 | * @param $directory 36 | */ 37 | public function __construct(Packages $assetPackages, $directory) 38 | { 39 | $this->assetPackages = $assetPackages; 40 | $this->directory = $directory; 41 | } 42 | 43 | /** 44 | * {@inheritdoc} 45 | */ 46 | public function getUrl($key) 47 | { 48 | return $this->assetPackages->getUrl( 49 | trim($this->directory, '/') . '/' . $key 50 | ); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /Resources/config/resolver_factories.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | jb_fileuploader.resolver_factory.asset.class: Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory\AssetsResolverFactory 3 | jb_fileuploader.resolver_factory.imagine.class: Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory\ImagineResolverFactory 4 | jb_fileuploader.resolver_factory.aws3.class: Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory\Aws3ResolverFactory 5 | jb_fileuploader.resolver_factory.cdn.class: Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory\CdnResolverFactory 6 | 7 | services: 8 | jb_fileuploader.resolver_factory.asset: 9 | class: "%jb_fileuploader.resolver_factory.asset.class%" 10 | tags: 11 | - { name: jb_fileuploader.resolver.factory } 12 | 13 | jb_fileuploader.resolver_factory.imagine: 14 | class: "%jb_fileuploader.resolver_factory.imagine.class%" 15 | tags: 16 | - { name: jb_fileuploader.resolver.factory } 17 | jb_fileuploader.resolver_factory.aws3: 18 | class: "%jb_fileuploader.resolver_factory.aws3.class%" 19 | tags: 20 | - { name: jb_fileuploader.resolver.factory } 21 | jb_fileuploader.resolver_factory.cdn: 22 | class: "%jb_fileuploader.resolver_factory.cdn.class%" 23 | tags: 24 | - { name: jb_fileuploader.resolver.factory } 25 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/css/jquery.fileupload-ui.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload UI Plugin CSS 9.0.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2010, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | .fileupload-buttonbar .btn, 14 | .fileupload-buttonbar .toggle { 15 | margin-bottom: 5px; 16 | } 17 | .progress-animated .progress-bar, 18 | .progress-animated .bar { 19 | background: url("../img/progressbar.gif") !important; 20 | filter: none; 21 | } 22 | .fileupload-process { 23 | float: right; 24 | display: none; 25 | } 26 | .fileupload-processing .fileupload-process, 27 | .files .processing .preview { 28 | display: block; 29 | width: 32px; 30 | height: 32px; 31 | background: url("../img/loading.gif") center no-repeat; 32 | background-size: contain; 33 | } 34 | .files audio, 35 | .files video { 36 | max-width: 300px; 37 | } 38 | 39 | @media (max-width: 767px) { 40 | .fileupload-buttonbar .toggle, 41 | .files .toggle, 42 | .files .btn span { 43 | display: none; 44 | } 45 | .files .name { 46 | width: 80px; 47 | word-wrap: break-word; 48 | } 49 | .files audio, 50 | .files video { 51 | max-width: 80px; 52 | } 53 | .files img, 54 | .files canvas { 55 | max-width: 100%; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactory/ResolverFactoryInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | /** 12 | * @namespace 13 | */ 14 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory; 15 | 16 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 17 | use Symfony\Component\DependencyInjection\ContainerBuilder; 18 | 19 | /** 20 | * ResolverFactoryInterface 21 | * @author jobou 22 | */ 23 | interface ResolverFactoryInterface 24 | { 25 | /** 26 | * Indicates which types of resolver is handled by this factory 27 | * 28 | * @var string 29 | */ 30 | public function getKey(); 31 | 32 | /** 33 | * Add configuration to extension 34 | * 35 | * @param ArrayNodeDefinition $node 36 | */ 37 | public function addConfiguration(ArrayNodeDefinition $node); 38 | 39 | /** 40 | * Create a resolver service definition 41 | * 42 | * @param ContainerBuilder $container 43 | * @param string $id 44 | * @param array $factory 45 | */ 46 | public function create(ContainerBuilder $container, $id, array $factory); 47 | } 48 | -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactory/CdnResolverFactory.php: -------------------------------------------------------------------------------- 1 | children() 36 | ->scalarNode('url')->isRequired()->cannotBeEmpty()->end() 37 | ->end() 38 | ; 39 | } 40 | 41 | /** 42 | * {@inheritdoc} 43 | */ 44 | public function create(ContainerBuilder $container, $id, array $config) 45 | { 46 | $container 47 | ->setDefinition($id, new DefinitionDecorator('jb_fileuploader.resolver.cdn.prototype')) 48 | ->addArgument($config['url']) 49 | ; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Resources/config/form_types.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | jb_fileuploader.form.type.crop.class: Jb\Bundle\FileUploaderBundle\Form\Type\CropType 3 | jb_fileuploader.form.type.crop_image_ajax.class: Jb\Bundle\FileUploaderBundle\Form\Type\CropImageAjaxType 4 | jb_fileuploader.form.type.file_ajax.class: Jb\Bundle\FileUploaderBundle\Form\Type\FileAjaxType 5 | jb_fileuploader.form.type.image_ajax.class: Jb\Bundle\FileUploaderBundle\Form\Type\ImageAjaxType 6 | 7 | services: 8 | jb_fileuploader.form.type.crop: 9 | class: "%jb_fileuploader.form.type.crop.class%" 10 | tags: 11 | - 12 | alias: jb_fileuploader_crop 13 | name: form.type 14 | 15 | jb_fileuploader.form.type.crop_image_ajax: 16 | class: "%jb_fileuploader.form.type.crop_image_ajax.class%" 17 | parent: jb_fileuploader.form.type.image_ajax 18 | tags: 19 | - 20 | alias: jb_crop_image_ajax 21 | name: form.type 22 | 23 | jb_fileuploader.form.type.file_ajax: 24 | arguments: 25 | - "@jb_fileuploader.file_history.manager" 26 | class: "%jb_fileuploader.form.type.file_ajax.class%" 27 | tags: 28 | - 29 | alias: jb_file_ajax 30 | name: form.type 31 | 32 | jb_fileuploader.form.type.image_ajax: 33 | class: "%jb_fileuploader.form.type.image_ajax.class%" 34 | parent: jb_fileuploader.form.type.file_ajax 35 | tags: 36 | - 37 | alias: jb_image_ajax 38 | name: form.type 39 | -------------------------------------------------------------------------------- /Service/Resolver/Aws3Resolver.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Resolver; 12 | 13 | use Aws\S3\S3Client; 14 | 15 | /** 16 | * Aws3Resolver 17 | * 18 | * @author jobou 19 | */ 20 | class Aws3Resolver implements ResolverInterface 21 | { 22 | /** 23 | * @var \Aws\S3\S3Client 24 | */ 25 | protected $client; 26 | 27 | /** 28 | * @var string 29 | */ 30 | protected $bucket; 31 | 32 | /** 33 | * @var string 34 | */ 35 | protected $directory; 36 | 37 | /** 38 | * Constructor 39 | */ 40 | public function __construct(S3Client $client, $bucket, $directory = null) 41 | { 42 | $this->client = $client; 43 | $this->bucket = $bucket; 44 | $this->directory = $directory; 45 | } 46 | 47 | /** 48 | * {@inheritdoc} 49 | */ 50 | public function getUrl($filename) 51 | { 52 | $path = $filename; 53 | if ($this->directory) { 54 | $path = sprintf('%s/%s', $this->directory, $path); 55 | } 56 | 57 | return $this->client->getObjectUrl($this->bucket, $path); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Resources/config/resolvers.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | jb_fileuploader.resolver.asset.prototype.class: Jb\Bundle\FileUploaderBundle\Service\Resolver\AssetsResolver 3 | jb_fileuploader.resolver.aws3.prototype.class: Jb\Bundle\FileUploaderBundle\Service\Resolver\Aws3Resolver 4 | jb_fileuploader.resolver.cdn.prototype.class: Jb\Bundle\FileUploaderBundle\Service\Resolver\CdnResolver 5 | jb_fileuploader.resolver_chain.class: Jb\Bundle\FileUploaderBundle\Service\ResolverChain 6 | jb_fileuploader.resolver.imagine.prototype.class: Jb\Bundle\FileUploaderBundle\Service\Resolver\ImagineCacheManagerResolver 7 | 8 | services: 9 | jb_fileuploader.resolver.aws3.prototype: 10 | class: "%jb_fileuploader.resolver.aws3.prototype.class%" 11 | abstract: true 12 | 13 | jb_fileuploader.resolver.cdn.prototype: 14 | class: "%jb_fileuploader.resolver.cdn.prototype.class%" 15 | abstract: true 16 | 17 | jb_fileuploader.resolver.asset.prototype: 18 | class: "%jb_fileuploader.resolver.asset.prototype.class%" 19 | arguments: 20 | - "@assets.packages" 21 | abstract: true 22 | 23 | jb_fileuploader.resolver.imagine.prototype: 24 | class: "%jb_fileuploader.resolver.imagine.prototype.class%" 25 | arguments: 26 | - "@liip_imagine.cache.manager" 27 | abstract: true 28 | 29 | jb_fileuploader.resolver_chain: 30 | class: "%jb_fileuploader.resolver_chain.class%" 31 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/css/demo.css: -------------------------------------------------------------------------------- 1 | @charset "UTF-8"; 2 | /* 3 | * jQuery File Upload Demo CSS 1.1.0 4 | * https://github.com/blueimp/jQuery-File-Upload 5 | * 6 | * Copyright 2013, Sebastian Tschan 7 | * https://blueimp.net 8 | * 9 | * Licensed under the MIT license: 10 | * http://www.opensource.org/licenses/MIT 11 | */ 12 | 13 | body { 14 | max-width: 750px; 15 | margin: 0 auto; 16 | padding: 1em; 17 | font-family: "Lucida Grande", "Lucida Sans Unicode", Arial, sans-serif; 18 | font-size: 1em; 19 | line-height: 1.4em; 20 | background: #222; 21 | color: #fff; 22 | -webkit-text-size-adjust: 100%; 23 | -ms-text-size-adjust: 100%; 24 | } 25 | a { 26 | color: orange; 27 | text-decoration: none; 28 | } 29 | img { 30 | border: 0; 31 | vertical-align: middle; 32 | } 33 | h1 { 34 | line-height: 1em; 35 | } 36 | blockquote { 37 | padding: 0 0 0 15px; 38 | margin: 0 0 20px; 39 | border-left: 5px solid #eee; 40 | } 41 | table { 42 | width: 100%; 43 | margin: 10px 0; 44 | } 45 | 46 | .fileupload-progress { 47 | margin: 10px 0; 48 | } 49 | .fileupload-progress .progress-extended { 50 | margin-top: 5px; 51 | } 52 | .error { 53 | color: red; 54 | } 55 | 56 | @media (min-width: 481px) { 57 | .navigation { 58 | list-style: none; 59 | padding: 0; 60 | } 61 | .navigation li { 62 | display: inline-block; 63 | } 64 | .navigation li:not(:first-child):before { 65 | content: "| "; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Service/FileHistoryManagerInterface.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | /** 14 | * FileHistoryManagerInterface 15 | * 16 | * @author jobou 17 | */ 18 | interface FileHistoryManagerInterface 19 | { 20 | /** 21 | * Create and save a file history object 22 | * 23 | * @param string $fileName 24 | * @param string $originalName 25 | * @param string $type 26 | * @param int $userId 27 | * 28 | * @return \Jb\Bundle\FileUploaderBundle\Entity\FileHistory 29 | */ 30 | public function createAndSave($fileName, $originalName, $type, $userId = null); 31 | 32 | /** 33 | * Instantiate a new file history object 34 | * 35 | * @param string $fileName 36 | * @param string $originalName 37 | * @param string $type 38 | * @param int $userId 39 | * 40 | * @return \Jb\Bundle\FileUploaderBundle\Entity\FileHistory 41 | */ 42 | public function create($fileName, $originalName, $type, $userId); 43 | 44 | /** 45 | * Find one FileHistory by filename 46 | * 47 | * @param string $fileName 48 | * 49 | * @return \Jb\Bundle\FileUploaderBundle\Entity\FileHistory 50 | */ 51 | public function findOneByFileName($fileName); 52 | } 53 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/blueimp-file-upload.jquery.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueimp-file-upload", 3 | "version": "9.8.0", 4 | "title": "jQuery File Upload", 5 | "author": { 6 | "name": "Sebastian Tschan", 7 | "url": "https://blueimp.net" 8 | }, 9 | "licenses": [ 10 | { 11 | "type": "MIT", 12 | "url": "http://www.opensource.org/licenses/MIT" 13 | } 14 | ], 15 | "dependencies": { 16 | "jquery": ">=1.6" 17 | }, 18 | "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", 19 | "keywords": [ 20 | "jquery", 21 | "file", 22 | "upload", 23 | "widget", 24 | "multiple", 25 | "selection", 26 | "drag", 27 | "drop", 28 | "progress", 29 | "preview", 30 | "cross-domain", 31 | "cross-site", 32 | "chunk", 33 | "resume", 34 | "gae", 35 | "go", 36 | "python", 37 | "php", 38 | "bootstrap" 39 | ], 40 | "homepage": "https://github.com/blueimp/jQuery-File-Upload", 41 | "docs": "https://github.com/blueimp/jQuery-File-Upload/wiki", 42 | "demo": "https://blueimp.github.io/jQuery-File-Upload/", 43 | "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", 44 | "maintainers": [ 45 | { 46 | "name": "Sebastian Tschan", 47 | "url": "https://blueimp.net" 48 | } 49 | ] 50 | } 51 | -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactoryConfiguration.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | /** 12 | * @namespace 13 | */ 14 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection; 15 | 16 | use Symfony\Component\Config\Definition\Builder\TreeBuilder; 17 | use Symfony\Component\Config\Definition\ConfigurationInterface; 18 | 19 | /** 20 | * Resolver factory configuration for the FileUploader Extension 21 | * 22 | * @author Jonathan Bouzekri 23 | */ 24 | class ResolverFactoryConfiguration implements ConfigurationInterface 25 | { 26 | /** 27 | * Generates the configuration tree builder 28 | * 29 | * @return TreeBuilder 30 | */ 31 | public function getConfigTreeBuilder() 32 | { 33 | $treeBuilder = new TreeBuilder(); 34 | 35 | $treeBuilder 36 | ->root('jb_fileuploader') 37 | ->ignoreExtraKeys() 38 | ->fixXmlConfig('resolver_factory', 'resolver_factories') 39 | ->children() 40 | ->arrayNode('resolver_factories') 41 | ->defaultValue(array()) 42 | ->prototype('scalar')->end() 43 | ->end() 44 | ->end() 45 | ->end() 46 | ; 47 | 48 | return $treeBuilder; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/ResolverCompilerPass.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\Compiler; 12 | 13 | use Symfony\Component\DependencyInjection\ContainerBuilder; 14 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 15 | use Symfony\Component\DependencyInjection\Reference; 16 | 17 | /** 18 | * ResolverCompilerPass 19 | * 20 | * @author jobou 21 | */ 22 | class ResolverCompilerPass implements CompilerPassInterface 23 | { 24 | /** 25 | * {@inheritDoc} 26 | */ 27 | public function process(ContainerBuilder $container) 28 | { 29 | if (!$container->hasDefinition('jb_fileuploader.resolver_chain')) { 30 | return; 31 | } 32 | 33 | $definition = $container->getDefinition( 34 | 'jb_fileuploader.resolver_chain' 35 | ); 36 | 37 | $taggedServices = $container->findTaggedServiceIds( 38 | 'jb_fileuploader.resolver' 39 | ); 40 | 41 | foreach ($taggedServices as $id => $tags) { 42 | foreach ($tags as $attributes) { 43 | $definition->addMethodCall( 44 | 'addResolver', 45 | array(new Reference($id), $attributes["alias"]) 46 | ); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Resources/config/validators.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | jb_fileuploader.validator_chain.class: Jb\Bundle\FileUploaderBundle\Service\ValidatorChain 3 | jb_fileupload.image.validator.class: Jb\Bundle\FileUploaderBundle\Service\Validator\ImageValidator 4 | jb_fileupload.image.crop.class: Jb\Bundle\FileUploaderBundle\Service\Validator\CropValidator 5 | jb_fileuploader.validator.manager.class: Jb\Bundle\FileUploaderBundle\Service\ValidatorManager 6 | jb_fileupload.file_owner.validator.class: Jb\Bundle\FileUploaderBundle\Service\Validator\Constraints\FileOwnerValidator 7 | 8 | services: 9 | jb_fileuploader.validator.manager: 10 | class: "%jb_fileuploader.validator.manager.class%" 11 | arguments: 12 | - "@jb_fileuploader.validator_chain" 13 | - "@jb_fileuploader.endpoint_configuration" 14 | 15 | jb_fileuploader.validator_chain: 16 | class: "%jb_fileuploader.validator_chain.class%" 17 | 18 | jb_fileupload.image.validator: 19 | class: "%jb_fileupload.image.validator.class%" 20 | tags: 21 | - { name: jb_fileuploader.validator, alias: Image } 22 | 23 | jb_fileupload.crop.validator: 24 | class: "%jb_fileupload.image.crop.class%" 25 | tags: 26 | - { name: jb_fileuploader.validator, alias: Crop } 27 | 28 | jb_fileupload.file_owner.validator: 29 | class: "%jb_fileupload.file_owner.validator.class%" 30 | arguments: 31 | - "@doctrine.orm.entity_manager" 32 | - "@security.token_storage" 33 | tags: 34 | - { name: validator.constraint_validator, alias: jb_file_owner } 35 | -------------------------------------------------------------------------------- /DependencyInjection/Compiler/ValidatorCompilerPass.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\Compiler; 12 | 13 | use Symfony\Component\DependencyInjection\ContainerBuilder; 14 | use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; 15 | use Symfony\Component\DependencyInjection\Reference; 16 | 17 | /** 18 | * ValidatorCompilerPass 19 | * 20 | * @author jobou 21 | */ 22 | class ValidatorCompilerPass implements CompilerPassInterface 23 | { 24 | /** 25 | * {@inheritDoc} 26 | */ 27 | public function process(ContainerBuilder $container) 28 | { 29 | if (!$container->hasDefinition('jb_fileuploader.validator_chain')) { 30 | return; 31 | } 32 | 33 | $definition = $container->getDefinition( 34 | 'jb_fileuploader.validator_chain' 35 | ); 36 | 37 | $taggedServices = $container->findTaggedServiceIds( 38 | 'jb_fileuploader.validator' 39 | ); 40 | 41 | foreach ($taggedServices as $id => $tags) { 42 | foreach ($tags as $attributes) { 43 | $definition->addMethodCall( 44 | 'addValidator', 45 | array(new Reference($id), $attributes["alias"]) 46 | ); 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueimp-file-upload", 3 | "version": "9.8.0", 4 | "title": "jQuery File Upload", 5 | "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", 6 | "keywords": [ 7 | "jquery", 8 | "file", 9 | "upload", 10 | "widget", 11 | "multiple", 12 | "selection", 13 | "drag", 14 | "drop", 15 | "progress", 16 | "preview", 17 | "cross-domain", 18 | "cross-site", 19 | "chunk", 20 | "resume", 21 | "gae", 22 | "go", 23 | "python", 24 | "php", 25 | "bootstrap" 26 | ], 27 | "homepage": "https://github.com/blueimp/jQuery-File-Upload", 28 | "author": { 29 | "name": "Sebastian Tschan", 30 | "url": "https://blueimp.net" 31 | }, 32 | "maintainers": [ 33 | { 34 | "name": "Sebastian Tschan", 35 | "url": "https://blueimp.net" 36 | } 37 | ], 38 | "repository": { 39 | "type": "git", 40 | "url": "git://github.com/blueimp/jQuery-File-Upload.git" 41 | }, 42 | "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", 43 | "licenses": [ 44 | { 45 | "type": "MIT", 46 | "url": "http://www.opensource.org/licenses/MIT" 47 | } 48 | ], 49 | "devDependencies": { 50 | "grunt": "~0.4.5", 51 | "grunt-bump-build-git": "~1.1.1", 52 | "grunt-contrib-jshint": "~0.10.0" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Service/Imagine/AwsS3Resolver.php: -------------------------------------------------------------------------------- 1 | storage = $storage; 21 | $this->bucket = $bucket; 22 | $this->acl = $acl; 23 | $this->objUrlOptions = $objUrlOptions; 24 | } 25 | 26 | /** 27 | * Returns the object path within the bucket. 28 | * 29 | * @param string $path The base path of the resource. 30 | * @param string $filter The name of the imagine filter in effect. 31 | * 32 | * @return string The path of the object on S3. 33 | */ 34 | protected function getObjectPath($path, $filter) 35 | { 36 | // If original in aws3, then it is in the images folder 37 | if ($filter == 'original') { 38 | return $path; 39 | } 40 | 41 | return parent::getObjectPath($path, $filter); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactory/AssetsResolverFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory; 12 | 13 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 14 | use Symfony\Component\DependencyInjection\ContainerBuilder; 15 | use Symfony\Component\DependencyInjection\DefinitionDecorator; 16 | 17 | /** 18 | * Class AssetsResolverFactory 19 | * 20 | * @package Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory 21 | */ 22 | class AssetsResolverFactory implements ResolverFactoryInterface 23 | { 24 | /** 25 | * {@inheritdoc} 26 | */ 27 | public function getKey() 28 | { 29 | return 'assets'; 30 | } 31 | 32 | /** 33 | * {@inheritdoc} 34 | */ 35 | public function addConfiguration(ArrayNodeDefinition $node) 36 | { 37 | $node 38 | ->children() 39 | ->scalarNode('directory')->isRequired()->cannotBeEmpty()->end() 40 | ->end() 41 | ; 42 | } 43 | 44 | /** 45 | * {@inheritdoc} 46 | */ 47 | public function create(ContainerBuilder $container, $id, array $config) 48 | { 49 | $container 50 | ->setDefinition($id, new DefinitionDecorator('jb_fileuploader.resolver.asset.prototype')) 51 | ->addArgument($config['directory']) 52 | ; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Service/EndpointConfiguration.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | /** 14 | * EndpointConfiguration 15 | * 16 | * @author jobou 17 | */ 18 | class EndpointConfiguration 19 | { 20 | /** 21 | * @var array 22 | */ 23 | protected $endpoints; 24 | 25 | /** 26 | * Constructor 27 | * 28 | * @param array $endpoints 29 | */ 30 | public function __construct(array $endpoints) 31 | { 32 | $this->endpoints = $endpoints; 33 | } 34 | 35 | 36 | /** 37 | * Get configuration value 38 | * 39 | * @param string $endpoint 40 | * @param string $key 41 | * 42 | * @return mixed 43 | */ 44 | public function getValue($endpoint, $key) 45 | { 46 | if (isset($this->endpoints['endpoints'][$endpoint]) 47 | && isset($this->endpoints['endpoints'][$endpoint][$key]) 48 | ) { 49 | return $this->endpoints['endpoints'][$endpoint][$key]; 50 | } 51 | 52 | if (isset($this->endpoints[$key])) { 53 | return $this->endpoints[$key]; 54 | } 55 | 56 | return null; 57 | } 58 | 59 | /** 60 | * Get enpoint configuration 61 | * 62 | * @param string $endpoint 63 | * @return mixed 64 | */ 65 | public function getEndpoint($endpoint) 66 | { 67 | return $this->endpoints[$endpoint]; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /Service/ResolverChain.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Exception\JbFileUploaderException; 14 | use Jb\Bundle\FileUploaderBundle\Service\Resolver\ResolverInterface; 15 | 16 | /** 17 | * ResolverChain 18 | * 19 | * @author jobou 20 | */ 21 | class ResolverChain 22 | { 23 | /** 24 | * @var array 25 | */ 26 | private $resolvers; 27 | 28 | /** 29 | * Constructor 30 | */ 31 | public function __construct() 32 | { 33 | $this->resolvers = array(); 34 | } 35 | 36 | /** 37 | * Add a resolver 38 | * 39 | * @param \Jb\Bundle\FileUploaderBundle\Service\Resolver\ResolverInterface $resolver 40 | */ 41 | public function addResolver(ResolverInterface $resolver, $alias) 42 | { 43 | $this->resolvers[$alias] = $resolver; 44 | } 45 | 46 | /** 47 | * 48 | * @param string $alias 49 | * 50 | * @return \Jb\Bundle\FileUploaderBundle\Service\Resolver\ResolverInterface 51 | * 52 | * @throws \Jb\Bundle\FileUploaderBundle\Exception\JbFileUploaderException 53 | */ 54 | public function getResolver($alias) 55 | { 56 | if (array_key_exists($alias, $this->resolvers)) { 57 | return $this->resolvers[$alias]; 58 | } 59 | 60 | throw new JbFileUploaderException('Unknown resolver ' . $alias); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Service/ValidatorChain.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Exception\JbFileUploaderException; 14 | use Jb\Bundle\FileUploaderBundle\Service\Validator\AbstractValidator; 15 | 16 | /** 17 | * ValidatorChain 18 | * 19 | * @author jobou 20 | */ 21 | class ValidatorChain 22 | { 23 | /** 24 | * @var array 25 | */ 26 | private $validators; 27 | 28 | /** 29 | * Constructor 30 | */ 31 | public function __construct() 32 | { 33 | $this->validators = array(); 34 | } 35 | 36 | /** 37 | * Add a validator 38 | * 39 | * @param \Jb\Bundle\FileUploaderBundle\Service\Validator\AbstractValidator $validator 40 | */ 41 | public function addValidator(AbstractValidator $validator, $alias) 42 | { 43 | $this->validators[$alias] = $validator; 44 | } 45 | 46 | /** 47 | * Get a validator by its alias 48 | * 49 | * @param string $alias 50 | * 51 | * @return \Jb\Bundle\FileUploaderBundle\Service\Validator\AbstractValidator 52 | * 53 | * @throws \Jb\Bundle\FileUploaderBundle\Exception\JbFileUploaderException 54 | */ 55 | public function getValidator($alias) 56 | { 57 | if (array_key_exists($alias, $this->validators)) { 58 | return $this->validators[$alias]; 59 | } 60 | 61 | throw new JbFileUploaderException('Unknown validator ' . $alias); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /EventListener/Validation/ConfiguredValidationListener.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\EventListener\Validation; 12 | 13 | use Oneup\UploaderBundle\Event\ValidationEvent; 14 | use Oneup\UploaderBundle\Uploader\Exception\ValidationException; 15 | use Jb\Bundle\FileUploaderBundle\Service\ValidatorManager; 16 | use Jb\Bundle\FileUploaderBundle\Exception\ValidationException as JbFileUploaderValidationException; 17 | 18 | /** 19 | * ConfiguredValidationListener 20 | * 21 | * @author jobou 22 | */ 23 | class ConfiguredValidationListener 24 | { 25 | /** 26 | * @var \Jb\Bundle\FileUploaderBundle\Service\ValidatorManager 27 | */ 28 | protected $validator; 29 | 30 | /** 31 | * Constructor 32 | * 33 | * @param \Jb\Bundle\FileUploaderBundle\Service\ValidatorManager $validator 34 | */ 35 | public function __construct(ValidatorManager $validator) 36 | { 37 | $this->validator = $validator; 38 | } 39 | 40 | /** 41 | * Validate a submited file 42 | * 43 | * @param ValidationEvent $event 44 | * @throws \Oneup\UploaderBundle\Uploader\Exception\ValidationException 45 | */ 46 | public function onValidate(ValidationEvent $event) 47 | { 48 | try { 49 | $this->validator->validate( 50 | $event->getType(), 51 | $event->getFile(), 52 | 'upload_validators' 53 | ); 54 | } catch (JbFileUploaderValidationException $e) { 55 | throw new ValidationException($e->getMessage(), null, $e); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/tutorial1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Hello World | Jcrop Demo 5 | 6 | 7 | 8 | 9 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 |
27 |
28 |
29 | 30 | 38 | 39 | [Jcrop Example] 40 | 41 |
42 |

43 | This example demonstrates the default behavior of Jcrop.
44 | Since no event handlers have been attached it only performs 45 | the cropping behavior. 46 |

47 |
48 | 49 | 55 | 56 |
57 | 58 |
59 |
60 |
61 |
62 | 63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /Form/Type/ImageAjaxType.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Form\Type; 12 | 13 | use Symfony\Component\Form\AbstractType; 14 | use Symfony\Component\OptionsResolver\OptionsResolver; 15 | use Symfony\Component\Form\FormView; 16 | use Symfony\Component\Form\FormInterface; 17 | 18 | /** 19 | * Class ImageAjaxType 20 | * @package Jb\Bundle\FileUploaderBundle\Form\Type 21 | */ 22 | class ImageAjaxType extends AbstractType 23 | { 24 | /** 25 | * {@inheritDoc} 26 | */ 27 | public function configureOptions(OptionsResolver $resolver) 28 | { 29 | $resolver->setDefined(array( 30 | 'default_image', 31 | 'img_width', 32 | 'img_height' 33 | )); 34 | 35 | $resolver->setDefaults( 36 | array( 37 | 'default_image' => 'bundles/jbfileuploader/img/default.png', 38 | 'loading_file' => 'bundles/jbfileuploader/img/ajax-loader.gif', 39 | ) 40 | ); 41 | } 42 | 43 | /** 44 | * {@inheritDoc} 45 | */ 46 | public function buildView(FormView $view, FormInterface $form, array $options) 47 | { 48 | $view->vars['download_link'] = false; 49 | $view->vars['default_image'] = $options['default_image']; 50 | 51 | if (isset($options['img_width'])) { 52 | $view->vars['img_width'] = $options['img_width']; 53 | } 54 | 55 | if (isset($options['img_height'])) { 56 | $view->vars['img_height'] = $options['img_height']; 57 | } 58 | } 59 | 60 | /** 61 | * {@inheritDoc} 62 | */ 63 | public function getParent() 64 | { 65 | return FileAjaxType::class; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/css/jquery.Jcrop.min.css: -------------------------------------------------------------------------------- 1 | /* jquery.Jcrop.min.css v0.9.12 (build:20140524) */ 2 | .jcrop-holder{direction:ltr;text-align:left;-ms-touch-action:none}.jcrop-hline,.jcrop-vline{background:#fff url(Jcrop.gif);font-size:0;position:absolute}.jcrop-vline{height:100%;width:1px!important}.jcrop-vline.right{right:0}.jcrop-hline{height:1px!important;width:100%}.jcrop-hline.bottom{bottom:0}.jcrop-tracker{height:100%;width:100%;-webkit-tap-highlight-color:transparent;-webkit-touch-callout:none;-webkit-user-select:none}.jcrop-handle{background-color:#333;border:1px #eee solid;width:7px;height:7px;font-size:1px}.jcrop-handle.ord-n{left:50%;margin-left:-4px;margin-top:-4px;top:0}.jcrop-handle.ord-s{bottom:0;left:50%;margin-bottom:-4px;margin-left:-4px}.jcrop-handle.ord-e{margin-right:-4px;margin-top:-4px;right:0;top:50%}.jcrop-handle.ord-w{left:0;margin-left:-4px;margin-top:-4px;top:50%}.jcrop-handle.ord-nw{left:0;margin-left:-4px;margin-top:-4px;top:0}.jcrop-handle.ord-ne{margin-right:-4px;margin-top:-4px;right:0;top:0}.jcrop-handle.ord-se{bottom:0;margin-bottom:-4px;margin-right:-4px;right:0}.jcrop-handle.ord-sw{bottom:0;left:0;margin-bottom:-4px;margin-left:-4px}.jcrop-dragbar.ord-n,.jcrop-dragbar.ord-s{height:7px;width:100%}.jcrop-dragbar.ord-e,.jcrop-dragbar.ord-w{height:100%;width:7px}.jcrop-dragbar.ord-n{margin-top:-4px}.jcrop-dragbar.ord-s{bottom:0;margin-bottom:-4px}.jcrop-dragbar.ord-e{margin-right:-4px;right:0}.jcrop-dragbar.ord-w{margin-left:-4px}.jcrop-light .jcrop-hline,.jcrop-light .jcrop-vline{background:#fff;filter:alpha(opacity=70)!important;opacity:.7!important}.jcrop-light .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#000;border-color:#fff;border-radius:3px}.jcrop-dark .jcrop-hline,.jcrop-dark .jcrop-vline{background:#000;filter:alpha(opacity=70)!important;opacity:.7!important}.jcrop-dark .jcrop-handle{-moz-border-radius:3px;-webkit-border-radius:3px;background-color:#fff;border-color:#000;border-radius:3px}.solid-line .jcrop-hline,.solid-line .jcrop-vline{background:#fff}.jcrop-holder img,img.jcrop-preview{max-width:none} -------------------------------------------------------------------------------- /DependencyInjection/ResolverFactory/Aws3ResolverFactory.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | /** 12 | * @namespace 13 | */ 14 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory; 15 | 16 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 17 | use Symfony\Component\DependencyInjection\ContainerBuilder; 18 | use Symfony\Component\DependencyInjection\DefinitionDecorator; 19 | use Symfony\Component\DependencyInjection\Reference; 20 | 21 | /** 22 | * Class Aws3ResolverFactory 23 | * 24 | * @author jobou 25 | * @package Jb\Bundle\FileUploaderBundle\DependencyInjection\ResolverFactory 26 | */ 27 | class Aws3ResolverFactory implements ResolverFactoryInterface 28 | { 29 | /** 30 | * {@inheritdoc} 31 | */ 32 | public function getKey() 33 | { 34 | return 'aws3'; 35 | } 36 | 37 | /** 38 | * {@inheritdoc} 39 | */ 40 | public function addConfiguration(ArrayNodeDefinition $node) 41 | { 42 | $node 43 | ->children() 44 | ->scalarNode('service_id')->isRequired()->cannotBeEmpty()->end() 45 | ->scalarNode('bucket')->isRequired()->cannotBeEmpty()->end() 46 | ->scalarNode('directory')->defaultValue(null)->end() 47 | ->end() 48 | ; 49 | } 50 | 51 | /** 52 | * {@inheritdoc} 53 | */ 54 | public function create(ContainerBuilder $container, $id, array $config) 55 | { 56 | $container 57 | ->setDefinition($id, new DefinitionDecorator('jb_fileuploader.resolver.aws3.prototype')) 58 | ->addArgument(new Reference($config['service_id'])) 59 | ->addArgument($config['bucket']) 60 | ->addArgument($config['directory']) 61 | ; 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Service/Validator/AbstractValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator; 12 | 13 | use Symfony\Component\OptionsResolver\OptionsResolver; 14 | 15 | /** 16 | * AbstractValidator 17 | * 18 | * @author jobou 19 | */ 20 | abstract class AbstractValidator 21 | { 22 | /** 23 | * Configure the validator 24 | * 25 | * @param OptionsResolver $resolver 26 | */ 27 | protected function configureOptions(OptionsResolver $resolver) 28 | { 29 | } 30 | 31 | /** 32 | * Apply the validator 33 | * 34 | * @param mixed $value 35 | * @param array $configuration 36 | * 37 | * @throws \Jb\Bundle\FileUploaderBundle\Exception\ValidationException 38 | */ 39 | public function applyValidator($value, array $configuration) 40 | { 41 | // Validate configuration 42 | $resolver = new OptionsResolver(); 43 | $this->configureOptions($resolver); 44 | $configuration = $resolver->resolve($configuration); 45 | 46 | $this->validate($value, $configuration); 47 | } 48 | 49 | /** 50 | * Extract the value used in the validator 51 | * 52 | * @param mixed $value 53 | * @return mixed|string 54 | */ 55 | protected function formatValue($value) 56 | { 57 | if ($value instanceof \SplFileInfo) { 58 | return $value->getPathname(); 59 | } 60 | 61 | return $value; 62 | } 63 | 64 | /** 65 | * Validate a value 66 | * 67 | * @param mixed $value 68 | * @param array $configuration 69 | * 70 | * @throws \Jb\Bundle\FileUploaderBundle\Exception\ValidationException 71 | */ 72 | abstract protected function validate($value, array $configuration); 73 | } 74 | -------------------------------------------------------------------------------- /Controller/CropController.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Controller; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Form\Type\CropType; 14 | use Symfony\Component\HttpFoundation\Request; 15 | use Symfony\Component\HttpFoundation\JsonResponse; 16 | use Symfony\Bundle\FrameworkBundle\Controller\Controller; 17 | 18 | /** 19 | * CropController 20 | * 21 | * @author jobou 22 | */ 23 | class CropController extends Controller 24 | { 25 | /** 26 | * Filter for croping 27 | * 28 | * @param Request $request 29 | * @param string $endpoint 30 | * 31 | * @return JsonResponse 32 | */ 33 | public function filterAction(Request $request, $endpoint) 34 | { 35 | $form = $this->createForm(CropType::class); 36 | 37 | $form->handleRequest($request); 38 | 39 | // Form invalid. Exit. 40 | if (!$form->isValid()) { 41 | return $this->createErrorResponse( 42 | $this->get('translator')->trans('Invalid crop parameters') 43 | ); 44 | } 45 | 46 | // Else process crop 47 | try { 48 | return new JsonResponse( 49 | $this->get('jb_fileuploader.croper')->crop($endpoint, $form->getData()) 50 | ); 51 | } catch (\Exception $e) { 52 | return $this->createErrorResponse($e->getMessage()); 53 | } 54 | } 55 | 56 | /** 57 | * Create error message 58 | * 59 | * @param string $message 60 | * 61 | * @return JsonResponse 62 | */ 63 | protected function createErrorResponse($message) 64 | { 65 | return new JsonResponse( 66 | array( 67 | 'error' => $message 68 | ), 69 | 400 70 | ); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /Service/ValidatorManager.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Service\ValidatorChain; 14 | use Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration; 15 | 16 | /** 17 | * ValidatorManager 18 | * 19 | * @author jobou 20 | */ 21 | class ValidatorManager 22 | { 23 | /** 24 | * @var \Jb\Bundle\FileUploaderBundle\Service\ValidatorChain 25 | */ 26 | protected $validators; 27 | 28 | /** 29 | * @var \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration 30 | */ 31 | protected $configuration; 32 | 33 | /** 34 | * Constructor 35 | * 36 | * @param \Jb\Bundle\FileUploaderBundle\Service\ValidatorChain $validators 37 | * @param \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration $configuration 38 | */ 39 | public function __construct(ValidatorChain $validators, EndpointConfiguration $configuration) 40 | { 41 | $this->validators = $validators; 42 | $this->configuration = $configuration; 43 | } 44 | 45 | /** 46 | * Validate by applying validators from validator chain 47 | * 48 | * @param string $endpoint 49 | * @param mixed $value 50 | * @param string $configKey 51 | * 52 | * @throws \Jb\Bundle\FileUploaderBundle\Exception\ValidationException 53 | */ 54 | public function validate($endpoint, $value, $configKey = 'upload_validators') 55 | { 56 | $validationConfiguration = $this->configuration->getValue($endpoint, $configKey); 57 | 58 | foreach ((array) $validationConfiguration as $validationType => $config) { 59 | $validator = $this->validators->getValidator($validationType); 60 | $validator->applyValidator($value, $config); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /Twig/CropExtension.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Twig; 12 | 13 | use Symfony\Component\Routing\Router; 14 | use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 15 | 16 | /** 17 | * CropExtension 18 | * 19 | * @author jobou 20 | */ 21 | class CropExtension extends \Twig_Extension 22 | { 23 | /** 24 | * @var \Symfony\Component\Routing\Router 25 | */ 26 | protected $router; 27 | 28 | /** 29 | * @var string 30 | */ 31 | protected $routeName; 32 | 33 | /** 34 | * Constructor 35 | * 36 | * @param \Symfony\Component\Routing\Router $router 37 | * @param string $routeName 38 | */ 39 | public function __construct(Router $router, $routeName) 40 | { 41 | $this->router = $router; 42 | $this->routeName = $routeName; 43 | } 44 | 45 | /** 46 | * {@inheritDoc} 47 | */ 48 | public function getFunctions() 49 | { 50 | return array( 51 | new \Twig_SimpleFunction( 52 | 'jb_fileuploader_crop_endpoint', 53 | array($this, 'getCropEndpoint') 54 | ) 55 | ); 56 | } 57 | 58 | /** 59 | * Get crop endpoint url 60 | * 61 | * @param $endpoint 62 | * @param array $parameters 63 | * @param int $absolute 64 | * 65 | * @return string 66 | */ 67 | public function getCropEndpoint( 68 | $endpoint, 69 | $parameters = array(), 70 | $absolute = UrlGeneratorInterface::ABSOLUTE_PATH 71 | ) { 72 | $parameters = array_merge($parameters, array('endpoint' => $endpoint)); 73 | 74 | return $this->router->generate($this->routeName, $parameters, $absolute); 75 | } 76 | 77 | /** 78 | * {@inheritdoc} 79 | */ 80 | public function getName() 81 | { 82 | return 'jb_fileuploader_crop_extension'; 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /Form/Type/CropImageAjaxType.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Form\Type; 12 | 13 | use Symfony\Component\Form\AbstractType; 14 | use Symfony\Component\OptionsResolver\OptionsResolver; 15 | use Symfony\Component\Form\FormView; 16 | use Symfony\Component\Form\FormInterface; 17 | 18 | /** 19 | * CropImageAjaxType 20 | */ 21 | class CropImageAjaxType extends AbstractType 22 | { 23 | /** 24 | * {@inheritDoc} 25 | */ 26 | public function configureOptions(OptionsResolver $resolver) 27 | { 28 | $resolver->setDefined( 29 | array( 30 | 'max_width', 31 | 'max_height', 32 | 'reset_button', 33 | 'reset_button_label', 34 | 'confirm_button_label', 35 | 'crop_options' 36 | ) 37 | ); 38 | 39 | $resolver->setDefaults( 40 | array( 41 | 'resolver_key' => 'croped_resolver', 42 | 'max_width' => 350, 43 | 'max_height' => 350, 44 | 'reset_button' => true, 45 | 'reset_button_label' => 'Reset', 46 | 'confirm_button_label' => 'Confirm', 47 | 'crop_options' => array() 48 | ) 49 | ); 50 | } 51 | 52 | /** 53 | * {@inheritDoc} 54 | */ 55 | public function buildView(FormView $view, FormInterface $form, array $options) 56 | { 57 | $view->vars['use_crop'] = true; 58 | $view->vars['max_width'] = $options['max_width']; 59 | $view->vars['max_height'] = $options['max_height']; 60 | $view->vars['reset_button'] = $options['reset_button']; 61 | $view->vars['reset_button_label'] = $options['reset_button_label']; 62 | $view->vars['confirm_button_label'] = $options['confirm_button_label']; 63 | $view->vars['crop_options'] = $options['crop_options']; 64 | } 65 | 66 | /** 67 | * {@inheritDoc} 68 | */ 69 | public function getParent() 70 | { 71 | return ImageAjaxType::class; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/cors/postmessage.html: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | jQuery File Upload Plugin postMessage API 18 | 19 | 20 | 21 | 74 | 75 | -------------------------------------------------------------------------------- /Form/Type/CropType.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Form\Type; 12 | 13 | use Symfony\Component\Form\AbstractType; 14 | use Symfony\Component\Form\Extension\Core\Type\IntegerType; 15 | use Symfony\Component\Form\Extension\Core\Type\TextType; 16 | use Symfony\Component\Form\FormBuilderInterface; 17 | use Symfony\Component\OptionsResolver\OptionsResolver; 18 | use Symfony\Component\Validator\Constraints\NotBlank; 19 | use Symfony\Component\Validator\Constraints\Range; 20 | 21 | /** 22 | * CropType 23 | */ 24 | class CropType extends AbstractType 25 | { 26 | /** 27 | * {@inheritdoc} 28 | */ 29 | public function buildForm(FormBuilderInterface $builder, array $options) 30 | { 31 | parent::buildForm($builder, $options); 32 | 33 | $builder 34 | ->add('x', IntegerType::class, [ 35 | 'constraints' => [ 36 | new NotBlank(), 37 | new Range(['min' => 0]), 38 | ] 39 | ]) 40 | ->add('y', IntegerType::class, [ 41 | 'constraints' => [ 42 | new NotBlank(), 43 | new Range(['min' => 0]), 44 | ] 45 | ]) 46 | ->add('width', IntegerType::class, [ 47 | 'constraints' => [ 48 | new NotBlank(), 49 | new Range(['min' => 0]), 50 | ] 51 | ]) 52 | ->add('height', IntegerType::class, [ 53 | 'constraints' => [ 54 | new NotBlank(), 55 | new Range(['min' => 0]), 56 | ] 57 | ]) 58 | ->add('filename', TextType::class, [ 59 | 'constraints' => [ 60 | new NotBlank(), 61 | ] 62 | ]); 63 | } 64 | 65 | /** 66 | * {@inheritdoc} 67 | */ 68 | public function configureOptions(OptionsResolver $resolver) 69 | { 70 | $resolver->setDefaults(array( 71 | 'csrf_protection' => false, 72 | )); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/non-image.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Non-image Cropping | Jcrop Demo 5 | 6 | 7 | 8 | 9 | 24 | 25 | 26 | 27 | 38 | 39 | 40 | 41 | 42 |
43 |
44 |
45 |
46 | 47 | 55 | 56 |

57 | 58 | This is an example of attaching Jcrop to a target that is not an image. You are now cropping a paragraph tag. 59 | 60 |

61 | 62 |
63 |

64 | Attaching Jcrop to a non-image element.
65 | This is mostly useful to implement other interfaces, such as canvas or over an arbitrary div. 66 |

67 |
68 | 69 | 70 | 76 | 77 |
78 | 79 |
80 |
81 |
82 |
83 | 84 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/README.md: -------------------------------------------------------------------------------- 1 | Jcrop Image Cropping Plugin 2 | =========================== 3 | 4 | Jcrop is the quick and easy way to add image cropping functionality to 5 | your web application. It combines the ease-of-use of a typical jQuery 6 | plugin with a powerful cross-platform DHTML cropping engine that is 7 | faithful to familiar desktop graphics applications. 8 | 9 | Cross-platform Compatibility 10 | ---------------------------- 11 | 12 | * Firefox 2+ 13 | * Safari 3+ 14 | * Opera 9.5+ 15 | * Google Chrome 0.2+ 16 | * Internet Explorer 6+ 17 | 18 | Feature Overview 19 | ---------------- 20 | 21 | * Attaches unobtrusively to any image 22 | * Supports aspect ratio locking 23 | * Supports minSize/maxSize setting 24 | * Callbacks for selection done, or while moving 25 | * Keyboard support for nudging selection 26 | * API features to create interactivity, including animation 27 | * Support for CSS styling 28 | * Experimental touch-screen support (iOS, Android, etc) 29 | 30 | Contributors 31 | ============ 32 | 33 | **Special thanks to the following contributors:** 34 | 35 | * [Bruno Agutoli](mailto:brunotla1@gmail.com) 36 | * dhorrigan 37 | * Phil-B 38 | * jaymecd 39 | * all others who have committed their time and effort to help improve Jcrop 40 | 41 | MIT License 42 | =========== 43 | 44 | **Jcrop is free software under MIT License.** 45 | 46 | #### Copyright (c) 2008-2014 Tapmodo Interactive LLC,
http://github.com/tapmodo/Jcrop 47 | 48 | Permission is hereby granted, free of charge, to any person obtaining 49 | a copy of this software and associated documentation files (the 50 | "Software"), to deal in the Software without restriction, including 51 | without limitation the rights to use, copy, modify, merge, publish, 52 | distribute, sublicense, and/or sell copies of the Software, and to 53 | permit persons to whom the Software is furnished to do so, subject to 54 | the following conditions: 55 | 56 | The above copyright notice and this permission notice shall be 57 | included in all copies or substantial portions of the Software. 58 | 59 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 60 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 61 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 62 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 63 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 64 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 65 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 66 | 67 | -------------------------------------------------------------------------------- /EventListener/Upload/UploadListener.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\EventListener\Upload; 12 | 13 | use Oneup\UploaderBundle\Event\PostPersistEvent; 14 | use Jb\Bundle\FileUploaderBundle\Entity\FileHistory; 15 | use Jb\Bundle\FileUploaderBundle\Service\FileHistoryManagerInterface; 16 | 17 | /** 18 | * UploadListener 19 | * Append the filename and route to the response 20 | */ 21 | class UploadListener 22 | { 23 | /** 24 | * @var FileHistoryManagerInterface 25 | */ 26 | protected $fileHistoryManager; 27 | 28 | /** 29 | * Constructor 30 | * 31 | * @param FileHistoryManagerInterface $fileHistoryManager 32 | */ 33 | public function __construct(FileHistoryManagerInterface $fileHistoryManager) 34 | { 35 | $this->fileHistoryManager = $fileHistoryManager; 36 | } 37 | 38 | /** 39 | * {@inheritDoc} 40 | */ 41 | public function onUpload(PostPersistEvent $event) 42 | { 43 | // Create and persist a file history object 44 | $fileHistory = $this->createFileHistory($event); 45 | 46 | // Add filename information to response 47 | $response = $event->getResponse(); 48 | $response['filename'] = $fileHistory->getFileName(); 49 | $response['originalname'] = $fileHistory->getOriginalName(); 50 | $response['filepath'] = $this->fileHistoryManager->getUrl($fileHistory); 51 | 52 | return $response; 53 | } 54 | 55 | /** 56 | * Create a filehistory to retrieve original name and uploading user 57 | * 58 | * @param PostPersistEvent $event 59 | * 60 | * @return FileHistory 61 | */ 62 | protected function createFileHistory(PostPersistEvent $event) 63 | { 64 | // Find original filename in request uploaded file 65 | $files = $event->getRequest()->files->all(); 66 | $uploadedFile = array_pop($files); 67 | $originalFileName = $uploadedFile->getClientOriginalName(); 68 | 69 | // Get generated filename 70 | $fileName = $event->getFile()->getBasename(); 71 | 72 | // Fill FileHistory object 73 | return $this->fileHistoryManager->createAndSave($fileName, $originalFileName, $event->getType()); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "blueimp-file-upload", 3 | "version": "9.8.0", 4 | "title": "jQuery File Upload", 5 | "description": "File Upload widget with multiple file selection, drag&drop support, progress bar, validation and preview images, audio and video for jQuery. Supports cross-domain, chunked and resumable file uploads. Works with any server-side platform (Google App Engine, PHP, Python, Ruby on Rails, Java, etc.) that supports standard HTML form file uploads.", 6 | "keywords": [ 7 | "jquery", 8 | "file", 9 | "upload", 10 | "widget", 11 | "multiple", 12 | "selection", 13 | "drag", 14 | "drop", 15 | "progress", 16 | "preview", 17 | "cross-domain", 18 | "cross-site", 19 | "chunk", 20 | "resume", 21 | "gae", 22 | "go", 23 | "python", 24 | "php", 25 | "bootstrap" 26 | ], 27 | "homepage": "https://github.com/blueimp/jQuery-File-Upload", 28 | "author": { 29 | "name": "Sebastian Tschan", 30 | "url": "https://blueimp.net" 31 | }, 32 | "maintainers": [ 33 | { 34 | "name": "Sebastian Tschan", 35 | "url": "https://blueimp.net" 36 | } 37 | ], 38 | "repository": { 39 | "type": "git", 40 | "url": "git://github.com/blueimp/jQuery-File-Upload.git" 41 | }, 42 | "bugs": "https://github.com/blueimp/jQuery-File-Upload/issues", 43 | "licenses": [ 44 | { 45 | "type": "MIT", 46 | "url": "http://www.opensource.org/licenses/MIT" 47 | } 48 | ], 49 | "dependencies": { 50 | "jquery": ">=1.6", 51 | "blueimp-tmpl": ">=2.5.4", 52 | "blueimp-load-image": ">=1.13.0", 53 | "blueimp-canvas-to-blob": ">=2.1.1" 54 | }, 55 | "main": [ 56 | "css/jquery.fileupload.css", 57 | "css/jquery.fileupload-ui.css", 58 | "css/jquery.fileupload-noscript.css", 59 | "css/jquery.fileupload-ui-noscript.css", 60 | "js/cors/jquery.postmessage-transport.js", 61 | "js/cors/jquery.xdr-transport.js", 62 | "js/vendor/jquery.ui.widget.js", 63 | "js/jquery.fileupload.js", 64 | "js/jquery.fileupload-process.js", 65 | "js/jquery.fileupload-validate.js", 66 | "js/jquery.fileupload-image.js", 67 | "js/jquery.fileupload-audio.js", 68 | "js/jquery.fileupload-video.js", 69 | "js/jquery.fileupload-ui.js", 70 | "js/jquery.fileupload-jquery-ui.js", 71 | "js/jquery.fileupload-angular.js", 72 | "js/jquery.iframe-transport.js" 73 | ], 74 | "ignore": [ 75 | "/*.*", 76 | "/cors", 77 | "css/demo-ie8.css", 78 | "css/demo.css", 79 | "css/style.css", 80 | "js/app.js", 81 | "js/main.js", 82 | "server", 83 | "test" 84 | ] 85 | } 86 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Jcrop: the jQuery Image Cropping Plugin 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 |
14 |
15 |
16 | 17 | 24 | 25 | 26 | 27 | Jcrop 28 | is the image cropping plugin for 29 | jQuery.
30 | You've successfully unpacked Jcrop. 31 |
32 | 33 |

Static Demos

34 | 35 | 55 | 56 |

Live Demo

57 | 58 | 62 | 63 |

Jcrop Links

64 | 65 | 69 | 70 | 76 |
77 | 78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Issue Guidelines 2 | 3 | The issues tracker should only be used for **bugs** or **feature requests**. 4 | 5 | Please post **support requests** and **general discussions** about this project to the [support forum](https://groups.google.com/d/forum/jquery-fileupload). 6 | 7 | ## Bugs 8 | 9 | Please follow these guidelines before reporting a bug: 10 | 11 | 1. **Update to the latest version** — Check if you can reproduce the issue with the latest version from the `master` branch. 12 | 13 | 2. **Use the GitHub issue search** — check if the issue has already been reported. If it has been, please comment on the existing issue. 14 | 15 | 3. **Isolate the demonstrable problem** — Try to reproduce the problem with the [Demo](https://blueimp.github.io/jQuery-File-Upload/) or with a reduced test case that includes the least amount of code necessary to reproduce the problem. 16 | 17 | 4. **Provide a means to reproduce the problem** — Please provide as much details as possible, e.g. server information, browser and operating system versions, steps to reproduce the problem. If possible, provide a link to your reduced test case, e.g. via [JSFiddle](http://jsfiddle.net/). 18 | 19 | 20 | ## Feature requests 21 | 22 | Please follow the bug guidelines above for feature requests, i.e. update to the latest version and search for exising issues before posting a new request. 23 | 24 | Generally, feature requests might be accepted if the implementation would benefit a broader use case or the project could be considered incomplete without that feature. 25 | 26 | If you need help integrating this project into another framework, please post your request to the [support forum](https://groups.google.com/d/forum/jquery-fileupload). 27 | 28 | ## Pull requests 29 | 30 | [Pull requests](https://help.github.com/articles/using-pull-requests) are welcome and the preferred way of accepting code contributions. 31 | 32 | However, if you add a server-side upload handler implementation for another framework, please continue to maintain this version in your own fork without sending a pull request. You are welcome to add a link and possibly documentation about your implementation to the [Wiki](https://github.com/blueimp/jQuery-File-Upload/wiki). 33 | 34 | Please follow these guidelines before sending a pull request: 35 | 36 | 1. Update your fork to the latest upstream version. 37 | 38 | 2. Follow the coding conventions of the original repository. Changes to one of the JavaScript source files are required to pass the [JSHint](http://www.jshint.com/) validation tool. 39 | 40 | 3. Keep your commits as atomar as possible, i.e. create a new commit for every single bug fix or feature added. 41 | 42 | 4. Always add meaningfull commit messages. 43 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Plugin JS Example 8.9.1 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2010, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* global $, window */ 13 | 14 | $(function () { 15 | 'use strict'; 16 | 17 | // Initialize the jQuery File Upload widget: 18 | $('#fileupload').fileupload({ 19 | // Uncomment the following to send cross-domain cookies: 20 | //xhrFields: {withCredentials: true}, 21 | url: 'server/php/' 22 | }); 23 | 24 | // Enable iframe cross-domain access via redirect option: 25 | $('#fileupload').fileupload( 26 | 'option', 27 | 'redirect', 28 | window.location.href.replace( 29 | /\/[^\/]*$/, 30 | '/cors/result.html?%s' 31 | ) 32 | ); 33 | 34 | if (window.location.hostname === 'blueimp.github.io') { 35 | // Demo settings: 36 | $('#fileupload').fileupload('option', { 37 | url: '//jquery-file-upload.appspot.com/', 38 | // Enable image resizing, except for Android and Opera, 39 | // which actually support image resizing, but fail to 40 | // send Blob objects via XHR requests: 41 | disableImageResize: /Android(?!.*Chrome)|Opera/ 42 | .test(window.navigator.userAgent), 43 | maxFileSize: 5000000, 44 | acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i 45 | }); 46 | // Upload server status check for browsers with CORS support: 47 | if ($.support.cors) { 48 | $.ajax({ 49 | url: '//jquery-file-upload.appspot.com/', 50 | type: 'HEAD' 51 | }).fail(function () { 52 | $('
') 53 | .text('Upload server currently unavailable - ' + 54 | new Date()) 55 | .appendTo('#fileupload'); 56 | }); 57 | } 58 | } else { 59 | // Load existing files: 60 | $('#fileupload').addClass('fileupload-processing'); 61 | $.ajax({ 62 | // Uncomment the following to send cross-domain cookies: 63 | //xhrFields: {withCredentials: true}, 64 | url: $('#fileupload').fileupload('option', 'url'), 65 | dataType: 'json', 66 | context: $('#fileupload')[0] 67 | }).always(function () { 68 | $(this).removeClass('fileupload-processing'); 69 | }).done(function (result) { 70 | $(this).fileupload('option', 'done') 71 | .call(this, $.Event('done'), {result: result}); 72 | }); 73 | } 74 | 75 | }); 76 | -------------------------------------------------------------------------------- /Resources/config/services.yml: -------------------------------------------------------------------------------- 1 | parameters: 2 | jb_fileuploader.file_ajax.upload_listener.class: Jb\Bundle\FileUploaderBundle\EventListener\Upload\UploadListener 3 | jb_fileuploader.file_ajax.validation_listener.class: Jb\Bundle\FileUploaderBundle\EventListener\Validation\ConfiguredValidationListener 4 | jb_fileuploader.file_history.manager.class: Jb\Bundle\FileUploaderBundle\Service\FileHistoryManager 5 | jb_fileuploader.endpoint_configuration.class: Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration 6 | jb_fileuploader.twig_extension.crop.class: Jb\Bundle\FileUploaderBundle\Twig\CropExtension 7 | jb_fileuploader.croper.class: Jb\Bundle\FileUploaderBundle\Service\Croper 8 | jb_fileuploader.crop.manager.class: Jb\Bundle\FileUploaderBundle\Service\CropFileManager 9 | 10 | services: 11 | jb_fileuploader.file_ajax.upload_listener: 12 | class: "%jb_fileuploader.file_ajax.upload_listener.class%" 13 | arguments: 14 | - "@jb_fileuploader.file_history.manager" 15 | tags: 16 | - { name: kernel.event_listener, event: oneup_uploader.post_persist, method: onUpload } 17 | 18 | jb_fileuploader.file_ajax.validation_listener: 19 | class: "%jb_fileuploader.file_ajax.validation_listener.class%" 20 | arguments: 21 | - "@jb_fileuploader.validator.manager" 22 | tags: 23 | - { name: kernel.event_listener, event: oneup_uploader.validation, method: onValidate } 24 | 25 | jb_fileuploader.file_history.manager: 26 | class: "%jb_fileuploader.file_history.manager.class%" 27 | arguments: 28 | - "@doctrine.orm.entity_manager" 29 | - "@security.token_storage" 30 | - "@jb_fileuploader.resolver_chain" 31 | - "@jb_fileuploader.endpoint_configuration" 32 | 33 | jb_fileuploader.endpoint_configuration: 34 | class: "%jb_fileuploader.endpoint_configuration.class%" 35 | arguments: 36 | - "%jb_fileuploader.endpoints%" 37 | 38 | jb_fileuploader.twig_extension.crop: 39 | class: "%jb_fileuploader.twig_extension.crop.class%" 40 | arguments: 41 | - "@router" 42 | - "%jb_fileuploader.crop_route%" 43 | tags: 44 | - { name: twig.extension } 45 | 46 | jb_fileuploader.croper: 47 | class: "%jb_fileuploader.croper.class%" 48 | arguments: 49 | - "@jb_fileuploader.crop.manager" 50 | - "@jb_fileuploader.resolver_chain" 51 | - "@jb_fileuploader.endpoint_configuration" 52 | - "@jb_fileuploader.validator.manager" 53 | 54 | jb_fileuploader.crop.manager: 55 | class: "%jb_fileuploader.crop.manager.class%" 56 | arguments: 57 | - "@liip_imagine.data.manager" 58 | - "@liip_imagine.filter.manager" 59 | - "@knp_gaufrette.filesystem_map" 60 | - "@jb_fileuploader.endpoint_configuration" 61 | -------------------------------------------------------------------------------- /Entity/FileHistory.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Entity; 12 | 13 | use Doctrine\ORM\Mapping as ORM; 14 | 15 | /** 16 | * FileHistory 17 | * 18 | * @ORM\Entity 19 | * @ORM\Table(name="jb_filehistory") 20 | */ 21 | class FileHistory 22 | { 23 | /** 24 | * @ORM\Id 25 | * @ORM\GeneratedValue(strategy="NONE") 26 | * @ORM\Column(type="string", length=255, name="file_name") 27 | * 28 | * @var string 29 | */ 30 | protected $fileName; 31 | 32 | /** 33 | * @ORM\Column(type="string", length=255, name="original_name") 34 | * 35 | * @var string 36 | */ 37 | protected $originalName; 38 | 39 | /** 40 | * @ORM\Column(type="string", length=255) 41 | * 42 | * @var string 43 | */ 44 | protected $type; 45 | 46 | /** 47 | * @ORM\Column(type="integer", nullable=true) 48 | * 49 | * @var int 50 | */ 51 | protected $userId; 52 | 53 | /** 54 | * Set fileName 55 | * 56 | * @param string $fileName 57 | * @return FileHistory 58 | */ 59 | public function setFileName($fileName) 60 | { 61 | $this->fileName = $fileName; 62 | 63 | return $this; 64 | } 65 | 66 | /** 67 | * Get fileName 68 | * 69 | * @return string 70 | */ 71 | public function getFileName() 72 | { 73 | return $this->fileName; 74 | } 75 | 76 | /** 77 | * Set originalName 78 | * 79 | * @param string $originalName 80 | * @return FileHistory 81 | */ 82 | public function setOriginalName($originalName) 83 | { 84 | $this->originalName = $originalName; 85 | 86 | return $this; 87 | } 88 | 89 | /** 90 | * Get originalName 91 | * 92 | * @return string 93 | */ 94 | public function getOriginalName() 95 | { 96 | return $this->originalName; 97 | } 98 | 99 | /** 100 | * Set userId 101 | * 102 | * @param integer $userId 103 | * @return FileHistory 104 | */ 105 | public function setUserId($userId) 106 | { 107 | $this->userId = $userId; 108 | 109 | return $this; 110 | } 111 | 112 | /** 113 | * Get userId 114 | * 115 | * @return integer 116 | */ 117 | public function getUserId() 118 | { 119 | return $this->userId; 120 | } 121 | 122 | /** 123 | * Set type 124 | * 125 | * @param string $type 126 | * @return FileHistory 127 | */ 128 | public function setType($type) 129 | { 130 | $this->type = $type; 131 | 132 | return $this; 133 | } 134 | 135 | /** 136 | * Get type 137 | * 138 | * @return string 139 | */ 140 | public function getType() 141 | { 142 | return $this->type; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /Service/CropFileManager.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Liip\ImagineBundle\Imagine\Data\DataManager; 14 | use Liip\ImagineBundle\Imagine\Filter\FilterManager; 15 | use Knp\Bundle\GaufretteBundle\FilesystemMap; 16 | use Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration; 17 | use Liip\ImagineBundle\Binary\BinaryInterface; 18 | 19 | /** 20 | * Croper 21 | * 22 | * @author jobou 23 | */ 24 | class CropFileManager 25 | { 26 | /** 27 | * @var \Liip\ImagineBundle\Imagine\Data\DataManager 28 | */ 29 | protected $dataManager; 30 | 31 | /** 32 | * @var \Liip\ImagineBundle\Imagine\Filter\FilterManager 33 | */ 34 | protected $filterManager; 35 | 36 | /** 37 | * @var \Knp\Bundle\GaufretteBundle\FilesystemMap 38 | */ 39 | protected $filesystemMap; 40 | 41 | /** 42 | * @var \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration 43 | */ 44 | protected $configuration; 45 | 46 | /** 47 | * Constructor 48 | * 49 | * @param DataManager $dataManager 50 | * @param FilterManager $filterManager 51 | * @param FilesystemMap $filesystemMap 52 | * @param EndpointConfiguration $configuration 53 | */ 54 | public function __construct( 55 | DataManager $dataManager, 56 | FilterManager $filterManager, 57 | FilesystemMap $filesystemMap, 58 | EndpointConfiguration $configuration 59 | ) { 60 | $this->dataManager = $dataManager; 61 | $this->filterManager = $filterManager; 62 | $this->filesystemMap = $filesystemMap; 63 | $this->configuration = $configuration; 64 | } 65 | 66 | /** 67 | * Transform the file 68 | * 69 | * @param array $data 70 | * 71 | * @return \Liip\ImagineBundle\Binary\BinaryInterface 72 | */ 73 | public function transformFile(array $data) 74 | { 75 | return $this->filterManager->apply( 76 | $this->dataManager->find('original', $data['filename']), 77 | array( 78 | 'filters' => array( 79 | 'crop'=> array( 80 | 'start' => array($data['x'], $data['y']), 81 | 'size' => array($data['width'], $data['height']) 82 | ) 83 | ) 84 | ) 85 | ); 86 | } 87 | 88 | /** 89 | * Save the transformed file 90 | * 91 | * @param string $endpoint 92 | * @param BinaryInterface $cropedFile 93 | * @param array $data 94 | */ 95 | public function saveTransformedFile($endpoint, BinaryInterface $cropedFile, array $data) 96 | { 97 | $this 98 | ->filesystemMap 99 | ->get( 100 | $this->configuration->getValue($endpoint, 'croped_fs') 101 | ) 102 | ->write( 103 | $data['filename'], 104 | $cropedFile->getContent() 105 | ); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /Service/Validator/Constraints/FileOwnerValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator\Constraints; 12 | 13 | use Symfony\Component\Validator\Constraint; 14 | use Symfony\Component\Validator\ConstraintValidator; 15 | use Doctrine\Common\Persistence\ObjectManager; 16 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 17 | 18 | /** 19 | * FileOwnerValidator 20 | * 21 | * @author jobou 22 | */ 23 | class FileOwnerValidator extends ConstraintValidator 24 | { 25 | /** 26 | * @var \Doctrine\Common\Persistence\ObjectManager 27 | */ 28 | protected $em; 29 | 30 | /** 31 | * @var \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface 32 | */ 33 | protected $tokenStorage; 34 | 35 | /** 36 | * Constructor 37 | * 38 | * @param \Doctrine\Common\Persistence\ObjectManager $em 39 | * @param \Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface $tokenStorage 40 | */ 41 | public function __construct(ObjectManager $em, TokenStorageInterface $tokenStorage) 42 | { 43 | $this->em = $em; 44 | $this->tokenStorage = $tokenStorage; 45 | } 46 | 47 | /** 48 | * Validate that the submitted file is owned by the authenticated user 49 | * 50 | * @param string $value 51 | * @param Constraint $constraint 52 | */ 53 | public function validate($value, Constraint $constraint) 54 | { 55 | if (!$value) { 56 | return; 57 | } 58 | 59 | $fileHistory = $this->em->getRepository('JbFileUploaderBundle:FileHistory')->find($value); 60 | if (!$fileHistory) { 61 | return; 62 | } 63 | 64 | // No userid associated with file. Every one can use it. 65 | if (!$fileHistory->getUserId()) { 66 | return; 67 | } 68 | 69 | // No token. Violation as there is a user id associate with file. 70 | $token = $this->tokenStorage->getToken(); 71 | if (!$token) { 72 | return $this->createViolation($value, $constraint); 73 | } 74 | 75 | // No user. Violation as there is a user id associate with file. 76 | $user = $token->getUser(); 77 | if (!$user) { 78 | return $this->createViolation($value, $constraint); 79 | } 80 | 81 | if ($user->getId() !== $fileHistory->getUserId()) { 82 | return $this->createViolation($value, $constraint); 83 | } 84 | 85 | return; 86 | } 87 | 88 | /** 89 | * Create violation for validator 90 | * 91 | * @param string $value 92 | * @param Constraint $constraint 93 | */ 94 | protected function createViolation($value, Constraint $constraint) 95 | { 96 | $this 97 | ->context 98 | ->buildViolation($constraint->message) 99 | ->setParameter('%filename%', $value) 100 | ->addViolation(); 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Form/Type/FileAjaxType.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Form\Type; 12 | 13 | use Symfony\Component\Form\AbstractType; 14 | use Symfony\Component\Form\Extension\Core\Type\TextType; 15 | use Symfony\Component\OptionsResolver\OptionsResolver; 16 | use Symfony\Component\Form\FormView; 17 | use Symfony\Component\Form\FormInterface; 18 | use Jb\Bundle\FileUploaderBundle\Service\FileHistoryManagerInterface; 19 | 20 | /** 21 | * FileAjaxType 22 | */ 23 | class FileAjaxType extends AbstractType 24 | { 25 | /** 26 | * @var FileHistoryManagerInterface 27 | */ 28 | protected $fileHistoryManager; 29 | 30 | /** 31 | * Constructor 32 | * 33 | * @param FileHistoryManagerInterface $fileHistoryManager 34 | */ 35 | public function __construct(FileHistoryManagerInterface $fileHistoryManager) 36 | { 37 | $this->fileHistoryManager = $fileHistoryManager; 38 | } 39 | 40 | /** 41 | * {@inheritDoc} 42 | */ 43 | public function configureOptions(OptionsResolver $resolver) 44 | { 45 | // Endpoint mandatory for fileupload bundle 46 | $resolver->setRequired(array('endpoint')); 47 | 48 | $resolver->setDefined(array( 49 | 'download_link', 50 | 'remove_link', 51 | 'loading_file', 52 | 'resolver_key', 53 | 'progress' 54 | )); 55 | 56 | $resolver->setDefaults(array( 57 | 'download_link' => true, 58 | 'remove_link' => true, 59 | 'loading_file' => 'bundles/jbfileuploader/img/ajax-loader-small.gif', 60 | 'resolver_key' => 'upload_resolver', 61 | 'progress'=>false 62 | )); 63 | } 64 | 65 | /** 66 | * {@inheritDoc} 67 | */ 68 | public function buildView(FormView $view, FormInterface $form, array $options) 69 | { 70 | $fileHistory = null; 71 | $fileHistoryUrl = null; 72 | if ($form->getData() !== null) { 73 | $fileHistory = $this->fileHistoryManager->findOneByFileName($form->getData()); 74 | $fileHistoryUrl = $this->fileHistoryManager->getUrl($fileHistory, $options['resolver_key']); 75 | } 76 | 77 | $className = 'jb_result_filename'; 78 | if (isset($view->vars['attr']['class'])) { 79 | $view->vars['attr']['class'] .= ' ' . $className; 80 | } else { 81 | $view->vars['attr']['class'] = $className; 82 | } 83 | 84 | $view->vars['file_history'] = $fileHistory; 85 | $view->vars['file_history_url'] = $fileHistoryUrl; 86 | $view->vars['endpoint'] = $options['endpoint']; 87 | $view->vars['download_link'] = $options['download_link']; 88 | $view->vars['remove_link'] = $options['remove_link']; 89 | $view->vars['loading_file'] = $options['loading_file']; 90 | $view->vars['progress'] = $options['progress']; 91 | $view->vars['use_crop'] = false; 92 | } 93 | 94 | /** 95 | * {@inheritDoc} 96 | */ 97 | public function getParent() 98 | { 99 | return TextType::class; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/crop.php: -------------------------------------------------------------------------------- 1 | 31 | 32 | 33 | Live Cropping Demo 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 68 | 79 | 80 | 81 | 82 | 83 |
84 |
85 |
86 |
87 | 88 | 96 | 97 | 98 | 99 | 100 | 101 |
102 | 103 | 104 | 105 | 106 | 107 |
108 | 109 |

110 | An example server-side crop script. Hidden form values 111 | are set when a selection is made. If you press the Crop Image 112 | button, the form will be submitted and a 150x150 thumbnail will be 113 | dumped to the browser. Try it! 114 |

115 | 116 | 117 |
118 |
119 |
120 |
121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Service/Croper.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Service\ResolverChain; 14 | use Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration; 15 | use Jb\Bundle\FileUploaderBundle\Exception\JbFileUploaderException; 16 | use Jb\Bundle\FileUploaderBundle\Service\ValidatorManager; 17 | 18 | /** 19 | * Croper 20 | * 21 | * @author jobou 22 | */ 23 | class Croper 24 | { 25 | /** 26 | * @var \Jb\Bundle\FileUploaderBundle\Service\CropFileManager 27 | */ 28 | protected $cropManager; 29 | 30 | /** 31 | * 32 | * @var \Jb\Bundle\FileUploaderBundle\Service\ResolverChain 33 | */ 34 | protected $resolvers; 35 | 36 | /** 37 | * @var \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration 38 | */ 39 | protected $configuration; 40 | 41 | /** 42 | * @var \Jb\Bundle\FileUploaderBundle\Service\ValidatorManager 43 | */ 44 | protected $validator; 45 | 46 | /** 47 | * Constructor 48 | * 49 | * @param \Jb\Bundle\FileUploaderBundle\Service\CropFileManager $cropManager 50 | * @param \Jb\Bundle\FileUploaderBundle\Service\ResolverChain $resolvers 51 | * @param \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration $configuration 52 | * @param \Jb\Bundle\FileUploaderBundle\Service\ValidatorManager $validator 53 | */ 54 | public function __construct( 55 | CropFileManager $cropManager, 56 | ResolverChain $resolvers, 57 | EndpointConfiguration $configuration, 58 | ValidatorManager $validator 59 | ) { 60 | $this->cropManager = $cropManager; 61 | $this->resolvers = $resolvers; 62 | $this->configuration = $configuration; 63 | $this->validator = $validator; 64 | } 65 | 66 | /** 67 | * Crop an image 68 | * 69 | * @param string $endpoint 70 | * @param array $data 71 | * 72 | * @return string 73 | */ 74 | public function crop($endpoint, array $data) 75 | { 76 | // Throw ValidationException if there is an error 77 | $this->validator->validate($endpoint, $data, 'crop_validators'); 78 | 79 | // Generate croped image 80 | $cropedFile = $this->cropManager->transformFile($data); 81 | 82 | // Save it to filesystem using gaufrette 83 | $this->cropManager->saveTransformedFile($endpoint, $cropedFile, $data); 84 | 85 | // Return data 86 | return array( 87 | 'filepath' => $this->resolvers->getResolver($this->getCropResolver($endpoint))->getUrl($data['filename']), 88 | 'filename' => $data['filename'] 89 | ); 90 | } 91 | 92 | /** 93 | * Get crop resolver configuration 94 | * 95 | * @param string $endpoint 96 | * @return string 97 | * 98 | * @throws JbFileUploaderException 99 | */ 100 | protected function getCropResolver($endpoint) 101 | { 102 | $cropedResolver = $this->configuration->getValue($endpoint, 'croped_resolver'); 103 | if (!$cropedResolver) { 104 | throw new JbFileUploaderException('No croped_resolver configuration for endpoint '.$endpoint); 105 | } 106 | 107 | return $cropedResolver; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/cors/jquery.xdr-transport.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery XDomainRequest Transport Plugin 1.1.3 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | * 11 | * Based on Julian Aubourg's ajaxHooks xdr.js: 12 | * https://github.com/jaubourg/ajaxHooks/ 13 | */ 14 | 15 | /* global define, window, XDomainRequest */ 16 | 17 | (function (factory) { 18 | 'use strict'; 19 | if (typeof define === 'function' && define.amd) { 20 | // Register as an anonymous AMD module: 21 | define(['jquery'], factory); 22 | } else { 23 | // Browser globals: 24 | factory(window.jQuery); 25 | } 26 | }(function ($) { 27 | 'use strict'; 28 | if (window.XDomainRequest && !$.support.cors) { 29 | $.ajaxTransport(function (s) { 30 | if (s.crossDomain && s.async) { 31 | if (s.timeout) { 32 | s.xdrTimeout = s.timeout; 33 | delete s.timeout; 34 | } 35 | var xdr; 36 | return { 37 | send: function (headers, completeCallback) { 38 | var addParamChar = /\?/.test(s.url) ? '&' : '?'; 39 | function callback(status, statusText, responses, responseHeaders) { 40 | xdr.onload = xdr.onerror = xdr.ontimeout = $.noop; 41 | xdr = null; 42 | completeCallback(status, statusText, responses, responseHeaders); 43 | } 44 | xdr = new XDomainRequest(); 45 | // XDomainRequest only supports GET and POST: 46 | if (s.type === 'DELETE') { 47 | s.url = s.url + addParamChar + '_method=DELETE'; 48 | s.type = 'POST'; 49 | } else if (s.type === 'PUT') { 50 | s.url = s.url + addParamChar + '_method=PUT'; 51 | s.type = 'POST'; 52 | } else if (s.type === 'PATCH') { 53 | s.url = s.url + addParamChar + '_method=PATCH'; 54 | s.type = 'POST'; 55 | } 56 | xdr.open(s.type, s.url); 57 | xdr.onload = function () { 58 | callback( 59 | 200, 60 | 'OK', 61 | {text: xdr.responseText}, 62 | 'Content-Type: ' + xdr.contentType 63 | ); 64 | }; 65 | xdr.onerror = function () { 66 | callback(404, 'Not Found'); 67 | }; 68 | if (s.xdrTimeout) { 69 | xdr.ontimeout = function () { 70 | callback(0, 'timeout'); 71 | }; 72 | xdr.timeout = s.xdrTimeout; 73 | } 74 | xdr.send((s.hasContent && s.data) || null); 75 | }, 76 | abort: function () { 77 | if (xdr) { 78 | xdr.onerror = $.noop(); 79 | xdr.abort(); 80 | } 81 | } 82 | }; 83 | } 84 | }); 85 | } 86 | })); 87 | -------------------------------------------------------------------------------- /Resources/doc/base/validation.md: -------------------------------------------------------------------------------- 1 | Validation 2 | ========== 3 | 4 | There are 3 types of validation in this bundle : 5 | 6 | * the one allowed by the oneup bundle mainly mime type and file size 7 | * An extension of the oneup bundle validation for image size and ratio 8 | * A validation when submitting croping parameters for image size and ratio 9 | 10 | Mime type and file size 11 | ----------------------- 12 | 13 | This validation comes up when uploading a file using the oneup bundle endpoint. 14 | 15 | It can be configured for each endpoint : 16 | 17 | ~~~ yml 18 | oneup_uploader: 19 | mappings: 20 | my_endpoint_name: 21 | allowed_mimetypes: [image/png, image/jpg, image/jpeg, image/gif] 22 | max_size: 2M 23 | ~~~ 24 | 25 | This configuration allows only upload of classic internet image types and limit the size to 2 MB. 26 | 27 | *Note : the max size must match php post_max_size and upload_max_filesize* 28 | 29 | For more information, check the [oneup bundle reference](https://github.com/1up-lab/OneupUploaderBundle/blob/master/Resources/doc/configuration_reference.md) 30 | 31 | Image upload validation 32 | ----------------------- 33 | 34 | One of the strength of this bundle is to extend oneup fileupload bundle to add image validation. With it, you can validate the following image attributes : 35 | 36 | * min width 37 | * max width 38 | * min height 39 | * max height 40 | * min ratio 41 | * max ratio 42 | 43 | The configuration reference is : 44 | 45 | ~~~ yml 46 | jb_file_uploader: 47 | endpoints: 48 | my_endpoint_name: 49 | upload_validators: 50 | Image: 51 | MinWidth: # min width value in pixels 52 | MaxWidth: # max width value in pixels 53 | MinHeight: # min height value in pixels 54 | MaxHeight: # max height value in pixels 55 | MinRatio: # min ratio (float) 56 | MaxRatio: # max ratio (float) 57 | ~~~ 58 | 59 | Example : 60 | 61 | ~~~ yml 62 | oneup_uploader: 63 | mappings: 64 | my_endpoint_name: 65 | allowed_mimetypes: [image/png, image/jpg, image/jpeg, image/gif] 66 | max_size: 2M 67 | 68 | jb_file_uploader: 69 | endpoints: 70 | my_endpoint_name: 71 | upload_validators: 72 | Image: 73 | MinWidth: 400 74 | ~~~ 75 | 76 | This configuration checks that the uploaded file for endpoint `my_endpoint_name` is an image that has a max size of 2M and a min width of 400px. 77 | 78 | Crop validation 79 | --------------- 80 | 81 | When using the croping function, you can validate that the croping information provided by the user matches your criteria. 82 | 83 | The configuration reference is almost the same as the one for image validation : 84 | 85 | ~~~ yml 86 | jb_file_uploader: 87 | endpoints: 88 | my_endpoint_name: 89 | crop_validators: 90 | Crop: 91 | MinWidth: # min width value in pixels 92 | MaxWidth: # max width value in pixels 93 | MinHeight: # min height value in pixels 94 | MaxHeight: # max height value in pixels 95 | MinRatio: # min ratio (float) 96 | MaxRatio: # max ratio (float) 97 | ~~~ 98 | 99 | Extension 100 | --------- 101 | 102 | All validators are service tagged `jb_fileuploader.validator` with an alias used in `config.yml`. They extends `Jb\Bundle\FileUploaderBundle\Service\Validator\AbstractValidator`. 103 | 104 | Do not hesitate to extend it if you need new validation (and make a pull request. Thanks in advance). 105 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/demo_files/demos.css: -------------------------------------------------------------------------------- 1 | /* Jcrop Demo Site CSS - 2014 Tapmodo Interactive LLC - MIT License 2 | Not required to run Jcrop - contains twitter bootstrap code */ 3 | /* To build these CSS files you must have LESS and run 4 | * $ git submodule init 5 | * $ git submodule update 6 | * ...to pull in the Twitter bootstrap files 7 | */ 8 | .clearfix { 9 | *zoom: 1; 10 | } 11 | .clearfix:before, 12 | .clearfix:after { 13 | display: table; 14 | content: ""; 15 | line-height: 0; 16 | } 17 | .clearfix:after { 18 | clear: both; 19 | } 20 | .hide-text { 21 | font: 0/0 a; 22 | color: transparent; 23 | text-shadow: none; 24 | background-color: transparent; 25 | border: 0; 26 | } 27 | .input-block-level { 28 | display: block; 29 | width: 100%; 30 | min-height: 30px; 31 | -webkit-box-sizing: border-box; 32 | -moz-box-sizing: border-box; 33 | box-sizing: border-box; 34 | } 35 | /* JCROP DEMOS CSS */ 36 | li small { 37 | color: #f07878; 38 | } 39 | .inline-labels label { 40 | display: inline; 41 | } 42 | div#interface.span3 fieldset { 43 | margin-bottom: 1.5em; 44 | } 45 | div#interface.span3 fieldset legend { 46 | margin-bottom: 2px; 47 | padding-bottom: 2px; 48 | line-height: 1.2; 49 | } 50 | .article h1 { 51 | color: #333; 52 | margin-top: .2em; 53 | } 54 | .jc-demo { 55 | text-align: center; 56 | } 57 | .jcropper-holder { 58 | border: 1px #bbb solid; 59 | } 60 | .jc-demo-box { 61 | text-align: left; 62 | margin: 2em auto; 63 | background: white; 64 | border: 1px #bbb solid; 65 | -webkit-border-radius: 4px; 66 | -moz-border-radius: 4px; 67 | border-radius: 4px; 68 | -webkit-box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25); 69 | -moz-box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25); 70 | box-shadow: 1px 1px 10px rgba(0, 0, 0, 0.25); 71 | padding: 1em 2em 2em; 72 | } 73 | form { 74 | margin: 1.5em 0; 75 | } 76 | form.coords label { 77 | margin-right: 1em; 78 | font-weight: bold; 79 | color: #900; 80 | } 81 | form.coords input { 82 | width: 3em; 83 | } 84 | .ui-widget-overlay { 85 | opacity: 0.80; 86 | filter: alpha(opacity=70); 87 | } 88 | .jc-dialog { 89 | padding-top: 1em; 90 | } 91 | .ui-dialog p tt { 92 | color: yellow; 93 | } 94 | .jcrop-light .jcrop-selection { 95 | -moz-box-shadow: 0px 0px 15px #999; 96 | /* Firefox */ 97 | -webkit-box-shadow: 0px 0px 15px #999; 98 | /* Safari, Chrome */ 99 | box-shadow: 0px 0px 15px #999; 100 | /* CSS3 */ 101 | } 102 | .jcrop-dark .jcrop-selection { 103 | -moz-box-shadow: 0px 0px 15px #000; 104 | /* Firefox */ 105 | -webkit-box-shadow: 0px 0px 15px #000; 106 | /* Safari, Chrome */ 107 | box-shadow: 0px 0px 15px #000; 108 | /* CSS3 */ 109 | } 110 | .jcrop-fancy .jcrop-handle.ord-e { 111 | -webkit-border-top-left-radius: 0px; 112 | -webkit-border-bottom-left-radius: 0px; 113 | } 114 | .jcrop-fancy .jcrop-handle.ord-w { 115 | -webkit-border-top-right-radius: 0px; 116 | -webkit-border-bottom-right-radius: 0px; 117 | } 118 | .jcrop-fancy .jcrop-handle.ord-nw { 119 | -webkit-border-bottom-right-radius: 0px; 120 | } 121 | .jcrop-fancy .jcrop-handle.ord-ne { 122 | -webkit-border-bottom-left-radius: 0px; 123 | } 124 | .jcrop-fancy .jcrop-handle.ord-sw { 125 | -webkit-border-top-right-radius: 0px; 126 | } 127 | .jcrop-fancy .jcrop-handle.ord-se { 128 | -webkit-border-top-left-radius: 0px; 129 | } 130 | .jcrop-fancy .jcrop-handle.ord-s { 131 | -webkit-border-top-left-radius: 0px; 132 | -webkit-border-top-right-radius: 0px; 133 | } 134 | .jcrop-fancy .jcrop-handle.ord-n { 135 | -webkit-border-bottom-left-radius: 0px; 136 | -webkit-border-bottom-right-radius: 0px; 137 | } 138 | .description { 139 | margin: 16px 0; 140 | } 141 | .jcrop-droptarget canvas { 142 | background-color: #f0f0f0; 143 | } 144 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/styling.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CSS Styling Example | Jcrop Demo 5 | 6 | 7 | 8 | 9 | 10 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 |
71 |
72 |
73 |
74 | 75 | 83 | 84 | [Jcrop Example] 85 | 86 |
87 |
88 | Manipulate classes 89 |
90 | 91 | 92 | 93 |
94 |
95 |
96 | 97 |

98 | Example styling tricks. Click the buttons above to change the appearance of Jcrop in real-time. 99 |

100 | 101 | 102 | 108 | 109 |
110 | 111 |
112 |
113 |
114 |
115 | 116 | 117 | 118 | 119 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/tutorial2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Basic Handler | Jcrop Demo 5 | 6 | 7 | 8 | 9 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 |
61 |
62 |
63 |
64 | 65 | 73 | 74 | 75 | [Jcrop Example] 76 | 77 | 78 |
82 | 83 |
84 | 85 | 86 | 87 | 88 | 89 | 90 |
91 |
92 | 93 |
94 |

95 | An example with a basic event handler. Here we've tied 96 | several form values together with a simple event handler invocation. 97 | The result is that the form values are updated in real-time as 98 | the selection is changed using Jcrop's onChange handler. 99 |

100 | 101 |

102 | That's how easily Jcrop can be integrated into a traditional web form! 103 |

104 |
105 | 106 | 107 | 113 | 114 |
115 | 116 |
117 |
118 |
119 |
120 | 121 | 122 | 123 | 124 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/jquery.fileupload-audio.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Audio Preview Plugin 1.0.3 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* jshint nomen:false */ 13 | /* global define, window, document */ 14 | 15 | (function (factory) { 16 | 'use strict'; 17 | if (typeof define === 'function' && define.amd) { 18 | // Register as an anonymous AMD module: 19 | define([ 20 | 'jquery', 21 | 'load-image', 22 | './jquery.fileupload-process' 23 | ], factory); 24 | } else { 25 | // Browser globals: 26 | factory( 27 | window.jQuery, 28 | window.loadImage 29 | ); 30 | } 31 | }(function ($, loadImage) { 32 | 'use strict'; 33 | 34 | // Prepend to the default processQueue: 35 | $.blueimp.fileupload.prototype.options.processQueue.unshift( 36 | { 37 | action: 'loadAudio', 38 | // Use the action as prefix for the "@" options: 39 | prefix: true, 40 | fileTypes: '@', 41 | maxFileSize: '@', 42 | disabled: '@disableAudioPreview' 43 | }, 44 | { 45 | action: 'setAudio', 46 | name: '@audioPreviewName', 47 | disabled: '@disableAudioPreview' 48 | } 49 | ); 50 | 51 | // The File Upload Audio Preview plugin extends the fileupload widget 52 | // with audio preview functionality: 53 | $.widget('blueimp.fileupload', $.blueimp.fileupload, { 54 | 55 | options: { 56 | // The regular expression for the types of audio files to load, 57 | // matched against the file type: 58 | loadAudioFileTypes: /^audio\/.*$/ 59 | }, 60 | 61 | _audioElement: document.createElement('audio'), 62 | 63 | processActions: { 64 | 65 | // Loads the audio file given via data.files and data.index 66 | // as audio element if the browser supports playing it. 67 | // Accepts the options fileTypes (regular expression) 68 | // and maxFileSize (integer) to limit the files to load: 69 | loadAudio: function (data, options) { 70 | if (options.disabled) { 71 | return data; 72 | } 73 | var file = data.files[data.index], 74 | url, 75 | audio; 76 | if (this._audioElement.canPlayType && 77 | this._audioElement.canPlayType(file.type) && 78 | ($.type(options.maxFileSize) !== 'number' || 79 | file.size <= options.maxFileSize) && 80 | (!options.fileTypes || 81 | options.fileTypes.test(file.type))) { 82 | url = loadImage.createObjectURL(file); 83 | if (url) { 84 | audio = this._audioElement.cloneNode(false); 85 | audio.src = url; 86 | audio.controls = true; 87 | data.audio = audio; 88 | return data; 89 | } 90 | } 91 | return data; 92 | }, 93 | 94 | // Sets the audio element as a property of the file object: 95 | setAudio: function (data, options) { 96 | if (data.audio && !options.disabled) { 97 | data.files[data.index][options.name || 'preview'] = data.audio; 98 | } 99 | return data; 100 | } 101 | 102 | } 103 | 104 | }); 105 | 106 | })); 107 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/jquery.fileupload-video.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Video Preview Plugin 1.0.3 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* jshint nomen:false */ 13 | /* global define, window, document */ 14 | 15 | (function (factory) { 16 | 'use strict'; 17 | if (typeof define === 'function' && define.amd) { 18 | // Register as an anonymous AMD module: 19 | define([ 20 | 'jquery', 21 | 'load-image', 22 | './jquery.fileupload-process' 23 | ], factory); 24 | } else { 25 | // Browser globals: 26 | factory( 27 | window.jQuery, 28 | window.loadImage 29 | ); 30 | } 31 | }(function ($, loadImage) { 32 | 'use strict'; 33 | 34 | // Prepend to the default processQueue: 35 | $.blueimp.fileupload.prototype.options.processQueue.unshift( 36 | { 37 | action: 'loadVideo', 38 | // Use the action as prefix for the "@" options: 39 | prefix: true, 40 | fileTypes: '@', 41 | maxFileSize: '@', 42 | disabled: '@disableVideoPreview' 43 | }, 44 | { 45 | action: 'setVideo', 46 | name: '@videoPreviewName', 47 | disabled: '@disableVideoPreview' 48 | } 49 | ); 50 | 51 | // The File Upload Video Preview plugin extends the fileupload widget 52 | // with video preview functionality: 53 | $.widget('blueimp.fileupload', $.blueimp.fileupload, { 54 | 55 | options: { 56 | // The regular expression for the types of video files to load, 57 | // matched against the file type: 58 | loadVideoFileTypes: /^video\/.*$/ 59 | }, 60 | 61 | _videoElement: document.createElement('video'), 62 | 63 | processActions: { 64 | 65 | // Loads the video file given via data.files and data.index 66 | // as video element if the browser supports playing it. 67 | // Accepts the options fileTypes (regular expression) 68 | // and maxFileSize (integer) to limit the files to load: 69 | loadVideo: function (data, options) { 70 | if (options.disabled) { 71 | return data; 72 | } 73 | var file = data.files[data.index], 74 | url, 75 | video; 76 | if (this._videoElement.canPlayType && 77 | this._videoElement.canPlayType(file.type) && 78 | ($.type(options.maxFileSize) !== 'number' || 79 | file.size <= options.maxFileSize) && 80 | (!options.fileTypes || 81 | options.fileTypes.test(file.type))) { 82 | url = loadImage.createObjectURL(file); 83 | if (url) { 84 | video = this._videoElement.cloneNode(false); 85 | video.src = url; 86 | video.controls = true; 87 | data.video = video; 88 | return data; 89 | } 90 | } 91 | return data; 92 | }, 93 | 94 | // Sets the video element as a property of the file object: 95 | setVideo: function (data, options) { 96 | if (data.video && !options.disabled) { 97 | data.files[data.index][options.name || 'preview'] = data.video; 98 | } 99 | return data; 100 | } 101 | 102 | } 103 | 104 | }); 105 | 106 | })); 107 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/app.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Plugin Angular JS Example 1.2.1 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* jshint nomen:false */ 13 | /* global window, angular */ 14 | 15 | (function () { 16 | 'use strict'; 17 | 18 | var isOnGitHub = window.location.hostname === 'blueimp.github.io', 19 | url = isOnGitHub ? '//jquery-file-upload.appspot.com/' : 'server/php/'; 20 | 21 | angular.module('demo', [ 22 | 'blueimp.fileupload' 23 | ]) 24 | .config([ 25 | '$httpProvider', 'fileUploadProvider', 26 | function ($httpProvider, fileUploadProvider) { 27 | delete $httpProvider.defaults.headers.common['X-Requested-With']; 28 | fileUploadProvider.defaults.redirect = window.location.href.replace( 29 | /\/[^\/]*$/, 30 | '/cors/result.html?%s' 31 | ); 32 | if (isOnGitHub) { 33 | // Demo settings: 34 | angular.extend(fileUploadProvider.defaults, { 35 | // Enable image resizing, except for Android and Opera, 36 | // which actually support image resizing, but fail to 37 | // send Blob objects via XHR requests: 38 | disableImageResize: /Android(?!.*Chrome)|Opera/ 39 | .test(window.navigator.userAgent), 40 | maxFileSize: 5000000, 41 | acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i 42 | }); 43 | } 44 | } 45 | ]) 46 | 47 | .controller('DemoFileUploadController', [ 48 | '$scope', '$http', '$filter', '$window', 49 | function ($scope, $http) { 50 | $scope.options = { 51 | url: url 52 | }; 53 | if (!isOnGitHub) { 54 | $scope.loadingFiles = true; 55 | $http.get(url) 56 | .then( 57 | function (response) { 58 | $scope.loadingFiles = false; 59 | $scope.queue = response.data.files || []; 60 | }, 61 | function () { 62 | $scope.loadingFiles = false; 63 | } 64 | ); 65 | } 66 | } 67 | ]) 68 | 69 | .controller('FileDestroyController', [ 70 | '$scope', '$http', 71 | function ($scope, $http) { 72 | var file = $scope.file, 73 | state; 74 | if (file.url) { 75 | file.$state = function () { 76 | return state; 77 | }; 78 | file.$destroy = function () { 79 | state = 'pending'; 80 | return $http({ 81 | url: file.deleteUrl, 82 | method: file.deleteType 83 | }).then( 84 | function () { 85 | state = 'resolved'; 86 | $scope.clear(file); 87 | }, 88 | function () { 89 | state = 'rejected'; 90 | } 91 | ); 92 | }; 93 | } else if (!file.$cancel && !file._index) { 94 | file.$cancel = function () { 95 | $scope.clear(file); 96 | }; 97 | } 98 | } 99 | ]); 100 | 101 | }()); 102 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/css/jquery.Jcrop.css: -------------------------------------------------------------------------------- 1 | /* jquery.Jcrop.css v0.9.12 - MIT License */ 2 | /* 3 | The outer-most container in a typical Jcrop instance 4 | If you are having difficulty with formatting related to styles 5 | on a parent element, place any fixes here or in a like selector 6 | 7 | You can also style this element if you want to add a border, etc 8 | A better method for styling can be seen below with .jcrop-light 9 | (Add a class to the holder and style elements for that extended class) 10 | */ 11 | .jcrop-holder { 12 | direction: ltr; 13 | text-align: left; 14 | /* IE10 touch compatibility */ 15 | -ms-touch-action: none; 16 | } 17 | /* Selection Border */ 18 | .jcrop-vline, 19 | .jcrop-hline { 20 | background: #ffffff url("Jcrop.gif"); 21 | font-size: 0; 22 | position: absolute; 23 | } 24 | .jcrop-vline { 25 | height: 100%; 26 | width: 1px !important; 27 | } 28 | .jcrop-vline.right { 29 | right: 0; 30 | } 31 | .jcrop-hline { 32 | height: 1px !important; 33 | width: 100%; 34 | } 35 | .jcrop-hline.bottom { 36 | bottom: 0; 37 | } 38 | /* Invisible click targets */ 39 | .jcrop-tracker { 40 | height: 100%; 41 | width: 100%; 42 | /* "turn off" link highlight */ 43 | -webkit-tap-highlight-color: transparent; 44 | /* disable callout, image save panel */ 45 | -webkit-touch-callout: none; 46 | /* disable cut copy paste */ 47 | -webkit-user-select: none; 48 | } 49 | /* Selection Handles */ 50 | .jcrop-handle { 51 | background-color: #333333; 52 | border: 1px #eeeeee solid; 53 | width: 7px; 54 | height: 7px; 55 | font-size: 1px; 56 | } 57 | .jcrop-handle.ord-n { 58 | left: 50%; 59 | margin-left: -4px; 60 | margin-top: -4px; 61 | top: 0; 62 | } 63 | .jcrop-handle.ord-s { 64 | bottom: 0; 65 | left: 50%; 66 | margin-bottom: -4px; 67 | margin-left: -4px; 68 | } 69 | .jcrop-handle.ord-e { 70 | margin-right: -4px; 71 | margin-top: -4px; 72 | right: 0; 73 | top: 50%; 74 | } 75 | .jcrop-handle.ord-w { 76 | left: 0; 77 | margin-left: -4px; 78 | margin-top: -4px; 79 | top: 50%; 80 | } 81 | .jcrop-handle.ord-nw { 82 | left: 0; 83 | margin-left: -4px; 84 | margin-top: -4px; 85 | top: 0; 86 | } 87 | .jcrop-handle.ord-ne { 88 | margin-right: -4px; 89 | margin-top: -4px; 90 | right: 0; 91 | top: 0; 92 | } 93 | .jcrop-handle.ord-se { 94 | bottom: 0; 95 | margin-bottom: -4px; 96 | margin-right: -4px; 97 | right: 0; 98 | } 99 | .jcrop-handle.ord-sw { 100 | bottom: 0; 101 | left: 0; 102 | margin-bottom: -4px; 103 | margin-left: -4px; 104 | } 105 | /* Dragbars */ 106 | .jcrop-dragbar.ord-n, 107 | .jcrop-dragbar.ord-s { 108 | height: 7px; 109 | width: 100%; 110 | } 111 | .jcrop-dragbar.ord-e, 112 | .jcrop-dragbar.ord-w { 113 | height: 100%; 114 | width: 7px; 115 | } 116 | .jcrop-dragbar.ord-n { 117 | margin-top: -4px; 118 | } 119 | .jcrop-dragbar.ord-s { 120 | bottom: 0; 121 | margin-bottom: -4px; 122 | } 123 | .jcrop-dragbar.ord-e { 124 | margin-right: -4px; 125 | right: 0; 126 | } 127 | .jcrop-dragbar.ord-w { 128 | margin-left: -4px; 129 | } 130 | /* The "jcrop-light" class/extension */ 131 | .jcrop-light .jcrop-vline, 132 | .jcrop-light .jcrop-hline { 133 | background: #ffffff; 134 | filter: alpha(opacity=70) !important; 135 | opacity: .70!important; 136 | } 137 | .jcrop-light .jcrop-handle { 138 | -moz-border-radius: 3px; 139 | -webkit-border-radius: 3px; 140 | background-color: #000000; 141 | border-color: #ffffff; 142 | border-radius: 3px; 143 | } 144 | /* The "jcrop-dark" class/extension */ 145 | .jcrop-dark .jcrop-vline, 146 | .jcrop-dark .jcrop-hline { 147 | background: #000000; 148 | filter: alpha(opacity=70) !important; 149 | opacity: 0.7 !important; 150 | } 151 | .jcrop-dark .jcrop-handle { 152 | -moz-border-radius: 3px; 153 | -webkit-border-radius: 3px; 154 | background-color: #ffffff; 155 | border-color: #000000; 156 | border-radius: 3px; 157 | } 158 | /* Simple macro to turn off the antlines */ 159 | .solid-line .jcrop-vline, 160 | .solid-line .jcrop-hline { 161 | background: #ffffff; 162 | } 163 | /* Fix for twitter bootstrap et al. */ 164 | .jcrop-holder img, 165 | img.jcrop-preview { 166 | max-width: none; 167 | } 168 | -------------------------------------------------------------------------------- /Service/FileHistoryManager.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service; 12 | 13 | use Jb\Bundle\FileUploaderBundle\Entity\FileHistory; 14 | use Doctrine\Common\Persistence\ObjectManager; 15 | use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface; 16 | use Jb\Bundle\FileUploaderBundle\Service\ResolverChain; 17 | use Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration; 18 | 19 | /** 20 | * FileHistoryManager 21 | * 22 | * @author jobou 23 | */ 24 | class FileHistoryManager implements FileHistoryManagerInterface 25 | { 26 | /** 27 | * @var \Doctrine\Common\Persistence\ObjectManager 28 | */ 29 | protected $em; 30 | 31 | /** 32 | * @var TokenStorageInterface 33 | */ 34 | protected $tokenStorage; 35 | 36 | /** 37 | * @var \Jb\Bundle\FileUploaderBundle\Service\ResolverChain 38 | */ 39 | protected $resolvers; 40 | 41 | /** 42 | * @var \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration 43 | */ 44 | protected $configuration; 45 | 46 | /** 47 | * Constructor 48 | * 49 | * @param ObjectManager $em 50 | * @param TokenStorageInterface $tokenStorage 51 | * @param \Jb\Bundle\FileUploaderBundle\Service\ResolverChain $resolvers 52 | * @param \Jb\Bundle\FileUploaderBundle\Service\EndpointConfiguration $configuration 53 | */ 54 | public function __construct( 55 | ObjectManager $em, 56 | TokenStorageInterface $tokenStorage, 57 | ResolverChain $resolvers, 58 | EndpointConfiguration $configuration 59 | ) { 60 | $this->em = $em; 61 | $this->tokenStorage = $tokenStorage; 62 | $this->resolvers = $resolvers; 63 | $this->configuration = $configuration; 64 | } 65 | 66 | /** 67 | * {@inheritDoc} 68 | */ 69 | public function createAndSave($fileName, $originalName, $type, $userId = null) 70 | { 71 | $fileHistory = $this->create($fileName, $originalName, $type, $userId); 72 | 73 | $this->em->persist($fileHistory); 74 | $this->em->flush(); 75 | 76 | return $fileHistory; 77 | } 78 | 79 | /** 80 | * {@inheritDoc} 81 | */ 82 | public function create($fileName, $originalName, $type, $userId) 83 | { 84 | $fileHistory = new FileHistory(); 85 | $fileHistory->setFileName($fileName); 86 | $fileHistory->setOriginalName($originalName); 87 | $fileHistory->setType($type); 88 | if ($userId === null) { 89 | $fileHistory->setUserId($this->getAuthUserId()); 90 | } else { 91 | $fileHistory->setUserId($userId); 92 | } 93 | 94 | return $fileHistory; 95 | } 96 | 97 | /** 98 | * {@inheritDoc} 99 | */ 100 | public function findOneByFileName($fileName) 101 | { 102 | return $this->em->getRepository('JbFileUploaderBundle:FileHistory')->find($fileName); 103 | } 104 | 105 | /** 106 | * {@inheritDoc} 107 | */ 108 | public function getUrl(FileHistory $fileHistory, $resolverType = 'upload_resolver') 109 | { 110 | // Add file path to response 111 | $resolver = $this->resolvers->getResolver( 112 | $this->configuration->getValue($fileHistory->getType(), $resolverType) 113 | ); 114 | return $resolver->getUrl($fileHistory->getFilename()); 115 | } 116 | 117 | /** 118 | * Get authenticated user id 119 | * 120 | * @return int 121 | */ 122 | protected function getAuthUserId() 123 | { 124 | $token = $this->tokenStorage->getToken(); 125 | if (null === $token) { 126 | return; 127 | } 128 | 129 | $user = $token->getUser(); 130 | if (!is_object($user)) { 131 | return; 132 | } 133 | 134 | return $user->getId(); 135 | } 136 | } 137 | -------------------------------------------------------------------------------- /Resources/views/Form/fields.html.twig: -------------------------------------------------------------------------------- 1 | {# 2 | All classes starting with jb_ are part of the markup. They are used in the js code. 3 | #} 4 | 5 | {% block file_ajax_row %} 6 |
7 | 8 | {{- form_label(form) -}} 9 | {{- form_errors(form) -}} 10 | {{- form_widget(form) -}} 11 |
12 | {% endblock %} 13 | 14 | {% block file_ajax_widget %} 15 | 16 | {{ 'Import a file'|trans({}, translation_domain) }} 17 | 23 | 24 | {% if remove_link %} 25 | | 26 | 27 | 28 | {{ 'Remove'|trans({}, translation_domain) }} 29 | 30 | 31 | {% endif %} 32 | 33 | {% if download_link %} 34 | {% if file_history is not null %} 35 | {{ file_history.originalName }} 36 | {% else %} 37 | 38 | {% endif %} 39 | {% endif %} 40 | {% if loading_generated is not defined %} 41 | {% if (progress is not defined) or (progress == false)%} 42 | 45 | {% else %} 46 | 49 | {% endif %} 50 | {% endif %} 51 | {% endblock %} 52 | 53 | {% block image_ajax_widget %} 54 | {% set previewSrc = asset(default_image) %} 55 | {% if file_history is not null %} 56 | {% set previewSrc = file_history_url %} 57 | {% endif %} 58 | 59 | 64 | 65 | 68 | 69 | {% set loading_generated = true %} 70 | {{ block('file_ajax_widget') }} 71 | {% endblock %} 72 | 73 | {% block crop_image_ajax_widget %} 74 |
75 | {{ block('image_ajax_widget') }} 76 |
77 | 89 | {% endblock %} 90 | 91 | {% block jb_crop_attributes -%} 92 | {% for key, option in crop_options %} 93 | data-{{ key }}="{{ option }}" 94 | {% endfor %} 95 | data-url="{{ jb_fileuploader_crop_endpoint(endpoint) }}" 96 | {%- endblock %} 97 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/cors/jquery.postmessage-transport.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery postMessage Transport Plugin 1.1.1 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2011, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* global define, window, document */ 13 | 14 | (function (factory) { 15 | 'use strict'; 16 | if (typeof define === 'function' && define.amd) { 17 | // Register as an anonymous AMD module: 18 | define(['jquery'], factory); 19 | } else { 20 | // Browser globals: 21 | factory(window.jQuery); 22 | } 23 | }(function ($) { 24 | 'use strict'; 25 | 26 | var counter = 0, 27 | names = [ 28 | 'accepts', 29 | 'cache', 30 | 'contents', 31 | 'contentType', 32 | 'crossDomain', 33 | 'data', 34 | 'dataType', 35 | 'headers', 36 | 'ifModified', 37 | 'mimeType', 38 | 'password', 39 | 'processData', 40 | 'timeout', 41 | 'traditional', 42 | 'type', 43 | 'url', 44 | 'username' 45 | ], 46 | convert = function (p) { 47 | return p; 48 | }; 49 | 50 | $.ajaxSetup({ 51 | converters: { 52 | 'postmessage text': convert, 53 | 'postmessage json': convert, 54 | 'postmessage html': convert 55 | } 56 | }); 57 | 58 | $.ajaxTransport('postmessage', function (options) { 59 | if (options.postMessage && window.postMessage) { 60 | var iframe, 61 | loc = $('').prop('href', options.postMessage)[0], 62 | target = loc.protocol + '//' + loc.host, 63 | xhrUpload = options.xhr().upload; 64 | return { 65 | send: function (_, completeCallback) { 66 | counter += 1; 67 | var message = { 68 | id: 'postmessage-transport-' + counter 69 | }, 70 | eventName = 'message.' + message.id; 71 | iframe = $( 72 | '' 75 | ).bind('load', function () { 76 | $.each(names, function (i, name) { 77 | message[name] = options[name]; 78 | }); 79 | message.dataType = message.dataType.replace('postmessage ', ''); 80 | $(window).bind(eventName, function (e) { 81 | e = e.originalEvent; 82 | var data = e.data, 83 | ev; 84 | if (e.origin === target && data.id === message.id) { 85 | if (data.type === 'progress') { 86 | ev = document.createEvent('Event'); 87 | ev.initEvent(data.type, false, true); 88 | $.extend(ev, data); 89 | xhrUpload.dispatchEvent(ev); 90 | } else { 91 | completeCallback( 92 | data.status, 93 | data.statusText, 94 | {postmessage: data.result}, 95 | data.headers 96 | ); 97 | iframe.remove(); 98 | $(window).unbind(eventName); 99 | } 100 | } 101 | }); 102 | iframe[0].contentWindow.postMessage( 103 | message, 104 | target 105 | ); 106 | }).appendTo(document.body); 107 | }, 108 | abort: function () { 109 | if (iframe) { 110 | iframe.remove(); 111 | } 112 | } 113 | }; 114 | } 115 | }); 116 | 117 | })); 118 | -------------------------------------------------------------------------------- /Resources/public/lib/jquery-file-upload/js/jquery.fileupload-validate.js: -------------------------------------------------------------------------------- 1 | /* 2 | * jQuery File Upload Validation Plugin 1.1.2 3 | * https://github.com/blueimp/jQuery-File-Upload 4 | * 5 | * Copyright 2013, Sebastian Tschan 6 | * https://blueimp.net 7 | * 8 | * Licensed under the MIT license: 9 | * http://www.opensource.org/licenses/MIT 10 | */ 11 | 12 | /* global define, window */ 13 | 14 | (function (factory) { 15 | 'use strict'; 16 | if (typeof define === 'function' && define.amd) { 17 | // Register as an anonymous AMD module: 18 | define([ 19 | 'jquery', 20 | './jquery.fileupload-process' 21 | ], factory); 22 | } else { 23 | // Browser globals: 24 | factory( 25 | window.jQuery 26 | ); 27 | } 28 | }(function ($) { 29 | 'use strict'; 30 | 31 | // Append to the default processQueue: 32 | $.blueimp.fileupload.prototype.options.processQueue.push( 33 | { 34 | action: 'validate', 35 | // Always trigger this action, 36 | // even if the previous action was rejected: 37 | always: true, 38 | // Options taken from the global options map: 39 | acceptFileTypes: '@', 40 | maxFileSize: '@', 41 | minFileSize: '@', 42 | maxNumberOfFiles: '@', 43 | disabled: '@disableValidation' 44 | } 45 | ); 46 | 47 | // The File Upload Validation plugin extends the fileupload widget 48 | // with file validation functionality: 49 | $.widget('blueimp.fileupload', $.blueimp.fileupload, { 50 | 51 | options: { 52 | /* 53 | // The regular expression for allowed file types, matches 54 | // against either file type or file name: 55 | acceptFileTypes: /(\.|\/)(gif|jpe?g|png)$/i, 56 | // The maximum allowed file size in bytes: 57 | maxFileSize: 10000000, // 10 MB 58 | // The minimum allowed file size in bytes: 59 | minFileSize: undefined, // No minimal file size 60 | // The limit of files to be uploaded: 61 | maxNumberOfFiles: 10, 62 | */ 63 | 64 | // Function returning the current number of files, 65 | // has to be overriden for maxNumberOfFiles validation: 66 | getNumberOfFiles: $.noop, 67 | 68 | // Error and info messages: 69 | messages: { 70 | maxNumberOfFiles: 'Maximum number of files exceeded', 71 | acceptFileTypes: 'File type not allowed', 72 | maxFileSize: 'File is too large', 73 | minFileSize: 'File is too small' 74 | } 75 | }, 76 | 77 | processActions: { 78 | 79 | validate: function (data, options) { 80 | if (options.disabled) { 81 | return data; 82 | } 83 | var dfd = $.Deferred(), 84 | settings = this.options, 85 | file = data.files[data.index], 86 | fileSize; 87 | if (options.minFileSize || options.maxFileSize) { 88 | fileSize = file.size; 89 | } 90 | if ($.type(options.maxNumberOfFiles) === 'number' && 91 | (settings.getNumberOfFiles() || 0) + data.files.length > 92 | options.maxNumberOfFiles) { 93 | file.error = settings.i18n('maxNumberOfFiles'); 94 | } else if (options.acceptFileTypes && 95 | !(options.acceptFileTypes.test(file.type) || 96 | options.acceptFileTypes.test(file.name))) { 97 | file.error = settings.i18n('acceptFileTypes'); 98 | } else if (fileSize > options.maxFileSize) { 99 | file.error = settings.i18n('maxFileSize'); 100 | } else if ($.type(fileSize) === 'number' && 101 | fileSize < options.minFileSize) { 102 | file.error = settings.i18n('minFileSize'); 103 | } else { 104 | delete file.error; 105 | } 106 | if (file.error || data.files.error) { 107 | data.files.error = true; 108 | dfd.rejectWith(this, [data]); 109 | } else { 110 | dfd.resolveWith(this, [data]); 111 | } 112 | return dfd.promise(); 113 | } 114 | 115 | } 116 | 117 | }); 118 | 119 | })); 120 | -------------------------------------------------------------------------------- /Resources/doc/base/install.md: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Update composer 5 | --------------- 6 | 7 | Add the bundle to your `composer.json` : 8 | 9 | ``` json 10 | { 11 | "require": { 12 | "jbouzekri/file-uploader-bundle": "~4.0" 13 | } 14 | } 15 | ``` 16 | 17 | And run the composer update command : 18 | 19 | ``` 20 | php composer.phar update 21 | ``` 22 | 23 | Enable bundles 24 | -------------- 25 | 26 | In the file `AppKernel.php`, enable all bundles necessary for this one : 27 | 28 | ``` php 29 | public function registerBundles() 30 | { 31 | $bundles = array( 32 | ... 33 | 34 | new Oneup\UploaderBundle\OneupUploaderBundle(), 35 | new Knp\Bundle\GaufretteBundle\KnpGaufretteBundle(), 36 | new Liip\ImagineBundle\LiipImagineBundle(), 37 | new Jb\Bundle\FileUploaderBundle\JbFileUploaderBundle(), 38 | ); 39 | 40 | ... 41 | } 42 | ``` 43 | 44 | Configure Oneup 45 | --------------- 46 | 47 | Add the base configuration for oneup bundle in `app/config.yml` : 48 | 49 | ``` yml 50 | oneup_uploader: 51 | mappings: 52 | gallery: 53 | frontend: blueimp 54 | ``` 55 | 56 | Enable the oneup upload route at the start of the `app/routing.yml` : 57 | 58 | ``` yml 59 | oneup_uploader: 60 | resource: . 61 | type: uploader 62 | ``` 63 | 64 | For more information about the oneup configuration, jump to [the bundle documentation](https://github.com/1up-lab/OneupUploaderBundle/blob/master/Resources/doc/index.md) 65 | 66 | Configure Liip 67 | -------------- 68 | 69 | Add the base configuration for liip bundle in `app/config.yml` with a special filter named original which will be used to serve the original image : 70 | 71 | ``` yml 72 | liip_imagine: 73 | filter_sets: 74 | original: ~ 75 | ``` 76 | 77 | Enable the liip resize route at the start of the `app/routing.yml` : 78 | 79 | ``` yml 80 | _liip_imagine: 81 | resource: "@LiipImagineBundle/Resources/config/routing.xml" 82 | ``` 83 | 84 | Load bundle form type theme 85 | --------------------------- 86 | 87 | This bundle provides form fields. You must load their HTML layout. In `app/config.yml`, reference the bundle form template : 88 | 89 | ``` 90 | twig: 91 | form_themes: 92 | - 'JbFileUploaderBundle:Form:fields.html.twig' 93 | ``` 94 | 95 | File metadata storage 96 | --------------------- 97 | 98 | The bundle stores some metadata in a table to keep trace of original file name or original uploader. 99 | 100 | Run the doctrine schema update command to create the table. 101 | 102 | ``` 103 | php bin/console doctrine:schema:update --force 104 | ``` 105 | 106 | Install assets 107 | -------------- 108 | 109 | The bundle and its dependencies provide some assets. Do not forget to run the assets install command : 110 | 111 | ``` 112 | php bin/console assets:install web --symlink 113 | ``` 114 | 115 | Load assets 116 | ----------- 117 | 118 | In your template or in the symfony base one `app/Resources/views/base.html.twig`, load all necessary assets : 119 | 120 | ``` twig 121 | {% block stylesheets %} 122 | 123 | 124 | 125 | {% endblock %} 126 | 127 | {% block javascripts %} 128 | 129 | 130 | 131 | 132 | 133 | 134 | 140 | {% endblock %} 141 | ``` 142 | 143 | End 144 | --- 145 | 146 | You have completed the basic installation. The bundle cannot be use yet because the base configuration does not provide enough information. 147 | 148 | Jump to the [Getting Started](getting_started.md) page to view a usable configuration reference and its explanation. 149 | -------------------------------------------------------------------------------- /Resources/public/lib/jcrop/demos/tutorial3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Aspect Ratio with Preview Pane | Jcrop Demo 5 | 6 | 7 | 8 | 9 | 61 | 62 | 63 | 64 | 97 | 98 | 99 | 100 | 101 |
102 |
103 |
104 |
105 | 106 | 114 | 115 | [Jcrop Example] 116 | 117 |
118 |
119 | Preview 120 |
121 |
122 | 123 |
124 |

125 | An example implementing a preview pane. 126 | Obviously the most visual demo, the preview pane is accomplished 127 | entirely outside of Jcrop with a simple jQuery-flavored callback. 128 | This type of interface could be useful for creating a thumbnail 129 | or avatar. The onChange event handler is used to update the 130 | view in the preview pane. 131 |

132 |
133 | 134 | 140 | 141 |
142 | 143 |
144 |
145 |
146 |
147 | 148 | 149 | 150 | 151 | -------------------------------------------------------------------------------- /Service/Validator/AbstractImageValidator.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\Service\Validator; 12 | 13 | use Symfony\Component\OptionsResolver\OptionsResolver; 14 | use Jb\Bundle\FileUploaderBundle\Exception\ValidationException; 15 | 16 | /** 17 | * AbstractImageValidator 18 | * 19 | * @author jobou 20 | */ 21 | abstract class AbstractImageValidator extends AbstractValidator 22 | { 23 | /** 24 | * {@inheritdoc} 25 | */ 26 | protected function configureOptions(OptionsResolver $resolver) 27 | { 28 | $resolver->setDefined(array( 29 | 'MinWidth', 30 | 'MaxWidth', 31 | 'MinHeight', 32 | 'MaxHeight', 33 | 'MinRatio', 34 | 'MaxRatio' 35 | )); 36 | } 37 | 38 | /** 39 | * {@inheritdoc} 40 | */ 41 | protected function validate($value, array $configuration) 42 | { 43 | // No configuration. Do nothing 44 | if (!isset($configuration['MinWidth']) && !isset($configuration['MaxWidth']) 45 | && !isset($configuration['MinHeight']) && !isset($configuration['MaxHeight']) 46 | && !isset($configuration['MinRatio']) && !isset($configuration['MaxRatio']) 47 | ) { 48 | return; 49 | } 50 | 51 | // Extract width height from value 52 | $size = $this->extractWidthHeight($value); 53 | 54 | // Validate 55 | $this->isValid($size['width'], $size['height'], $configuration); 56 | } 57 | 58 | /** 59 | * Extract width and height from value 60 | * 61 | * @return array associative with key width and height 62 | */ 63 | abstract protected function extractWidthHeight($value); 64 | 65 | /** 66 | * Common image/crop validator check 67 | * 68 | * @param int $width 69 | * @param int $height 70 | * @param array $configuration 71 | * 72 | * @throws ValidationException 73 | */ 74 | protected function isValid($width, $height, array $configuration) 75 | { 76 | if (isset($configuration['MinWidth']) && $this->validateConfig('MinWidth', $configuration)) { 77 | if ($width < $configuration['MinWidth']) { 78 | throw new ValidationException('Minimum width must be '.$configuration['MinWidth'].'px'); 79 | } 80 | } 81 | 82 | if (isset($configuration['MaxWidth']) && $this->validateConfig('MaxWidth', $configuration)) { 83 | if ($width > $configuration['MaxWidth']) { 84 | throw new ValidationException('Maximum width must be '.$configuration['MaxWidth'].'px'); 85 | } 86 | } 87 | 88 | if (isset($configuration['MinHeight']) && $this->validateConfig('MinHeight', $configuration)) { 89 | if ($height < $configuration['MinHeight']) { 90 | throw new ValidationException('Minimum height must be '.$configuration['MinHeight'].'px'); 91 | } 92 | } 93 | 94 | if (isset($configuration['MaxHeight']) && $this->validateConfig('MaxHeight', $configuration)) { 95 | if ($height > $configuration['MaxHeight']) { 96 | throw new ValidationException('Minimum height must be '.$configuration['MaxHeight'].'px'); 97 | } 98 | } 99 | 100 | $ratio = round($width / $height, 2); 101 | 102 | if (isset($configuration['MinRatio']) && $this->validateConfig('MinRatio', $configuration, true)) { 103 | if ($ratio < $configuration['MinRatio']) { 104 | throw new ValidationException('Minimum ratio must be '.$configuration['MinRatio']); 105 | } 106 | } 107 | 108 | if (isset($configuration['MaxRatio']) && $this->validateConfig('MaxRatio', $configuration, true)) { 109 | if ($ratio > $configuration['MaxRatio']) { 110 | throw new ValidationException('Maximum ratio must be '.$configuration['MaxRatio']); 111 | } 112 | } 113 | } 114 | 115 | /** 116 | * Validate configuration value 117 | * 118 | * @param string $key 119 | * @param array $configuration 120 | * @param bool $isFloat 121 | * 122 | * @return bool 123 | * 124 | * @throws ValidationException 125 | */ 126 | protected function validateConfig($key, array $configuration, $isFloat = false) 127 | { 128 | if (!$isFloat && !ctype_digit((string) $configuration[$key])) { 129 | throw new ValidationException(sprintf('"%s" is not a valid %s configuration', $configuration[$key], $key)); 130 | } 131 | 132 | if ($isFloat && !is_numeric((string) $configuration[$key])) { 133 | throw new ValidationException(sprintf('"%s" is not a valid %s configuration', $configuration[$key], $key)); 134 | } 135 | 136 | return true; 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /DependencyInjection/JbFileUploaderExtension.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | /** 12 | * @namespace 13 | */ 14 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection; 15 | 16 | use Symfony\Component\DependencyInjection\ContainerBuilder; 17 | use Symfony\Component\HttpKernel\DependencyInjection\Extension; 18 | use Symfony\Component\DependencyInjection\Loader; 19 | use Symfony\Component\Config\FileLocator; 20 | use Symfony\Component\Config\Definition\Processor; 21 | use Symfony\Component\DependencyInjection\Reference; 22 | 23 | /** 24 | * Class JbFileUploaderExtension 25 | * @package Jb\Bundle\FileUploaderBundle\DependencyInjection 26 | */ 27 | class JbFileUploaderExtension extends Extension 28 | { 29 | /** 30 | * @var array 31 | */ 32 | protected $factories = null; 33 | 34 | /** 35 | * {@inheritDoc} 36 | */ 37 | public function load(array $configs, ContainerBuilder $container) 38 | { 39 | $processor = new Processor(); 40 | 41 | // first assemble the resolver factories 42 | $factoryConfig = new ResolverFactoryConfiguration(); 43 | $config = $processor->processConfiguration($factoryConfig, $configs); 44 | $factories = $this->createResolverFactories($config, $container); 45 | 46 | $config = $this->processConfiguration(new MainConfiguration($factories), $configs); 47 | $this->loadConfiguration($container, $config); 48 | 49 | $resolvers = array(); 50 | foreach ($config['resolvers'] as $name => $resolver) { 51 | $resolvers[$name] = $this->createResolver($name, $resolver, $container, $factories); 52 | } 53 | 54 | $loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config')); 55 | $loader->load('form_types.yml'); 56 | $loader->load('resolvers.yml'); 57 | $loader->load('services.yml'); 58 | $loader->load('validators.yml'); 59 | 60 | $resolverChain = $container->findDefinition('jb_fileuploader.resolver_chain'); 61 | 62 | foreach ($resolvers as $name => $resolver) { 63 | $resolverChain->addMethodCall('addResolver', array(new Reference($resolver), $name)); 64 | } 65 | } 66 | 67 | /** 68 | * Load configuration 69 | * 70 | * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container 71 | * @param array $config 72 | */ 73 | protected function loadConfiguration(ContainerBuilder $container, array $config) 74 | { 75 | $container->setParameter('jb_fileuploader.endpoints', $config); 76 | $container->setParameter('jb_fileuploader.crop_route', $config['crop_route']); 77 | } 78 | 79 | /** 80 | * Creates the resolver factories 81 | * 82 | * @param array $configs 83 | * @param ContainerBuilder $container 84 | * 85 | * @return null|array 86 | */ 87 | protected function createResolverFactories(array $configs, ContainerBuilder $container) 88 | { 89 | if (null !== $this->factories) { 90 | return $this->factories; 91 | } 92 | 93 | // load bundled resolver factories 94 | $tempContainer = new ContainerBuilder(); 95 | $parameterBag = $container->getParameterBag(); 96 | $loader = new Loader\YamlFileLoader($tempContainer, new FileLocator(__DIR__.'/../Resources/config')); 97 | $loader->load('resolver_factories.yml'); 98 | 99 | // load user-created resolver factories 100 | foreach ($configs['resolver_factories'] as $factory) { 101 | $loader->load($parameterBag->resolveValue($factory)); 102 | } 103 | 104 | $services = $tempContainer->findTaggedServiceIds('jb_fileuploader.resolver.factory'); 105 | 106 | $factories = array(); 107 | foreach (array_keys($services) as $id) { 108 | $factory = $tempContainer->get($id); 109 | $factories[str_replace('-', '_', $factory->getKey())] = $factory; 110 | } 111 | 112 | return $this->factories = $factories; 113 | } 114 | 115 | /** 116 | * Create resolver 117 | * 118 | * @param string $name 119 | * @param array $config 120 | * @param ContainerBuilder $container 121 | * @param array $factories 122 | * 123 | * @return string 124 | * 125 | * @throws \LogicException 126 | */ 127 | protected function createResolver($name, array $config, ContainerBuilder $container, array $factories) 128 | { 129 | foreach ($config as $key => $resolver) { 130 | if (array_key_exists($key, $factories)) { 131 | $id = sprintf('jb_fileuploader.%s_resolver', $name); 132 | $factories[$key]->create($container, $id, $resolver); 133 | 134 | return $id; 135 | } 136 | } 137 | 138 | throw new \LogicException(sprintf('The resolver \'%s\' is not configured.', $name)); 139 | } 140 | } 141 | -------------------------------------------------------------------------------- /Resources/doc/base/reference.md: -------------------------------------------------------------------------------- 1 | Reference 2 | ========= 3 | 4 | This page will not go over the configuration details for each dependency. These bundles already have complete documentation : 5 | * [KnpGaufretteBundle](https://github.com/KnpLabs/KnpGaufretteBundle) 6 | * [OneupUploaderBundle](https://github.com/1up-lab/OneupUploaderBundle/blob/88ae15b1a4e51f0df78394697e7f01bb36e6789d/Resources/doc/index.md) 7 | * [LiipImagineBundle](https://github.com/liip/LiipImagineBundle) 8 | 9 | Options Detail 10 | -------------- 11 | 12 | ``` yml 13 | jb_fileuploader: 14 | resolvers: 15 | resolver_name: 16 | resolver_type: 17 | ... # resolver configuration for the type 18 | upload_resolver: 19 | croped_resolver: 20 | crop_route: jb_image_crop_endpoint 21 | croped_fs: 22 | endpoints: 23 | oneup_endpoint_name: 24 | upload_resolver: 25 | croped_resolver: 26 | croped_fs: 27 | upload_validators: 28 | validator_type_1: 29 | # validator configuration for the selected type 30 | # add other validators 31 | crop_validators: 32 | validator_type_1: 33 | # validator configuration for the selected type 34 | # add other validators 35 | ``` 36 | 37 | endpoints 38 | --------- 39 | 40 | `endpoints` key allows to configures each oneup endpoint. 41 | 42 | The `oneup_endpoint_name` must match the name of an endpoint in the oneup bundle configuration. 43 | 44 | If no configuration has been provided for an endpoint, you must define the global resolver and fs whose will be used as fallback. 45 | 46 | resolvers 47 | --------- 48 | 49 | `resolvers` key is a factory. You can define your own resolvers by specifying a name, a type, and a configuration according to the type. 50 | 51 | ``` yml 52 | jb_file_uploader: 53 | resolvers: 54 | upload: 55 | assets: 56 | directory: uploads 57 | ``` 58 | 59 | This example configures a resolver named `upload` of the type `assets`. The type assets demands that you configure a directory key. Here we set `uploads`. 60 | This resolver will be used to generates assets urls from a directory uploads placed in the web folder. 61 | 62 | For more information about the different types of resolver, [read the resolver documentation](resolvers.md) 63 | 64 | upload_resolver 65 | --------------- 66 | 67 | `upload_resolver` key configures the resolver to be used when displaying the preview image or the not yet croped image after upload. 68 | 69 | It can be configured per endpoint : 70 | 71 | ``` yml 72 | jb_fileuploader: 73 | endpoints: 74 | oneup_endpoint_name: 75 | upload_resolver: my_upload_resolver 76 | ``` 77 | 78 | Or you can set a global one : 79 | 80 | ``` yml 81 | jb_fileuploader: 82 | upload_resolver: my_upload_resolver 83 | ``` 84 | 85 | Note that if an endpoint does not have an upload_resolver, it will try to load the global one. 86 | 87 | croped_resolver 88 | --------------- 89 | 90 | `croped_resolver` key configures the resolver to be used for displaying croped image. It allows to store the croped image in a different folder 91 | or storage from the original. 92 | 93 | It can be configured per endpoint : 94 | 95 | ``` yml 96 | jb_fileuploader: 97 | endpoints: 98 | oneup_endpoint_name: 99 | croped_resolver: my_croped_resolver 100 | ``` 101 | 102 | Or you can set a global one : 103 | 104 | ``` yml 105 | jb_fileuploader: 106 | croped_resolver: my_croped_resolver 107 | ``` 108 | 109 | Note that if an endpoint does not have a croped_resolver, it will try to load the global one. 110 | 111 | crop_route 112 | ---------- 113 | 114 | `croped_resolver` key configures the route used to crop images 115 | 116 | ``` yml 117 | jb_fileuploader: 118 | crop_route: jb_image_crop_endpoint 119 | ``` 120 | 121 | croped_fs 122 | --------- 123 | 124 | `croped_fs` key configures the gaufrette filesystem used to store the croped image. It is presently used by the croped route when croping an original image. 125 | 126 | It can be configured per endpoint : 127 | 128 | ``` yml 129 | jb_fileuploader: 130 | endpoints: 131 | oneup_endpoint_name: 132 | croped_fs: gaufrette_croped_fs 133 | ``` 134 | 135 | Or you can set a global one : 136 | 137 | ``` yml 138 | jb_fileuploader: 139 | croped_fs: gaufrette_croped_fs 140 | ``` 141 | 142 | Note that if an endpoint does not have a croped_fs, it will try to load the global one. 143 | 144 | upload_validators 145 | ----------------- 146 | 147 | `upload_validators` key configures validation when uploading a file. It can be configured per endpoint. 148 | 149 | For more information about the different types of validators, [read the validator documentation](validation.md) 150 | 151 | *Note : some validation like the file mime type or size must be done with oneup bundle configuration* 152 | 153 | crop_validators 154 | --------------- 155 | 156 | `crop_validators` key configures validation when uploading the croped configuration just before croping the file server side. It can be configured per endpoint. 157 | 158 | For more information about the different types of validators, [read the validator documentation](validation.md) 159 | -------------------------------------------------------------------------------- /DependencyInjection/MainConfiguration.php: -------------------------------------------------------------------------------- 1 | 7 | * @license https://github.com/jbouzekri/FileUploaderBundle/blob/master/LICENSE 8 | * @link https://github.com/jbouzekri/FileUploaderBundle 9 | */ 10 | 11 | namespace Jb\Bundle\FileUploaderBundle\DependencyInjection; 12 | 13 | use Symfony\Component\Config\Definition\Builder\TreeBuilder; 14 | use Symfony\Component\Config\Definition\ConfigurationInterface; 15 | use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition; 16 | 17 | /** 18 | * JbFileUploaderBundle configuration structure. 19 | * 20 | * @author Jonathan Bouzekri 21 | */ 22 | class MainConfiguration implements ConfigurationInterface 23 | { 24 | /** 25 | * @var array 26 | */ 27 | protected $factories; 28 | 29 | /** 30 | * Constructor 31 | * 32 | * @param array $factories 33 | */ 34 | public function __construct(array $factories) 35 | { 36 | $this->factories = $factories; 37 | } 38 | 39 | /** 40 | * Generates the configuration tree builder. 41 | * 42 | * @return TreeBuilder The tree builder 43 | */ 44 | public function getConfigTreeBuilder() 45 | { 46 | $treeBuilder = new TreeBuilder(); 47 | $rootNode = $treeBuilder->root('jb_fileuploader'); 48 | 49 | $this->addResolversSection($rootNode, $this->factories); 50 | 51 | $rootNode 52 | ->children() 53 | ->scalarNode('upload_resolver')->end() 54 | ->scalarNode('croped_resolver')->end() 55 | ->scalarNode('crop_route')->defaultValue('jb_image_crop_endpoint')->end() 56 | ->scalarNode('croped_fs')->end() 57 | ->arrayNode('endpoints') 58 | ->defaultValue(array()) 59 | ->prototype('array') 60 | ->children() 61 | ->scalarNode('upload_resolver')->end() 62 | ->scalarNode('croped_resolver')->end() 63 | ->scalarNode('croped_fs')->end() 64 | ->append($this->getValidators('upload_validators')) 65 | ->append($this->getValidators('crop_validators')) 66 | ->end() 67 | ->end() 68 | ->end() 69 | ->end(); 70 | 71 | return $treeBuilder; 72 | } 73 | 74 | /** 75 | * Add resolvers section 76 | * 77 | * @param \Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition $node 78 | * @param array $factories 79 | */ 80 | protected function addResolversSection(ArrayNodeDefinition $node, array $factories) 81 | { 82 | $resolverNodeBuilder = $node 83 | ->fixXmlConfig('resolver') 84 | ->children() 85 | ->arrayNode('resolvers') 86 | ->useAttributeAsKey('name') 87 | ->prototype('array') 88 | ->performNoDeepMerging() 89 | ->children() 90 | ; 91 | 92 | foreach ($factories as $name => $factory) { 93 | $factoryNode = $resolverNodeBuilder->arrayNode($name)->canBeUnset(); 94 | 95 | $factory->addConfiguration($factoryNode); 96 | } 97 | } 98 | 99 | /** 100 | * Add a custom validator key to configuration 101 | * 102 | * @param $key 103 | * 104 | * @param string $key 105 | * 106 | * @return TreeBuilder 107 | */ 108 | protected function getValidators($key) 109 | { 110 | $treeBuilder = new TreeBuilder(); 111 | $rootNode = $treeBuilder->root($key); 112 | 113 | $rootNode 114 | ->defaultValue(array()) 115 | ->prototype('variable') 116 | ->end() 117 | ->beforeNormalization() 118 | ->always() 119 | ->then(function ($values) { 120 | // Normalize null as array 121 | foreach ($values as $key => $value) { 122 | if ($value === null) { 123 | $values[$key] = array(); 124 | } 125 | } 126 | return $values; 127 | }) 128 | ->end(); 129 | 130 | $this->addValidatorValidation($rootNode); 131 | 132 | return $rootNode; 133 | } 134 | 135 | /** 136 | * Add validation to a validator key 137 | * 138 | * @param ArrayNodeDefinition $node 139 | */ 140 | protected function addValidatorValidation(ArrayNodeDefinition $node) 141 | { 142 | $node->validate() 143 | ->ifTrue(function ($value) { 144 | if (!is_array($value)) { 145 | return true; 146 | } 147 | 148 | // All key must be string. Used as alias for the validator service 149 | if (count(array_filter(array_keys($value), 'is_string')) != count($value)) { 150 | return true; 151 | } 152 | 153 | // All value must be array. Used as configuration for validator 154 | if (count(array_filter(array_values($value), 'is_array')) != count($value)) { 155 | return true; 156 | } 157 | 158 | return false; 159 | }) 160 | ->thenInvalid('Invalid validators configuration') 161 | ->end(); 162 | } 163 | } 164 | --------------------------------------------------------------------------------