symfony2admingenerator / AvocodeFormExtensionsBundle

(old-legacy) Symfony2 form extensions for Admingenerator project (also working standalone!)
Other
48 stars 31 forks source link

Upload collection error #15

Closed denys281 closed 11 years ago

denys281 commented 11 years ago

When I submit my form I have error:

Warning: Invalid argument supplied for foreach() in .../vendor/avocode/form-extensions-bundle/Avocode/FormExtensionsBundle/Form/EventListener/CollectionUploadSubscriber.php line 122

And when I upload images, there are no preview for images.

My config:

gallery:
        label:            Зображення
        dbType:           collection
        formType:         collection_upload
        addFormOptions:
          nameable:         true
          nameable_field:   name
          editable:         [name]
          type:             \Webmil\Frontend\AboutBundle\Form\AboutGalleryType
          acceptFileTypes:            /(\.|\/)(gif|jpe?g|png)$/i
          previewSourceFileTypes:     /^image\/(gif|jpeg|png)$/
          previewAsCanvas:            true
          prependFiles:               false 
          allow_add:                  true
          allow_delete:               true
          error_bubbling:   false
          options:
            data_class:    \Webmil\Frontend\AboutBundle\Entity\AboutGallery       

My form type:

  public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('id', null)
            ->add('name', null)
        ;
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Webmil\Frontend\AboutBundle\Entity\AboutGallery'
        ));
    }

    public function getName()
    {
        return 'webmil_frontend_aboutbundle_aboutgallerytype';
    }
ioleo commented 11 years ago

@denys281 Show your Gallery entity class

denys281 commented 11 years ago

@loostro

namespace Webmil\Frontend\AboutBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Knp\DoctrineBehaviors\Model as ORMBehaviors;
use Avocode\FormExtensionsBundle\Form\Model\UploadCollectionFileInterface;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * AboutGallery
 *
 * @ORM\Table(name="about_gallery")
 * @ORM\Entity(repositoryClass="Webmil\Frontend\AboutBundle\Entity\AboutGalleryRepository")
 * @Vich\Uploadable
 */
class AboutGallery implements UploadCollectionFileInterface
{
  use ORMBehaviors\Timestampable\Timestampable
  ;
  /**
   * @var integer
   *
   * @ORM\Column(name="id", type="integer")
   * @ORM\Id
   * @ORM\GeneratedValue(strategy="AUTO")
   */
  private $id;

    /**
   * @var string
   *
   * @ORM\Column(name="name", type="string", length=255, nullable=true)
   */
  private $name;
   /**
   * @Assert\File(
   *     maxSize="10M",
   *     mimeTypes={"image/png", "image/jpeg", "image/pjpeg"}
   * )
   * @Vich\UploadableField(mapping="about_gallery", fileNameProperty="imageName")
   *
   * @var File $file
   */
  public $file;

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

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

  /**
   * @ORM\ManyToOne(targetEntity="About", inversedBy="gallery")
   * @ORM\JoinColumn(name="about_id", referencedColumnName="id")
   */
  private $about;

  /**
   * Set imageName
   *
   * @param string $imageName
   * @return AboutGallery
   */
  public function setImageName($imageName)
  {
    $this->imageName = $imageName;

    return $this;
  }

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

  /**
   * Set about
   *
   * @param \Webmil\Frontend\AboutBundle\Entity\About $about
   * @return Model
   */
  public function setAbout(\Webmil\Frontend\AboutBundle\Entity\About $about)
  {
    $this->about = $about;
    return $this;
  }

  /**
   * Get news
   *
   * @return \Webmil\Frontend\AboutBundle\Entity\About
   */
  public function getAbout()
  {
    return $this->about;
  }

  /**
   * Get size
   *
   * @return integer
   */
  public function getSize()
  {
    return $this->file->getSize();
  }

  /**
   * @inheritDoc
   */
  public function setParent($parent)
  {
    // note FileInterface has changed, now it simply requiers a setParent method
    // which in my case simply calls setAlbum (becouse my parent is named "news")
    $this->setAbout($parent);
  }

  public function getPreview()
  {
    return (preg_match('/image\/.*/i', $this->file->getMimeType()));
  }

