Search code examples
phpsymfonysonata-admin

Get path in entity with Sonata and Symfony 3


I need to get the path of the web/uploads folder from the entity, this is my code:

<?php

class Product{
  protected $id;
  ...
  protected $imageName;

  protected $file;
  ...
  public function getAbsolutePath(){
      return null === $this->imageName ? null : $this->getUploadRootDir().'/'.$this->imageName;
  }

  public function getWebPath(){
    return null === $this->imageName ? null : $this->getUploadDir().'/'.$this->imageName;
  }

  protected function getUploadRootDir($basepath){
    // the absolute directory path where uploaded documents should be saved
    return $basepath.$this->getUploadDir();
  }

  protected function getUploadDir(){
    // get rid of the __DIR__ so it doesn't screw when displaying uploaded doc/image in the view.
    return 'uploads/products';
  }

  public function upload($basepath){
    // the file property can be empty if the field is not required
    if (null === $this->file) {
        return;
    }

    if (null === $basepath) {
        return;
    }

    // we use the original file name here but you should
    // sanitize it at least to avoid any security issues

    // move takes the target directory and then the target filename to move to
    $this->file->move($this->getUploadRootDir($basepath), $this->file->getClientOriginalName());

    // set the path property to the filename where you'ved saved the file
    $this->setImageName($this->file->getClientOriginalName());

    // clean up the file property as you won't need it anymore
    $this->file = null;
  }
}

And this is the Admin class

<?php

class Product extends Admin {
...
  protected function configureFormFields(FormMapper $formMapper) {
    $formMapper
            ->with('General')
...
            ->add('file', 'file', array('required' => false))
...
            ->end()
    ;
  }
...
  public function prePersist($product) {
    $this->saveFile($product);
  }

  public function preUpdate($product) {
    $this->saveFile($product);
  }

  public function saveFile($product) {
    $basepath = $this->getRequest()->getBasePath();
    $product->upload($basepath);
  }
}

The name of the file is updated well, but the image don't copy at the path web/uploads. source: http://blog.code4hire.com/2011/08/symfony2-sonata-admin-bundle-and-file-uploads/


Solution

  • I have solved this way

    <?php
    
    class Product{
    
      const SERVER_PATH_TO_IMAGE_FOLDER = '/server/path/to/images';
    
      protected $id;
    ...
      protected $imageName;
    
      protected $file;
    ...
    
      public function upload($basepath){
        if (null === $this->file) {
            return;
        }
    
        $this->file->move(self::SERVER_PATH_TO_IMAGE_FOLDER, $this->file->getClientOriginalName());
    
        // set the path property to the filename where you'ved saved the file
        $this->setImageName($this->file->getClientOriginalName());
    
        // clean up the file property as you won't need it anymore
        $this->file = null;
      }
    }
    

    And the admin class:

    <?php
    
    class Product extends Admin {
    ...
      protected function configureFormFields(FormMapper $formMapper) {
        $formMapper
                ->with('General')
    ...
                ->add('file', 'file', array('required' => false))
    ...
                ->end()
        ;
      }
    ...
      public function prePersist($product) {
        $product->upload();
      }
    
    }