Php Symfony奏鸣曲媒体捆绑一对多关系

Php Symfony奏鸣曲媒体捆绑一对多关系,php,symfony,sonata-admin,sonata-media-bundle,Php,Symfony,Sonata Admin,Sonata Media Bundle,我有一个与sonata AdminBundle合作的项目,我想使用mediaBundle进行上传。我有一个实体原型,可以有许多图像。我想有一个表单,这样我可以在保存之前添加许多图像。 我跟着台阶走了进去 但它不起作用,我不明白为什么 编辑: 要明确的是:我有3个部分,我想能够上传其中每一个许多图像 这是我的原型实体: <?php namespace AppBundle\Entity; use Doctrine\ORM\Mapping as ORM; use Symfony\Compon

我有一个与sonata AdminBundle合作的项目,我想使用mediaBundle进行上传。我有一个实体原型,可以有许多图像。我想有一个表单,这样我可以在保存之前添加许多图像。 我跟着台阶走了进去 但它不起作用,我不明白为什么

编辑: 要明确的是:我有3个部分,我想能够上传其中每一个许多图像

这是我的原型实体:

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Prototype
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\PrototypeRepository")
 * @Vich\Uploadable
 * @ORM\HasLifecycleCallbacks
 */
class Prototype
{
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="nom", type="string", length=255)
 */
private $nom;


/**
 * @var string
 *
 * @ORM\Column(name="description", type="string", length=255)
 */
private $description;

/**
 * @var \DateTime
 *
 * @ORM\Column(name="dateCreation", type="date")
 */
private $dateCreation;


/**
 * @ORM\Column(type="string", length=255, name="fichier_nom")
 *
 * @var string $nomFichier
 */
public $nomFichier;


/**
 * @ORM\Column(type="datetime")
 *
 * @var \DateTime $updatedAt
 */
public $updatedAt;


   /**
* Unmapped property to handle file uploads
* @Vich\UploadableField(mapping="prototype_fichier", fileNameProperty="nomFichier")
*
* @var File $file
*/
private $file;


     /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Projet", inversedBy="prototypes")
     * @ORM\joinColumn(name="projet_id", referencedColumnName="id")
     */
private $projet;

/**
 * @Assert\NotBlank()
 * @ORM\OneToMany(targetEntity="AppBundle\Entity\PrototypeHasMedia", mappedBy="prototype",cascade={"persist","remove"} )
 */
protected $links;


/**
 * Remove widgetImages
 *
 * @param \Application\Sonata\MediaBundle\Entity\Media $widgetImages
 */
public function removeLinks(\AppBundle\Entity\PrototypeHasMedia $links)
{
$this->links->removeElement($links);
}


/**
 * Get widgetImages
 *
 * @return \Doctrine\Common\Collections\Collection
 */
public function getLinks()
{
return $this->links;
}


/**
 * {@inheritdoc}
 */
public function setLinks($links)
{
$this->links = new ArrayCollection();


foreach ($links as $prototype) {
    $this->addLinks($prototype);
}
}

/**
 * {@inheritdoc}
 */
public function addLinks(\AppBundle\Entity\PrototypeHasMedia $links)
{
$links->setPrototype($this);


$this->links[] = $links;
}


public function __construct()
{   
    $this->dateCreation =  new \DateTime("now");
    $this->nom = "";
    $this->description = " ";

}


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


/**
 * Get nom
 *
 * @return string 
 */
public function getNom()
{
    return $this->nom;
}

public function __toString()
{
return $this->getNom();
}

/**
 * Set nom
 *
 * @param string $nom
 * @return Prototype
 */
public function setNom($nom)
{
    $this->nom = $nom;

    return $this;
}


/**
 * Set description
 *
 * @param string $description
 * @return Prototype
 */
public function setDescription($description)
{
    $this->description = $description;

    return $this;
}

/**
 * Get description
 *
 * @return string 
 */
public function getDescription()
{
    return $this->description;
}

/**
 * Set dateCreation
 *
 * @param \DateTime $dateCreation
 * @return Prototype
 */
public function setDateCreation($dateCreation)
{
    $this->dateCreation = $dateCreation;

    return $this;
}

/**
 * Get dateCreation
 *
 * @return \DateTime 
 */
public function getDateCreation()
{
    return $this->dateCreation;
}


/**
 * Set projet
 *
 * @param \AppBundle\Entity\Projet $projet
 * @return Prototype
 */
public function setProjet(\AppBundle\Entity\Projet $projet = null)
{
    $this->projet = $projet;
    return $this;
}

/**
 * Get projet
 *
 * @return \AppBundle\Entity\Projet 
 */
public function getProjet()
{
    return $this->projet;
}



