Skip Navigation

[Resolved] Adoption & Sponsoring System for Charity Website

This support ticket is created 5 years, 3 months ago. There's a good chance that you are reading advice that it now obsolete.

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.

Sun Mon Tue Wed Thu Fri Sat
- 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 7:00 – 14:00 -
- 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 15:00 – 16:00 -

Supporter timezone: Europe/London (GMT+00:00)

This topic contains 18 replies, has 2 voices.

Last updated by tobiasF-3 5 years, 3 months ago.

Assisted by: Nigel.

Author
Posts
#1297449
Screenshot 2019-07-22 at 11.09.37.jpg
Screenshot 2019-07-22 at 11.10.35.jpg
Screenshot 2019-07-22 at 11.09.54.jpg
Screenshot 2019-07-22 at 11.10.08.jpg
Example.png

I am trying to setup a adoption and sponsoring system on our dog charity website with Toolset. I have managed to do this in the past with Formidable Forms on our old website hidden link. But I would now like to recreate a similar functionality with Toolset, CPTs, Relationships and Toolset CRED forms on our new website hidden link. For the purpose of keeping it simple, let's only talk about the sponsoring system for now. Once I have this figured out, I will be able to adjust for the adoption system.

The basics - there are:
- Dogs (that can be adopted or sponsored by Contacts)
- Contacts (these are people who have logged into our website and would like to sponsor or adopt a dog)

Each dog can have 4 types of annual sponsorships:
- Doctor (€100)
- Food (€200)
- Training (€300)
- Full (€600)

There are 2 possibilities how a dog can be sponsored:
1) a dog can have up to 3 sponsors: one in each category 'Doctor', 'Food' & 'Training'
2) or a dog has 1 sponsor that covers all costs (one in category 'Full')

I would now like people to be able to
- browse the dogs on our website
- click on one dog they would like to sponsor
- (opitional: become a member and login if they are not logged-in yet)
- choose the sponsorship type
- fill out a form and pay the sponsorship amount through the form
- Next: on the dog profile the person should then show up under the sponsorship that the person paid for this dog
- this sponsorship type should then not be available anymore to other users for this dog

Is there any documentation that you are following?
- I have tried to follow many documentations on your website, especially the new relationships, but I am always hitting some kind of different wall, sorry.
- so far I have setup the following:
- CPT for Dog
- CPT for Contacts
- Relationship (many-to-many) between Dog & Contacts
I am struggling with: how to setup the sponsorships, so that a contact can click on a dog, choose a sponsorship, pay for it and then get AUTOMATICALLY associated with the dog.

Is there a similar example that we can see?
hidden link
- click on one of the dogs
- click on 'more info' under 'Doctor'
- click on buy now for an example of the form
- go to this link to see how it looks like, when somebody (Lisa) sponsored a dog:
hidden link
- this info is added automatically when the form is sent and the sponsorship paid

What is the link to your site?
hidden link
WORK IN PROGRESS, but you can see where I am at
- CPT Dogs: hidden link
- CPT Contacts: hidden link
- Dog Layout: hidden link
- Dog Content Template: hidden link
- Relationship: hidden link

