Created
January 25, 2017 11:22
-
-
Save joshlopes/b7da7234734ea71fcb2204ab55101180 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace AppBundle\Form\Type; | |
use Domain\Bundle\ImageBundle\Service\ImageManager; | |
use Domain\Bundle\ImageBundle\Service\RackspaceImageDisplay; | |
use AppBundle\Form\DataTransformer\DomainImageTransformer; | |
use AppBundle\Validator\Constraints\DomainFlexibleImage; | |
use AppBundle\Validator\Constraints\DomainImage; | |
use Symfony\Component\Form\AbstractType; | |
use Symfony\Component\Form\Extension\Core\Type\FileType; | |
use Symfony\Component\Form\Extension\Core\Type\FormType; | |
use Symfony\Component\Form\FormBuilderInterface; | |
use Symfony\Component\Form\FormEvent; | |
use Symfony\Component\Form\FormEvents; | |
use Symfony\Component\Form\FormInterface; | |
use Symfony\Component\Form\FormView; | |
use Symfony\Component\OptionsResolver\Options; | |
use Symfony\Component\OptionsResolver\OptionsResolver; | |
class DomainImageType extends AbstractType | |
{ | |
/** @var ImageManager */ | |
private $imageManager; | |
/** @var RackspaceImageDisplay */ | |
private $rackspaceImageDisplay; | |
/** @var array */ | |
private $preSetData; | |
/** | |
* @param ImageManager $imageManager | |
*/ | |
public function setImageManager(ImageManager $imageManager) | |
{ | |
$this->imageManager = $imageManager; | |
} | |
/** | |
* @param RackspaceImageDisplay $rackspaceManager | |
*/ | |
public function setRackspaceImageDisplay(RackspaceImageDisplay $rackspaceManager) | |
{ | |
$this->rackspaceImageDisplay = $rackspaceManager; | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function buildForm(FormBuilderInterface $builder, array $options) | |
{ | |
if ($options['isRemovable']) { | |
// Remove checkbox that will tell us when we want to remove the image | |
$builder->add('remove', CheckboxType::class, ['required' => false]); | |
} | |
$builder->add( | |
'file', | |
FileType::class, | |
[ | |
'constraints' => $options['image_constraint'], | |
'required' => $options['image_required'], | |
'help_label' => $options['help_label'], | |
'attr' => [ | |
'accept' => 'image/*', // tell mobile phones to use gallery app to select a photo | |
], | |
] | |
); | |
$transformer = new DomainImageTransformer( | |
$this->imageManager, | |
$options['pretty-name'], | |
$options['storageAlias'] | |
); | |
$builder | |
->get('file') | |
->addModelTransformer($transformer); | |
$builder->addEventListener(FormEvents::PRE_SET_DATA, [$this, 'onPreSetData']); | |
$builder->addEventListener(FormEvents::SUBMIT, [$this, 'onSubmit']); | |
} | |
/** | |
* This is done for BC where data is the direct file path | |
* | |
* @param FormEvent $formEvent | |
*/ | |
public function onPreSetData(FormEvent $formEvent) | |
{ | |
$data = $formEvent->getData(); | |
if (!is_array($data)) { | |
$data = [ | |
'file' => $data | |
]; | |
} | |
$this->preSetData[] = $data; | |
$formEvent->setData($data); | |
} | |
/** | |
* For BC send just the string | |
* | |
* @param FormEvent $formEvent | |
*/ | |
public function onSubmit(FormEvent $formEvent) | |
{ | |
$data = $formEvent->getData(); | |
$preSetData = array_shift($this->preSetData); | |
if (!empty($data['remove'])) { | |
// We want to remove the file | |
$data = null; | |
} elseif (null === $data['file']) { | |
// Persist the same file | |
$data = $preSetData['file']; | |
} else { | |
$data = $data['file']; | |
} | |
$formEvent->setData($data); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function configureOptions(OptionsResolver $resolver) | |
{ | |
$resolver->setDefaults( | |
[ | |
// Preview settings, to render the image on the template | |
'preview' => false, | |
// If set to true a checkbox will also be rendered when ticked this is removed | |
'isRemovable' => false, | |
// Tells which storage to use, leave null for default | |
'storageAlias' => null, | |
// Image constraint | |
'image_constraint' => new DomainImage(), | |
// Image required | |
'image_required' => false, | |
] | |
); | |
$resolver->setRequired(['pretty-name']); | |
} | |
/** | |
* @see sf2/app/Resources/views/shared/form/fields.html.twig:140 | |
* | |
* {@inheritdoc} | |
*/ | |
public function buildView(FormView $view, FormInterface $form, array $options) | |
{ | |
$thumbnail = $this->rackspaceImageDisplay->getUrl($form->get('file')->getData(), true); | |
$view->vars = array_replace( | |
$view->vars, | |
[ | |
'thumbnail' => $thumbnail, | |
'preview' => $options['preview'], | |
'isRemovable' => $options['isRemovable'], | |
] | |
); | |
} | |
/** | |
* {@inheritdoc} | |
*/ | |
public function getParent() | |
{ | |
return FormType::class; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment