1
votes

I have a Symfony 2.8 based project, I have Sonata admin bundle and Sonata user bundle well installed and all is working good.

I have an "Image" entity that it meant to contain my uploaded file. I followed the official Sonata tutorial to how to upload a file (https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_file_uploads.html) and all is working perfectly when I want to upload a file from the admin panel.

Now, I need a to offer the possibility to a simple connected user (not admin) to upload a file as well from a form.

Here's the example I have:

I have this "Offer" class that has an "Image" attribute:

class Offer {

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

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

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

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

    /**
     * @ORM\OneToOne(targetEntity="AIEM\PlatformBundle\Entity\Image", cascade={"all"})
     */
    private $image;

   //Getters and Setters
}

Before adding the "Image" entity, I persisted an offer using the classic way : Getting my data from the request (example : $offer->setTitre($request->request->get('title'));). But now since I have a OneToMany with a file, I don't know how to proceed.

I'll be grateful if you can share some ideas.

EDIT Here's my OfferAdmin, and it's working perfectly in sonata admin

class OfferAdmin extends Admin {

    protected function configureFormFields(FormMapper $formMapper) {
        $formMapper->add('title', 'text')
                ->add('image', 'sonata_type_admin')
                ->add('body', 'textarea', array("attr" => array("class" => "ckeditor")));
    }

    protected function configureDatagridFilters(DatagridMapper $datagridMapper) {
        $datagridMapper->add('titre')
                ->add('date');
    }

    protected function configureListFields(ListMapper $listMapper) {
        $listMapper->addIdentifier('titre');
    }

    public function prePersist($page) {
        $this->manageEmbeddedImageAdmins($page);
    }

    public function preUpdate($page) {
        $this->manageEmbeddedImageAdmins($page);
    }

    private function manageEmbeddedImageAdmins($page) {

        /** @var Image $image */
        $image = $page->getImage();

        if ($image) {
            if ($image->getFile()) {
                // update the Image to trigger file management
                $image->refreshUpdated();
            } elseif (!$image->getFile() && !$image->getFilename()) {
                // prevent Sf/Sonata trying to create and persist an empty Image
                $page->$setImage(null);
            }
        }
    }

}

And the form I want the user to add the file from looks like this

<form method="post" action="{{ path('aiem_platform_add_offer')}}">
    <div class="form-group">
        <label for="title">Title</label>
        <input type="text" class="form-control" id="title" name="title" placeholder="Title">
    </div>


    <div class="form-group">
        <input type="file" class="form-control" id="myFile" name="myFile">
    </div>

    <div class="form-group">
        <label for="contenu">Contenu</label>
        <textarea class="form-control ckeditor" id="body" name="body"></textarea>
    </div>

    <button type="submit" class="btn btn-default">Add</button>
</form>

Thank you

1
Is your file upload working is sonata admin ? From which context do you want handle the file upload ? Please add the method in your question. - chalasr
@chalasr : I edited my question and added OfferAdmin. And yes, it's working perfectly in the admin panel, I can add an offer with an 'Image' and the file is well uploaded and all is good. Now I want to add an offer from outside the admin panel. I want a simple connected user to be able to add the file from a simple form (also added to question) - Auranx

1 Answers

1
votes

Use something like the following for the form handling method :

public function handleOfferForm(Request $request)
{
    $em = $this->getDoctrine()->getManager();
    $offer = new Offer();
    // Handle your basic fields using $request->request->get('field')

    $file = $request->files->get('myFile');

    $image = new Image();
    $image->setFile($file);
    // Set your other fields ...
    $image->upload(); // Image should have this method (from the sonata doc)

    $offer->addImage($image);

    $em->persist($offer);
    $em->flush();

    // Return a redirection or which response you want 
}

Also, create the corresponding POST route in your routing (named like in your form action), and it should works.

EDIT

Make your form open tag like follows :

<form enctype="multipart/form-data">