Is panel.file.replace hook working?

As the title states, I can’t get that hook to work.
Tested on a couple of projects, on different servers. Kirby versions 2.5.9 and 2.5.10.

Maybe I just don’t understand when it’s supposed to get triggered, this is how I expect it to be triggered: file image.png is uploaded to the panel, but there already exists a file with that name, thus image.png is replaced.

Neither of the following snippets work:

kirby()->hook('panel.file.replace', function($file) {

kirby()->hook('panel.file.replace', function($file, $oldFile) {

I think that hook is only triggered if you actually use the file replace function, not if you just overwrite an existing file by uploading a new one.

Hmm that’s kinda problematic. I don’t want my panel users to overwrite images. I want the file to be renamed or something in case the that filename already exists. Do you know of any plugins/solutions that tackle this problem?

Have you tried if you can fetch this with the panel.file.upload hook?

Or maybe try with permissions.

Unfortunately, the docs state that

Hooks are being triggered after the event is called in the Panel.

Furthermore panel.file.upload only returns the uploaded file as a parameter, not the old file.

I guess the permissions solution suggested by @texnixe is the way to go. I’ll only allow file upload if the file doesn’t already exist.

Thanks for the help guys.

panel.file.replace seems to work when you use this button right here, inside the file page.


As for panel.file.replace that seems to be triggered when the file has extra fields defined inside a blueprint and those gets updated, not the file itself.

kirby()->hook('panel.file.replace', function($file) {
    f::write(kirby()->roots()->content() . "/test-replace.txt", 'Replace', false);

kirby()->hook('panel.file.update', function($file) {
    f::write(kirby()->roots()->content() . "/test-update.txt", 'Update', false);

Tested this quickly and the two files are created as expected.

I keep adding :slight_smile:
replace is also triggered correctly if you drag & drop a file directly into the single file page, inside the admin.

The hooks are not really a solution, because they are triggered when it is already to late for @Shurugaz use case . Kirby 2 doesn’t have pre-event hooks… so permissions are the only feasible way.

Looks like a permission is also too late.


// site/roles/editor.php
return [
	'name'        => 'Editor',
	'default'     => false,
	'permissions' => [
		'*'                 => true,
		'panel.file.upload' => function() {

			if($this->state() === 'ui') {
				// always show the upload button
				return true;

			$panel = $this->panel();
			$kirby = $this->kirby();
			$page = $this->target()->page();
			$uploadedName = $this->target()->upload()->filename();
			$errorMessage = 'You are not allowed to overwrite files.';
			f::write($kirby->roots()->index() .'/log.txt', dump($page->file($uploadedName)));

			if ($page->file($uploadedName)->exists()) {
				$panel->redirect('pages/' . $page->id() . '/edit');
				return false;

			return true;


The file is already overwritten by the time this gets fired. Any ideas?

I was re-reading your first post. Quick q just to make sure I’m understanding what you want to achieve.

You want to allow multiple images to be uploaded on the page but you want to avoid a file to be overwritten if for some reason a user uploads a file with the same name.

Is that correct?

This is likely to throw an error, because if the file doesn’t exist, you can’t call the exist method on it. You have to do this differently

if($file = $page->file($uploadedName)) {
  // code

Can’t look into this now, but will tonight.

Exactly, I want files to be uploaded, just not to be overwritten.

Hmm, yes, looks as if the file is first uploaded and then the Panel permission decides if it likes to keep the file or not.