dustin10 / VichUploaderBundle

A simple Symfony bundle to ease file uploads with ORM entities and ODM documents.
MIT License
1.84k stars 519 forks source link

Impossible to determine the class name. Either specify it explicitly or give an object #738

Closed phtmgt closed 7 years ago

phtmgt commented 7 years ago

The exception is thrown after the file is successfully uploaded and the system tries to redirect the user back to the page where the form is located.

This seems to be related to issue #737 (737 occurs with VichImageType and I temporarily overcome it by using VichFileType, which gets me here), as the stack trace includes this line:

$view->vars['download_uri'] = $this->resolveUriOption($options['download_uri'], $object, $form); in vendor/vich/uploader-bundle/Form/Type/VichFileType.php (line 159)

garak commented 7 years ago

Please check if latest release (1.6.1) is good for you

phtmgt commented 7 years ago

Nope, it does not solve it. But it solves issue #737.

garak commented 7 years ago

Please provide some informations to try to reproduce your issue

phtmgt commented 7 years ago

Function before Exception:

PropertyMappingFactory->getClassName(array('name' => 'X', 'phone' => '02233844648', 'slogan' => 'Never give up', 'info' => 'Yes!', 'address' => null, 'postcode' => 'SXX XXX', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), null)

Stack Trace:

RuntimeException: Impossible to determine the class name. Either specify it explicitly or give an object

