How should I perform post persive / update actions in doctrine 2.1 that include re-saving in db?

Using doctrine 2.1 (and zend framework 1.11, and not that it is important for this question), how can I perform post persist and post update actions, which includes re-saving in db?

For example, creating a unique token based on the just generated primary key or creating a thumbnail for the uploaded image (which does not really require re-saving in db, but still)?


EDIT - explain, will we?

The above question is actually a question of two scenarios. Both scenarios relate to the following state:

Say I have a User object. When an object turns red after it is marked for saving, it will have a normal automatically generated mysql identifier - this means that the number of starts usually starts with 1, 2, 3, etc.

Each user can upload an image that he can use in the application, which will also have a record in db. So I have another object called Image . Each Image object also has an automatically generated identifier - the same methodology as the user identifier.

Now here are the scripts:

  • When a user uploads an image, I want to create a thumbnail for this image right after it is saved in db. This should happen for every new or updated image.
    Because we try to stay smart, I don’t want the code to generate a thumbnail so it is written like this:

    $ image = new Image (); ...
    $ EntityManager-> are saved ($ images);
    $ EntityManager-> flush ();
    callToFunctionThatGeneratesThumbnailOnImage ($ image);

    but I want this to happen automatically when the object is saved (well, on the edge of the saved object), like the prePersist or preUpdate .

  • Since the user uploaded the image, he receives a link to it. It probably looks something like this: http://www.mysite.com/showImage?id=[IMAGEID] .
    This allows someone to simply change the image in this link and see other user images.
    Therefore, to prevent such a thing, I want to create a unique token for each image. Since it really doesn't have to be complicated, I was thinking about using the md5 value of the image id with some salt.
    But for this, I need to have an identifier for this image, which I will only have after flushing the saved object, and then generate md5, and then save it in db again.

Understand that image links must be publicly available, so I can't just let an authenticated user view them using any permission rules.

+6
source share
2 answers

In the end, I listened to @Arms, who commented on the question.
I began to use the service level to perform such actions.
So now I have a service level method that creates an Image object. After it calls persist and flush, it calls a method that generates a thumbnail.

The Service Layer template is a good solution for such things.

+2
source

You probably already know about Doctrine events. What could you do:

Use the postPersist event postPersist . This happens after inserting the database, so automatically generated identifiers are available.

The EventManager class can help you with this:

 class MyEventListener { public function postPersist(LifecycleEventArgs $eventArgs) { // in a listener you have the entity instance and the // EntityManager available via the event arguments $entity = $eventArgs->getEntity(); $em = $eventArgs->getEntityManager(); if ($entity instanceof User) { // do some stuff } } } $eventManager = $em->getEventManager(): $eventManager->addEventListener(Events::postPersist, new MyEventListener()); 

Be sure to check e. d. if User already has Image , otherwise, if you call a flash in the event listener, you may end up in an infinite loop.

Of course, you can also make your User class aware of this operation of creating an image with an inline postPersist eventHandler and add @HasLifecycleCallbacks to your mapping and then always paint over at the end of the e request. d. in the shutdown function, but, in my opinion, this type of material belongs to an individual listener. YMMV.

If you need an identifier for an object before cleaning, immediately after creating the object, another approach is to create identifiers for objects inside your application, e. d. using uuids .

Now you can do something like:

 class Entity { public function __construct() { $this->id = uuid_create(); } } 

Now you already have the identifier set when you just do:

 $e = new Entity(); 

And you only need to call EntityManager :: flush at the end of the request

+7
source

Source: https://habr.com/ru/post/897152/


All Articles