Home › Toolset Professional Support › [Resolved] Automatically connect post created with Form to an existing post using post relationships
Problem: I have a Form that creates posts. I would like to automatically link the new post to another post using post relationships.
Solution: Create a link to the new post Form that includes the existing post ID in a URL parameter. Then use a generic field in the new post Form to capture that post ID and pass it into a cred_save_data callback. Use the Post Relationships API to link the two posts.
Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api
https://toolset.com/documentation/programmer-reference/cred-api/
This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.
Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.
This topic is split from https://toolset.com/forums/topic/selecting-custom-post-type-posts-created-by-a-user-for-a-final-selection/
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
8:00 – 12:00 | 8:00 – 12:00 | 8:00 – 12:00 | 8:00 – 12:00 | 8:00 – 12:00 | - | - |
13:00 – 17:00 | 13:00 – 17:00 | 13:00 – 17:00 | 13:00 – 17:00 | 13:00 – 17:00 | - | - |
Supporter timezone: America/New_York (GMT-04:00)
Related documentation:
This topic contains 18 replies, has 2 voices.
Last updated by DieterR7285 5 years, 3 months ago.
Assisted by: Christian Cox.
You click "Create new member" and display the new Member Form. You would like to automatically associate the new Member with the Riedel-Gupta report, correct? If so, this will require custom code using the Forms API and the Post Relationships API, because there is not currently a built-in way to create a post and also add it to a many-to-many relationship automatically.
The general idea is that you would create a hidden generic field in the new Member Form, and insert the ID of the Riedel-Gupta Report as the value of that field. Then you would use the cred_save_data API to get the value of that hidden field when the form is submitted, and use the toolset_connect_posts API to link the new member and the report.
As was mentioned in your last answer. Could you please explain in more detail how you would create a hidden field to assign the report ID using the cred_save_data API to make a new member entry directly related to the report it was created under.
Hi, I apologize for the delay but somehow I missed the message you sent requesting more information. I was reviewing resolved threads and saw that you wanted more info, so I have created this ticket where we can discuss in more detail.
Step 1: Create a generic "hidden" field in the new post Form. Give it a slug like "connect-to-report". Add the report ID as the value of this field. You may have to use a custom URL structure to pass the report ID into the URL of the page containing the new Member Form. For example, on the single Report page, you can create a link like this:
<a href="/create-new-member/?r=[wpv-post-id]">Create a new Member report</a>
The "r" parameter will hold the ID of the current Report page. Then in the Form builder, you'll have to use expert mode to set the value of the hidden field using the "r" parameter:
[cred_generic_field type='hidden' field='connect-to-report'] { "default":"[wpv-search-term param="r"]" } [/cred_generic_field]
Let's try to get this much set up, then we can move on to the custom code part. Let me know if you get stuck and I can take a closer look.
Hello Christian,
Sorry now it took me a while to have a look and get into it again.
I have added the hidden field into the add-member-form Post form as was suggested and found the post ID was available but hidden in the post form correctly. Meaning I see the empty post form and the hidden field with the post ID of the report were the form resides in the reports details view at the moment.
Moving to the second step I am not quite sure about the link to the add-member-form Post form as it is on the same page as the present report CPT.
The add-member-form Post form is also on the members listing page which has no direct link to any existing report as it just lists all members. I asume I would have to either take it out from there all together if I want a new member CPT post to be always linked to a report from the moment it was created. Or I keep both options one to create a new member which has no association to a report yet and needs to be assigned later. And keep the add-member-form Post form directly integrated in the reports details page listing assigned members and allowing to create a new member related to that report.
If you could please have another look, provided credentials are still valid.
Kind Regards
Dieter
Moving to the second step I am not quite sure about the link to the add-member-form Post form as it is on the same page as the present report CPT.
Okay that's fine. In this case, there is no need for a link or URL parameter. You will set the value of the generic field using the ID of the current post (the current Report). You can get the ID of the current post using the wpv-post-id shortcode and the $current_page operator, like this:
[cred_generic_field type='hidden' field='connect-to-report'] { "default":"[wpv-post-id item='$current_page']" } [/cred_generic_field]
Now when you check the Form in the Report post, you should see a hidden field with the current Report's ID set as its value. If that is working as expected, the next step is to set up a Forms hook to capture that value and use it to create a relationship with the toolset_connect_posts API.
add_action('cred_save_data', 'tssupp_connect_member_to_report',10,2); function tssupp_connect_member_to_report($post_id, $form_data) { $forms = array( 12345 ); if ( in_array( $form_data['id'], $forms ) ) { $report_id = $_POST["connect-to-report"]; toolset_connect_posts( 'relationship-slug', $report_id, $post_id); } }
You will change 12345 to match the numeric ID of the new Member Form, and change relationship-slug to match the slug of this post relationship. You can find that in Toolset > Relationships. The login credentials have already been cleared from our database since the last post was marked resolved, so if you need me to check anything in the backend I'll need the login again.
The only active relationship is Astro Report Members, and the slug is "report-members" as seen here. Report Members is the parent post type, and Astro Reports is the child post type in your post relationship. Is that what you expect? I think I was confused about which is the parent and which is the child. If this is correct, you should change this line:
toolset_connect_posts( 'astro-report-members-relationship', $report_id, $post_id);
Change it to:
toolset_connect_posts( 'report-members', $post_id, $report_id);
The syntax requires the parameters in order: slug, parent post ID, child post ID. In this case, $post_id refers to the Report Member just created by the Form (the parent). $report_id refers to the Astro Report you want to connect (the child).
Hello Christian,
All right you are talking about the Relationships and not the Relationship Forms. Even so being a many to many relationship the report-members Relationship configuration between the two CPTs is meant for the Astro Report to be the parent and the Report Member to be the child.
Having changed the slug to the report-members as suggested however did not add the newly created member to the report the add-member-form with the hidden field it was residing in!?
I also noticed that the form would not show any other messages than validation errors. Before I would see a "Post Saved" but now it just reloads and keeps the entries form the submitted field contents loaded!? I tried both with and without the function "Submit this form without reloading the page (use AJAX)" being active.
Kind Regards
Dieter
Even so being a many to many relationship the report-members Relationship configuration between the two CPTs is meant for the Astro Report to be the parent and the Report Member to be the child.
Check the report-members relationship editor, and you can see it's not set up this way. I'm attaching a screenshot where you can see Report Member is set as the parent, and Astro Report is set as the child. Here's the editor:
hidden link
I checked your theme's functions.php file, and this line has the report and member IDs backwards:
toolset_connect_posts( 'report-members', $report_id, $post_id);
You should switch those IDs before testing again.
Hello Christian,
Thanks for pointing out what the parent - child settings are as was done not by purpose. And was not aware about being able to see it via the settings.
I had a play and changed the parent - child settings around with the side-effect that I had to change the relationship form implementation accordingly from parent_item='$current' to child_item='$current'.
Also I noticed that the front-end views do not reflect anymore what is saved in the CPTs of either reports or members. I surely have destroyed something but I am trying to understand the does and don'ts here. And after many browser cache refreshes re-saving of the relationships and relationship form. I found I had to refresh the Query Filter of the Views in question I could resolve this display issue.
Seemingly after changing the relationship settings one needs to "refresh" all the dependent views for the changes to take affect.
And I just copied the code from your previous example. But if I understand you and the code correctly switching the $report_id with $post_id caters for that reverse set-up of parent - child which I had before.
I managed to get the add to report going. Yet how do I make the whole reports details page reload to show the newly added member after I have submitted the new member creation form!?
Kind Regards
Dieter
A few more questions came up:
Similar to my last question how do I make the details page reload after assigning a member to a report listing out all assigned reports!?
Also I am seeing now by default the success message "Relationship Saved" on the Assign to existing relationship form "astro-report-members-relationship"!?
And how do you prevent duplicate relationship assignment to a report visible in the report back-end? Or does this have no impact as member is shown only once in front-end?
How can I prevent a certain user role from having access to the WordPress back-end still providing that role with all required rights to use the front-end forms?
Seemingly after changing the relationship settings one needs to "refresh" all the dependent views for the changes to take affect.
Yes, I'm sorry I didn't warn you explicitly about this, but I recommend never changing relationship settings after you have already created posts and linked them in the relationship. The system isn't designed to support this type of change retroactively. A warning is displayed in the relationship editor screen to try to prevent this (see the screenshot), because once it's done it's not easy to revert. You would have to re-connect all the posts in the new relationship, and modify any View filters, Forms, or shortcode attributes that relied on this relationship. Also any custom code that uses the relationship slug, or requires parent and child post IDs in some specific order. Other unexpected problems could occur, so it might be a good idea to start with a new relationship.
I managed to get the add to report going. Yet how do I make the whole reports details page reload to show the newly added member after I have submitted the new member creation form!?
Similar to my last question how do I make the details page reload after assigning a member to a report listing out all assigned reports!?
You can use the Forms API and the following custom code template to trigger a page reload after submitting a Form:
add_filter('cred_success_redirect', 'tssupp_reload_member_form_page', 10, 3); function tssupp_reload_member_form_page($url, $post_id, $form_data) { if (in_array($form_data['id'], array(12345))) { //Edit the member form ID if (isset($_REQUEST['_cred_cred_prefix_cred_container_id'])) { $url = get_permalink($_REQUEST['_cred_cred_prefix_cred_container_id']); } } return $url; } add_filter('cred_success_redirect', 'tssupp_reload_details_form_page', 10, 3); function tssupp_reload_details_form_page($url, $post_id, $form_data) { if (in_array($form_data['id'], array(12345))) { //Edit the details form ID if (isset($_REQUEST['_cred_cred_prefix_cred_container_id'])) { $url = get_permalink($_REQUEST['_cred_cred_prefix_cred_container_id']); } } return $url; }
Change 12345 to match each form's numeric ID, and add this code to your child theme's functions.php file or a new code snippet in Toolset > Settings > Custom Code. You must set both Forms to redirect to some page or post in the Form editor. It doesn't really matter which one you choose, because it will be overridden with this custom code, but it is required to select something.
Also I am seeing now by default the success message "Relationship Saved" on the Assign to existing relationship form "astro-report-members-relationship"!?
I don't understand the problem, can you clarify for me? Are you saying the success message is shown before the Form is submitted? Or the success message is shown but the relationship is not saved? Or you want to change the message text to something else?
And how do you prevent duplicate relationship assignment to a report visible in the report back-end?
I don't understand the problem, can you clarify for me? How would a duplicate relationship assignment occur? In the example we were discussing, a Report can have many Members, and many Members can be linked to the same Report. However, you cannot link the same Member to one Report multiple times in the same relationship.
How can I prevent a certain user role from having access to the WordPress back-end still providing that role with all required rights to use the front-end forms?
Here's a ticket that discusses some options: https://toolset.com/forums/topic/block-completely-backend-access-to-a-user-role/
If you need more detailed instructions, let's split this question into a separate ticket.
Sorry I should have added images before to illustrate the issues.
Also I am seeing now by default the success message "Relationship Saved" on the Assign to existing relationship form "astro-report-members-relationship"!?
- You can use the Forms API and the following custom code template to trigger a page reload after submitting a Form:
I added the script provided into the Toolset - Settings - Custom Code and tried the same in functions.php and changed the ID to the astro-report-members-relationship ID. But that did not trigger a page refresh to show the new assignment of a report to a member. I also added the page ID of the Report Members yet.
I added the astro-report-members-relationship form on to the Member details and edit Member page as well as the Report Members listing page. And it works in all places assigning the member to the report. Yet does not reload the page automatically to show the new assignment only after manual reloading the page the changes will show.
The astro-report-members-relationship form is set to "Redirect Back from which the user came from", but is still not reloading. And if I try to set it to "Go to a specific page/post" I cannot specify any page or post!?
Also I am seeing now by default the success message "Relationship Saved" on the Assign to existing relationship form "astro-report-members-relationship"!?
- I don't understand the problem, can you clarify for me? Are you saying the success message is shown before the Form is submitted? Or the success message is shown but the relationship is not saved? Or you want to change the message text to something else?
It shows the "Relationship Saved" message by default on the Member details and Report Members listing page. But not on the edit Member page!?
And how do you prevent duplicate relationship assignment to a report visible in the report back-end?
- I don't understand the problem, can you clarify for me? How would a duplicate relationship assignment occur? In the example we were discussing, a Report can have many Members, and many Members can be linked to the same Report. However, you cannot link the same Member to one Report multiple times in the same relationship.
When you add a member to a report it will be shown accordingly for each time in the back-end CPT reports page. Please see attached screenshot.
How can I prevent a certain user role from having access to the WordPress back-end still providing that role with all required rights to use the front-end forms?
- Here's a ticket that discusses some options: https://toolset.com/forums/topic/block-completely-backend-access-to-a-user-role/
If you need more detailed instructions, let's split this question into a separate ticket.
Thanks I managed to implement this solution successfully.
Okay I thought we were discussing new post forms. I apologize, I'm having trouble following the various different issues here so let's refocus. The form redirection scripts I provided will only work with Forms that create or edit some post. There is no redirection API available for Relationship Forms at the moment. However, you should be able to choose the option "Stay on the same page" in the Relationship Form settings and disable AJAX to refresh the page where the Form is shown. Maybe I'm misunderstanding what you want to accomplish here? If so, please tell me more about the problem, how to reproduce it step by step, and a URL where I should look to see the problem.
In the Relationship Form even with AJAX deactivated and trying all the different settings of the "After visitors submit this form". After submitting it still would not reload the page and make the changes visible automatically!?
Anyway the issues are visible on the CPT Report Members (Manasi Gupta) post in the back-end. And on the front-end in the Report Members (Manasi Gupta) details page accordingly. As per the screenshots from before.
What has been magically resolved just now is the message "Relationship Saved" on the Report Members listing page (hidden link), assuming AJAX related as well!?
The reload a page issue after submitting the new member form was now also partly resolved when deactivating AJAX.
It works now on the report details page. But if I create a new member on the report members listings page I get an error message "The site is experiencing technical difficulties.", please see attached screenshot, with a strange URL (hidden link).
On a different note can the response/reload time be shortened when one clicks on the remove relationship link ("Remove member from this report?") as it takes about 10 to 20 seconds until the page reloads!?
But if I create a new member on the report members listings page I get an error message "The site is experiencing technical difficulties.",
Here is the server log corresponding to my test:
[16-Sep-2019 20:05:58 UTC] PHP Fatal error: Uncaught InvalidArgumentException: The element to connect with doesn't belong to the relationship definition provided. in /home3/isolarfi/public_html/dev.astrofamilystory.com/wp-content/plugins/layouts/vendor/toolset/toolset-common/inc/m2m/potential_association/query_posts.php:85
When I load the /members/ page, the connect-to-post hidden field value is 498. If you follow the code here, you can see that means $report_id will also be 498...but there is no Astro Report post with ID 498.
add_action('cred_save_data', 'tssupp_connect_member_to_report',10,2); function tssupp_connect_member_to_report($post_id, $form_data) { $forms = array( 94 ); if ( in_array( $form_data['id'], $forms ) ) { $report_id = $_POST["connect-to-report"]; toolset_connect_posts( 'report-members', $report_id, $post_id); } }
The /members/ Page has an ID of 498, so that's why the failure is shown. The toolset_connect_posts function is trying to connect the /members/ Page in this post relationship, but there is a fatal error because Pages are not part of this post relationship. So you need to figure out a way to remove the hidden field or its value if the Form is shown on the /members/ page, but keep the value when it is shown on another page. You'll need to place some kind of conditional in the code or in the Form itself.
I see, could you point me into the right direction on implementing a conditional code. As when I tried to implement a conditional in the add-new-member-form it would just hide the hidden field. So not really a solution as it is still picked up by the custom code in the functions.php.
Another solution I could successfully implement is simply duplicate the add-new-member-form and remove the hidden field in one used for the /members/ page.
One issue still bugging me, as reported above, is that the message "Relationship Saved" is constantly displayed in the member details page, any ideas!?