Skip to content

Commit d7df62f

Browse files
authored
Merge pull request #69 from forkcms/symfony-form-file-and-image
Symfony form file and image
2 parents 6d04f33 + 6a93b2c commit d7df62f

File tree

2 files changed

+447
-0
lines changed

2 files changed

+447
-0
lines changed
+221
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
# Uploading files
2+
3+
You can find a base value object that you can use to upload files.
4+
5+
It can be used in combination with the form type `Backend\Form\Type\FileType`
6+
7+
While most of the things you need to do are already written for you, you will still need to add some configuration for each implementation.
8+
9+
## Basic implementation
10+
11+
### Create a value object
12+
13+
Not all files are created equal. The file you want to upload has a specific meaning in your application and therefor your implementation should reflect that.
14+
15+
* Create a new class
16+
* Extend the class `Common\Doctrine\ValueObject\AbstractFile`
17+
* Implement the `getUploadDir()` method (for documentation about this see the phpdoc)
18+
19+
After implementing this your value object will be transformed into the web path of your file when it is sent to the template.
20+
21+
This way you can just use it like `myEntity.myFile`
22+
23+
#### Example
24+
25+
```php
26+
<?php
27+
28+
namespace Backend\Modules\Users\ValueObject;
29+
30+
use Common\Doctrine\ValueObject\AbstractFile;
31+
32+
final class CV extends AbstractFile
33+
{
34+
/**
35+
* @return string
36+
*/
37+
protected function getUploadDir()
38+
{
39+
return 'user/cv';
40+
}
41+
}
42+
```
43+
44+
### Create a DBALType
45+
46+
In order to save the file to the database using doctrine we need a DBALType
47+
48+
* Create a new class
49+
* Extend the class `Common\Doctrine\Type\AbstractFileType`
50+
* Implement the methods `createFromString()` and `getName()`
51+
* Register your DBALType (doctrine.dbal.types)
52+
53+
#### Example
54+
55+
```php
56+
<?php
57+
58+
namespace Backend\Modules\Users\DBALType;
59+
60+
use Common\Doctrine\Type\AbstractFileType;
61+
use Backend\Modules\Users\ValueObject\CV;
62+
63+
final class CVType extends AbstractFileType
64+
{
65+
/**
66+
* @param string $fileName
67+
*
68+
* @return CV
69+
*/
70+
protected function createFromString($fileName)
71+
{
72+
return CV::fromString($fileName);
73+
}
74+
75+
/**
76+
* @return string
77+
*/
78+
public function getName()
79+
{
80+
return 'cv';
81+
}
82+
}
83+
```
84+
85+
**app/config/config.yml** or the config file you load via DependencyInjection in the prepend method
86+
87+
```yaml
88+
doctrine:
89+
dbal:
90+
types:
91+
user_cv_type: Backend\Modules\Users\DBALType\CVType
92+
```
93+
94+
### Update your entity
95+
96+
Now that we have our DBAL type and our value object we can add it to our entity
97+
98+
* Add a property to your class for your value object
99+
* Set the column type to the name your DBAL type is registered on
100+
* Add the `@ORM\HasLifecycleCallbacks` annotation to the entity
101+
* Add the lifecycle callbacks to your entity as described in the phpdoc of the `Common\Doctrine\ValueObject\AbstractFile` class
102+
103+
#### Example
104+
105+
```php
106+
<?php
107+
108+
namespace Backend\Modules\Users\Entity;
109+
110+
use Doctrine\ORM\Mapping as ORM;
111+
use Backend\Modules\Users\ValueObject\CV;
112+
113+
/**
114+
* User entity
115+
*
116+
* @ORM\Table()
117+
* @ORM\Entity
118+
* @ORM\HasLifecycleCallbacks()
119+
*/
120+
class User
121+
{
122+
/**
123+
* @var CV
124+
*
125+
* @ORM\Column(type="user_cv_type")
126+
*/
127+
protected $cv;
128+
129+
/**
130+
* @return CV
131+
*/
132+
public function getCv()
133+
{
134+
return $this->cv;
135+
}
136+
137+
/**
138+
* @param CV $cv
139+
* @return self
140+
*/
141+
public function setCv($cv)
142+
{
143+
$this->cv = $cv;
144+
145+
return $this;
146+
}
147+
148+
/**
149+
* @ORM\PreUpdate()
150+
* @ORM\PrePersist()
151+
*/
152+
public function prepareToUploadCV()
153+
{
154+
$this->cv->prepareToUpload();
155+
}
156+
157+
/**
158+
* @ORM\PostUpdate()
159+
* @ORM\PostPersist()
160+
*/
161+
public function uploadCV()
162+
{
163+
$this->cv->upload();
164+
}
165+
166+
/**
167+
* @ORM\PostRemove()
168+
*/
169+
public function removeCV()
170+
{
171+
$this->cv->remove();
172+
}
173+
}
174+
```
175+
176+
### Update your form type
177+
178+
For the last step you need to add your file to your form.
179+
180+
* Use `Backend\Form\Type\FileType` as the form type
181+
* Set the fully qualified class name (FQCN) of your value object in the option `file_class` (tip: you can use `MyFile::class` for that)
182+
183+
#### Example
184+
185+
```php
186+
<?php
187+
188+
namespace Backend\Modules\Users\Form;
189+
190+
use Backend\Form\Type\FileType;
191+
use Backend\Modules\Users\ValueObject\CV;
192+
use Symfony\Component\Form\FormBuilderInterface;
193+
194+
class UserType
195+
{
196+
/**
197+
* {@inheritdoc}
198+
*/
199+
public function buildForm(FormBuilderInterface $builder, array $options)
200+
{
201+
$builder->add('cv', FileType::class, ['file_class' => CV::class]);
202+
}
203+
}
204+
```
205+
206+
## Advanced implementation
207+
208+
If you want you can use events on the form that has the file type and set a prefix on the generated filename with the method `setNamePrefix` on the file value object
209+
210+
## Extra configuration options
211+
212+
To make your life even easier, the form FileType has some interesting configuration options on top of the default options that the Symfony FileType already has.
213+
214+
* `show_preview`: By default we will show a link to view the current file if there is one. You can disable this using this option.
215+
* `preview_label`: You can use it to change the translation label that will be in the link to view your current file.
216+
* `show_remove_file`: If your file is not required we will automatically add the option for the user to remove the file, You can disable this using this option.
217+
* `remove_file_label`: You can use it to change the translation label of the remove file checkbox.
218+
* `required_file_error`: You can use it to change the translation label of the error when the file is required but no file was uploaded.
219+
* `help_text_message`: You can use it to change the help text below the file. This will by default show the max upload size in a nice message
220+
* `help_text_argument`: You can use it to change the argument used in the help text below the file. This will by default contain max upload size in a human readable format
221+
* `accept`: You can use this to set the accept attribute on the input field and limit the files that can be selected.

0 commit comments

Comments
 (0)