Change asset name on upload public function init()
{
    craft()-&gt;on('assets.onBeforeSaveAsset', function(Event $event) {
        $asset = $event-&gt;params['asset'];
        $asset-&gt;setAttribute('filename', 'new name');
        craft()-&gt;assets-&gt;storeFile($asset);
    }
    );
}


Here is the code I use in the primary plugin class. This is just a test as i'm learning. I know it should better be in service.
This is supposed to change the filename upon uploading.

Anyway this does nothing, when I upload an asset in the cp, the dialog with progress bars pops up but get stuck.
How should I modify this for it to work ?
First, when you attach event listeners using craft.on, the naming convention for the event name is assets.beforeSaveEntry, not assets.onBeforeSaveEntry (i.e., skip the on part). Both names appear to work, but the former is the one used in the docs and I'd recommend using that.

Second, the reason why your upload "gets stuck" is your call to craft()-&gt;assets-&gt;storeFile inside the event listener. Basically, that call results in a loop, because craft-&gt;assets-&gt;storeFile() will fire another beforeSaveAsset event – making your script execute continually before timing out.

As for actually changing the filename on upload; unfortunately, if there's a reliable way to change the asset filename before the asset is saved, I haven't been able to find it.

However, if you can work with the assets.saveAsset event (which is fired after the asset is uploaded and saved on the server), I found a way:

First, set up an event listener for assets.saveAsset. Inside the event listener, you need to check the $event object's isNewAsset property; making sure the filename is only changed the first time the asset is saved and preventing the loop mentioned above.

Concerning the actual filename, there's a couple of issues to consider. For one, the filename needs to be unique (to that particular folder, as least). If you attempt to store an asset with an existing filename, Craft will use the original filename for your upload (I'd expect Craft to either ask if you wanted to replace the existing file, or suffix the filename with a number, but that doesn't appear to be the case). Secondly, the filename needs to include the file's extension (i.e. jpg or pdf). And finally; because this code runs after the asset has been saved and the file is already stored on the server, it isn't enough to set the filename attribute to the AssetFileModel object (i.e. $asset), you'll also need to rename the actual file.

Keeping these issues in mind, here's a working example:

craft()-&gt;on('assets.saveAsset', function (Event $event) {

    if ($event-&gt;params['isNewAsset']) {

        $asset = $event-&gt;params['asset'];

        // Set the filename to a variable, appending the file extension
        $filename = 'filename-'.md5(time()).'.'.$asset-&gt;getExtension();

        // Rename the file on the server
        craft()-&gt;assets-&gt;renameFile($asset, $filename);

        // Set filename attribute and re-save asset
        $asset-&gt;setAttribute('filename', $filename);
        craft()-&gt;assets-&gt;storeFile($asset);

    }
});


Note that in the above example, I'm hashing the current timestamp and adding it to the filename as an easy fix to ensure that it's unique. I don't know how you want your filenames to look or if duplicate filenames would even be an issue in your case, but you could of course implement a solution that tests for duplicate filenames and/or generates unique filenames in a different manner.

To be honest, although the above should work I do feel this solution is a bit convoluted and I wouldn't be surprised if there's a better way – if there is, hopefully you'll have another answer.