/**
 * If manually uploading a file (i.e. not using Symfony Form) ensure an instance
 *
 * @param File|\Symfony\Component\HttpFoundation\File\UploadedFile $file
 */
public function setFile(File $file = null)
{
    $this->file = $file;

    if ($file) {

        $this->updatedAt = new \DateTime('now');
    }
}

/**
 * @return File
 */
public function getFile()
{
    return $this->file;
}

/**
 * @param string $nomFichier
 */
public function setNomFichier($nomFichier)
{
    $this->nomFichier = $nomFichier;
}

/**
 * @return string
 */
public function getNomFichier()
{
    return $this->nomFichier;
}


/**
 * Set updatedAt
 *
 * @param \DateTime $updatedAt
 * @return Prototype
 */
public function setUpdatedAt($updatedAt)
{
    $this->updatedAt = $updatedAt;

    return $this;
}

/**
 * Get updatedAt
 *
 * @return \DateTime 
 */
public function getUpdatedAt()
{
    return $this->updatedAt;
}





/**
 * Add links
 *
 * @param \AppBundle\Entity\PrototypeHasMedia $links
 * @return Prototype
 */
public function addLink(\AppBundle\Entity\PrototypeHasMedia $links)
{
    $this->links[] = $links;

    return $this;
}

/**
 * Remove links
 *
 * @param \AppBundle\Entity\PrototypeHasMedia $links
 */
public function removeLink(\AppBundle\Entity\PrototypeHasMedia $links)
{
    $this->links->removeElement($links);
}
}

我希望这可以解决您的问题,您也可以在中找到示例代码的github链接answer@MKhalidJunaid谢谢你的回答我试着跟随链接但是我不能解决我的问题,正如我所说的,我想在每个部分中上传:在“tablette”和“mobile”中,就像在“desktop”中一样,这只是一个示例。从这里开始,你必须了解symfony和sonata是如何协同工作的。这里没有人会为你的应用程序编写完整的代码。你只需了解它们的工作方式,如果按照我之前的回答可以解决你的问题问题1部分,然后你可以使用相同的逻辑来实现这个功能,你的其他部分也一样,但要求一个完整的工作示例,我想没有太多的时间来写它没有冒犯,但尝试学习的逻辑,它是如何上传多个图像在1部分,然后实现其他部分,我希望我已经清除我的观点,我没有希望有人能为我写一个代码,我只需要一个提示来理解它是如何工作的!无论如何,感谢您的帮助。我希望这可以解决您的问题。您也可以在中找到示例代码的github链接answer@MKhalidJunaid谢谢你的回答我试着跟随链接但是我不能解决我的问题,正如我所说的,我想在每个部分中上传:在“tablette”和“mobile”中,就像在“desktop”中一样,这只是一个示例。从这里开始,你必须了解symfony和sonata是如何协同工作的。这里没有人会为你的应用程序编写完整的代码。你只需了解它们的工作方式,如果按照我之前的回答可以解决你的问题问题1部分,然后你可以使用相同的逻辑来实现这个功能,你的其他部分也一样,但要求一个完整的工作示例,我想没有太多的时间来写它没有冒犯,但尝试学习的逻辑,它是如何上传多个图像在1部分,然后实现其他部分,我希望我已经清除我的观点,我没有希望有人能为我写一个代码,我只需要一个提示来理解它是如何工作的!无论如何,谢谢你的帮助
<?php

namespace AppBundle\Entity;

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




/**
 * PrototypeHasMedia
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\PrototypeHasMediaRepository")
 */
class PrototypeHasMedia
{

    /**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
* @var \Application\Sonata\MediaBundle\Entity\Media
* @Assert\NotBlank()
* @ORM\ManyToOne(targetEntity="Application\Sonata\MediaBundle\Entity\Media", cascade={"persist"}, fetch="LAZY")
* @ORM\JoinColumn(name="media_id", referencedColumnName="id")
*/
protected $media;


/**
 * @var \AppBundle\Entity\Prototype
* @Assert\NotBlank()
 * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Prototype", cascade={"persist","remove"} ,inversedBy="links", fetch="LAZY" )
 * @ORM\JoinColumn(name="prototype_id", referencedColumnName="id",nullable=true)
 */
protected $prototype;






/**
 * @var string
 * @ORM\Column(name="link", type="text")
 */
private $link;

/**
 * @var string
 *
 * @ORM\Column(name="commentaire", type="string", length=255)
 */
private $commentaire;

/**
 * @var string
 *
 * @ORM\Column(name="typeDevice", type="string", length=255)
 */
private $typeDevice;


/**
 * Set media
 *
 * @param \Application\Sonata\MediaBundle\Entity\Media $media
 * @return PrototypeHasMedia
 */
public function setMedia(\Application\Sonata\MediaBundle\Entity\Media $media = null)
{
    $this->media = $media;

    return $this;
}

/**
 * Get media
 *
 * @return \Application\Sonata\MediaBundle\Entity\Media 
 */
public function getMedia()
{
    return $this->media;
}



/**
 * Set prototype
 *
 * @param \AppBundle\Entity\Prototype $prototype
 * @return PrototypeHasMedia
 */
public function setPrototype(\AppBundle\Entity\Prototype $prototype = null)
{
    $this->prototype = $prototype;

    return $this;
}

/**
 * Get prototype
 *
 * @return \AppBundle\Entity\Prototype 
 */
public function getPrototype()
{
    return $this->prototype;
}

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

