简体   繁体   中英

How to stop doctrine from updating my entity during is lifecycle

I'm working on one of my entity in Symfony 2. I'm trying to make that if I upload a zip file, my entity open the zip file, find a file with the name _projet and than generate a name. The thing is that I need to stop the entire uploading and updating process if an error happen, like it isn't able to open the zip or that it doesn't find a file named _projet. I'm basically tweaking what is showed in this cookbook:

http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html

It is said at one point that:

// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error

So I want to do the same thing if something bad happens and maybe somehow tell my controller that there was a problem (I use flush() in my controller)

Here is my code so far:

/**
 * @ORM\PrePersist()
 * @ORM\PreUpdate()
 */
public function preUpload()
{
    //If there is a file for the project
    if (null !== $this->getFichierFile())
    {
        //Create uniq name
        $nomFichierProjet = sha1(uniqid(mt_rand(), true));

        //Check if it's a zip
        if($this->getFichierFile()->guessExtension()=="zip")
        {
            //New zip archive
            $zip=new ZipArchive;

            //While indicate if an error happen
            $erreur=true;

            //Open the zip
            if($zip->open($formulaire['fichierFile']->getData())===TRUE)
            {
                //Loop throw file in zip
                for($i=0; $i<$zip->numFiles; $i++) 
                {
                    //If the file is named _projet
                    if(pathinfo($zip->getNameIndex($i))['filename']=="_projet")
                    {
                        //Crate the file name
                        $this->fichier=$nomFichierProjet.'.'.pathinfo($zip->getNameIndex($i))['extension'];

                        //No error
                        $erreur=false;

                        //Quit loop
                        break;
                    }
                }
            }

            //If an error happen
            if($erreur)
            {
                //Prevent persisting
            }

        }
        else
        {
            //Create file name
            $this->fichier = $nomFichierProjet.'.'.$this->getFichierFile()->guessExtension();
        }
    }
}

You can simply do that, defining an custom Upload exception. You should throw it if an error occurred during handling the upload and catch it in your controller and handle the error:

So, create an exception by extending the base Exception

<?php
// path/to/your/AppBundle/Exception
namespace AppBundle\Exception;

class UploadException extends \Exception{
    // Nothing special here, but you also can collect
    // more information if you want, by overriding the 
    // constructor, or use public properties or getter
    // and setter. it all up to you ;)
}

throw it in your entity if there are some error during handling the upload

//in your Entity::preUpload() method
// [...]

//If an error happen
if($erreur)
{
    // Prevent persisting
    // It does not matter, which exception is thrown here, you could even
    // throw a "normal" `\Exception`, but for better error handling you
    // should use your own.
    throw new \AppBundle\Exception\UploadException('An error occourred during upload!');
}

and catch and handle it in your controller:

// in your controller
try{
    $em->persist($entity);
    $em->flush();
} catch (\AppBundle\Exception\UploadException $e){
    // Handle the upload error
    // Catching your own exception (`\AppBundle\Exception\UploadException`)
    // you are sure now that the error occurred during your upload handling.
}

Happy coding

Flush's call is the only thing that provides update on your entity, so typicaly I do it like skroczek. If you don't want to trigger exceptions you can do it with array like :

$errors = array();
//zip not found
errors[] = "zip not found";
if (count($errors) == 0) {
  $em->persist($entity);
  $em->flush();
}

Does that help you?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM