Skip to content

Instantly share code, notes, and snippets.

@joshlopes
Created January 25, 2017 11:22
Show Gist options
  • Save joshlopes/b7da7234734ea71fcb2204ab55101180 to your computer and use it in GitHub Desktop.
Save joshlopes/b7da7234734ea71fcb2204ab55101180 to your computer and use it in GitHub Desktop.
<?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