at vendor/vich/uploader-bundle/Mapping/PropertyMappingFactory.php:204 at Vich\UploaderBundle\Mapping\PropertyMappingFactory->getClassName(array('name' => 'Georgi Abv', 'phone' => '02013844648', 'slogan' => 'Never give up', 'info' => 'If you want a neat and clean refurbishment i am the right person to hire. I have more than 20 years of experience in the home improvements. Yes!', 'address' => null, 'postcode' => 'SE11 5SN', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), null) (vendor/vich/uploader-bundle/Mapping/PropertyMappingFactory.php:103) at Vich\UploaderBundle\Mapping\PropertyMappingFactory->fromField(array('name' => 'Georgi Abv', 'phone' => '02013844648', 'slogan' => 'Never give up', 'info' => 'If you want a neat and clean refurbishment i am the right person to hire. I have more than 20 years of experience in the home improvements. Yes!', 'address' => null, 'postcode' => 'SE11 5SN', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), 'file', null) (vendor/vich/uploader-bundle/Storage/AbstractStorage.php:160) at Vich\UploaderBundle\Storage\AbstractStorage->getFilename(array('name' => 'Georgi Abv', 'phone' => '02013844648', 'slogan' => 'Never give up', 'info' => 'If you want a neat and clean refurbishment i am the right person to hire. I have more than 20 years of experience in the home improvements. Yes!', 'address' => null, 'postcode' => 'SE11 5SN', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), 'file', null) (vendor/vich/uploader-bundle/Storage/FileSystemStorage.php:54) at Vich\UploaderBundle\Storage\FileSystemStorage->resolveUri(array('name' => 'Georgi Abv', 'phone' => '02013844648', 'slogan' => 'Never give up', 'info' => 'If you want a neat and clean refurbishment i am the right person to hire. I have more than 20 years of experience in the home improvements. Yes!', 'address' => null, 'postcode' => 'SE11 5SN', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), 'file') (vendor/vich/uploader-bundle/Form/Type/VichFileType.php:178) at Vich\UploaderBundle\Form\Type\VichFileType->resolveUriOption(true, array('name' => 'Georgi Abv', 'phone' => '02013844648', 'slogan' => 'Never give up', 'info' => 'If you want a neat and clean refurbishment i am the right person to hire. I have more than 20 years of experience in the home improvements. Yes!', 'address' => null, 'postcode' => 'SE11 5SN', 'file' => object(UploadedFile), 'cover' => null, 'ins_policy' => null, 'files' => array(), 'subscribe' => false), object(Form)) (vendor/vich/uploader-bundle/Form/Type/VichImageType.php:72) at Vich\UploaderBundle\Form\Type\VichImageType->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => 'VichUploaderBundle', 'auto_initialize' => true, 'trim' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'sonata_admin' => null, 'sonata_field_description' => null, 'label_render' => true, 'sonata_help' => null, 'horizontal_label_class' => '', 'horizontal_label_offset_class' => '', 'horizontal_input_wrapper_class' => '', 'delete_label' => 'form.label.delete', 'imagine_pattern' => null, 'label' => false, 'attr' => array('class' => 'btn btn-default btn-file'), 'data_class' => null, 'empty_data' => object(Closure), 'required' => false, 'error_bubbling' => false, 'label_attr' => array('class' => 'btn btn-sm btn-info upload mt-1 mb-3 fa fa-2x fa-camera'), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'allow_delete' => true, 'download_link' => null, 'download_uri' => true, 'download_label' => 'download', 'image_uri' => true)) (vendor/symfony/symfony/src/Symfony/Component/Form/ResolvedFormType.php:148) at Symfony\Component\Form\ResolvedFormType->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => 'VichUploaderBundle', 'auto_initialize' => true, 'trim' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'sonata_admin' => null, 'sonata_field_description' => null, 'label_render' => true, 'sonata_help' => null, 'horizontal_label_class' => '', 'horizontal_label_offset_class' => '', 'horizontal_input_wrapper_class' => '', 'delete_label' => 'form.label.delete', 'imagine_pattern' => null, 'label' => false, 'attr' => array('class' => 'btn btn-default btn-file'), 'data_class' => null, 'empty_data' => object(Closure), 'required' => false, 'error_bubbling' => false, 'label_attr' => array('class' => 'btn btn-sm btn-info upload mt-1 mb-3 fa fa-2x fa-camera'), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'allow_delete' => true, 'download_link' => null, 'download_uri' => true, 'download_label' => 'download', 'image_uri' => true)) (vendor/symfony/symfony/src/Symfony/Component/Form/Extension/DataCollector/Proxy/ResolvedTypeDataCollectorProxy.php:110) at Symfony\Component\Form\Extension\DataCollector\Proxy\ResolvedTypeDataCollectorProxy->buildView(object(FormView), object(Form), array('block_name' => null, 'disabled' => false, 'label_format' => null, 'translation_domain' => 'VichUploaderBundle', 'auto_initialize' => true, 'trim' => true, 'property_path' => null, 'mapped' => true, 'by_reference' => true, 'inherit_data' => false, 'compound' => true, 'method' => 'POST', 'action' => '', 'post_max_size_message' => 'The uploaded file was too large. Please try to upload a smaller file.', 'error_mapping' => array(), 'invalid_message' => 'This value is not valid.', 'invalid_message_parameters' => array(), 'allow_extra_fields' => false, 'extra_fields_message' => 'This form should not contain extra fields.', 'csrf_protection' => true, 'csrf_field_name' => '_token', 'csrf_message' => 'The CSRF token is invalid. Please try to resubmit the form.', 'csrf_token_manager' => object(CsrfTokenManager), 'csrf_token_id' => null, 'sonata_admin' => null, 'sonata_field_description' => null, 'label_render' => true, 'sonata_help' => null, 'horizontal_label_class' => '', 'horizontal_label_offset_class' => '', 'horizontal_input_wrapper_class' => '', 'delete_label' => 'form.label.delete', 'imagine_pattern' => null, 'label' => false, 'attr' => array('class' => 'btn btn-default btn-file'), 'data_class' => null, 'empty_data' => object(Closure), 'required' => false, 'error_bubbling' => false, 'label_attr' => array('class' => 'btn btn-sm btn-info upload mt-1 mb-3 fa fa-2x fa-camera'), 'upload_max_size_message' => object(Closure), 'validation_groups' => null, 'constraints' => array(), 'allow_delete' => true, 'download_link' => null, 'download_uri' => true, 'download_label' => 'download', 'image_uri' => true)) (vendor/symfony/symfony/src/Symfony/Component/Form/Form.php:1019) at Symfony\Component\Form\Form->createView(object(FormView)) (vendor/symfony/symfony/src/Symfony/Component/Form/Form.php:1022) at Symfony\Component\Form\Form->createView() (src/AppBundle/Controller/MainController.php:1469) at AppBundle\Controller\MainController->editProfileAction(object(Request)) at call_user_func_array(array(object(MainController), 'editProfileAction'), array(object(Request))) (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:153) at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1) (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/HttpKernel.php:68) at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true) (vendor/symfony/symfony/src/Symfony/Component/HttpKernel/Kernel.php:171) at Symfony\Component\HttpKernel\Kernel->handle(object(Request)) (web/app_dev.php:30) at require('/Users/xxxxxxxx/PhpStormProjects/flattro.com/web/app_dev.php') (vendor/symfony/symfony/src/Symfony/Bundle/WebServerBundle/Resources/router.php:42)

Composer:

"require": {
        "php": "7.1",
        "symfony/symfony": "^3.1",
        "doctrine/orm": "^2.5",
        "doctrine/doctrine-bundle": "^1.6",
        "doctrine/doctrine-cache-bundle": "^1.3",
        "symfony/swiftmailer-bundle": "^2.3",
        "symfony/monolog-bundle": "^3.1",
        "sensio/distribution-bundle": "^5.0",
        "sensio/framework-extra-bundle": "^3.0",
        "knplabs/knp-markdown-bundle": "^1.5",
        "doctrine/doctrine-migrations-bundle": "^1.1",
        "sonata-project/admin-bundle": "^3.4",
        "sonata-project/doctrine-orm-admin-bundle": "^3.0",
        "jms/serializer": "^1.3",
        "symfony/twig-bundle": "^3.1",
        "symfony/framework-bundle": "^3.1",
        "friendsofsymfony/message-bundle": "^1.3",
        "friendsofsymfony/user-bundle": "^2.0",
        "excelwebzone/recaptcha-bundle": "^1.4",
        "braintree/braintree_php": "^3.15",
    "ekino/wordpress-bundle": "^1.2",
        "presta/sitemap-bundle": "^1.5",
    "whiteoctober/breadcrumbs-bundle": "^1.2",
        "endroid/twitter": "^1.3",
        "martin-georgiev/social-post-bundle": "^2.0",
        "friendsofsymfony/rest-bundle": "^2.1",
        "nelmio/cors-bundle": "^1.5",
        "jms/serializer-bundle": "^1.4",
        "vresh/twilio-bundle": "^1.0",
        "mremi/url-shortener-bundle": "^1.1",
        "symfony/web-server-bundle": "^3.3",
        "symfony/flex": "^1.0",
        "javiereguiluz/easyadmin-bundle": "^1.16",
        "vich/uploader-bundle": "^1.6",
        "liip/imagine-bundle": "^1.8"
    },

Form:

