Buenas noches!!
Estoy intentando implementar en el bundle FOSCommentBundle
añadir fotos, para ello estoy utilizando los eventos que el mismo proporciona que son los siguientes:
- fos_comment.comment.pre_persist
- fos_comment.comment.post_persist
- fos_comment.comment.create
- fos_comment.thread.pre_persist
- fos_comment.thread.post_persist
- fos_comment.thread.create
- fos_comment.vote.pre_persist
- fos_comment.vote.post_persist
- fos_comment.vote.create
El que utilizo es fos_comment.comment.pre_persist
. Y lo creo como servicio de esta manera:
acme_comment.listener: class: Acme\CommentBundle\Event\CreateCommentListener arguments: - @doctrine.orm.entity_manager - @fos_comment.manager.comment - @security.context - @request_stack tags: - {name: kernel.event_listener, event: fos_comment.comment.pre_persist, method: onCommentPersist }
Después tengo la clase Acme\CommentBundle\Event\CreateCommentListener
:
namespace Acme\CommentBundle\Event; use FOS\CommentBundle\Events; use FOS\CommentBundle\Event\CommentEvent; use FOS\CommentBundle\Model\CommentInterface; use FOS\CommentBundle\Model\CommentManagerInterface; use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\Security\Core\SecurityContext; use Symfony\Component\HttpFoundation\RequestStack; use Doctrine\Orm\EntityManager; use Acme\FotosBundle\Entity\Fotos as Foto; class CreateCommentListener { private $em; private $commentManager; private $user; private $requestStack; private $securityContext; public function __construct(EntityManager $em,CommentManagerInterface $commentManager, SecurityContext $securityContext,RequestStack $requestStack) { $this->em = $em; $this->requestStack = $requestStack->getCurrentRequest(); $this->commentManager = $commentManager; $this->securityContext = $securityContext; if ($this->securityContext->getToken() !== null) { $this->user = $this->securityContext->getToken()->getUser(); } else { $this->user = false; } } /** * Disallows comments in a closed thread. * * @param \FOS\CommentBundle\Event\CommentEvent $event */ public function onCommentPersist(CommentEvent $event) { if($this->user !== false){ /* @var $comment \FOS\CommentBundle\Model\CommentInterface */ $comment = $event->getComment(); $fotos = $this->requestStack->files; var_dump($fotos->all()); //aqui compruebo que estoy recibiendo las fotos die(); $iFoto=1; foreach ($fotos as $foto){ echo $foto->getClientOriginalName(); $foto= new Foto(); $foto->subirFoto($comment->getThread()->getId()); $foto->setMessages($post); $foto->setComment($comment); $foto->setUser($this->user); $foto->setNumero($iFoto); $this->em->persist($foto); $this->em->flush(); $iFoto++; } die("nada"); echo $post->getId(); } }
Sigo en el siguiente POST.
Respuestas
Aqui hago un var_dump($fotos->all());
, pero nada me devuelve
array(0) { }
Te muestro también la entidad Comment que es la que reemplaza a la original:
<?php namespace Acme\CommentBundle\Entity; use Doctrine\ORM\Mapping as ORM; use FOS\CommentBundle\Entity\Comment as BaseComment; use FOS\CommentBundle\Model\SignedCommentInterface; use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\HttpFoundation\File\UploadedFile; use Doctrine\Common\Collections\ArrayCollection; use Symfony\Component\Validator\Constraints as Assert; use Jc\Util; /** * @ORM\Entity * @ORM\ChangeTrackingPolicy("DEFERRED_EXPLICIT") */ class Comment extends BaseComment implements SignedCommentInterface { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id; /** * Thread of this comment * * @var Thread * @ORM\ManyToOne(targetEntity="Acme\CommentBundle\Entity\Thread") */ protected $thread; /** * Author of the comment * * @ORM\ManyToOne(targetEntity="Application\Sonata\UserBundle\Entity\User" , inversedBy="comments") * @var User */ protected $author; /** * @var File * * @ORM\OneToMany( * targetEntity="Acme\FotosBundle\Entity\Fotos", * mappedBy="comment", * cascade={"all"}, * orphanRemoval=true) * @Assert\Valid() * */ private $fotos; public function __construct() { //$this->fotos = new ArrayCollection(); $this->createdAt=new \DateTime(date('Y-m-d H:i:s')); } public function __toString() { return (string) "Comentario del hilo:".$this->getAuthorName() ?: 'Nuevo comentario'; } public function setAuthor(UserInterface $author) { $this->author = $author; } public function getAuthor() { return $this->author; } public function getAuthorName() { if (null === $this->getAuthor()) { return 'Anónimo'; } return $this->getAuthor()->getUsername(); } /** * Get id * * @return integer */ public function getId() { return $this->id; } /** * Add fotos * * @param \Acme\FotosBundle\Entity\Fotos $fotos * @return Comment */ public function addFoto(\Acme\FotosBundle\Entity\Fotos $fotos) { $this->fotos[] = $fotos; return $this; } /** * Remove fotos * * @param \Acme\FotosBundle\Entity\Fotos $fotos */ public function removeFoto(\Acme\FotosBundle\Entity\Fotos $fotos) { $this->fotos->removeElement($fotos); } /** * Get fotos * * @return \Doctrine\Common\Collections\Collection */ public function getFotos() { return $this->fotos; } }
También muestro el Formulario CommentType.php
<?php namespace Acme\CommentBundle\Form\Type; use Symfony\Component\Form\FormEvent; use Symfony\Component\Form\FormEvents; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolverInterface; use FOS\CommentBundle\Form\CommentType as BaseType; use FOS\CommentBundle\Model\CommentInterface; use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityRepository; class CommentType extends AbstractType { protected $em; public function __construct(EntityManager $em) { $this->em = $em; } public function buildForm(FormBuilderInterface $builder, array $options) { //parent::buildForm($builder, $options); $builder ->add('body', 'textarea') ->add('fotos', 'file', array( 'multiple' => true, 'required'=>false, 'data_class' => null, )) ; } public function setDefaultOptions(OptionsResolverInterface $resolver) { $resolver->setDefaults(array( 'data_class' => 'Acme\CommentBundle\Entity\Comment' )); } public function getName() { return 'comment_form'; } public function getParent() { return 'fos_comment_comment'; } }
También en la vista he puesto el {{ form_enctype(form) }}
La verdad ya no se que hacer más he probado de todo y sigue sin salirme nada.
¿Cómo lo tengo que hacer?
@jcarlosweb
Hola,
Puedes probar a modificar la linea:
$this->requestStack = $requestStack->getCurrentRequest(); //Por $this->requestStack = $requestStack->getMasterRequest();
Solo para verificar si estas en un subRequest al momento de ser invocado el listener. De ser así, ese es el problema.
Por otro lado, si usas o tienes la posibilidad de Usar la versión 2.6 de symfony, allí tienes la función dump($var), que te permite visualizar la informacion de un objeto php mucho mejor que con var_dump.
@manuel_j555
Muchas gracias Manuel como siempre eres muy amable.
Pero sigue saliéndome lo mismo. He probado también hacer un var_dump($fotos)
sin el objeto files
para ver que me muestra y me muestra lo siguiente:
object(Symfony\Component\HttpFoundation\FileBag)#12 (1) { ["parameters":protected]=> array(0) { } }
Por cierto en el Composer para la actualización de la version 2.6, ¿qué forma es la mejor? ¿De esta manera: "symfony/symfony": "2.6.*"
?
Bueno Manuel espero puedas ayudarme ha resolver el problema, a veces me desespero mucho con Symfony.
Un abrazo.
@jcarlosweb
Sigo sin saber porque no me muestra las foto en el request. ¿Tiene que ver algo con foscommentbunle
, que solamente registre lo que viene predefinido en su formulario?.
Por ejemplo para coger el texto del textarea si puedo cogerlo lo hago así:
$this->requestStack->request->get('fos_comment_comment')['body']
Pero las fotos imposible; me da el resultado del anterior post. Pongo de paso el html que me genera el formulario:
<form class="fos_comment_comment_new_form" action="http://test.local/app_dev.php/api/threads/129/comments" data-parent="" method="POST" enctype="multipart/form-data" > <div class="fos_comment_form_errors"> </div> <textarea id="fos_comment_comment_body" name="fos_comment_comment[body]" required="required"></textarea> <div> <label for="fos_comment_comment_fotos">Fotos</label> <input type="file" id="fos_comment_comment_fotos" name="fos_comment_comment[fotos][]" multiple="multiple" /> </div> <input type="hidden" id="fos_comment_comment__token" name="fos_comment_comment[_token]" value="SNEMKNEjvjj5XJl5r0Eu8aZEPRulUiA8dDVcn06ZmOw" /> <div class="fos_comment_submit"> <input type="submit" class="btn btn-primary" value="Enviar comentario" /> </div> </form>
@jcarlosweb
Verifica si en la variable global $_FILES
hay elementos. Si es así, deberás indagar sobre el proceso ejecutado al enviar el formulario, a ver en que momento es llamado tu listener.
Con respecto a actualizar Symfony, como lo has colocado está bien.
Por otro lado en el profiler tienes la información del formulario, puedes inspeccionar allí también a ver si se enviaron los archivos.
@manuel_j555
Me retorna array(0) { }
. Increíble.......
@jcarlosweb
Manuel tengo que añadir que el formulario se envía por jQuery. No si será ese el problema.
Este es el archivo javascript que provee el bundle: comments.js
@jcarlosweb
Bueno, parece ser que es por culpa del archivo JavaScript que proporciona. Vamos a ver cómo puedo modificar el archivo para conseguir que coja las imágenes. Esto va a ser complicado.
@jcarlosweb
Bueno al final lo que voy hacer es hacerlo propio, porque ha sido una equivocación coger un bundle el cual ya no tiene ni soporte y seguro que tardaré mucho menos.
Un cordial saludo.
@jcarlosweb