I am trying to use a hook, to update a specific structure on every user with a specific role. This is the structure on the page:
projectDeliveryTeamStructure:
label: Test Structure
type: structure
fields:
task:
label: Task
type: text
This is the structure on the user
projectDeliveryTeamStructure:
label: Test Structure
type: structure
columns:
task:
width: 2/3
progress:
width: 1/3
fields:
task:
label: Task
type: text
progress:
label: Progress
type: select
default: incomplete
options:
incomplete: Incomplete
pending: Pending
complete: Complete
I need my hook to make the text
columns match up, across all users. This is what I have so far:
'page.update:after' => function ($newPage, $oldPage) {
if ($newPage->template() == 'building-block') {
// Now I am sure it is a building block page being updated
$blockName = $newPage->slug();
function toUpper($matches) {
return strtoupper($matches[1]);
}
$blockName = preg_replace_callback('/[-_](.)/', 'toUpper', $blockName);
$structure = $blockName . 'Structure';
// Now I have the name of the structure, which is the same as on the user.
$kirby = kirby();
$users = $kirby->users()->role('participant');
// Now I have all the users that need their structure field updating.
foreach ($users as $user) {
$user->update([
]);
}
}
},
I am not sure what to do in the loop to apply the update. If anyone has any thoughts that would be great
With update you mean, you want to add this information as a new item to the structure field? Not update an existing task field?
I would like to totally mirror it. So for instance if on save the structure on the page looked like this:
Projectdeliveryteamstructure:
-
task: I am the first entry
-
task: I am the second one
The structure for the users would look like this:
Projectdeliveryteamstructure:
-
task: I am the first entry
progress: pending
-
task: I am the second one
progress: pending
The progress
shouldn’t be changed, and if new lines are added these should be set to incomplete
This would only make sense if the structure items were not sortable, so that you can always be sure that the first entry on the page matches the first entry on the user. Or your items would need to have an id by which they would be identifiable.
Hi,
From the user panel the client will just be editing the progress section, which is a select box. The text would not be editable, and the rows should not be sortable from the user panel.
I get your point about the unique IDs, these would be really useful so the progress was attached to the task. Is that possible?
I have implemented AutoID now on the user and on the page, so that should help with linking up the values. On the page I now have:
Projectdeliveryteamstructure:
-
autoid: t35wmkbg
task: I am the first one
-
autoid: 85q4bcmy
task: I am the second one
-
autoid: cwg2yc5q
task: I am the third one
Any pointers on what I need to do with my hook to get this to update for the user?
Hi,
I finally got this working! Thanks everyone who took the time to take a look.
@mikeharrison Would you like to share your solution? It might actually help other who want to do the same…
Sure - it’s pretty messy / embarrasing but it does work! Here it is:
'page.update:after' => function ($newPage, $oldPage) {
if ($newPage->template() == 'building-block') {
// Now I am sure it is a building block page being updated
$blockName = $newPage->slug();
function toUpper($matches) {
return strtoupper($matches[1]);
}
$blockName = preg_replace_callback('/[-_](.)/', 'toUpper', $blockName);
// This generates the structure names that match those on the user template
$leadershipAndCommunicationKeyTasks = $blockName . 'LeadershipAndCommunicationKeyTasks';
//This gets the structures off the page
$updatedleadershipAndCommunicationKeyTasks = $newPage->leadershipAndCommunicationKeyTasks()->yaml();
// Get all participant users
$kirby = kirby();
$users = $kirby->users()->role('participant');
// Loop through and make the changes
foreach ($users as $user) {
$currentUserLeadershipAndCommunicationKeyTasks = $user->$leadershipAndCommunicationKeyTasks()->yaml();
foreach ($currentUserLeadershipAndCommunicationKeyTasks as $a) {
$one[$a['autoid']] = $a;
}
foreach ($updatedleadershipAndCommunicationKeyTasks as $a){
if ( isset($one[$a['autoid']])){
$a['progress'] = $one[$a['autoid']]['progress'];
}
$updatedleadershipAndCommunicationKeyTasks2[] = $a;
}
$user->save([
$leadershipAndCommunicationKeyTasks => Data::encode($updatedleadershipAndCommunicationKeyTasks2, "yaml"),
]);
}
}
},