Vichuploaderbundle: Embeddable object

Created on 17 Nov 2014  Â·  27Comments  Â·  Source: dustin10/VichUploaderBundle

Is there any way to get this bundle working on an embeddable object?
E.g. main entity with Uploadable annotation, Embedded sub-entity with UploadableField annotation

Enhancement

All 27 comments

In the current state of the bundle, I don't think so. The "uploadable fields" detection stays at the property level and can't go further.

In fact, I think it should work.

Embeddable objects will need to have the Uploadable annotation and be configured as usual, the only thing to do is properly create the form (ie: use an embedded form type). It should work as expected since it's conceptually the same as using relations.

@K-Phoen That's what I thought, but can't get it to work with Doctrine Embeddable and embedded form type. Problem seems to be that Embeddables are persisted in the same table, so prePersist / preUpdate won't be called separately.

Hi, 1.4 is still unable to work on an embeddable object ?

I have recipeEntity (main entity) with recipeStepEntity (sub entity).
recipeEntity have oneToOne relation with recipeImageEntity (who have uploadable annotation) and recipeStepEntity have oneToOne relation with recipeStepImageEntity (who have uploadable annotation)

Create and update recipe Form with recipeSteps (embedded collection) give me this error :
"Expected argument of type "AppBundle\Entity\RecipeStepImage or null", "AppBundle\Entity\RecipeImage" given"

@skhattane your case is involving relationships, not embedding.
Anyway it looks like you're doing something wrong.

@garak my bad. you're right.
Can you confirm that my usecase is possible with this bundle ?

Of course it is

Shame on me ! I used "RecipeImageType" instead "RecipeStepImageType" in my RecipeStepType...
Everything work perfectly now. Awesome Bundle !

For my knowledge : Is there a way to add Ajax Image Upload to work with this bundle or the approach have to be completely different ?

Hello!

Don't understand why bundle not working with ORM\Embeddable entity (but works without). Can anyone share some examples of code (didn't see them in manual)?

My codes are here (config, enitites, controller): https://gist.github.com/TrogWarZ/a134123a61867d42b26f7e56ea2a6255

There is no errors but pdf file is not uploaded. If i move anything about upload to MainEntity – works great. But this is not what i need.

What about your form?

I don't have form for this route. Uploaded file is grabbed from $paramFetcher->get('pdf').

If you provide an example of code, with your config, that is reproducible with a classic form, I can help you.

Which code do you need in addition to my snippet (link in my first comment)? There is part of my config.yml too. But i don't have forms – how do i provide them?

With regular entities without embeddable (when emb_file and emb_name is moved to MainEntity) – everything is working okay. I can provide working code without embeddable and forms if it helps.

I just need a reproducible code. Your current code is a bit "out of normal", e.g. it's not clear what ParamFetcher is nor why you use merge instead of persist.

what ParamFetcher is

ParamFetcher is from Symfony. It just validates params from request. In my case, it gets UploadedFile instance. See var_dump($pf->get('pdf')) example:

/var/www/myproject/api/src/AcmeBundle/Controller/MainEntityController.php:767:
class Symfony\Component\HttpFoundation\File\UploadedFile#14 (7) {
  private $test =>
  bool(false)
  private $originalName =>
  string(26) "test_pdf_valid.pdf"
  private $mimeType =>
  string(15) "application/pdf"
  private $size =>
  int(1036)
  private $error =>
  int(0)
  private $pathName =>
  string(14) "/tmp/phpxDUJwT"
  private $fileName =>
  string(9) "phpxDUJwT"
}

why you use merge instead of persist

There is merge because i'm updating entity that already exists in database (i get it from repository in line 26). If i need to create new entity, i will use persist.

Here is second gist: https://gist.github.com/TrogWarZ/eef344bf91f69756d7d9a3e374966227 The difference is in location of emb_file parameter – when it not in embedded entity, pdf file uploads and saves good.

But you don't need to merge an existing entity, unless you changed default Doctrine behaviour. Anyway, I can only help you if you provide a more standard use case

I didn't change doctrine behaviours.

But i got your request. Can you provide example of standard use with upload to doctrine embeddable entity? In docs i see just regular entity upload (which works fine for me too).

OK, I just tried with a minimal code, and embedded is working if:

  • you annotate with @Vich\Uploadable both embedding and embedded objects
  • you provide proxy setters and getters for the UploadableField and for its related string column

@garak Could you point me out how you made this work?

Sorry for waiting – i'm very busy right now to post minimal project with this – can post on the next week, i think. Just tested ideas from your comment and they're not working )-:

Thanks for gist – will try it!

This gist is not working. You should copy uploadable field, and its getter/setter, and getter/setter for fileNameProperty to parent object

/**
 * @Vich\Uploadable
 */
class User
{
    /**
     * @Vich\UploadableField(mapping="image", fileNameProperty="imageName")
     *
     * @var File
     */
    private $imageFile; // Not used

    /**
     * @param string $imageName
     *
     */
    public function setImageName($imageName)
    {
        $this->foo->setImageName($imageName);
    }
    /**
     * @return string|null
     */
    public function getImageName()
    {
        return $this->foo->getImageName();
    }

    /**
     * @param File $image
     */
    public function setImageFile(File $image = null)
    {
        $this->foo->setImageFile($image);
    }
    /**
     * @return File|null
     */
    public function getImageFile()
    {
        return $this->foo->getImageFile();
    }
}

I've thought about what I was trying to achieve by using Embeddable object and decided that it's not good approach after that. What we are trying to do here is have an abstraction for uploads and better way would be to create a mapped superclass for that (which works as expected)

/**
 * @Vich\Uploadable
 * @ORM\MappedSuperclass
 */
abstract class AbstractImage
{
    /**
     * @var File
     * @Vich\UploadableField(mapping="upload", fileNameProperty="path")
     * @ORM\Column(type="string")
     */
    protected $file;

    /**
     * @var string
     * @ORM\Column(type="string")
     */
    protected $path;

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

Is there any way this feature will be implemented? Now it's too redundant to use this bundle with embeddables.

BTW, there is bundle which support embeddables - atom-php/uploader-bundle (unfortunately without documentation in english)

It is implemented

I think it's little bit tricky, as I need to proxy every fields and methods related to file from embeddable to parent object

If you find a better solution, feel free to propose it

Was this page helpful?
0 / 5 - 0 ratings

Related issues

fleskalebas picture fleskalebas  Â·  6Comments

eved42 picture eved42  Â·  7Comments

cipherchien picture cipherchien  Â·  3Comments

petrjirasek picture petrjirasek  Â·  7Comments

Propscode picture Propscode  Â·  4Comments