$form = $this->createFormBuilder()
                ->add('name', TextType::class, ['data' => $user->getName(), 'label' => 'Name', 'attr' => ['class' => 'form-control']])
                ->add('phone', TextType::class, ['data' => $user->getPhone(), 'label' => 'Phone Number', 'attr' => ['class' => 'form-control']])
                ->add('slogan', TextType::class, ['required' => false, 'data' => $user->getSlogan(), 'label' => 'Tagline', 'attr' => ['class' => 'form-control', 'placeholder' => '']])
                ->add('info', TextareaType::class, ['required' => false, 'data' => $user->getInfo(), 'label' => 'Additional Information', 'attr' => ['class' => 'form-control', 'rows' => 5]])
                // ->add('interestedin', ChoiceType::class, array('label' => false, 'data' => $selected, 'expanded' => true, 'multiple' => true, 'attr' => array('class' => 'row d-flex'), 'choices' => array_combine($interestedin, $interestedin)))
                ->add('address', TextType::class, ['required' => false, 'data' => $user->getAddress(), 'attr' => ['class' => 'form-control', 'placeholder' => 'Address']])
                ->add('postcode', TextType::class, ['data' => $user->getPostcode(), 'attr' => ['class' => 'form-control', 'placeholder' => 'Post Code e.g. SE23 3XJ']])
                ->add('file', VichImageType::class, ['required' => false, 'label_attr' => ['class' => 'btn btn-sm btn-info upload mt-1 mb-3 fa fa-2x fa-camera'], 'label' => false, 'attr' => ['class' => 'btn btn-default btn-file']])
                ->add('cover', VichImageType::class, ['required' => false, 'label_attr' => ['class' => 'upload btn btn-sm btn-info fa fa-2x fa-picture-o float-xs-right'], 'label' => false, 'attr' => ['class' => 'btn btn-default btn-file']])
                ->add('ins_policy', VichFileType::class, ['required' => false, 'label_attr' => ['class' => 'hidden-xs-up mb-3'], 'label' => 'Upload Insurance Policy', 'attr' => ['class' => 'form-control']])
                ->add('files', FileType::class, ['required' => false, 'multiple' => true, 'data_class' => null, 'label' => false, 'label_attr' => ['class' => 'upload btn btn-success'], 'attr' => ['class' => 'hidden-xs-up']])
                // ->add('vertx', HiddenType::class, array('data' => rtrim($vertx_val, ","), 'attr' => array('class' => 'form-control')))
                // ->add('verty', HiddenType::class, array('data' => rtrim($verty_val, ","), 'attr' => array('class' => 'form-control')))
                ->add('subscribe', CheckboxType::class, ['data' => $user->isSubscribed(), 'label' => false, 'attr' => ['class' => 'ml-1'], 'required' => false])
                ->add('save', SubmitType::class, ['label' => 'Submit', 'attr' => ['class' => 'btn btn-success click mt-1 mb-3']])
                ->getForm();

User entity:

namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Finder\Finder;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Acme\Resize;
use Symfony\Component\HttpFoundation\File\File;
use Vich\UploaderBundle\Mapping\Annotation as Vich;

/**
 * Users
 *
 * @ORM\Table(name="users", uniqueConstraints={@ORM\UniqueConstraint(name="UNIQ_1483A5E9E7927C74", columns={"email"})})
 * @ORM\Entity
 * @Vich\Uploadable
 * 
 */
class Users extends BaseUser
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    protected $id;

// ............................

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

    /**
     * @Vich\UploadableField(mapping="profile_images", fileNameProperty="profilePhoto")
     * @var File
     */
    private $profilePhotoFile;

    public function setProfilePhotoFile(File $profilePhoto = null)
    {
        $this->profilePhotoFile = $profilePhoto;

        // VERY IMPORTANT:
        // It is required that at least one field changes if you are using Doctrine,
        // otherwise the event listeners won't be called and the file is lost
        if ($profilePhoto) {
            // if 'updatedAt' is not defined in your entity, use another property
            $this->updatedAt = new \DateTime('now');
        }
    }

    public function getProfilePhotoFile()
    {
        return $this->profilePhotoFile;
    }

    public function setProfilePhoto($profilePhoto)
    {
        $this->profilePhoto = $profilePhoto;
    }

    public function getProfilePhoto()
    {
        return $this->profilePhoto;
    }

//...................

Action:

if ($form['file']->getData() != NULL) {
                $user->setProfilePhotoFile(($form['file']->getData()));

The errors occur with all instances of VichImageType and VichFile Type. However, the images and files are successfully uploaded.

garak commented 7 years ago

Can you try to rename your form field consistently with your entity property? So, name it "profilePhotoFile" and avoid to directly call setter.

phtmgt commented 7 years ago

If I don't directly call the setter, how do I go about uploading the image? Thanks.

Update: I tried your suggestion (setting form field consistently and not calling setter) and the same exception occurs.

garak commented 7 years ago

Just call $form->handleRequest($request), supposing that your entity is bound to your form

phtmgt commented 7 years ago

This works. Thank you. Now I will have to figure out how to have extra fields added to the mapped (bound) form.