преобразование набора входных данных формы в JSON - PullRequest
1 голос
/ 03 апреля 2019

Так что это будет звучать немного сложно, так как я абсолютный новичок в JSON, но терпите меня, ребята, мне это действительно нужно. позвольте мне начать с показа моего лица

<?php

namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="App\Repository\TypeParkingRepository")
 */
class TypeParking
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=55)
     */
    private $libelle;


    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $jourdebut;

    /**
     * @ORM\Column(type="date", nullable=true)
     */
    private $jourfin;


    /**
     * @ORM\Column(type="json_array", nullable=true)
     */
    private $exception;


    public function getId(): ?int
    {
        return $this->id;
    }



    public function getJourdebut(): ?\DateTimeInterface
    {
        return $this->jourdebut;
    }

    public function setJourdebut(\DateTimeInterface $jourdebut): self
    {
        $this->jourdebut = $jourdebut;

        return $this;
    }

    public function getJourfin(): ?\DateTimeInterface
    {
        return $this->jourfin;
    }

    public function setJourfin(\DateTimeInterface $jourfin): self
    {
        $this->jourfin = $jourfin;

        return $this;
    }


    public function getException() {
        return array_merge([
            'name' => null,
            'datedebut' => null, 
            'datefin' => null, 
            'heuredebut' => null, 
            'heurefin' => null, 

            // other sub-fields "empty" values
        ], $this->exception ?? [] // prevent array_merge from failing if exception is empty
        );
    }

    public function setException($exception): self
    {
        $this->exception = $exception;

        return $this;
    }

    public function getLibelle(): ?string
    {
        return $this->libelle;
    }

    public function setLibelle(string $libelle): self
    {
        $this->libelle = $libelle;

        return $this;
    }
}

Как вы можете видеть, у меня есть это свойство, называемое исключением, теперь у этого свойства есть много вложенных свойств, таких как name, datedebut, datefin ... Поэтому мне пришлось использовать для этого формат JSON. поэтому я создал этот тип формы с именем TypeParkingType.php

<?php

namespace App\Form;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\DateTimeType;
use Symfony\Component\Form\Extension\Core\Type\TimeType;
use Symfony\Component\Form\Extension\Core\Type\DateType;

use App\Entity\TypeParking;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

class TypeParkingType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('libelle')
            ->add('tempsmax')
            ->add('jourdebut')
            ->add('jourfin')

            ->add('jourstravail_jour', TextType::class, ['property_path' => 'jourstravail[jour]'])
            ->add('jourstravail_debut', TextType::class, ['property_path' => 'jourstravail[debut]'])
            ->add('jourstravail_fin', TextType::class, ['property_path' => 'jourstravail[fin]'])


            ->add('Exception_Name', TextType::class, ['property_path' => 'exception[name]'])
            ->add('Starting_date', DateTimeType::class, [
                'property_path' => 'exception[datedebut]',
            ])
            ->add('Ending_date', DateTimeType::class, [
                'property_path' => 'exception[datefin]',
            ])
            ->add('Starting_time', TextType::class, ['property_path' => 'exception[heuredebut]'])
            ->add('Ending_time', TextType::class, ['property_path' => 'exception[heurefin]'])

        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => TypeParking::class,
        ]);
    }
}


К сожалению, это не работает, потому что даже после вставки данных в базу данных это происходит непрактичным способом, который невозможно прочитать. Чтобы сделать его более сложным, каждая форма может иметь более одного исключения, что означает, что я должен анализировать данные таким образом, как: Ex: {имя-исключения (datedebut: ..., datefin ..., time: ...), exceptionname2 ....}

что я имею в виду под невозможным, так это то, что он дает мне строку, подобную этой https://imgur.com/a/ydYbpaQ, которая:

  1. выдает мне эту ошибку, когда я перехожу на страницу редактирования для выбранного типа: Unable to transform value for property path "exception[datedebut]": Expected a \DateTimeInterface.

  2. Я не могу извлечь данные по одному из него

TL; DR: как вставить значения, связанные с исключением, в одну строку JSON в базе данных.

1 Ответ

0 голосов
/ 03 апреля 2019

Мой совет - добавить новый ExceptionType, в который вы перемещаете свои поля исключений (присвойте ему data_class из null (по сути: массив).

в основной форме:

->add('exception', CollectionType::class, [
     'entry_type' => ExceptionType::class,
     // have a look at the other options!
   ]); 

(см. https://symfony.com/doc/current/reference/forms/types/collection.html для получения информации о CollectionType)

Для вашей проблемы с сериализацией и десериализацией (это, по сути, так), я бы предложил использовать преобразователь данных, который вы применяете к полю даты.

по сути, он принимает строку даты '2019-01-02' или что-то еще и превращает ее в DateTime и наоборот. Таким образом, DateTime, предоставленный вашей формой, не сериализуется в какой-либо объект, а в строку.

см. https://symfony.com/doc/current/form/data_transformers.html

Ваш CallbackTransformer будет выглядеть примерно так:

        new CallbackTransformer(
            function (string $string=null) {
                // transform string to DateTime
                return $string ? new \DateTime($string) : null;
            },
            function (\DateTime $datetime=null) {
                // transform the string back to an array
                return $datetime ? $datetime->format('Y-m-d') : null
            }
        )

, чтобы это работало должным образом для существующих записей в базе данных, вы должны удалить их или исправить вручную, чтобы строка даты была просто ГГГГ-ММ-ДД вместо { ... }, и вы должны обернуть ваши исключения до сих пор в '[...]' так что это массив.

обновление

Конечно, из-за изменений в исключении (теперь содержащем несколько исключений вместо одного), вы должны изменить метод getException вашей сущности:

public function getException() {
    return $this->exception ?? [];
}

возможно, вы можете отбросить весь метод ... Я не совсем уверен, что

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...