Pertanyaan Mengisi kotak centang di Symfony2 berdasarkan ArrayCollection ()


EDIT - Pertanyaan yang didefinisikan ulang dan termasuk kode khusus tambahan

Dalam proyek Symfony2 saya, saya memiliki entitas (Konfigurasi) yang mencakup hubungan OneToMany dengan entitas lain (ConfigurationsFeatures). Saya mencoba membangun formulir yang memungkinkan pengguna untuk mengubah nilai dalam entitas Konfigurasi dan juga memilih nilai yang akan dipertahankan ke entitas ConfigurationsFeatures. Ada dua skenario di mana formulir tersebut digunakan:

1) Buat konfigurasi baru -> membuat formulir kosong dengan kolom untuk nilai-nilai dalam Konfigurasi dan kumpulan kotak centang untuk nilai potensial di ConfigurationsFeatures; sumber nilai potensial sebenarnya adalah entitas ketiga, CoreCodes. Setelah divalidasi, Nilai-nilai dari formulir tersebut tetap ada ke entitas Konfigurasi dan kotak centang yang dipilih akan tetap ada di ConfigurationsFeatures.

2) Perbarui konfigurasi yang ada -> render formulir dengan nilai-nilai Konfigurasi yang ada ditampilkan di bidang dan render kumpulan kotak centang untuk semua kemungkinan nilai-nilai ConfigurationsFeatures NAMUN memiliki nilai-nilai yang sudah ada dipilih.

Saya telah membangun jenis bentuk dan tindakan pengontrol untuk skenario # 1, mengujinya, dan semuanya berfungsi. Namun, saya tidak bisa menyelesaikan "sudah ada nilai yang sudah dipilih" di bagian kotak centang pada formulir. Saya menyadari bahwa saat ini saya sudah menyiapkan pengontrol saya, saya pada dasarnya membandingkan apel dengan jeruk karena $ entity-> getFeatures () mengembalikan entitas ArrayCollection dari ConfigurationsFeatures dan tidak ada yang bisa dipetakan dalam bentuk, karena formulir tersebut menggunakan kumpulan entitas CoreCodes.

Jadi bagaimana cara menjembatani celah ini?


Entity \ Configurations (menyimpan konfigurasi individual)

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Lynux\AssetBundle\Entity\Core\Configurations
 * ... ORM declarations ...
 */
class Configurations
{
    // ... plain old properties, nothing fancy here... 

    /**
     * @ORM\OneToMany(targetEntity="Lynux\AssetBundle\Entity\Core\ConfigurationsFeatures", mappedBy="configurationFk")
     */
    private $features;

    public function __construct()
    {
        $this->features = new ArrayCollection();
    }

    // getters and setters

    /**
     * Set features
     */
    public function setFeatures(ArrayCollection $features)
    {
        $this->features = $features;
    }

    /**
     * Get features
     */
    public function getFeatures()
    {
        return $this->features;
    }
}

Entity \ ConfigurationsFeatures (menyimpan fitur yang dipilih per konfigurasi)

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;

/**
 * Lynux\AssetBundle\Entity\Core\ConfigurationsFeatures
 * ... ORM declarations ...
 */
class ConfigurationsFeatures
{
    /**
     * @var Codes
     *
     * @ORM\ManyToOne(targetEntity="Lynux\AssetBundle\Entity\Core\Codes")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="feature_fk", referencedColumnName="id")
     * })
     */
    private $featureFk;

    /**
     * @var Configurations
     *
     * @ORM\ManyToOne(targetEntity="Lynux\AssetBundle\Entity\Core\Configurations", inversedBy="features")
     * @ORM\JoinColumns({
     *   @ORM\JoinColumn(name="configuration_fk", referencedColumnName="id")
     * })
     */
    private $configurationFk;

    /**
     * Set featureFk
     *
     * @param Lynux\AssetBundle\Entity\Core\Codes $featureFk
     * @return ConfigurationsFeatures
     */
    public function setFeatureFk(\Lynux\AssetBundle\Entity\Core\Codes $featureFk = null)
    {
        $this->featureFk = $featureFk;

        return $this;
    }

    /**
     * Get featureFk
     *
     * @return Lynux\AssetBundle\Entity\Core\Codes
     */
    public function getFeatureFk()
    {
        return $this->featureFk;
    }

    /**
     * Set configurationFk
     *
     * @param Lynux\AssetBundle\Entity\Core\Configurations $configurationFk
     * @return ConfigurationsFeatures
     */
    public function setConfigurationFk(\Lynux\AssetBundle\Entity\Core\Configurations $configurationFk = null)
    {
        $this->configurationFk = $configurationFk;

        return $this;
    }

    /**
     * Get configurationFk
     *
     * @return Lynux\AssetBundle\Entity\Core\Configurations
     */
    public function getConfigurationFk()
    {
        return $this->configurationFk;
    }
}

