{"id":444,"date":"2014-06-08T13:07:56","date_gmt":"2014-06-08T20:07:56","guid":{"rendered":"http:\/\/www.keganv.com\/?p=444"},"modified":"2017-05-14T14:54:03","modified_gmt":"2017-05-14T21:54:03","slug":"upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property","status":"publish","type":"post","link":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/","title":{"rendered":"Upload Multiple Images In Symfony2 With Validation On A Single Entity Property"},"content":{"rendered":"<p>I wanted a way to upload files\/images that would all be tied to just a single property on the entity object. The <code>@var file<\/code> field type declared for properties in the entity can only validate a single uploaded file, as the <code>Symfony\\Component\\HttpFoundation\\File\\UploadedFile<\/code> class expects a string. I wanted to handle multiple files uploaded, (array of files).<\/p>\n<p>Like everything, there is more than one way to do something, and below is the solution I implemented. This tutorial doesn&#8217;t cover how to make the multiple file uploader pretty, this just covers backend functionality.<br \/>\n<!--more--><\/p>\n<h3>The Entity File<\/h3>\n<p>Let&#8217;s first take a look at a very simplified entity, only showing the property &#8220;images&#8221; which I wanted to store in the database as an array of image paths to my web\/media folder. I made my property nullable so it can be optional on the form.<\/p>\n<p><code><\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nnamespace YourFolder\\YourBundle\\Entity;\r\n\r\nuse Doctrine\\ORM\\Mapping as ORM;\r\n\r\n\/**\r\n * EntityName\r\n * @ORM\\Table(name=&quot;entityname&quot;)\r\n *\/\r\nclass Review\r\n{\r\n    \/**\r\n     * @var array\r\n     *\r\n     * @ORM\\Column(name=&quot;images&quot;, type=&quot;array&quot;, nullable=true)\r\n     *\/\r\n    private $images;\r\n}\r\n<\/pre>\n<p><\/code><\/p>\n<h3>The Form Type File<\/h3>\n<p>Now let&#8217;s take a look at the form type which actually builds the form for the output. We&#8217;re adding two attributes to the images input; accept images only, and multiple. Again, this is a very simplified example, all your other properties would need to be added to the builder as well. <\/p>\n<p><code><\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nnamespace YourFolder\\YourBundle\\Form;\r\n\r\nuse Symfony\\Component\\Form\\AbstractType;\r\n\/\/ more use statements ...\r\n\r\nclass FormType extends AbstractType\r\n{\r\n    \/**\r\n     * @param FormBuilderInterface $builder\r\n     * @param array $options\r\n     *\/\r\n    public function buildForm(FormBuilderInterface $builder, array $options)\r\n    {\r\n        $builder\r\n            -&gt;add('images', 'file', array(\r\n                'attr' =&gt; array(\r\n                    'accept' =&gt; 'image\/*',\r\n                    'multiple' =&gt; 'multiple'\r\n                )\r\n            ))\r\n        ;\r\n    }\r\n\r\n    \/\/ other functions here ...\r\n}\r\n<\/pre>\n<p><\/code><\/p>\n<h3>The Controller<\/h3>\n<p>This controller action isn&#8217;t exactly skinny, some of the checks could be moved out into other private functions, however for the ease of this blog post, let&#8217;s proceed to party. Basically, below we check if the form POST has any files set (images property). If it does, then I fire off the validation and uploading to a service. We&#8217;ll look at that next.<\/p>\n<p><code><\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\n\/\/ ... other actions and annotations\r\npublic function createAction(Request $request)\r\n{\r\n    $entity = new Review();\r\n    $form = $this-&gt;createCreateForm($entity);\r\n    $form-&gt;handleRequest($request);\r\n    \r\n    if ($form-&gt;isValid()) {\r\n       \/\/ Handle the uploaded images          \r\n       $files = $form-&gt;getData()-&gt;getImages();\r\n    }\r\n    \r\n    \/\/ If there are images uploaded           \r\n    if($files&#x5B;0] != '') {\r\n        $constraints = array('maxSize'=&gt;'1M', 'mimeTypes' =&gt; array('image\/*'));\r\n        $uploadFiles = $this-&gt;get('your_namespace.fileuploader')-&gt;create($files, $constraints);\r\n    }\r\n\r\n    if($uploadFiles-&gt;upload()) {\r\n        $entity-&gt;setImages($uploadFiles-&gt;getFilePaths());\r\n    } else {\r\n        \/\/ If there are file constraint validation issues\r\n        foreach($uploadFiles-&gt;getErrors() as $error) {\r\n            $this-&gt;get('session')-&gt;getFlashBag()-&gt;add('error', $error);\r\n        }\r\n        return array(\r\n            'entity' =&gt; $entity,\r\n            'form'   =&gt; $form-&gt;createView(),\r\n        );\r\n    }\r\n    \/\/ ... persist, flush, success message, redirect, other functionality\r\n}\r\n<\/pre>\n<p><\/code><\/p>\n<h3>Services Configuration<\/h3>\n<p>I like using YAML, and basically always choose to use it over XML when possible. The services.yml file is pretty straight forward. Set up your service with your namespace and then inject the entity manager, <a href=\"http:\/\/symfony.com\/doc\/current\/book\/service_container.html#injecting-the-request\" target=\"_blank\">the request stack<\/a>, the validator, and the kernel. You&#8217;ll see why in the next section!<\/p>\n<p><code><\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nservices:\r\n    your_namespace.fileuploader:\r\n        class: Namespace\\YourBundle\\Services\\FileUploader\r\n        arguments: &#x5B; @doctrine.orm.entity_manager, @request_stack, @validator, @kernel ]\r\n\r\n    \/\/ ... other services\r\n<\/pre>\n<p><\/code><\/p>\n<h3>Creating The Service (FileUploader) Class<\/h3>\n<p>Finally, let&#8217;s look at the actual FileUploader class which I set up as a service. Now we can call this service from anywhere in our app, keeping the code DRY. You can see in the construct where I injected all the services I needed from the services.yml file above. <\/p>\n<p>Summing up this file, it creates an object with the files and their constraints, loops through each file to test them against the constraints and returns true (uploads and moves file) or returns false (prints out the list of constraint violations). <\/p>\n<p><code><\/p>\n<pre class=\"brush: php; title: ; notranslate\" title=\"\">\r\nnamespace YourFolder\\YourBundle\\Services;\r\n\r\nuse Symfony\\Component\\HttpFoundation\\RequestStack;\r\nuse Symfony\\Component\\HttpFoundation\\File\\Exception\\FileException;\r\nuse Symfony\\Component\\Validator\\Constraints\\File;\r\nuse Doctrine\\ORM\\EntityManager;\r\nuse Symfony\\Component\\Validator\\ValidatorInterface;\r\nuse Symfony\\Component\\HttpKernel\\Kernel;\r\n\r\nclass FileUploader\r\n{\r\n    \/\/ Entity Manager\r\n    private $em;\r\n\r\n    \/\/ The request\r\n    private $request;\r\n    \r\n    \/\/ Validator Service\r\n    private $validator;\r\n    \r\n    \/\/ Kernel\r\n    private $kernel;\r\n\r\n    \/\/ The files from the upload\r\n    private $files;\r\n\r\n    \/\/ Directory for the uploads\r\n    private $directory;\r\n\r\n    \/\/ File pathes array\r\n    private $paths;\r\n\r\n    \/\/ Constraint array\r\n    private $constraints;\r\n\r\n    \/\/ Array of file constraint object\r\n    private $fileConstraints;\r\n\r\n    \/\/ Error array\r\n    private $errors;\r\n\r\n    public function __construct(EntityManager $em, RequestStack $requestStack, Validator $validator, Kernel $kernel)\r\n    {\r\n        $this-&gt;em = $em;\r\n        $this-&gt;request = $requestStack-&gt;getCurrentRequest();\r\n        $this-&gt;validator = $validator;\r\n        $this-&gt;kernel = $kernel;\r\n        $this-&gt;directory = 'web\/uploads';\r\n        $this-&gt;paths = array();\r\n        $this-&gt;errors = array();\r\n    }\r\n    \r\n    \/\/ Create FileUploader object with constraints\r\n    public function create($files, $constraints = NULL)\r\n    {\r\n        $this-&gt;files = $files;\r\n        $this-&gt;constraints = $constraints;\r\n        if($this-&gt;constraints)\r\n        {\r\n            $this-&gt;fileConstraints = $this-&gt;createFileConstraint($this-&gt;constraints);\r\n        }\r\n        return $this;\r\n    }\r\n\r\n    \/\/ Upload the file \/ handle errors\r\n    \/\/ Returns boolean\r\n    public function upload()\r\n    {   \r\n        if(!$this-&gt;files) {\r\n            return true;\r\n        }\r\n\r\n        foreach($this-&gt;files as $file) {\r\n            if(isset($file)) {\r\n                if($this-&gt;fileConstraints) {\r\n                    $this-&gt;errors&#x5B;] = $this-&gt;validator-&gt;validateValue($file, $this-&gt;fileConstraints);\r\n                }\r\n\r\n                $extension = $file-&gt;guessExtension();\r\n                if(!$extension) {\r\n                    $extension = 'bin';\r\n                }\r\n                $fileName = $this-&gt;createName().'.'.$extension;\r\n                $this-&gt;paths&#x5B;] = $fileName;\r\n\r\n                if(!$this-&gt;hasErrors()) {   \r\n                    $file-&gt;move($this-&gt;getUploadRootDir(), $fileName);   \r\n                } else {\r\n                    foreach($this-&gt;paths as $path) {\r\n                        $fullpath = $this-&gt;kernel-&gt;getRootDir() . '\/..\/' . $path;\r\n\r\n                        if(file_exists($fullpath)) {\r\n                            unlink($fullpath);\r\n                        }\r\n                    }\r\n\r\n                    $this-&gt;paths = null;\r\n                    return false;\r\n                }\r\n            }           \r\n        }\r\n        return true;\r\n    }\r\n\r\n    \/\/ Get array of relative file paths\r\n    public function getFilePaths()\r\n    {\r\n        return $this-&gt;paths;\r\n    }\r\n\r\n    \/\/ Get array of error messages\r\n    public function getErrors()\r\n    {   \r\n        $errors = array();\r\n\r\n        foreach($this-&gt;errors as $errorListItem) {\r\n            foreach($errorListItem as $error) {\r\n                $errors&#x5B;] = $error-&gt;getMessage();\r\n            }\r\n        }\r\n        return $errors;\r\n    }\r\n\r\n    \/\/ Get full file path\r\n    private function getUploadRootDir()\r\n    {\r\n        return $this-&gt;kernel-&gt;getRootDir() . '\/..\/'. $this-&gt;directory;\r\n    }\r\n\r\n    \/\/ Generate random string for file name\r\n    private function createName()\r\n    {\r\n        \/\/ Entity manager\r\n        $em = $this-&gt;em;\r\n        \r\n        \/\/ Get Form request\r\n        $form_data = $this-&gt;request-&gt;request-&gt;get('kmv_ampbundle_review');\r\n        \r\n        \/\/ Get brand name\r\n        $brand_name = $em-&gt;getRepository('KmvAmpBundle:Brand')-&gt;find($form_data&#x5B;'brand'])-&gt;getName();\r\n        $brand_name = str_replace(' ', '-', $brand_name);\r\n        \r\n        \/\/ Get model name\r\n        $model_name = $em-&gt;getRepository('KmvAmpBundle:Model')-&gt;find($form_data&#x5B;'model'])-&gt;getName();\r\n        $model_name = str_replace(' ', '-', $model_name);\r\n        \r\n        \/\/ Create name\r\n        $image_name = strtolower($brand_name.'-'.$model_name).'-'.mt_rand(0,9999);\r\n        return $image_name;\r\n    }\r\n\r\n    \/\/ Create array of file constraint objects\r\n    private function createFileConstraint($constraints)\r\n    {\r\n        $fileConstraints = array();\r\n        foreach($constraints as $constraintKey =&gt; $constraint) {\r\n            $fileConstraint = new File();\r\n            $fileConstraint-&gt;$constraintKey = $constraint;\r\n            if($constraintKey == &quot;mimeTypes&quot;) {\r\n                $fileConstraint-&gt;mimeTypesMessage = &quot;The file type you tried to upload is invalid.&quot;;\r\n            }\r\n            $fileConstraints&#x5B;] = $fileConstraint;\r\n        }\r\n\r\n        return $fileConstraints;\r\n    }\r\n\r\n    \/\/ Check if there are constraint violations\r\n    private function hasErrors()\r\n    {   \r\n        if(count($this-&gt;errors) &gt; 0) {\r\n            foreach($this-&gt;errors as $error) {\r\n                if($error-&gt;__toString()) {\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n}\r\n<\/pre>\n<p><\/code><\/p>\n<h3>The Twig View File<\/h3>\n<p>Below is how I output my html with the entity properties. The trick here is to concatenate the extra <code>[]<\/code> onto the form field name, or so that you can have an array of uploaded files. The rest is pretty standard. You can also see how I chose to output my messages related to the file constraints themselves.<\/p>\n<p><code><\/p>\n<pre class=\"brush: xml; title: ; notranslate\" title=\"\">\r\n&lt;fieldset&gt;\r\n    &lt;legend\\&gt;Media&lt;\/legend&gt;\r\n    &lt;div class=&quot;form_field&quot;&gt;\r\n        {{ form_label(form.images) }}\r\n        {{ form_widget(form.images, { 'full_name': 'kmv_ampbundle_review&#x5B;images]' ~ '&#x5B;]' }) }}\r\n        {% if errorMessages is defined %}\r\n            &lt;ul class=&quot;error&quot;&gt;\r\n            {% for errorMessage in errorMessages %}\r\n                &lt;li&gt;{{ errorMessage }}&lt;\/li&gt;\r\n            {% endfor %}\r\n        &lt;\/ul&gt;\r\n        {% endif %}\r\n    &lt;\/div&gt;\r\n    \/\/ Other fields ...\r\n&lt;\/fieldset&gt;\r\n<\/pre>\n<p><\/code><\/p>\n<p>Whew! That&#8217;s it, I hope this helps you or gives you some ideas on how to set up multiple file uploading in your Symfony2 project!<\/p>\n","protected":false},"excerpt":{"rendered":"I wanted a way to upload files\/images that would all be tied to just a single property on the entity object. The @var file field type declared for properties in the entity can only validate a single uploaded file, as the Symfony\\Component\\HttpFoundation\\File\\UploadedFile class expects a string. I wanted to handle multiple files uploaded, (array of &#8230; <br\/> <a class=\"view-article btn btn-primary flip pull-left\" href=\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\"><span>View Article<\/span><\/a>","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10],"tags":[],"class_list":["post-444","post","type-post","status-publish","format-standard","hentry","category-coding-programming"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.1 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Upload Multiple Images In Symfony2 On Single Property<\/title>\n<meta name=\"description\" content=\"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Upload Multiple Images In Symfony2 On Single Property\" \/>\n<meta property=\"og:description\" content=\"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\" \/>\n<meta property=\"og:site_name\" content=\"KeganV\" \/>\n<meta property=\"article:published_time\" content=\"2014-06-08T20:07:56+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2017-05-14T21:54:03+00:00\" \/>\n<meta name=\"author\" content=\"Kegan V.\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Kegan V.\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\"},\"author\":{\"name\":\"Kegan V.\",\"@id\":\"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276\"},\"headline\":\"Upload Multiple Images In Symfony2 With Validation On A Single Entity Property\",\"datePublished\":\"2014-06-08T20:07:56+00:00\",\"dateModified\":\"2017-05-14T21:54:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\"},\"wordCount\":506,\"commentCount\":15,\"publisher\":{\"@id\":\"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276\"},\"articleSection\":[\"Coding &amp; Programming\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\",\"url\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\",\"name\":\"Upload Multiple Images In Symfony2 On Single Property\",\"isPartOf\":{\"@id\":\"https:\/\/www.keganv.com\/#website\"},\"datePublished\":\"2014-06-08T20:07:56+00:00\",\"dateModified\":\"2017-05-14T21:54:03+00:00\",\"description\":\"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.\",\"breadcrumb\":{\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.keganv.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Upload Multiple Images In Symfony2 With Validation On A Single Entity Property\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.keganv.com\/#website\",\"url\":\"https:\/\/www.keganv.com\/\",\"name\":\"KeganV\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.keganv.com\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276\",\"name\":\"Kegan V.\",\"logo\":{\"@id\":\"https:\/\/www.keganv.com\/#\/schema\/person\/image\/\"},\"sameAs\":[\"http:\/\/www.keganv.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Upload Multiple Images In Symfony2 On Single Property","description":"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/","og_locale":"en_US","og_type":"article","og_title":"Upload Multiple Images In Symfony2 On Single Property","og_description":"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.","og_url":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/","og_site_name":"KeganV","article_published_time":"2014-06-08T20:07:56+00:00","article_modified_time":"2017-05-14T21:54:03+00:00","author":"Kegan V.","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Kegan V.","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#article","isPartOf":{"@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/"},"author":{"name":"Kegan V.","@id":"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276"},"headline":"Upload Multiple Images In Symfony2 With Validation On A Single Entity Property","datePublished":"2014-06-08T20:07:56+00:00","dateModified":"2017-05-14T21:54:03+00:00","mainEntityOfPage":{"@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/"},"wordCount":506,"commentCount":15,"publisher":{"@id":"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276"},"articleSection":["Coding &amp; Programming"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/","url":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/","name":"Upload Multiple Images In Symfony2 On Single Property","isPartOf":{"@id":"https:\/\/www.keganv.com\/#website"},"datePublished":"2014-06-08T20:07:56+00:00","dateModified":"2017-05-14T21:54:03+00:00","description":"Learn how to upload multiple images or files tied to a single property while still having validation constraints on the server level for the uploaded files.","breadcrumb":{"@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/www.keganv.com\/upload-multiple-images-in-symfony2-with-validation-on-a-single-entity-property\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.keganv.com\/"},{"@type":"ListItem","position":2,"name":"Upload Multiple Images In Symfony2 With Validation On A Single Entity Property"}]},{"@type":"WebSite","@id":"https:\/\/www.keganv.com\/#website","url":"https:\/\/www.keganv.com\/","name":"KeganV","description":"","publisher":{"@id":"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.keganv.com\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"en-US"},{"@type":["Person","Organization"],"@id":"https:\/\/www.keganv.com\/#\/schema\/person\/412e7755f594475dc403b6d774b80276","name":"Kegan V.","logo":{"@id":"https:\/\/www.keganv.com\/#\/schema\/person\/image\/"},"sameAs":["http:\/\/www.keganv.com"]}]}},"_links":{"self":[{"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/posts\/444"}],"collection":[{"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/comments?post=444"}],"version-history":[{"count":62,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/posts\/444\/revisions"}],"predecessor-version":[{"id":985,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/posts\/444\/revisions\/985"}],"wp:attachment":[{"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/media?parent=444"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/categories?post=444"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.keganv.com\/api\/wp\/v2\/tags?post=444"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}