pimcore/pimcore — pull request #7 by subspacer (2012-01-08 09:10:14+00:00)
Title: Revised file management and new file hooks

My company hosts sites using Amazon EC2. In order to scale horizontally, we need to synchronize pimcore's files on multiple app servers without using NFS. After some prior discussion, it seems like adding new hooks would be the best approach to solve this problem. This would allow plugins to interact with pimcore's file lifecycle. For this purpose, I am proposing two hooks:

preFileChange

Called before a file is created, modified, or deleted.

postFileChange

Called after a file is created, modified, or deleted.

The following is an example of how one of the hooks is used in a plugin:

```php
public function postFileChange(Pimcore_Event_File $event) {
$file = $event->getFile();
$filetype = get_class($file);
$filename = $file->getPath();
$eventType = get_class($event); //Pimcore_Event_File_Created, Modified, or Deleted
}
```

These hooks _could_ be added around every file save operation in pimcore like this:

```php
$file = new Pimcore_File($filepath);
$file->dispatchPreEvent(Pimcore_Event::EVENT_TYPE_FILE_MODIFIED);
file_put_contents($filepath, $contents);
$file->dispatchPostEvent(Pimcore_Event::EVENT_TYPE_FILE_MODIFIED);
```

But this would require adding the same code around every file operation, which seems redundant. Instead, I saw an opportunity for improving pimcore's file management by unifying file operations into the Pimcore_File class. That way, the above code would become:

```php
$file = new Pimcore_File($filepath);
$file->setContents($contents);
$file->save();
```

Here are a few of the advantages of promoting files to a first class pimcore object:

1. Less code repetition. For example, almost every file saving operation currently has code similar to the following:

if(!exists(dirname($destination)) {
mkdir(dirname($destination));
}

file_put_contents($destination, $contents);

chmod($destination, 0766);

In my revision, this logic only has to be maintained once in Pimcore_File->save().

2. File hooks are called automatically and consistently. The hooks can be dispatched both in core or in plugins simply by manipulating the file.
3. More flexibility. Centralizing file actions opens more possibilities. For example, it would be easy to log every file operation. Every file action could even be extended to make a custom file driver for something like mogileFS.

Because I would like feedback before continuing further, so far I have only added the new file management to the following areas in pimcore:

* Versions
* Object Classes
* Fieldcollections
* Objectbricks
* Recyclebin
* Assets

Although some of these might not be necessary, the remaining areas I can think of are:

* Log files
* Temporary files
* Various XML config files
* Grid view configs
* WebDAV

Since there may be times when you only need basic file manipulation without the overhead of hooks, I added the ability to disable file events by calling _Pimcore_File::disableEvents()_, similar to the way versioning can be disabled. I'm thinking it might be useful to also have a system setting to permanently disable file hooks for those who don't need it.