Questions:
- should the Sponsorships be a CPT, is that correct?
- or should it be an intermediary posttype for the Relationship`
You see, I am confused 🙂

Hope this helps., thank you so much for your help!
Tobias

#1297513
#1297559

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Tobias

This is a bit of a head-scratcher alright.

I'm about to take a break, and will return to this, but let me just share some initial thoughts.

A key part of this is the payment integration.

In Toolset this is achieved via WooCommerce using the Toolset Forms Commerce add-on, which lets you add payment to forms. You can read about it here: https://toolset.com/documentation/user-guides/using-cred-commerce-to-add-payments-to-forms/

The way it works that pertains to this case is that you charge users to publish a post.

Now that doesn't seem to make much sense in your case, because your contacts don't want to publish anything, they want to sponsor a dog.

But we can probably adapt this so that when a contact sponsors a dog, they "publish" a relationship intermediate post between contacts and dogs, and get charged for doing so.

Your form to publish an intermediate post would need to include fields with the id of the dog post and the id of the contact post, which are then used by some custom code that utilises the Forms API and Relationships API to join the dog and contact posts via this intermediate post, which would initially have a draft status until payment which then updates it to published.

I can guide you on implementing the above if you think it would work in your case.

I'm still thinking about the relationship structure.

One option is to have a single "sponsorship" relationship between dogs and contacts, and the intermediate post has a custom field that specifies whether this particular sponsorship is for Doctor, Food, or Training (or Full). When it comes to displaying the dog details you can query sponsorships where the intermediate field is doctor, query sponsorships where the intermediate field is food, etc...

An alternative would be to create separate relationships, one for doctor-sponshorships, one for food-sponsorships, and one for training-sponsorships.

I can see certain advantages to this approach, but the key thing to determine is how to handle "full", which requires some conditional logic. I'll resume thinking about this after my break...

#1297593

Thank you very much Nigel for your thorough investigation. I am very happy to hear that it's possible. I will follow any approach that you might consider best and also longterm most flexible and professional.

Payments I was able to achieve in the past with the CRED form and also changing the a status of a dog afterwards by changing a custom field of the dog's custom field type after sending the CRED form. Then I was able to filter by that custom field and therefore the paid for dogs would not show up again in certain lists.

But I was never able to automatically create relationships between a dog and a contact, which I think is what you are solving right now 🙂

One more thing: if it makes it eternally easier to allow any contact to sponsor any type of sponsorship as many times as he/she wants for a dog, then we might change the way our sponsorships work. But only if its MUCH better from a backend point of view. Until now, we've like the fact, that one could personally and specifally donate for a dog and see it directly afterwards on the website.

Thank you so much for your support and looking forward to your solutions 🙂

#1297605

The solution should then be easily adaptable for adoptions: there it works like this:
- dogs which are marked as adoptable show up in a list for: adoptable dogs
- one contact can then adopt a dog by filling out a form
- the dog is then connected with a relationship to the contact
- the dog is removed from the adoptable dogs list

I think this should be straightforward once we have solved the sponsoring system above, right?

#1297797

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Tobias

I've been trying to set up a site to test the possible implementation, and I've run into a key problem early on.

As I said above I think the way to integrate this with a payment option is to use Forms Commerce to charge to publish an intermediate sponsor post and then use the API to attach the corresponding Pet and Contact posts.

But our API to connect posts doesn't let you do that: you specify the posts to connect and it creates the intermediate post.

I'm having to consult with the developers about possible alternatives, because without this I don't see how to proceed with this method.

I'll update again.

#1297811

Hey Nigel. Bummer, but thanks so much for looking further into this. As I've said before I am open to any solution you might find. Keeping my fingers crossed and let me know if I can help with any more info. Thx!

#1299221

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Tobias

I got a suggestion from the Types developer yesterday afternoon so I'm going to test it this morning and I'll update you again then. I haven't forgotten.

#1299277

Sounds great, Nigel and thank you so much for keeping me in the loop. Really great support. Looking forward to hearing more... and good luck!

#1299471

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

I tested the suggestion for connecting related posts to an existing intermediate post and it worked, so I think we have the ingredients available to implement this.

From your question it sounds like you are already familiar with quite a lot of this, so I'm making some broad-brush suggestions and only getting specific where I need to, but if you find that there is a part of this that you want to adopt but can't then let me know and I can elaborate further.

Using the display of a dog as our starting point.

The dog has 3 sponsorship slots, doctor, food, training.

In each slot we should display a link to sponsor the dog, or the name of the contact if already sponsored.

One option I considered was to make a single "sponsorship" relationship between dogs and contacts, with a custom field to denote which type of sponsorship it was.

But there is a current limitation with Types relationships (which we intend to remove at some point) in that you cannot have more than one connection between the same posts in the same relationship, which would mean that one person could not sponsor the same dog in more than one slot (e.g. doctor and food), and also limits how we implement the full sponsorship.

So, I suggest you create three m2m relationships between dogs and contacts, one for each type of sponsorship.

When a contact sponsors a dog for food, you will connect the contact and dog posts in the food-sponsorship relationship. When a contact sponsors a dog for medical costs, you will connect the contact and dog posts in the doctor-sponsorship relationship. Likewise for training.

As far as handling the "Full" sponsorship, you could either create a fourth such relationship, or, better, I think, you could add some customisation so that in such a case connections would be made in each of the three main sponsorship relationships, so that each slot was filled by the same contact.

The way the sponsorship works is via Forms Commerce and the integration with WooCommerce for payments.

Let me include the link again about how that works: https://toolset.com/documentation/user-guides/using-cred-commerce-to-add-payments-to-forms/

For each relationship you will create a form to publish the intermediate post type of that relationship, linked to a product for that kind of sponsorship with the relevant price. The intermediate post will be published with a draft status, and upon payment will become published.

Now, when publishing the intermediate post, you need to connect it to the relevant dog and contact posts.

The contact post id we can get because we know the ID of the currently logged-in user, and so we can look up the id of their contact post.

The dog id we need to pass to the form when we link to the form from the template for the dog.

So... include a generic field in your forms for the dog_id, where the value comes from a URL parameter, e.g. from

[wpv-search-term param='dog_id']

Insert the form into a page, and then add a link to the page passing the dog_id in your template for dogs, e.g.

<a href="[wpv-post-url item='123']?dog_id=[wpv-post-id]">Sponsor this dog</a>

You could hard-code the URL of the page with the form, but I'm generating it here with the wpv-post-url shortcode and the ID of the page.

(Note that I'm talking about "the form" but you will be repeating this for the different kinds of sponsorship.)

So right now our template for dogs links to a form to sponsor the dog, which publishes an intermediate post (that you will connect to WC payments using Forms Commerce).

What's missing is the code that will need to run when this form is submitted to connect the dog and the contact.

We've included a generic field for the dog_id, so that will be available in the $_POST object, so we can use the cred_save_data hook to connect up the dog and contact posts to this newly published intermediate post.

Here is an example of such code. Note that I first declare a function I'm going to need to make the connection.

/**
 * Define function to join posts to existing intermediate post in M2M relationship
 *
 */
function ts_connect_existing($relationship_slug, $parent, $child, $intermediary_post_id)
{

    $relationship_definition = Toolset_Relationship_Definition_Repository::get_instance()->get_definition($relationship_slug);
    $result = $relationship_definition->create_association($parent, $child, $intermediary_post_id);
}

/**
 * Connect dog and contact posts to the intermediate post created by the form
 */
add_action('cred_save_data', 'ts_connect_to_intermediate', 10, 2);
function ts_connect_to_intermediate($post_id, $form_data)
{

    if (in_array($form_data['id'], array(128))) {

        $dog_id = $_POST['dog_id'];
        // contact post of current user
        $contacts = get_posts( array(
            'post_type'     =>  'contact',
            'post_status'   =>  'publish',
            'post_author'   =>  get_current_user_id(),
            'limit'         =>  1
        ) );
        $contact_id = $contacts[0]->ID;

        ts_connect_existing( "sponsorship", $contact_id, $pet_id, $post_id );
    }
}

Note also that this is fairly crude, I'm not performing any error-handling here, it is for demonstration purposes.

So based on this example it should be possible from viewing a dog to sponsor it.

You'll then need to go back to your template for dogs and where you display the link to the sponsorship form you will need to add some conditional display logic to either display the link to the form or display the name of the sponsor.

Actually, this is a fairly big topic (see https://toolset.com/documentation/user-guides/conditional-html-output-in-views/), but we can fairly easily sidestep it.

Imagine you already have a sponsor. So to display their name you are going to need a View which gets the contact related (in the relevant relationship) to the current dog, and you will be able to output the contact title (their name) or other contact fields.

But what if the View returns no results, i.e. there is no current sponsor?

Well, in that case we want to link to the form to sponsor the dog, so that's where you add that link, inside the no-items-found section of this View that looks for existing sponsors.

That is quite a lot to digest, but I think you have there most of what you need to implement this. If I've missed something or something specific is not clear, let me know.

#1299609

Wow Nigel, thank you SO MUCH for all this very helpful information. And I am glad I've asked, since I would have never been able to figure this out on my own. As you have said: I have some knowledge about wordpress and the types plugin and everything that you see on the Dog Rose webpage was done by me, but I am not a coder so I am VERY grateful for your detailed instructions. It will take me a while to test it, but hopefully by the end of the weekend I got around to to everything and give you feedback. So it would be cool if we can keep this thread open until I get back to you? Thx a lot again and I am excited to get cranking 🙂 Have a great day. Tobi

#1299681

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

No problem, it was an interesting challenge.

I'll mark this as awaiting your reply, which means you should have at least a week before you are prompted to comment.

#1301893

Hey Nigel, so I've set up everything you said, but I am having a few questions. Are you around today?

#1301907

Hey Nigel, so I've hit a road block and I think it has to do with the example code you have provided me with. Everything works expcept the automatic connection between the dog and contact after submitting the form. When I do the connection manually then even the view in the end works. But I think I am doing something wrong when applying the code. Do I have to make any changes to the code you've provided? Do I have to add the form ID or relationship slug names? Als, is the $pet_id variable on line31 a mistake? should it say $dog_id? I've tried several things, changing some of the core, but nothing quite worked.

check out what I've got so far here:
hidden link

Click on 'Sponsor a doctor for this dog'

This brings you to a very rudimentary form for 'Doctor Sponsorship' (when logged-in)

Click submit brings you to the payment options. Leave everything as is and choose payment order (you won't get charged 🙂

Then I think it should execute the code, right? But no connection is made between the contact and the dog...

Your help is greatly appreciated!
Thx
Tobias

#1302755

Nigel
Supporter

Languages: English (English ) Spanish (Español )

Timezone: Europe/London (GMT+00:00)

Hi Tobias

The code was for illustration and there are a few things you will need to edit, and yes there is an error at the end where I use "$pet_id" in place of "$dog_id". (My local test site had a pet custom post type which I was using for testing.)

The first part of the code to define the function required to connect the intermediate post needs no changes. The second part I've updated below to make it clear what you would need to edit:

/**
 * Connect dog and contact posts to the intermediate post created by the form
 */
add_action('cred_save_data', 'ts_connect_to_intermediate', 10, 2);
function ts_connect_to_intermediate($post_id, $form_data)
{

    // Edit the form ID ( 123 in the example below )
    if (in_array($form_data['id'], array(123))) {

        // Edit the slug of the generic field included in the form which contains the ID of the dog
        // that will be available in the $_POST object ( 'dog_id' in the example below )
        $dog_id = $_POST['dog_id'];

        // Retrieves contact post of current user
        $contacts = get_posts( array(
            'post_type'     =>  'contact',
            'post_status'   =>  'publish',
            'post_author'   =>  get_current_user_id(),
            'limit'         =>  1
        ) );
        $contact_id = $contacts[0]->ID;
 
        // Edit slug of relationship between dogs and contacts ( 'sponsorship' in example below )
        ts_connect_existing( "sponsorship", $contact_id, $dog_id, $post_id );
    }
}

Is that clear?