Skip to content

Instantly share code, notes, and snippets.

@AhmedSamy
Created June 1, 2014 11:44
Show Gist options
  • Save AhmedSamy/83065cc2035f11f0415e to your computer and use it in GitHub Desktop.
Save AhmedSamy/83065cc2035f11f0415e to your computer and use it in GitHub Desktop.
<?php
namespace Ma7shy\BackendBundle\Form\Type\Field;
use Doctrine\ODM\MongoDB\DocumentManager;
use Ma7shy\BackendBundle\Form\Transformer\ObjectToDocumentTransformer;
use Ma7shy\BackendBundle\Form\Transformer\ObjectToRefTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolverInterface,
Symfony\Component\Routing\Router;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class UserAjaxField extends AbstractType
{
/** @var $router UrlGeneratorInterface */
protected $router;
/** @var $em DocumentManager */
protected $dm;
/**
* @param UrlGeneratorInterface $router
* @param DocumentManager $dm
*/
function __construct(UrlGeneratorInterface $router, DocumentManager $dm)
{
$this->router = $router;
$this->dm = $dm;
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->addModelTransformer(
new ObjectToDocumentTransformer($this->dm, 'Ma7shy\UserBundle\Document\User', 'id', 'fullName', false)
);
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(
[
'label' => 'User',
'configs' => [
'width' => '300px',
'ajax' => [
'url' => $this->router->generate('ma7shy_backend_users_userautocomplete', [], true),
'type' => 'GET',
'dataType' => 'json',
'data' => "function (term, page) {
return {
term: term,
page_limit: 5,
page: page,
};
}",
'results' => "function (data, page) {
return {results: data};
}"
],
],
'class' => 'Ma7shy\UserBundle\Document\user',
'empty_value' => '-- Select Creator --'
]
);
}
/**
* @return null|string|\Symfony\Component\Form\FormTypeInterface
*/
public function getParent()
{
return 'thrace_select2_ajax';
}
/**
* @return string
*/
public function getName()
{
return 'user_ajax_type';
}
}
<?php
namespace Ma7shy\BackendBundle\Form\Transformer;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Util\Inflector;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Doctrine\Common\Persistence\ObjectManager;
/**
* Class ObjectToDocumentTransformer
*
* @package Ma7shy\BackendBundle\Form\Transformer
*/
class ObjectToDocumentTransformer implements DataTransformerInterface
{
/** @var $om ObjectManager */
private $om;
/** @var $objectRepository string */
private $objectRepository;
/** @var $identifier null */
private $identifier;
/** @var $displayPropery null */
private $displayProperty;
/** @var $multiple boolean */
private $multiple;
/**
* @param ObjectManager $om
* @param $objectRepository
* @param null $identifier
* @param null $displayProperty
* @param $multiple
*/
public function __construct(
ObjectManager $om,
$objectRepository,
$identifier = null,
$displayProperty = null,
$multiple
) {
$this->om = $om;
$this->objectRepository = $objectRepository;
$this->identifier = $identifier;
$this->displayProperty = !isset($displayProperty) ? $identifier : $displayProperty;
$this->multiple = $multiple;
}
/**
* @param mixed $entity
*
* @return mixed|string
*/
public function transform($entity)
{
if ($this->multiple) {
if (!$entity instanceof \ArrayAccess && !is_array($entity)) {
return '';
}
$entities = [];
foreach ($entity as $singleId) {
$entities[] = $this->transformSingle($singleId);
}
return implode(', ', $entities);
} else {
if (is_null($entity) || !is_object($entity)) {
return '';
}
return $this->transformSingle($entity);
}
}
/**
* @param $entity
*
* @return mixed|string
*/
public function transformSingle($entity)
{
$meta = $this->om->getClassMetadata(get_class($entity));
if ($this->identifier !== null) {
$getter = 'get' . Inflector::camelize($this->identifier);
return $entity->$getter();
}
$identifier = current($meta->getIdentifierValues($entity));
if ($identifier === null) {
return '';
}
return $identifier;
}
/**
* @param mixed $id
*
* @return ArrayCollection|mixed|null|object
*/
public function reverseTransform($id)
{
if (!$id) {
return null;
}
if ($this->multiple) {
if (strpos($id, ',') === false) {
return new ArrayCollection([$this->reverseTransformSingle($id)]);
} else {
$id = array_unique(array_filter(array_map('trim', explode(',', $id))));
}
$entities = new ArrayCollection();
foreach ($id as $singleId) {
$entities->add($this->reverseTransformSingle($singleId));
}
return $entities;
} else {
return $this->reverseTransformSingle($id);
}
}
/**
* @param $id
*
* @return object
* @throws \Symfony\Component\Form\Exception\TransformationFailedException
*/
public function reverseTransformSingle($id)
{
if ($this->identifier !== null) {
$findOneBy = 'findOneBy' . Inflector::camelize($this->identifier);
$entity = $this->om->getRepository($this->objectRepository)->$findOneBy($id);
} else {
$entity = $this->om->getRepository($this->objectRepository)->find($id);
}
if (null === $entity) {
throw new TransformationFailedException(sprintf(
'An entity with id "%s" does not exist!',
$id
));
}
return $entity;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment