1 of 2
1
Multiple POST actions
Posted: 07 December 2010 08:55 PM   [ Ignore ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

I am new to SafeCracker and fairly new to EE, so bear with my ignorance of a few details.

I am building a form for a client which MUST use a PHP script at a 3rd party vendor as my POST action, but I would like to have the contents of the form published into a channel via SafeCracker. 

Is there a way to have SafeCracker publish the form contents to the desired channel and THEN run the 3rd party’s PHP POST action?

Any input would be GREATLY appreciated!

Profile
 
 
Posted: 07 December 2010 09:10 PM   [ Ignore ]   [ # 1 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

You’d have to write a custom extension to do this, and probably use curl to submit your 3rd party POST action.

Profile
 
 
Posted: 07 December 2010 09:26 PM   [ Ignore ]   [ # 2 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Thank you for the quick reply.  Is there any documentation you can point me to as a place to start?  Is there anything specific to SafeCracker I need to know to do this, or is it a boilerplate EE development process?

Profile
 
 
Posted: 07 December 2010 09:30 PM   [ Ignore ]   [ # 3 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

More of an EE thing. Here’s a list of the hooks in SafeCracker: http://barrettnewton.com/safecracker/user_guide/development/#section_hooks You probably would use safecracker_submit_entry_end.

And here are the docs on EE extension development: http://expressionengine.com/user_guide/development/extensions.html

Profile
 
 
Posted: 07 December 2010 09:31 PM   [ Ignore ]   [ # 4 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Many thanks!

Profile
 
 
Posted: 08 December 2010 08:13 PM   [ Ignore ]   [ # 5 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

So, I’ve done some homework and poked around, but I think I may be trying to do this the hard way. 

I followed your advice and built an extension using cURL to gather up the POST values and make a cURL connection to the gateway system (though I have no idea how to test what might not be working… it’s not posting any errors presently, but it’s not doing what I want either).  I think this might be the wrong way forward.  At the very least I’m missing something important.

What I want to do is essentially make the return=”” parameter an external url as opposed to a template path and pass that POST data to that URL after it finished writing to the channel.  When the form has been submitted, after writing to the channel, I should be at a shopping cart checkout site that hosted externally.

I’ve found a CI reference to this kind of external redirect CI Redirect - CI forums, but I don’t technically want to do a redirect in the 301 sense.  I want to add an action that is an external php url.  Here’s the default form code with some account details xx’ed out:

<form id="giftcert" action="https://secure.integritypaymentgateway.com/cart/cart.php" method="POST">
    <
input type="text" size="6" name="amount" value="53.00" />
    <
input type="text" size="26" name="merchant_defined_field_1" value="Recipient (if not purchaser)" />
    <
input type="text" size="24" name="merchant_defined_field_2" value="Full name of purchaser" />
    <
textarea rows="4" cols="53" name="merchant_defined_field_3">Leave a message here for your recipient</textarea>
    <
div id="ship_radio">
      <
input type="radio" name="merchant_defined_field_4" value="by_mail" />
      <
label>First Class Mail ($1.75 fee)</label><br />
      <
input type="radio" name="merchant_defined_field_4" value="by_email" />
      <
label>Digital Delivery (via email)</label>
    </
div>
    <
input type="hidden" name="title" value='{current_time format="{DATE_W3C}"}'>
    <
input type="hidden" name="key_id" value="XXXXXXXXX" />
    <
input type="hidden" name="action" value="process_variable" />
    <
input type="hidden" name="order_description" value="Gift Certificate" />
    <
input type="hidden" name="language" value="en" />
    <
input type="hidden" name="url_finish" value="http://client_domain.com" />
    <
input type="hidden" name="customer_receipt" value="true" />
    <
input type="hidden" name="hash" value="action|order_description|XXXXXXXXXXXXXXXXXXXXXXXXXX" />
    <
input type="submit" name="submit" value="SUBMIT" />
  </
form

So I swapped out the form tags for these:

{exp:safecracker id="giftcert" channel="gift_cert_orders" return="https://secure.integritypaymentgateway.com/cart/cart.php" logged_out_member_id="2"}
     
<.......rest of the form.......>
  
{/exp:safecracker} 

I’ve also made sure to use a correct return=“site/index” style return parameter, but it still doesn’t work.  It just redirects me to my home page regardless.

I don’t have enough characters to paste my extension code, but I’ll put it in the next post for reference.

[ Edited: 08 December 2010 08:19 PM by Samuel Allen | No1 ]
Profile
 
 
Posted: 08 December 2010 08:16 PM   [ Ignore ]   [ # 6 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

This is what I tried for my extension code.  Keep in mind, this is my first extension, and I’m not too savvy at cURL either.  I’m sure I noobed this to a fare-thee-well.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

  
/**
  * multiPOST - Allows safeCracker to execute an additional POST action after submitting form data to the specified channel 
  * 
  * @package multiPOST
  * @version  0.1
  * @author Samuel Allen | No1, inc.
  * @license  Private - All rights reserved by No1, inc.
  */
  
  
class multiPOST_ext {
    
var $name 'multiPOST';
    var 
$version    '1.0.0';
    var 
$description  "Runs second POST action after form data is pushed into the channel";
    var 
$settings_exist 'n';
    var 
$docs_url   '';
    var 
$settings   '';
    
    
// -------------------------------
    //   Constructor
    // -------------------------------
    
    
function multiPOST_ext($settings '')
    
{
      $this
->EE =& get_instance();

        
$this->settings $settings;
    
// END Constructor

    
function curl_POST() {
      
//create array of data to be posted
      
$post_data['amount''53.00';
      
$post_data['merchant_defined_field_1''Recipient (if not purchaser)';
      
$post_data['merchant_defined_field_2''Full name of purchaser';
      
$post_data['merchant_defined_field_3''Leave a message here for your recipient';
      
$post_data['merchant_defined_field_4''by_email';
      
$post_data['key_id''XXXXXXXX';
      
$post_data['action''process_variable';
      
$post_data['order_description''Gift Certificate';
      
$post_data['language''en';
      
$post_data['url_finish''http://client_domain.com';
      
$post_data['customer_receipt''true';
      
$post_data['hash''action|order_description|XXXXXXXXXXXXXXXXXXXXXXXX';
      
      
//traverse array and prepare data for posting (key1=value1)
      
foreach ( $post_data as $key => $value{
        $post_items[] 
$key '=' $value;
      
}
      
      
//create the final string to be posted using implode()
      
$post_string implode ('&'$post_items);
      
      
//create cURL connection
      
$curl_connection curl_init('https://secure.integritypaymentgateway.com/cart/cart.php');
      
      
//set options
      
curl_setopt($curl_connectionCURLOPT_CONNECTTIMEOUT30);
      
curl_setopt($curl_connectionCURLOPT_USERAGENT"Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
      
curl_setopt($curl_connectionCURLOPT_RETURNTRANSFERtrue);
      
curl_setopt($curl_connectionCURLOPT_SSL_VERIFYPEERfalse);
      
curl_setopt($curl_connectionCURLOPT_FOLLOWLOCATION1);
      
      
//set data to be posted
      
curl_setopt($curl_connectionCURLOPT_POSTFIELDS$post_string);
      
      
//perform our request
      
$result curl_exec($curl_connection);
      
      
//show information regarding the request
      
print_r(curl_getinfo($curl_connection));
      echo 
curl_errno($curl_connection) . '-' curl_error($curl_connection);
      
      
//close the connection
      
curl_close($curl_connection);
    
}
    
    
// -------------------------------
    //   Activate Extension
    // -------------------------------
  
    
function activate_extension() {
        $data 
= array(
          
'class'      => "multiPOST_ext",
          
'method'    => "curl_POST",
          
'hook'      => "safecracker_submit_entry_end",
          
'settings'    => "",
          
'priority'    => 1,
          
'version'    => $this->version,
          
'enabled'    => "y"
        
);
  
        
// insert in database
        
$this->EE->db->insert('exp_extensions'$data);
    
// END Activate Extension

  
    // --------------------------------
    //  Update Extension
    // --------------------------------  
    
    
function update_extension($current '')
    
{
      
return TRUE;
    
// END Update Extension
    
    // -------------------------------
    //   Deactivate Extension
    // -------------------------------
    
function disable_extension() {
      $this
->EE->db->where('class''multiPOST_ext');
      
$this->EE->db->delete('extensions');
    
// END Deactivate Extension
  
// END CLASS

/* End of file ext.multipost.php */
/* Location: ./solo_system/expressionengine/third_party/multipost/ext.multipost.php */ 

My guess is I made this waaay more complicated than it needs to be, but I would appreciate any assistance.  Thanks in advance!

Profile
 
 
Posted: 08 December 2010 08:18 PM   [ Ignore ]   [ # 7 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

So you want to be as though the user actually POSTs to https://secure.integritypaymentgateway.com/cart/cart.php? Is that essentially what you’re getting at?

Profile
 
 
Posted: 08 December 2010 08:27 PM   [ Ignore ]   [ # 8 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Exactly so!  But only after the data has been saved to a channel entry first.

Profile
 
 
Posted: 08 December 2010 08:42 PM   [ Ignore ]   [ # 9 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

I hate to say this, but it’s not really possible this way. The cURL is a POST request coming from your web server, not from the user/client, which is not really what you want, assuming that your offsite cart intends to create a cookie/session for the client browser. It’s not possible to make two client POST requests from one form/action.

Unless…

You use ajax, first to submit the entry form asynchronously, and once that request is complete, do a normal, non-ajax form submit to the offsite cart.

Profile
 
 
Posted: 08 December 2010 09:34 PM   [ Ignore ]   [ # 10 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Thanks for the reply.

I see in your usage examples an AJAX driven form example...  Just to make sure I understand what you’re saying, would I use something like that example, but put in place of the:

if (data.success{
                alert(
'You successfully added a new entry with entry_id '.data.entry_id)
            } 
else... 

a series of setAttribute statements to set the safecracker form tags back the way I need them to work with our shopping cart vendor and then submit with JS?

Thanks for all your help with this.  You are saving my life!

Profile
 
 
Posted: 09 December 2010 01:53 AM   [ Ignore ]   [ # 11 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

Yeah, something like:

success: function(data{
    
if ( ! data.success{
        alert(
'THERE WAS AN ERROR');
    
else {
        
var form = $('form#publishForm').get(0);
        
form.setAttribute('action''https://secure.integritypaymentgateway.com/cart/cart.php');
        
form.submit();
    
}
Profile
 
 
Posted: 10 December 2010 08:20 AM   [ Ignore ]   [ # 12 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Okay…  So I’m most of the way there, I think. 

I’ve essentially built what we’ve discussed, but instead of getting an alert error or redirecting, I’m getting a blank page with the following at the top:

{"success":1,"errors":[],"field_errors":[],"entry_id":"34","url_title":"2010-12-09t211303-0600","channel_id":"2"

in plain text.  The records are getting set in EE, but it seems the AJAXey part isn’t working.  :(  Or maybe I’m just not understanding what’s happening.  Any input would be appreciated.

I’m also wondering if it might make sense to create an page template which does nothing but repost the record’s values into a new form which auto submits the way I need it to.

Here’s my script:

$(document).ready(function(){
    
$('#giftcert').ajaxForm({
      dataType
'json',
      
success: function(data{
        
if ( ! data.success{
          alert(
'Failed with the following errors: '+data.errors.join(', '));
        
else {
          
var form = $('#giftcert').get(0);
          
form.setAttribute('action''https://secure.integritypaymentgateway.com/cart/cart.php');
          
form.submit();
        
}
      }
     }
);
   
}); 
Profile
 
 
Posted: 10 December 2010 08:22 AM   [ Ignore ]   [ # 13 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Okay…  So I’m most of the way there, I think. 

I’ve essentially built what we’ve discussed, but instead of getting an alert error or redirecting, I’m getting a blank page with the following at the top:

{"success":1,"errors":[],"field_errors":[],"entry_id":"34","url_title":"2010-12-09t211303-0600","channel_id":"2"

in plain text.  The records are getting set in EE, but it seems the AJAXey part isn’t working.  :(  Or maybe I’m just not understanding what’s happening.  Any input would be appreciated.

I’m also wondering if it might make sense to create an page template which does nothing but repost the record’s values into a new form which auto submits the way I need it to.

Here’s my script:

$(document).ready(function(){
    
$('#giftcert').ajaxForm({
      dataType
'json',
      
success: function(data{
        
if ( ! data.success{
          alert(
'Failed with the following errors: '+data.errors.join(', '));
        
else {
          
var form = $('#giftcert').get(0);
          
form.setAttribute('action''https://secure.integritypaymentgateway.com/cart/cart.php');
          
form.submit();
        
}
      }
     }
);
   
}); 
Profile
 
 
Posted: 10 December 2010 08:23 AM   [ Ignore ]   [ # 14 ]
Has a Great Personality
Rank
Total Posts:  49
Joined  2010-12-07

Blargh!  Sorrry for the double post.  Had a network hiccup.

Profile
 
 
Posted: 10 December 2010 09:07 PM   [ Ignore ]   [ # 15 ]
Teen Scream
Avatar
RankRankRank
Total Posts:  3541
Joined  2009-05-29

Your form is not submitting via ajax. Check your browser for JS errors.

Profile
 
 
   
1 of 2
1
 
‹‹ what going wrong      Two problems ››