Search

I got about the same scenario as some in this thread and in brendo's tutorial.

I am trying to build a shopping cart / webshop

I,ve got 2 events; orders and clients. The client event get's executed after successfully submitting the orders event. and post a relation to the orders section through selectbox link, exactly like in the tutorial.

Here's the trigger function in the orders (1st) event which executes the 2nd event on success and posts it's relation:

protected function __trigger(){
    unset($_POST['fields']);
    $_POST['fields'] = $this->post[$this->ROOTELEMENT]['fields'];
    $_POST['id'] = $this->post[$this->ROOTELEMENT]['id'];

    include(TOOLKIT . '/events/event.section.php');
    // Check that this event returned successfully, if it did,
    // inject the clients event and orders entry ID
    if($result->getAttribute('result') == "success") {
    $_POST['action']['clients'] = 'Submit';
    $_POST['clients']['fields']['orders'] = $result->getAttribute('id');
}
    return $result;
}

This is all working.

Now i finally like to trigger a third event on successful save of the clients (2nd) event. The third event is called 'update-inventory' and updates the 'inventory (number) field in the 'webshop' section. based on calculating the items in the shopping cart with the stock.

I created the event with 'allow multiple' and rendered the following form:

<xsl:apply-templates select="cartds/entry" mode="inventory"/>
<input name="action[update-inventory]" type="submit" value="Submit" />

<xsl:template match="cartds/entry" mode="inventory">
<xsl:variable name="quantity"><xsl:value-of select="/data/shopping-cart/item[@id = current()/@id]/@num"/></xsl:variable>
<input name="fields[{position() - 1}][inventory]" type="text" value="{inventory - $quantity}"/>
<input name="id[{position() - 1}]" type="hidden" value="{@id}" />
</xsl:template>

results in:

<input name="fields[0][inventory]" type="text" value="0" />
<input name="id[0]" type="hidden" value="75" />
<input name="fields[1][inventory]" type="text" value="6" />
<input name="id[1]" type="hidden" value="73" />
<input name="fields[2][inventory]" type="text" value="16" />
<input name="id[2]" type="hidden" value="71" />
<input name="action[update-inventory]" type="submit" value="Submit" />

This is working stand alone, but i'd like to trigger it at the very end only when the client event is successfull, But this means i somehow have to add the form value's in the client's trigger event.. right? This is where i got stuck, cause i haven no idea how to replicate this in php

I came up with this so far:

Here's the trigger function in the clients (2st) event:

protected function __trigger(){
    unset($_POST['fields']);
    $_POST['fields'] = $this->post[$this->ROOTELEMENT]['fields'];
    $_POST['id'] = $this->post[$this->ROOTELEMENT]['id'];

    include(TOOLKIT . '/events/event.section.php');
    // Check that this event returned successfully, if it did,
    // inject the Inventory event and entry ID
    if($result->getAttribute('result') == "success") {
    $_POST['action']['update-inventory'] = 'Submit';
    $_POST['update-inventory']['fields']['inventory'] = $this->post[$this->ROOTELEMENT]['fields']['inventory'];
}
    return $result;
}

This is obviously not working, cause i hardly know what i'm doing when it comes to php I somehow have to pass the id's of the entries that need to be updated… just like in the form...

Hope someone can help me out here… thanks

Could you place a redirect in the second event to restart the chained event? i.e redirect to a success url with the ID of the parent entry appended and inside that event trigger, update the DS entry ID's present in the Datasource that way?

Cremol, Just realised, you have to add the [0] to get it to recognise multiple entires right?

$_POST['update-inventory']['fields'][0]['inventory'] = $this->post[$this->ROOTELEMENT]['fields'][0]['inventory'];

Or is your inventory DS setup differently?

EDIT:

Maybe do a count of the total inventory items from Event number 2 and loop over them to produce the matching [$countvarhere][fields][inventory] relation?

Thanks moonoo,

I tried adding the [0], which adds entry position="0" to the response xml.
As i can see from the response xml, it only tries to add (not update) one entrie.
So i guess i indeed have to place the values in a loop.
I am not even sure where it get's the value's from? from the $_post array? I really have no idea what i am doing here...

So i think i'll go for option B; trigger the event on the redirect page.
So what's best practice here? Redirect to a success page with the update-inventory event attached, and then auto-submit on page load? something like this?
I'm gonna play around with this, but if anyone get push me in the right direction, would be appreciated...

Cheers

Hi Cremol,

If you're updating an event you need the hidden input Id for each of the entries you wish to update...

check this reply from Marco: http://getsymphony.com/discuss/thread/95814/#position-3

Failing that a redirect.. but I'm not sure now if the data you require.. i.e the ID's would be available to you as you know Datasources are fired after events and also being as you'd be redirecting there would be no POST array anymore (I think).

You on twitter/IRC ?

I have managed to update multiple entries the normal way, rendering the form in xslt. that worked, the problem is to replicate this form in the event's trigger function... in php... i am stuck there...

For the redirect;
The Id's and inventory would still be available in the redirect page, cause the datasource is filtered by the id's from the the shopping-cart extension (your 2.3 branch :), which are saved in a cookie i guess... So i can replicate the inventory-update form in the redirect page.

Question now is how to fire the event on redirect, and prevent people from firing the event again on reload, cause this would mess up the inventory...

I'm not a twitterer btw :-0

You can trigger the action if a condition is present in the $_POST array or maybe a url param? Not 100% sure on that front cos of the order in which delegates are fired.