Entity \ CoreCodes (sumber nilai potensial untuk ConfigurationsFeatures-> featureFk)

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Lynux\AssetBundle\Entity\Core\Codes
 *
 * @ORM\Table(name="core_codes")
 */
class Codes
{
    /**
     * @var integer $id
     *
     * @ORM\Column(name="id", type="integer", nullable=false, unique=true)
     * @ORM\Id
     * @Assert\NotBlank(message="ID cannot be blank!")
     * @Assert\Regex(pattern="/^\d+$/", match=true, message="ID must be an integer!")
     * @Assert\MinLength(limit=8, message="ID must be 8 digits in length!")
     * @Assert\MaxLength(limit=8, message="ID must be 8 digits in length!")
     */
    private $id;

    // ... various properties, not applicable to question ...

    /**
     * Set id
     *
     * @param integer $id
     * @return Codes
     */
    public function setId($id)
    {
        $this->id = $id;

        return $this;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    // ... getters and setters for other properties ...
}

Ketik \ FormConfigurations

use Doctrine\ORM\EntityRepository;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;

class FormConfigurations extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $features = $this->features;

        // ... builders for other properties ...

        $builder->add(
            'features',
            'entity',
            array(
                'class'         => 'LynuxAssetBundle:Core\Codes',
                'property_path' => false,
                'query_builder' => function(EntityRepository $er) use ($features)
                    {
                        return $er->createQueryBuilder('u')
                            ->where('u.submodule = :submodule')
                            ->setParameter('submodule', 'feature');
                    },
                'expanded' => true,
                'multiple' => true,
                'property' => 'title',));
    }

    public function getName()
    {
        return 'FormConfigurations';
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(
            array(
                'data_class' => 'Lynux\AssetBundle\Entity\Core\Configurations',));
    }
}

Controller \ ConfigurationsController :: createAction ()

public function createAction(Request $request)
{
    $config = $request->getSession()->get('configuration');
    $manage = $this->getDoctrine()->getEntityManager();

    $entity = new Configurations();
    $form   = $this->createForm(new FormConfigurations($features), $entity);
    $failed = null;

    $features = $manage
        ->getRepository('LynuxAssetBundle:Core\Codes')
        ->findBySubmodule('feature');

    if ('POST' == $request->getMethod()) {
        $form->bind($request);

        if ($form->isValid()) {
            $status = $manage
                ->getRepository('LynuxAssetBundle:Core\Codes')
                ->findOneById(10103022);

            $entity->setToken($entity->getName());
            $entity->setStatusFk($status);
            $entity->setCreateAccountFk($this->getUser());

            $features = $form->get('features')->getData();
            foreach($features as $feature) {
                $addFeature = new ConfigurationsFeatures();
                $addFeature->setConfigurationFk($entity);
                $addFeature->setFeatureFk($feature);
                $manage->persist($addFeature);
            }
            $manage->persist($entity);
            $manage->flush();

            return $this->redirect($this->generateUrl(
                'CoreConfigurationsConfirm',
                array(
                    'code'  => 'create',
                    'token' => $entity->getToken(),)));
        } else {
            $failed = true;
        }
    }

Controller \ ConfigurationsController :: updateAction ()

public function updateAction(Request $request, $token)
{
    $manage = $this->getDoctrine()->getEntityManager();
    $entity = $manage
        ->getRepository('LynuxAssetBundle:Core\Configurations')
        ->findOneByToken($token);

    $form   = $this->createForm(new FormConfigurations($features), $entity);

    if ('POST' == $request->getMethod()) {
        $form->bind($request);

        if ($form->isValid()) {
            $currentFeatures = $manage
                ->getRepository('LynuxAssetBundle:Core\ConfigurationsFeatures')
                ->findByConfigurationFk($entity);
            foreach($currentFeatures as $currentFeature) {
                $manage->remove($currentFeature);
            }

            $features = $form->get('features')->getData();
            foreach($features as $feature) {
                $addFeature = new ConfigurationsFeatures();
                $addFeature->setConfigurationFk($entity);
                $addFeature->setFeatureFk($feature);
                $manage->persist($addFeature);
            }

            $manage->flush();
        }
    }

4
2017-10-16 20:47


asal


Jawaban:


Ahh sabar dan ketekunan ... Aku sadar bahwa aku sedang mengkonversi koleksi CoreCodes ke koleksi ConfigurationsFeatures ketika bertahan ke database. Demikian juga masuk akal untuk mengkonversi dari ConfigurationsFeatures ke CoreCodes ketika menampilkan formulir.

// ConfigurationsController::updateAction()

$formFeatures    = new ArrayCollection();
$currentFeatures = $entity->getFeatures();
foreach($currentFeatures as $feature) {
    $formFeatures->add($feature->getFeatureFk());
}

if ('POST' != $request->getMethod()) { // first time the form is loaded
    $form->get('features')->setData($formFeatures);
}

4
2017-10-22 21:13