sameer manek
sameer manek

Reputation: 763

Symfony2: cannot upload an image to database

I am trying to add a new product to my database via this form:

<form id="add_product" method="post" action="{{ path('company_addp') }}">
        <span class="fa fa-times close" onclick="new_prod()"></span><br />
        <span>Add new product:</span>
        <div id="holder">

        </div>
        <label for="img" style="display:inline-block; color: #5eb5e0; cursor: pointer;">click here</label> to add a picture
        <input type="file" name="upload" id="img" style="display: none;" />
        <input type="text" placeholder="product name" name="name">
        <textarea placeholder="product description" name="desc"></textarea>
        <input type="text" placeholder="price" name="price"/>
        <input type="text" placeholder="quantity" name="qty" />
        <input type="text" placeholder="category" name="type" />
        <input type="submit" value="add product" />
    </form>

via this controller:

    public function addproductAction(Request $request){
        if($request->getMethod() == "POST"){
            $session = $request->getSession();
            $id = $session->get('id');
            $type = $session->get('type');
            if($type == "comp"){

                $em = $this->getDoctrine()->getManager();
                $prod = new Products();
                $prod->setName($request->get('name'));
                $prod->setCompany($id);
                $prod->setDsc($request->get('desc'));
                $prod->setPrice($request->get('price'));
                $prod->setStock($request->get('qty'));
                $prod->setType($request->get('type'));
                $file = $request->files->get('upload');

                if(!is_null($file)){
                    // generate a random name for the file but keep the extension
                    $filename = uniqid().".".$file->getClientOriginalExtension();
                    $path = "assets/product";
                    $file->move($path,$filename); // move the file to a path
                    $prod->setPic($filename);
                    $em->flush();
                }

                $em->persist($prod);
                $em->flush();
                return $this->redirectToRoute('company_homepage');
            }
        }
        else{
            return new Response('you are trying to access wrong route!');
        }
    }
}

but somehow null is being returned in place of the name of the pic, as of this is the msg I am getting when I submit the form:

An exception occurred while executing 'INSERT INTO products (name, dsc, pic, company, type, price, sold, stock) VALUES (?, ?, ?, ?, ?, ?, ?, ?)' with params ["johnsonn's baby shampoo", "it is a baby shampoo and does not hurt the eyes, also good for hair", null, 2, "baby products", "150", null, "990"]:

SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'pic' cannot be null

I dont know what the problem is as I am not getting this error for other place where I am updateing the pic with the same code

Upvotes: 0

Views: 227

Answers (1)

user1516851
user1516851

Reputation:

I would implement the logic of the file-upload in your entity because of redundancy problems with the code. Controllers should be tiny and don't have logic to handle file-uploads.

<?php
// src/AppBundle/Bundle/Entity/Image.php

const SERVER_PATH_TO_IMAGE_FOLDER = '/server/path/to/images';

/**
 * Unmapped property to handle file uploads
 */
private $file;

/**
 * Sets file.
 *
 * @param UploadedFile $file
 */
public function setFile(UploadedFile $file = null)
{
    $this->file = $file;
}

/**
 * Get file.
 *
 * @return UploadedFile
 */
public function getFile()
{
    return $this->file;
}

/**
 * Manages the copying of the file to the relevant place on the server
 */
public function upload()
{
    // the file property can be empty if the field is not required
    if (null === $this->getFile()) {
        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 target filename as params
    $this->getFile()->move(
        self::SERVER_PATH_TO_IMAGE_FOLDER,
        $this->getFile()->getClientOriginalName()
    );

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

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

/**
 * Lifecycle callback to upload the file to the server
 */
public function lifecycleFileUpload()
{
    $this->upload();
}

/**
 * Updates the hash value to force the preUpdate and postUpdate events to fire
 */
public function refreshUpdated()
{
    $this->setUpdated(new \DateTime());
}

// ... the rest of your class lives under here, including the generated fields
//     such as filename and updated

https://sonata-project.org/bundles/admin/master/doc/cookbook/recipe_file_uploads.html

However.

Set this attribute to your form tag:

enctype="multipart/form-data"

cause this mistake I would suggest you using FormTypes of the Symfony Form Component

http://symfony.com/doc/current/book/forms.html

Why do you flush the entity manager at this line

$prod->setPic($filename);
$em->flush(); // <-

Do you check the return statement of the move method on uploaded File?

Upvotes: 1

Related Questions