What about hashed field in the section, that is created in the first trigger.. and in the redirect check for the hash existing when arriving on page to trigger the event?

Maybe even using a hashed url param from the main inventory entry as a unique identifier? Im on my phone so cant find a post that Nick and Hiub commented on which I found useful.

EDIT

Here's the post I found useful http://getsymphony.com/discuss/thread/68411/

ichat or IRC if you wanted to chat further.

Thanks for pointing me in the right direction,
Gonna look into this next week (year) :-)

First of all; Happy newyear to all!

Moonoo; I Read the post and it looks very promissing; But like @timchesney, i can't get the redirect to work in the chained event;

protected function __trigger(){
    unset($_POST['fields']);
    $_POST['fields'] = $this->post[$this->ROOTELEMENT]['fields'];
    $_POST['id'] = $this->post[$this->ROOTELEMENT]['id'];

// redirect user on completion
    $_POST['redirect'] = '/order-confirmation/';

    include(TOOLKIT . '/events/event.section.php');
    return $result;
}

Is not redirecting... :-(

Any idea's?

Try using a redirect like this:

redirect('http://google.com');

See what happens.

if($result->getAttribute('result') == "success") {
    redirect('http://google.com');
    }  

Got me to google on succesfull save!
Cheerio!

Boosh! Happy coding ;)

For now..., here's the next problem ;-)

(I am gonna do this step by step);
Step 1: Trigger the event on pageload... (after redirect)
Step 2: Prevent event to trigger after refreshing page

As i understand the event can be triggered by a condition in the $_POST array...
So i somehow need some post data that's only available once... (like response xml) from the previous event maybe?

@moonoo: Also looked at your hashed field solution, but i don't really understand...
The hash value would still exist on a page refresh, right?

Hi Cremol, did you get any further with your event working correctly?

I've used the SymQl extension from Nick Dunn to query the DB for an entry that has just been submitted in order to pass the values onto another section.

It's worth a look being as the redirect will destroy the post array when you redirect.

I just finished an Event that will handle this issue :D

Tomorrow (Wendsday, around 6am GMT) I'll push the extension to GitHub.

Now then :) nice one.

Here's an extension that deals with this issue.

@moonoo,
I kinda went back to the drawingboard and added the paypal extension...
But i'm still coping with the same problem i think.
So setup now is:
• Submit client data,
• Reroute to paypal,
• Trigger update-inventory event in the paypal response page.
So i added the form and update-inventory event to the response page, which again is working stand alone..
But when triggered through paypal's response ipn, the event get's executed but without the formdata...
I guess because the hidden response page is not actually loaded, but only acts as a reciever for the paypal response. So it does not have access to the form data (at least that's my conclusion, i hope i am wrong here).
So again i need to replicate the formdata inside the event.

I could give SymQl a try, but i think the form is too complex to replicate (at least for me).
So hopefully there's another way to submit the form after completing the paypal transaction.

@ VladG: I think your extension would have handled the event chaining, looks great!
But i am not sure if it offers a solution for submitting the form on the hidden page...

Hi Cremol,

If you have a page listening for post data from Paypal IPN.. or is it GET data sent via url GET params?/

Either way we are no longer listening for a Submit button action as the page isn't a user page as such... hence we should be listening for a $_POST array being set (isset($_POST['fields']['value-from-paypal']) in the load function.

So our lister is customised to wait for Paypal to send the data to our page.. once the POST data gets there, it won't do anything unless our load function conditions are met.

So in your case:

private function load(){

if(isset($_POST['ipn']) && is_numeric($_POST['ipn']) or something similar) return $this->__trigger();
}

I think there also might be a need to check if paypal returns the right array structure.. i.e are we listening for flat $_POST['somevale']; or $_POST['paypal']['somevale']; in order to map to Symphony fields.

Just my 2 cents after using SymQl successfully I feel it's a nice quick solution to check a submitted shopping card order against what Paypal sends back.

Thanks for the explanation!
I already managed to get the event triggered by this condition in the load function: (stolen from the paypal payments: save IPN data event)
(it's post data…)

public function load(){
    $this->post = $_POST;
    if (isset($_POST['verify_sign'])) return $this->__trigger();
}
    protected function __trigger(){
    $_POST['action']['update-inventory'] = 'Submit';

    include(TOOLKIT . '/events/event.section.php');
    return $result;
}

    } 

Hoping that $_POST['action']['update-inventory'] = 'Submit'; would submit the form data,
It does create an entry but does not post the values in the form.
So basically my question is; can these formvalues be posted trough this event?
I need to post the form cause it took a little xslt math to create it and i am not too confident to replicate this using php (and the SymQl extension).

Ok cool,

Have you tried using postbin.heroku.com ? send the paypal redirect to this service to assess what POST values you are getting from Paypal.

I got a feeling the $_POST array from paypal isn't mapping to Symphonys $_POST['fields']['values']; convention so we might need to manipulate the incoming value from paypal to match to Symphonys ones i.e:

public function load(){
    $this->post = $_POST;
    if (isset($_POST['verify_sign'])) return $this->__trigger();
}
    protected function __trigger(){

    $_POST['fields']['symphony_ipn_field'] = $_POST['verify_sign'];    
    $_POST['action']['update-inventory'] = 'Submit';

    include(TOOLKIT . '/events/event.section.php');
    return $result;
}

Does Paypal send $GET or $POST data?

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details