<p>Got it working with this:</p>
<pre><code>Event::on(Asset::class,Element::EVENT_AFTER_SAVE,
  static function (ModelEvent $event) {
    if (Craft::$app-&gt;request-&gt;isSiteRequest) {
      $asset = $event-&gt;sender;
      $folderId = $asset-&gt;getFolder();
      $now = new DateTime();
      $timestamp = $now-&gt;getTimestamp();
      $newAssetTitle = Craft::$app-&gt;getRequest()-&gt;getBodyParam('imageTitle');
      $asset-&gt;title = $newAssetTitle;
      $newAssetFilename = StringHelper::toKebabCase($asset-&gt;title) . '-' . $timestamp . '.' . $asset-&gt;getExtension();
      if (!empty($asset)) {
        Craft::$app-&gt;assets-&gt;moveAsset($asset, $folderId, $newAssetFilename);
      }
    }
  }
);
</code></pre>

CC BY-SA 4.0
2023-01-13T05:32:30.747Z
2023-01-13T05:32:30.747Z
supazu
<p>I just found a very nice solution for changing the filename usind the <code>Assets::EVENT_SET_FILENAME</code> event:</p>
<pre><code>Event::on(Assets::class, Assets::EVENT_SET_FILENAME, function (SetAssetFilenameEvent $event) {
    $event-&gt;filename = YourHelper::sanitizeFilename($event-&gt;originalFilename);
});
</code></pre>
<p>where <code>YourHelper::sanitizeFilename(...)</code> is a placeholder function for your own modifier.</p>
<p>And since I assume that the reason people looking for this issue are sometimes dealing with special characters like e.g. german Umlaute, here is another learning:</p>
<ul>
<li>MacOS sometimes seems to use a so called &quot;Trema&quot; character to map Umlaute into filenames instead of using UTF-8 Umlaute.</li>
<li>The &quot;Trema&quot; character is a horizontal colon placed above the previous character.</li>
<li>In order to correctly convert those Umlaute into ASCII, it's easy to replace the &quot;Trema&quot; character with an &quot;e&quot; to achieve the same result as converting a real UTF-8 Umlaut into its 2 character equivalent.</li>
</ul>
<p><code>$filename = str_replace(['Ä', 'Ö', 'Ü', 'ä', 'ö', 'ü', 'ß', '̈'], ['AE', 'OE', 'UE', 'ae', 'oe', 'ue', 'ss', 'e'], $filename);</code></p>
<p>Please note: the &quot;Trema&quot; character is the last one in the search array, which is optically placed above the first quotation mark, so it looks like a broken quotation mark or a dirty screen :-)</p>

CC BY-SA 4.0
2023-03-21T13:50:14.293Z
2023-03-21T13:50:14.293Z
Matthias Redl-Mann
<p>If you're using Craft 4.0.0 or later, you should be able to use <code>$asset-&gt;setFilename($newAssetFilename)</code> (<a href="https://docs.craftcms.com/api/v4/craft-elements-asset.html#method-setfilename" rel="nofollow noreferrer">docs</a>).</p>

CC BY-SA 4.0
2023-01-12T10:56:26.613Z
Thanks for the reply. Unfortunately, that doesn't seem to do it...
supazu
CC BY-SA 4.0
2023-01-12T12:26:12.190Z
Hmm, that's strange. There's a few issues on SE which suggest using `moveAsset` to achieve this, which might be worth a try. Something like: `Craft::$app->assets->moveAsset($asset, $asset->getFolder(), $newAssetFilename);` The [docs for moveAsset](https://docs.craftcms.com/api/v4/craft-services-assets.html#method-moveasset) do suggest it's intended for renaming.
Martin Spain
CC BY-SA 4.0
2023-01-12T12:32:07.693Z
I did try that actually, but get `Asset is missing its folder ID`. I assume that's because it's on `EVENT_BEFORE_HANDLE_FILE`. I got it working with `EVENT_AFTER_SAVE` but then renaming the title broke.
supazu
CC BY-SA 4.0
2023-01-12T09:42:18.153Z
2023-01-12T09:42:18.153Z
Martin Spain
<p>I'm trying to rename files uploaded by users on the frontend. Changing the title is working, but I can't rename the file.</p>
<p>Would appreciate some help!</p>
<pre><code>Event::on(
  Asset::class,Asset::EVENT_BEFORE_HANDLE_FILE,function (AssetEvent $event) {
    if (Craft::$app-&gt;request-&gt;isSiteRequest) {
      $asset = $event-&gt;asset;
      $now = new DateTime();
      $timestamp = $now-&gt;getTimestamp();

      $newAssetTitle = Craft::$app-&gt;getRequest()-&gt;getBodyParam('imageTitle');
      $newAssetFilename = StringHelper::toKebabCase($newAssetTitle) . '-' . $timestamp . '.' . $asset-&gt;getExtension();

      $asset-&gt;title = $newAssetTitle; // this works
      $asset-&gt;filename = $newAssetFilename; // this doesn't work
    }
  }
);
</code></pre>

<assets><modules>
Change asset title and filename on upload
# Change asset title and filename on upload

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

I'm trying to rename files uploaded by users on the frontend. Changing the title is working, but I can't rename the file.
Would appreciate some help!
Event::on(
  Asset::class,Asset::EVENT_BEFORE_HANDLE_FILE,function (AssetEvent $event) {
    if (Craft::$app->request->isSiteRequest) {
      $asset = $event->asset;
      $now = new DateTime();
      $timestamp = $now->getTimestamp();

      $newAssetTitle = Craft::$app->getRequest()->getBodyParam('imageTitle');
      $newAssetFilename = StringHelper::toKebabCase($newAssetTitle) . '-' . $timestamp . '.' . $asset->getExtension();

      $asset->title = $newAssetTitle; // this works
      $asset->filename = $newAssetFilename; // this doesn't work
    }
  }
);

**Tags:** assets, modules


---

## 3 answers

### Answer by username_0 on 2023-01-13. Score: 1 | Accepted answer

Got it working with this:
Event::on(Asset::class,Element::EVENT_AFTER_SAVE,
  static function (ModelEvent $event) {
    if (Craft::$app->request->isSiteRequest) {
      $asset = $event->sender;
      $folderId = $asset->getFolder();
      $now = new DateTime();
      $timestamp = $now->getTimestamp();
      $newAssetTitle = Craft::$app->getRequest()->getBodyParam('imageTitle');
      $asset->title = $newAssetTitle;
      $newAssetFilename = StringHelper::toKebabCase($asset->title) . '-' . $timestamp . '.' . $asset->getExtension();
      if (!empty($asset)) {
        Craft::$app->assets->moveAsset($asset, $folderId, $newAssetFilename);
      }
    }
  }
);


---

### Answer by username_1 on 2023-03-21. Score: 2

I just found a very nice solution for changing the filename usind the Assets::EVENT_SET_FILENAME event:
Event::on(Assets::class, Assets::EVENT_SET_FILENAME, function (SetAssetFilenameEvent $event) {
    $event->filename = YourHelper::sanitizeFilename($event->originalFilename);
});

where YourHelper::sanitizeFilename(...) is a placeholder function for your own modifier.
And since I assume that the reason people looking for this issue are sometimes dealing with special characters like e.g. german Umlaute, here is another learning:

MacOS sometimes seems to use a so called "Trema" character to map Umlaute into filenames instead of using UTF-8 Umlaute.
The "Trema" character is a horizontal colon placed above the previous character.
In order to correctly convert those Umlaute into ASCII, it's easy to replace the "Trema" character with an "e" to achieve the same result as converting a real UTF-8 Umlaut into its 2 character equivalent.

$filename = str_replace(['Ä', 'Ö', 'Ü', 'ä', 'ö', 'ü', 'ß', '̈'], ['AE', 'OE', 'UE', 'ae', 'oe', 'ue', 'ss', 'e'], $filename);
Please note: the "Trema" character is the last one in the search array, which is optically placed above the first quotation mark, so it looks like a broken quotation mark or a dirty screen :-)


---

### Answer by username_2 on 2023-01-12. Score: 1

If you're using Craft 4.0.0 or later, you should be able to use `$asset->setFilename($newAssetFilename)` ([docs](https://docs.craftcms.com/api/v4/craft-elements-asset.html#method-setfilename)).

> **Comments:**
> **username_0**: Thanks for the reply. Unfortunately, that doesn't seem to do it...  
> **username_2**: Hmm, that's strange. There's a few issues on SE which suggest using `moveAsset` to achieve this, which might be worth a try. Something like: `Craft::$app->assets->moveAsset($asset, $asset->getFolder(), $newAssetFilename);` The [docs for moveAsset](https://docs.craftcms.com/api/v4/craft-services-assets.html#method-moveasset) do suggest it's intended for renaming.  
> **username_0**: I did try that actually, but get `Asset is missing its folder ID`. I assume that's because it's on `EVENT_BEFORE_HANDLE_FILE`. I got it working with `EVENT_AFTER_SAVE` but then renaming the title broke.  

---