    /**
 * Set link
 *
 * @param string $link
 * @return PrototypeHasMedia
 */
public function setLink($link)
{
    $this->link = $link;

    return $this;
}

/**
 * Get link
 *
 * @return string
 */
public function getLink()
{
    return $this->link;
}

/**
 * Set commentaire
 *
 * @param string $commentaire
 * @return Image
 */
public function setCommentaire($commentaire)
{
    $this->commentaire = $commentaire;

    return $this;
}

/**
 * Get commentaire
 *
 * @return string 
 */
public function getCommentaire()
{
    return $this->commentaire;
}

/**
 * Set typeDevice
 *
 * @param string $typeDevice
 * @return Image
 */
public function setTypeDevice($typeDevice)
{
    $this->typeDevice = $typeDevice;

    return $this;
}

/**
 * Get typeDevice
 *
 * @return string 
 */
public function getTypeDevice()
{
    return $this->typeDevice;
}
}
<?php


namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;





class PrototypeAdmin extends Admin
{   

protected function configureFormFields(FormMapper $formMapper)
{
    $formMapper
        ->with('Général')
            ->add('nom', 'text', array('label' => 'Nom'))
            ->add('description','text',array('label'=>'Description'))
            ->add('dateCreation', 'date', array('label' => 'Date de création'))

            ->add('projet','entity',array('class' => 'AppBundle\Entity\Projet'))
        ->end()

        ->with('Desktop')

           ->add('links', 'sonata_type_collection', array(
            'cascade_validation' => false,
            'type_options' => array('delete' => false),
        ), array(

            'edit' => 'inline',
            'inline' => 'table',
            'sortable' => 'position',
            'link_parameters' => array('context' => 'prototype'),
            'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
        )
    )


        ->end()

        ->with('Tablette')

           ->add('links', 'sonata_type_collection', array(
            'cascade_validation' => false,
            'type_options' => array('delete' => false),
        ), array(

            'edit' => 'inline',
            'inline' => 'table',
            'sortable' => 'position',
            'link_parameters' => array('context' => 'prototype'),
            'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
        )
    )
        ->end()


        ->with('Mobile')

            ->add('links', 'sonata_type_collection', array(
            'cascade_validation' => false,
            'type_options' => array('delete' => false),
        ), array(

            'edit' => 'inline',
            'inline' => 'table',
            'sortable' => 'position',
            'link_parameters' => array('context' => 'prototype'),
            'admin_code' => 'sonata.admin.prototype_has_media' /*here provide service name for junction admin */
        )
    )
        ->end()

        ->with('Dossier Complet')
            ->add('file', 'file', array('required' => false , 'label' => 'Dossier complet'))
        ->end()
     ;

}


protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
    $datagridMapper
        ->add('nom')
        ->add('dateCreation')
        ->add('projet.id')
    ;
}


protected function configureListFields(ListMapper $listMapper)
{   

    $listMapper
        ->add('nom')
        ->add('description')
        ->add('dateCreation')
        ->add('_action', 'actions', array(
                'actions' => array(
                'show' => array(),
                'delete' => array(),
            )
        ))

    ;
}



}
<?php


namespace AppBundle\Admin;

use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Show\ShowMapper;





class PrototypeHasMediaAdmin extends Admin
{ 

protected function configureFormFields(FormMapper $formMapper)
{
$link_parameters = array();

if ($this->hasParentFieldDescription()) {
    $link_parameters = $this->getParentFieldDescription()->getOption('link_parameters', array());
}

if ($this->hasRequest()) {
    $context = $this->getRequest()->get('context', null);

    if (null !== $context) {
        $link_parameters['context'] = $context;
    }
}

$formMapper

    ->add('media', 'sonata_type_model_list', array('required' => false), array(
        'link_parameters' => $link_parameters
    ))


    ->add('link', 'text', array('required' => false))
    ->add('commentaire', 'text', array('required' => false))
    ->add('typeDevice', 'text', array('required' => false))

    ->add('prototype','entity',array('class' => 'AppBundle\Entity\Prototype'))


;
}

}