I’m trying to add users to a specific structure depending on their role via a hook. My structure looks like this:
Codes:
-
code: ATEST
user:
- 40oDx6nv
-
code: BTEST
user: [ ]
-
code: CTEST
user: [ ]
Codes are manually added to the Structure and the User field left empty so when a new user is created they are assigned a code by being added to the next empty user field in the structure. Here’s my hook (in update:after
to make testing easier, will be changed to create:after
and adjusted later):
'user.update:after' => function ($newUser,$oldUser) {
if($newUser->role() == 'customer'){
$site = $this->site();
$yaml = $site->content()->codes()->yaml();
foreach($yaml as $y) {
if(!isset($y['user'])) {
$y['user'] = $newUser;
break;
}
}
}
},
This doesn’t do anything though. I’ve never updated a structure before, only ever added to one, so I’m pretty sure that’s where I’m going wrong here. Any ideas?
Inside the structure field, does the user field only ever have one user or can there be multiple ones? What is the condition for adding a user to a particular code? Please describe in a bit more details what exactly you want to achieve.
Your hook doesn’t contain any code that updates anything…
It should be one user per field.
I’m trying to assign a pre-defined promotion code to users when their account is created. The accounts are being created from the frontend (successfully) after a payment from Stripe is made. So my client enters promotion codes in the structure field and leaves the user field blank. A user then signs up, and in a user.creater:after
hook I check for the next code in the structure field that has an empty user field and write that user to the structure field. I was trying to repurpose this code to do that: Update specific structure field - #2 by texnixe
So first problem, you need a user.create:after
hook instead of user.update:after
hook.
Secondly, you need to find the key of the array item with an empty users field.
'hooks' => [
'user.create:after' => function ($user) {
if ($user->role()->name() === 'customer') {
$site = site();
$codes = $site->codes()->yaml();
$emptyItems = array_filter($codes, function ($item) {
return empty($item['user']);
});
if (!empty($emptyItems)) {
$key = array_key_first($emptyItems);
$codes[$key]['user'] = [$user->id()];
}
$site->update(['codes' => Data::encode($codes, 'yaml')]);
}
},
]
1 Like
Works great, thank you! I was using user.update
just to make testing easier. I definitely need to brush up on my PHP, I didn’t know array_key_first
existed!