  public function setFile(\Symfony\Component\HttpFoundation\File\File $file)
  {
    $this->file = $file;
    return $this;
  }

  /**
   * Get file
   * 
   * @return Symfony\Component\HttpFoundation\File\File
   */
  public function getFile()
  {
    return $this->file;
  }

   /**
   * Set name
   *
   * @param string $name
   * @return AboutGallery
   */
  public function setName($name) {
    $this->name = $name;

    return $this;
  }

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

}
ioleo commented 11 years ago

@denys281 not this class, the parent class (the one that has gallery field)

denys281 commented 11 years ago

@loostro thank you! I review my class and find bug, I forget add annotation relations to the gallery field. But when I want delete file I have js error

TypeError: that is undefined
 that._adjustMaxNumberOfFiles(1); // line 144

And when I want save entry without add any files I have htm5 validation:

Please select a file
ioleo commented 11 years ago

@denys281 atm i have no idea why ur getting that error

about html5 validation -> it should be disabled, i'll study a fix

denys281 commented 11 years ago

@loostro about uploader. Error in collection.upload.js

 destroy: function (e, data) {
                    var that = $(this).data('fileupload');
                    that._adjustMaxNumberOfFiles(1);
                    that._transition(data.context).done(
                        function () {
                            $(this).remove();
                            that._trigger('destroyed', e, data);
                        }
                    );
                },

All buttons (delete, upload) are in td with class delete.

Click on delete btn or in other area in .delete td, call destroy function. And $(this) is div with id edit_about_gallery_widget_container . That div has not any data attribute fileupload. Class .delete

    <td class="delete">
      <div class="btn-toolbar">
        <a href="/uploads/about/51f0d84a74bd5.jpeg" target="_blank" class="btn btn-info">
          <i class="icon-download icon-white"></i><span> Download</span>
        </a>
        <button class="btn btn-danger">
          <i class="icon-trash icon-white"></i><span> Delete</span>
        </button>
        <span class="btn btn-toggle disabled input-append">
          <input type="checkbox" value="1" name="delete">
        </span>
      </div>
    </td>
ioleo commented 11 years ago

@denys281 yes I'm also experiencing this error. I'm investigating a fix now.

ioleo commented 11 years ago

Ok, I know whats wrong. When moveing files out of AdmingeneratorBundle I also updated the blueimp plugin that this widget uses. The newer version has removed the _adjustMaxNumberOfFiles() function instead jquery.fileupload-validate.js was added. I'm testing right now how to achieve the same functionality with the new version.

ioleo commented 11 years ago

Testing fixes in fix-collection-upload branch.

ioleo commented 11 years ago

It seems blueimp went through a major refactoring that I've missed. Currently updateing all options and docs to match new blueimp structure.

ioleo commented 11 years ago

Blueimp has added (on user side) audio and video preview :) I will definately study how to implement them in future, but right now only image preview will be supported. Closeing in to merge.

ioleo commented 11 years ago

Ok, so file upload is fixed, sortable is also fixed, now there are 2 more issues:

will fininish fixes tomorrow

denys281 commented 11 years ago

@loostro you're cool. very big thak you!.

ioleo commented 11 years ago

God, its 40 Celsius degrees in shadow today..

denys281 commented 11 years ago

@loostro yes, but air conditioner save us :)

ioleo commented 11 years ago

Delete issue fixed. Will also change the sortable handle from the whole element to a handle icon and prevent sending extra files.

@denys281 I work at home (have my own company) and I have no air conditioner! :P Must add that to "to buy" list.

ioleo commented 11 years ago

@denys281 soon the fixes will be merged. About your issue with thumbnails - there are 2 types of files in this widget:

Widget options are for client-side thumbnail generation (done by JS library blueimp/jQuery-file-upload).

For server-side thumbnail generation you can use a library like liip/imagine-bundle or avalanche/imagine-bundle (i recommend liip). For more info about this read previewFilter option documentation

denys281 commented 11 years ago

@loostro after save it is all ok, but after load with uploader I can't see image preview. And if exist any dependency with avalanche/imagine-bundle ?

ioleo commented 11 years ago

@denys281 I don't understand that:

after save it is all ok, but after load with uploader ...

could you elaborate?

Also please read the previewFilter option documentation it explains how to set up server-side thumbnails.

