IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

FOSRestBundle : Post et datetime


Sujet :

Symfony PHP

  1. #1
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut FOSRestBundle : Post et datetime
    Bonjour

    J'essaye de crééer une API REST en utilisant le bundle FOSRestBundle.

    Pour les méthodes de type get, c'est vraiment un plaisir, quelques lignes et tout fonctionne.

    En revanche, pour POST, j'ai bien plus de mal. Si les variables habituelles (text, etc..) fonctionne bien, le champs date time n'est pas aussi conciliant. Le format de date est toujours invalide, et je ne sais ni celui attendu(un comble pour celui qui programme l'application) ni comment modifier celui ci.

    C'est peut être aussi juste un problème de manière d'envoyer les paramètres par json... je n'ai vraiment aucune idée de ce qui est attendu, et je m'arrachje les cheveux sur la doc et les tutos depuis hier.

    Mon entité :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
     
    <?php
     
    namespace Exif\CoreBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    use JMS\Serializer\Annotation\Expose;
    use Symfony\Component\Validator\Constraints as Assert;
    /**
     * Photo
     *
     * @ORM\Table()
     * @ORM\Entity(repositoryClass="Exif\CoreBundle\Repository\PhotoRepository")
     */
    class Photo
    {
        /**
         * @var integer
         *
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         * 
         * @Expose
         */
        private $id;
     
        /**
         * @var integer
         *
         * @ORM\Column(name="hash", type="integer")
         * @Assert\NotBlank()
         * @Expose
         */
        private $hash;
        /**
         * @var integer
         *
         * @ORM\Column(name="filesize", type="integer")
         * @Assert\NotBlank()
         * @Expose
         */
        private $filesize;
     
        /**
         * @var \DateTime
         *
         * @ORM\Column(name="datePicture", type="datetime")
         * 
         * @Assert\NotBlank()
         * @Expose
         */
        private $datePicture;
     
        /**
         * @ORM\ManyToOne(targetEntity="Camera", inversedBy="photos")
         * @ORM\JoinColumn(name="camera_id", referencedColumnName="id")
         * 
         * @Assert\NotBlank()
         * @Expose
         **/
        private $camera;
        /**
         * Get id
         *
         * @return integer 
         */
        public function getId()
        {
            return $this->id;
        }
     
        /**
         * Set hash
         *
         * @param string $hash
         * @return Photo
         */
        public function setHash($hash)
        {
            $this->hash = $hash;
     
            return $this;
        }
     
        /**
         * Get hash
         *
         * @return string 
         */
        public function getHash()
        {
            return $this->hash;
        }
     
        /**
         * Set datePicture
         *
         * @param \DateTime $datePicture
         * @return Photo
         */
        public function setDatePicture($datePicture)
        {
            $this->datePicture = $datePicture;
     
            return $this;
        }
     
        /**
         * Get datePicture
         *
         * @return \DateTime 
         */
        public function getDatePicture()
        {
            return $this->datePicture;
        }
     
        /**
         * Set camera
         *
         * @param \Exif\CoreBundle\Entity\Camera $camera
         * @return Photo
         */
        public function setCamera(\Exif\CoreBundle\Entity\Camera $camera = null)
        {
            $this->camera = $camera;
     
            return $this;
        }
     
        /**
         * Get camera
         *
         * @return \Exif\CoreBundle\Entity\Camera 
         */
        public function getCamera()
        {
            return $this->camera;
        }
     
        /**
         * Set filesize
         *
         * @param integer $filesize
         * @return Photo
         */
        public function setFilesize($filesize)
        {
            $this->filesize = $filesize;
     
            return $this;
        }
     
        /**
         * Get filesize
         *
         * @return integer 
         */
        public function getFilesize()
        {
            return $this->filesize;
        }
    }
    Mon formulaire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
    <?php
     
    namespace Exif\CoreBundle\Form;
     
    use Symfony\Component\Form\AbstractType;
    use Symfony\Component\Form\FormBuilderInterface;
    use Symfony\Component\OptionsResolver\OptionsResolverInterface;
     
    class PhotoType extends AbstractType
    {
            /**
         * @param FormBuilderInterface $builder
         * @param array $options
         */
        public function buildForm(FormBuilderInterface $builder, array $options)
        {
            $builder
                ->add('useremail', 'email', array('mapped' => false))
                ->add('hash')
                ->add('filesize')
                ->add('datePicture', 'datetime', array(
                    'description' => 'The date when the picture was taken',
                    'format' => 'yyyy/MM/dd HH:mm',
                ))
                ->add('camera')
            ;
        }
     
        /**
         * @param OptionsResolverInterface $resolver
         */
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'Exif\CoreBundle\Entity\Photo',
                'csrf_protection'   => false,
            ));
        }
     
        /**
         * @return string
         */
        public function getName()
        {
            return '';
        }
    }
    Et enfin mon controlleur (methode cpostAction à regarder, le reste c'est pour laisser un exemple général)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
     
    <?php
     
    namespace Exif\CoreBundle\Controller;
     
    use Symfony\Component\HttpFoundation\Request;
    use FOS\RestBundle\Controller\FOSRestController;
    use FOS\RestBundle\Routing\ClassResourceInterface;
    use FOS\RestBundle\Controller\Annotations as Rest;
    use Nelmio\ApiDocBundle\Annotation\ApiDoc;
     
    use FOS\RestBundle\View\View;
    use Symfony\Component\Security\Core\Exception\AccessDeniedException;
    use FOS\RestBundle\Controller\Annotations\Get;
    use Exif\CoreBundle\Entity\Photo;
    use Exif\CoreBundle\Form\PhotoType;
     
    class PhotosController extends FOSRestController implements ClassResourceInterface {
        /**
         * Collection get action
         * @var Request $request
         * @return array
         *
         * @Rest\View()
         */
        public function cgetAction(Request $request)
        {
            $em = $this->getDoctrine()->getManager();
            $entities = $em->getRepository('ExifCoreBundle:Photo')->findAll();
            return array(
                'entities' => $entities,
            );
        }
        /**
        * @ApiDoc(
        *   resource = true,
        *   description = "return datas about one photo",
        *   input = "integer",
        *   statusCodes = {
        *     200 = "Returned when successful",
        *     404 = "Returned when no photo had been found"
        *   }
        * )
        * @Rest\View()
        */
        public function getAction($id) {
            $photo = $this->getDoctrine()->getRepository('ExifCoreBundle:Photo')->findOneById($id);
            if (!is_object($photo)) {
                throw $this->createNotFoundException();
            }
            return $photo;
        }
        /**
         * @Get("/photos/{hash}/{filesize}")
         * @Rest\View()
         */
        public function searchAction($hash, $filesize) {
            $photo = $this->getDoctrine()->getRepository('ExifCoreBundle:Photo')->findOneBy(array("hash" => $hash, "filesize" => $filesize));
            if (!is_object($photo)) {
                throw $this->createNotFoundException();
            }
            return $photo;
        }
        /**
         * @Rest\View()
         */
        public function getUsersAction($id) {
            $users = $this->getDoctrine()->getRepository('ExifCoreBundle:User')->findByPhoto($id);
            if (empty($users)) {
                throw $this->createNotFoundException();
            }
            return $users;
        }
        /**
        * Collection post action
        * @ApiDoc
        * @var Request $request
        * @return View|array
        */
        public function cpostAction(Request $request)
        {
            return $this->processForm($request,new Photo());
        }
        private function processForm(Request $request, Photo $photo)
        {
            $statusCode = $photo->getId() ? 201 : 204;
     
            $form = $this->createForm(new PhotoType(), $photo);
            $form->submit($request);
     
            if ($form->isValid()) {
                $em = $this->getDoctrine()->getManager();
                $em->persist($photo);
                $em->flush();
     
                return $this->redirectView(
                        $this->generateUrl(
                            'api_get_photo',
                            array('id' => $photo->getId())
                            ),
                        Codes::HTTP_CREATED
                        );
            }
     
            return array(
                'form' => $form,
            );        
        }
     
        /**
         * Put action
         * @var Request $request
         * @var integer $id Id of the entity
         * @return View|array
         */
        public function putAction($id) {
            $entity = $this->getEntity($id);
            $form = $this->createForm(new PhotoType(), $entity);
            $form->bind($this->getRequest());
     
            if ($form->isValid()) {
                $em = $this->getDoctrine()->getManager();
                $em->persist($entity);
                $em->flush();
     
                return $this->view(null, Codes::HTTP_NO_CONTENT);
            }
     
            return array(
                'form' => $form,
            );
        }
     
    }
    Ma requete : http://exif.dev/app_dev.php/api/photos.json

    Mes paramètres :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    filesize=1024&hash=12345678&useremail=t&datePicture=2013%2F10%2F16%2012%3A00&camera=1
    la reponse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    {"code":400,"message":"Validation Failed","errors":{"children":{"useremail":[],"hash":[],"filesize":[],"datePicture":{"errors":["This value is not valid."],"children":{"date":{"children":{"year":[],"month":[],"day":[]}},"time":{"children":{"hour":[],"minute":[]}}}},"camera":[]}}}
    Si vous avez la moindre idée, je suis preneur...

    Merci,
    Pierre

  2. #2
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Septembre 2009
    Messages
    875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Septembre 2009
    Messages : 875
    Points : 1 313
    Points
    1 313
    Par défaut
    Est ce que ca marche avec 2012/01/01? si ça fonctionnec'est juste qu'il considère le format y/d/m a la place de y/m/d

  3. #3
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    Bonjour,

    Ca ne fonctionne pas.

    Je soupçonne un problème du coté de jmsserializer.
    Est-ce que vous savez comment on peut le debugger ?

    Merci,
    Pierre

  4. #4
    Expert éminent
    Avatar de pmithrandir
    Homme Profil pro
    Responsable d'équipe développement
    Inscrit en
    Mai 2004
    Messages
    2 418
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Responsable d'équipe développement
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2004
    Messages : 2 418
    Points : 7 295
    Points
    7 295
    Par défaut
    bon, j'ai trouvé une solution... loin d'être idéale je dois bien l'avouer. (et a mon avis pas au top niveau efficacité)


    J'ai mis un champs texte, + un transformer datetimetostring pour remplacer mon datetime.

    Ca m'étonnerait fortement que ce cas ne soit pas prévu en auto avec jsmserializer, mais il ne rentre même pas dans le dateHandler, ce qui me parait bizarre.

    Si quelqu'un a mieux, je suis preneur, la on perd pas mal d'avantage a l'utilisation des formulaires... on ne peut plus les partager entre une interface graphique et l'api REST comme pour les autres champs.

    Pierre

Discussions similaires

  1. [2.x] Symfony2 FosRestBundle, mise en place Post
    Par ghis33 dans le forum Symfony
    Réponses: 2
    Dernier message: 02/10/2013, 17h23
  2. [CR6][CR8] cohabitation sur un même poste
    Par obi dans le forum SAP Crystal Reports
    Réponses: 8
    Dernier message: 27/11/2003, 20h24
  3. [Choix SGBD] Application mono-poste mais beaucoup de données
    Par Wavyx dans le forum Décisions SGBD
    Réponses: 5
    Dernier message: 16/03/2003, 18h24
  4. Post incrémentation?
    Par Defrag dans le forum C
    Réponses: 4
    Dernier message: 08/10/2002, 10h36
  5. probleme d'installation sur d'autres postes
    Par VBkiller dans le forum Composants VCL
    Réponses: 4
    Dernier message: 18/09/2002, 18h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo