Add user to file on upload

I have a site where users can upload images from the frontend. I want to add their user accounts to a user field in the image’s template right on upload but am running into some issues. Right now I am updating the file directly after it has been uploaded. That works in 99% of the cases, however there have been 2-3 times where that hasn’t worked and no user was added.

$file = page($page)->createFile([
          'source'   => $upload['tmp_name'],
          'filename' => $name,
          'template' => 'image',
          'content' => [
            'date' => date('Y-m-d h:m')
          ]
        ]);
        $file->update([
          'user' => $user
        ]);

Ideally I would want it to work like this, but this way it somehow fails without error. Any ideas?

$file = page($page)->createFile([
          'source'   => $upload['tmp_name'],
          'filename' => $name,
          'template' => 'image',
          'content' => [
            'date' => date('Y-m-d h:m'),
            'user' => $user
          ]
        ]);

Hm, that’s a bit weird, if you can add the date, you should be able to add the user as well.

What is $user in this case?

$user = $kirby->user();

I think I figured it out. I still had a file.create:after hook in the config that was doing the same thing and was probably interfering.
Somehow I always find the solution to my problems 2 minutes after opening a post in the forum. Sorry Sonja and thanks as always. :kissing_smiling_eyes:

Just on a side note, I wouldn’t rely on the magic method to give you the user ID, better use $kirby->user()->id() explicitly.

1 Like

Something like this, you mean?

$loggedInUserId = $kirby->user()->id();
$user = $kirby->users()->findByKey($loggedInUserId);

$kirby->user() already gives you the currently logged in user

 'user' => $kirby->user() ? $kirby->user()->id() : null

It is not absolutely necessary to do it this way, because the magic __toString() method automatically returns the ID in a string context. But as I said above, it’s always better to be explicit about things instead of relying on magic.

Got it, thank you!

I thought I had fixed this issue but unfortunately it still occurs from time to time. Code is still the same as above with the change to the passed user variable.
However, whereas before the user field was sometimes left blank, it no sometimes shows - kirby.
Could it have something to do with a faulty image / server traffic / metadata? Very confused and no idea where else to look for an error. Any ideas?

So kirby is actually written in the content file? Maybe Kirby falls back to the impersonated kirby user if for some reason the logged in Kirby user disappears for some misterious reason? But that’s just a wild guess.

Could you provide the project (or the relevant parts of it) for testing? How often does this happen?

When does this error pop up? While creating the file from the frontend?

Yes, kirby is actually written in the content file and the error only occurs when uploading from the frontend (at least so far). I will provide template & controller tomorrow.

Thank you!

@texnixe I have uploaded the relevant parts here. I would be very grateful if you could take a look!

A few notes that might make things easier to understand:

The website is about photographic conversations between two photographers. They take turns in uploading images. The upload function is only available to them after their partner has uploaded a new photo. They also receive an email informing them about the upload. All of this takes place in the conversation template/controller/model and I assume that’s where the error lies.
When a photographer uploads an image, she/he should be added to the user field of the image. That’s where things go wrong and sometimes the field just stays empty. This in turn also messes with the email that is being sent, where sometimes photographers receive emails when they themselves upload, not when their partner does. (Edit: I think I fixed this, there was a mistake in the getPartner() method.)

Again, I would be really thankful if you could take a look. I’ve never built anything this complex and I am sure that are some quirks/mistakes in the code.

Admin login is:
kirby@kirby.com
kirbykirby

I’ll look into it later.

1 Like

Hm, I’m having problems testing the workflow. But there are in general multiple code snippets where you rely on objects being present which will all throw errors if the object does not exist:

Examples:

$this->lastPhotograph()->user()->toUser()->id() // if `toUser()` doesn't return a user, calling `id()` will throw an error

'to'       => $page->getPartner()->email(),  // what if there is no partner

I guess I would have to create some users and add them in a conversation page as photographers first for this to work at all?

Thanks for looking into this! And sorry for not making this clearer.

There should already be two dummy users and a conversation setup in the repository.
In order to check the upload function you would have to log in as userone on the frontend and the navigate to the dummy conversation:

userone@user.com
useronepassword

Edit: Forgot that the accounts folder is of course marked in the .gitignore file. They are there now.

Ok, that seems to work now and the mails are sent correctly.

However, since you set $success to true, I would then send the email on the condition that this is true.

Since a user must be logged in to upload an image, impersonating the kirby user is not necessary, since the user is authenticated anyway.

Also, the email template is missing from your repo.

Aaah, do you think that $kirby->impersonate() could have been the culprit and sometimes messed with the $user variable?

Because I have noticed before that my getPartner() method worked fine in the template, however in the controller it sometimes returned the logged in photographer, not the partner.
That’s why in the meantime I had switched to sending through the $user and $partner with the form submission and then using that to create the file and send the email. Not very elegant but the bug hasn’t happened again until now.

I’m not sure, but somehow this double authentication definitely doesn’t make sense.

1 Like