denys281 commented 11 years ago

@loostro When I upload photo first time, I don't see preview. Than, I push save btn, my image successful saved, and I can see all previews.

My options

         previewMaxWidth:            100
          previewMaxHeight:           100
          previewAsCanvas:            true
          prependFiles:               false 
          allow_add:                  true
          allow_delete:               true

If previewFilter is required options ?

ioleo commented 11 years ago

@denys281 your preview is loading the FULL image in an img tag with width and height attributes. This causes the user browser to download full-size image for the preview. If you want to preview only a thumbnail, you must use some library to generate a thumbnail for your image.

ioleo commented 11 years ago

@denys281 loadImageFileTypes doc sais Preview images are only displayed for browsers supporting the URL or webkitURL APIs or the readAsDataURL method of the FileReader interface.

denys281 commented 11 years ago

@loostro I can select only one file. Do you have same problem? And when I add for example three files (three times, because I can not add more then one file ) it save only one file.

ioleo commented 11 years ago

@denys281 paste your config (generator.yml), I'll try to reproduce this

denys281 commented 11 years ago

@loostro my gallery config:

       gallery:
        label:            Зображення
        dbType:           collection
        formType:         collection_upload
        addFormOptions:
          maxNumberOfFiles: 20
          nameable:         true
          nameable_field:   name
          editable:         [name]
          type:             \Webmil\Frontend\AboutBundle\Form\AboutGalleryType
          acceptFileTypes:            /(\.|\/)(gif|jpe?g|png)$/i
          loadImageFileTypes:     /^image\/(gif|jpeg|png)$/
          previewMaxWidth:            100
          previewMaxHeight:           100
          previewAsCanvas:            true
          prependFiles:               false 
          allow_add:                  true
          allow_delete:               true
          options:
            data_class:    \Webmil\Frontend\AboutBundle\Entity\AboutGallery    
ioleo commented 11 years ago

Reopening issue. I'll try to check that today.

denys281 commented 11 years ago

@loostro tmp fix. In form_widgets.html.html change line 115.

<input multiple type="file" {{ block('widget_attributes') }} />

ioleo commented 11 years ago

@denys281 this is weird, the multiple attribute should be added by {{ block('widget_attributes') }}

denys281 commented 11 years ago

@loostro yes. And where we set widget_attributes ?)

ioleo commented 11 years ago

@denys281 I just checked and.. we don't ! I was sure we do... but I confused that with "multipart" option. I'll make a fix now.

EDIT: added fix here

ioleo commented 11 years ago

Thanks for reporting this!

denys281 commented 11 years ago

@loostro thank you for fix.

denys281 commented 11 years ago

@loostro I was on vacation, so I can not test fix. Today I tested it, and it still don't add multiple option.

ioleo commented 11 years ago

Did you clear your cache?

The option is defined here and it should be rendered by {{ block('widget_attributes') }} here

denys281 commented 11 years ago

Yes, I cleared cache. Do this fix work for you?

denys281 commented 11 years ago

@loostro in old version, when upload type was part of Admingenerator, we have just:

<input type="file" {{ block('widget_attributes') }} multiple />

so I think it is better to make this, because current version doesn't work :(

ioleo commented 11 years ago

Does it work for you when you add multiple?

denys281 commented 11 years ago

@loostro yes it works. I think that I find another bug when multiple works. For example you add "n" photo, than without saving you add another "k" photo. Then after saving, saves only "k" photo.

stajnert commented 11 years ago

I have the same error. I can add only one photo when I try add multiple - only the last one is uploaded.

ioleo commented 11 years ago

Reopening to take a closer look again.

sescandell commented 11 years ago

This issue is normally closed now thanks to @loostro commit and PR #70.

Don't hesitate to reopen it if I'm wrong,

ioleo commented 11 years ago

@sescandell @panslaw @denys281 i believe commit 5174502fbcc9253d7668ff504c5064319620244b is no longer necessary -> the error was in Admingenerator see #680 for details

satiricon commented 11 years ago

@loostro But without the multiple attribute you can't select more than one file in the browse dialog. It's quite necessary I think.

sescandell commented 11 years ago

I agree with @satiricon That's why I let the attribute in my last contribution