views:

231

answers:

3

Using Symfony 1.4.5 with Doctrine

I have a model which includes an uploaded image as one of the columns - creating and updating the record is fine (using the doSave() method to deal with the upload and any changes to the file).

The problem I'm having is if the record is deleted - I want it to remove the associated file as well. But I can't find anyway to do this after several hours of hunting through documentation and Google.

Is there a way to specify some kind of post-delete code?

+2  A: 

It's a while since I last used Doctrine but I seem to remember there is a post delete hook function that you can use for this kind of thing. If you look into the source for the Doctrine base class you should be able to find the exact method name and usage.

EDIT: The method is postDelete() and is found in the Doctrine_Record class

Here's the section from the Symfony documentation that covers advanced Doctrine usage.

Colonel Sponsz
actually - that page doesn't go into anywhere near enough detail - and the doctrine API is equally useless.
HorusKol
What happens when you create a postDelete() method in your model class? Can you get that to take an action - even just log a message?
Colonel Sponsz
I can get code in the postDelete() method to run, no problem - but i don't see how to get the filename of the image that i need to delete...
HorusKol
Again, not sure how it works with Doctrine, but with Propel the class still exists with all the field values even after the data has been deleted from the database. One of these sounds like it will be the filename so you can reference it in the postDelete() method. A starting point would be to try something like logging the filename field from the record class in the postDelete() method - if you can do that then you can do the delete.
Colonel Sponsz
+2  A: 

Hijacking Colonel Sponsz's answer, the postDelete() method is definitely the way to go. +1 to him :-) But, you'll need to enable Doctrine callbacks in your config/ProjectConfiguration.class.php. Add this method:

public function configureDoctrine(Doctrine_Manager $manager)
{
  $manager->setAttribute(Doctrine_Core::ATTR_USE_DQL_CALLBACKS, true);
}

Clear your Symfony cache, and Doctrine will fire the callback methods such as postDelete() at the appropriate times.

richsage
thanks for the extra info - although, I think it's already sorted as when I put an echo in the postDelete method, I do get the expected output without having to explicitly add this to the config
HorusKol
Actually you only need to add this config when using DQL callbacks (preDqlSelect, preDqlUpdate and preDqlDelete)
DuoSRX
ahh my mistake - I'd never seemed to be able to get the post* methods working without this somehow. Maybe that's a hangover from my Doctrine 1.0 days... :-)
richsage
+2  A: 

Final solution:

in /lib/model/doctrine/Image.class.php

class Image extends BaseImage
{
  public function postDelete()
  {
    $filename = $this->getFilename();

    $filepath = sfConfig::get('sf_upload_dir') . '/' . $filename;
    @unlink($filepath);
  }
}

Thanks to Colonel Sponz for pointing me in the right direction

HorusKol
You can also handle it with Doctrine events, but for simple actions like deleting a record-specific file, your solution is just fine
Benoit
yeah, i read up on the events/listeners - if I start to get an unwieldy postDelete process I'll probably switch to that
HorusKol