Introduction
We check several Formidable related community support sites daily, sometimes more than once a day. We're always looking for opportunities to help others, but once in a while we'll bypass an opportunity or two because the amount of research required to solve the challenge takes as much time as doing the job itself. With our busy schedule, we don't have the time to do unpaid research.
Such is the challenge faced by Michael Clark. From his posts, Michael seems to have technical knowledge that exceeds that of the typical Formidable user we usually help. But when we saw Michael's posts about the problem that is the subject of this article, we were reluctant to look into a solution because of the time commitment. In fact, nobody answered his concerns for any of his posts. We're sure it was frustrating for Michael.
Then Michael submitted the problem to us through our project application process. If you want to work with us, we have a minimum 4-hr. fee payable in advance and Michael literally dropped this in our lap
After accepting the assignment and conferring with our new client, we started looking into the problem. Let's allow Michael to explain with his own words as input in the project application.
I need a code snippet that lets me change the role of a user by clicking a link in a view that updates a form field. The user is registered automatically and their role is set through the Formidable form.
Michael CLark
Here's the two functions from the Formidable code examples I've tried to use (via the Code Snippets plugin):
I have a View where I update a field via a link as is described in the knowledgebase here:
https://formidableforms.com/knowledgebase/insert-a-link-to-change-the-value-of-a-single-field/
This works as intended, the value of the field changes (but the frm_after_update function doesn't run).
After that update, a user's role must change. I'm using the frm_after_update hook as described here: https://formidableforms.com/knowledgebase/frm_after_update_entry/#kb-change-a-users-role
When manually editing an entry in Formidable's entry editor in the WP admin, this function works. When updating the field via the link, the action in the function does not happen. I need the frm_after_update function to be triggered when a frm-entry-update-field link in a View is clicked.
Challenge
These are our findings from the debug sessions. Michael had written this code:
We debugged this from top to bottom and found nothing wrong. The code fired and executed correctly anytime we updated an entry in the back end.
Front-end editing is a completely different paradigm than back end and direct form editing. The front-end editing we're talking about here is completely Ajax based. Every time you edit a field in a view, you trigger an Ajax process.
Direct and back end form editing requires a form submit action to update the database. The frm_after_update_entry action fires after a form submit. There is no form submit with Ajax editing. Ajax editing essentially writes to the database without a submit button getting clicked. Debugging is a completely different process as well.
For front-end editing, Formidable provides the frm_after_update_field action to trigger any additional steps after the field is updated. There's not a lot of documentation about this action either. But since there is a good code example for sending an email after a field edit in a view, we decided to start there and modify Formidable's code for our purpose.
Solution
We always advocate for using keys instead of field ids. It sometimes means a couple of extra lines of code to convert the key to the the id for functions, but it’s worth it. See this for more detail: https://formidable-masterminds.com/writing-transportable-code-keys-vs-ids/.
We ended up doing a hybrid of the two solutions. Trying it straight up the way Formidable wrote it, still doesn’t fire the frm_after_update_entry even when updating the form using FrmFormActionsController::trigger_actions(‘update’, $form, $entry, ‘email’). Triggering actions does not trigger form submit or frm_after_update_entry. That’s why the hybrid.
We wrote the update_wordpress_user_role() function to do one thing, update the WordPress user role from Formidable’s WordPress actions when called as a function. We pass the $userid and $role as parameters. The code Michael wrote already uses these parameters, so the only change to his code is that we removed the following section of code:
$user = get_userdata( $userid ); if ( $user && ! $user->has_cap('administrator') ) { $user->set_role( $role ); }
Updating the User Role
We made that block the shared function body and replaced these lines in his code with a call to the new function, which may not be as bulletproof as we like to leave them in the wild. There’s no error checking against the called WordPress function. We don’t think it will ever error out though, and with only 4-hrs. available, there’s only so much we can build into things.
frm_after_update_entry Function
frm_after_update_field Function
For small jobs like this, we go for “it works”! And this code works. We spent the bulk of our time working on the function for the front end. We had to rewrite Formidable’s code to get the entry’s user id. Everything else was there to call the shared function to update the role.
We hard coded the $userid_field variable with 15 because it’s used further below in the function. You can eventually use a key there and look up the id at this variable’s set point. That’s another place we think could use improving in our code on this project if you ever feel like playing around with things.
Great write up, as usual, Victor. I was indeed frustrated, but not because no one in the online forums responded with a fix for me. I usually only get frustrated by my own limitations and the fact that I couldn’t understand – given the two use cases and code examples from Formidable’s own knowledgebase – why those two functions just didn’t work as intended together.
Again, a frustration with a limitation in my understanding, not a frustration with the wonderfully capable, creative, and generous Formidable community.
Paying for your time: money well spent. Hopefully others will be able to benefit from this, too.
As for error checking: nearly *all* of the code examples in the FF knowledgebase are devoid of error checking loops. And, being less proficient than I’d like, I usually turn to the logs, crossing my fingers in the hopes that whatever breaks will leave me a meaningful enough trace in the logs to help point me toward a fix 🙂