<p>You probably just confused the entry model and the asset model, see if the code below works for you.
I guess the <code>entries.onBeforeSaveEntry</code> event is a better match in this case, and I also added some conditionals to
only do something for a specific entry section and type, and if there's exactly one asset selected. I hope this helps (code is untested)!</p>

<pre><code>craft()-&gt;on('entries.beforeSaveEntry', function(Event $event)
{
    $entry = $event-&gt;params['entry'];

    if (($entry-&gt;section['handle'] == 'friends') &amp;&amp; ($entry-&gt;type['handle'] == 'friends'))
    {
        $title = $entry-&gt;slug;
        $assets = $entry-&gt;imgdir;

        if (count($assets) != 1)
        {
            $event-&gt;params['entry']-&gt;addError('imgdir', Craft::t('Exactly 1 asset has to be selected.'));
            $event-&gt;performAction = false;
        }
        else
        {
            $filename = $title.'.'.$assets[0]-&gt;getExtension();

            craft()-&gt;assets-&gt;renameFile($assets[0], $filename);
            craft()-&gt;assets-&gt;storeFile($assets[0]);
        }
    }
});
</code></pre>

CC BY-SA 3.0
2016-04-12T14:28:23.973Z
Does this work with Amazon S3 too? My application is a bit different. Immediately after upload, I need to push the mp3 file to Soundcloud using their API. I have experience with their API. I just don't know how I access the file to send to them.
David A McInnis
CC BY-SA 3.0
2016-04-12T15:11:03.083Z
@david yes, you can use the asset events to do your things with an external API. Probably worth adding a new question for this though.
carlcs
CC BY-SA 3.0
2016-01-13T13:31:52.193Z
Thanks for your answer. I tried your code but it does not change the image filename, it's as if it does nothing particular.
Benj
CC BY-SA 3.0
2016-01-13T14:50:57.300Z
You forgot to add the file extension to the new title, as suggested in mmikkel's original answer and so did I, corrected it in the answer above.
carlcs
CC BY-SA 4.0
2018-10-21T23:33:08.450Z
What would be the equivalent in Craft 3? https://craftcms.stackexchange.com/a/27604/298 works, but I want the new file name to be a concatenation of Post Date (or upload time stamp) & the entry's author id.
Andrea DeMers
CC BY-SA 3.0
2016-01-13T12:01:44.500Z
2016-01-13T14:47:07.067Z
2016-01-13T14:47:07.067Z
carlcs
<p>In Craft 3, here's a version that worked for me to change the file name after upload (in a module's <code>init()</code> function):</p>

<pre><code>Event::on(
Elements::class,
Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (ElementEvent $event) {
        $asset = $event-&gt;element;
        if ($event-&gt;isNew &amp;&amp; $asset instanceof craft\elements\Asset) {
             $newFileName = "something.txt";
              Craft::$app-&gt;assets-&gt;moveAsset($asset,$asset-&gt;getFolder(),filter_var($asset-&gt;getFilename(), $newFileName);
        }
     }
);
</code></pre>

CC BY-SA 4.0
2018-09-05T07:10:57.897Z
2018-09-06T18:40:39.527Z
2018-09-06T18:40:39.527Z
Udo
<pre><code>craft()-&gt;on('entries.saveEntry', function(Event $event)
{
    // entry slug, will be used as image name
    $EntryTitle = $event-&gt;params['entry']['slug'];

    // Get attached image
    $entry = $event-&gt;params['entry']['imgdir'][0];

    craft()-&gt;assets-&gt;renameFile($entry, $EntryTitle);
    $entry-&gt;setAttribute('filename', $EntryTitle);
    craft()-&gt;assets-&gt;storeFile($entry);

});
</code></pre>

<p>This <code>init()</code> code gets the current entry title right after it was saved, and is supposed to use it to rename an attached file.
I used a method given by another developer in the context of a saveAsset, but it doesn't seem to work in this new context (→ see <a href="https://craftcms.stackexchange.com/q/13154/125">Change asset name on upload</a>).</p>

<p>I'm not sure i've set the <code>$entry</code> variable to correct data. Fact is I'm able trough the path you see above, to get access to the asset. 
Please tell me where this code is wrong.</p>

<plugin-development><assets><events>
Rename a file using onSaveEntry event
# Rename a file using onSaveEntry event

(Asked by: username_0 on 2016-01-12)

craft()->on('entries.saveEntry', function(Event $event)
{
    // entry slug, will be used as image name
    $EntryTitle = $event->params['entry']['slug'];

    // Get attached image
    $entry = $event->params['entry']['imgdir'][0];

    craft()->assets->renameFile($entry, $EntryTitle);
    $entry->setAttribute('filename', $EntryTitle);
    craft()->assets->storeFile($entry);

});

This init() code gets the current entry title right after it was saved, and is supposed to use it to rename an attached file.
I used a method given by another developer in the context of a saveAsset, but it doesn't seem to work in this new context (→ see Change asset name on upload).
I'm not sure i've set the $entry variable to correct data. Fact is I'm able trough the path you see above, to get access to the asset. 
Please tell me where this code is wrong.

**Tags:** plugin-development, assets, events


---

## 2 answers

### Answer by username_1 on 2016-01-13. Score: 3 | Accepted answer

You probably just confused the entry model and the asset model, see if the code below works for you.
I guess the entries.onBeforeSaveEntry event is a better match in this case, and I also added some conditionals to
only do something for a specific entry section and type, and if there's exactly one asset selected. I hope this helps (code is untested)!
craft()->on('entries.beforeSaveEntry', function(Event $event)
{
    $entry = $event->params['entry'];

    if (($entry->section['handle'] == 'friends') && ($entry->type['handle'] == 'friends'))
    {
        $title = $entry->slug;
        $assets = $entry->imgdir;

        if (count($assets) != 1)
        {
            $event->params['entry']->addError('imgdir', Craft::t('Exactly 1 asset has to be selected.'));
            $event->performAction = false;
        }
        else
        {
            $filename = $title.'.'.$assets[0]->getExtension();

            craft()->assets->renameFile($assets[0], $filename);
            craft()->assets->storeFile($assets[0]);
        }
    }
});

> **Comments:**
> **username_0**: Thanks for your answer. I tried your code but it does not change the image filename, it's as if it does nothing particular.  
> **username_1**: You forgot to add the file extension to the new title, as suggested in mmikkel's original answer and so did I, corrected it in the answer above.  
> **username_2**: Does this work with Amazon S3 too? My application is a bit different. Immediately after upload, I need to push the mp3 file to Soundcloud using their API. I have experience with their API. I just don't know how I access the file to send to them.  
> **username_1**: @david yes, you can use the asset events to do your things with an external API. Probably worth adding a new question for this though.  
> **username_3**: What would be the equivalent in Craft 3? https://craftcms.stackexchange.com/a/27604/298 works, but I want the new file name to be a concatenation of Post Date (or upload time stamp) & the entry's author id.  

---

### Answer by username_4 on 2018-09-05. Score: 1

In Craft 3, here's a version that worked for me to change the file name after upload (in a module's init() function):
Event::on(
Elements::class,
Elements::EVENT_AFTER_SAVE_ELEMENT,
    function (ElementEvent $event) {
        $asset = $event->element;
        if ($event->isNew && $asset instanceof craft\elements\Asset) {
             $newFileName = "something.txt";
              Craft::$app->assets->moveAsset($asset,$asset->getFolder(),filter_var($asset->getFilename(), $newFileName);
        }
     }
);


---

