function repairSerializedArray(&$broken) { // array and string length can be ignored // a:0:{} // s:4:"four"; // i:1; // b:0; true/false // N; null $data = array(); $index = null; $last_len = null; $len = strlen($broken); $i = 0; while (strlen($broken)) { $i++; if ($i > $len) { break; } if (substr($broken, 0, 1) == '}') { $broken = substr($broken, 1); return $data; } else { $bite = substr($broken, 0, 2); switch ($bite) { case 's:': // key or value $re = '/^s:\\d+:"([^\\"]+)";/'; if (preg_match($re, $broken, $m)) { if ($index === null) { $index = $m[1]; } else { $data[$index] = $m[1]; $index = null; } $broken = preg_replace($re, '', $broken); } break; case 'i:': // key or value $re = '/^i:(\\d+);/'; if (preg_match($re, $broken, $m)) { if ($index === null) { $index = (int) $m[1]; } else { $data[$index] = (int) $m[1]; $index = null; } $broken = preg_replace($re, '', $broken); } break; case 'b:': // value only $re = '/^b:[01];/'; if (preg_match($re, $broken, $m)) { $data[$index] = (bool) $m[1]; $index = null; $broken = preg_replace($re, '', $broken); } break; case 'a:': // value only $re = '/^a:\\d+:\\{/'; if (preg_match($re, $broken, $m)) { $broken = preg_replace('/^a:\\d+:\\{/', '', $broken); $data[$index] = repairSerializedArray($broken); $index = null; } break; case 'N;': // value only $broken = substr($broken, 2); $data[$index] = null; $index = null; break; } } } return $data; }
/** * Display a single row from the ipnlog * * Not only display the row, but beautify the serialized POST data from the transaction * for easy viewing. * * @param int $id Unique identifier for the row of the ipnlog to display * @param string $txn_id Unique identifier for the row (txn_id) of the ipnlog to display * @return string HTML of the ipnlog row specified by $id */ function PAYPAL_ipnlog_single($id, $txn_id) { global $_TABLES, $LANG_PAYPAL_1, $_CONF, $_PAY_CONF, $_SCRIPTS; $input_ipn = 0; $js = 'jQuery(document).ready(function() { jQuery(".paypal_handle_purchase").live("click", function() { var action = jQuery(this).attr("class"); var ipn = jQuery(this).attr("ipn"); var string = \'&action=\' + action + \'&ipn=\' + ipn; if (confirm(\'' . $LANG_PAYPAL_1['confirm_handle_purchase'] . '\')) { //jQuery(this).parent().parent().fadeOut("slow"); jQuery.ajax({ type: "POST", url: "' . $_CONF['site_url'] . '/admin/plugins/paypal/ajax.php", data: string, cache: false, async:false, success: function(result){ jQuery(".paypal_handle_purchase").parent().replaceWith("<span style=\\"color:red;\\">"+result+"</span>"); } }); } return false; }); });'; $_SCRIPTS->setJavaScriptLibrary('jquery'); $_SCRIPTS->setJavaScript($js, true); // Get ipnlog from database if ($id > 0) { $sql = "SELECT * FROM {$_TABLES['paypal_ipnlog']} WHERE id = {$id}"; } else { $sql = "SELECT * FROM {$_TABLES['paypal_ipnlog']} WHERE txn_id = '{$txn_id}'"; } $res = DB_query($sql); $A = DB_fetchArray($res); // Start Display $display .= COM_startBlock($LANG_PAYPAL_1['ipn_history'] . " (#{$A['id']})"); // Create ipnlog template $ipnlog = new Template($_CONF['path'] . 'plugins/paypal/templates'); $ipnlog->set_file(array('ipnlog' => 'ipnlog_detail.thtml')); $ipnlog->set_var('site_url', $_CONF['site_url']); $ipnlog->set_var('IPN_log', $LANG_PAYPAL_1['IPN_log']); $ipnlog->set_var('IP_address', $LANG_PAYPAL_1['IP_address']); $ipnlog->set_var('date_time', $LANG_PAYPAL_1['date_time']); $ipnlog->set_var('Verified', $LANG_PAYPAL_1['verified']); $ipnlog->set_var('transaction', $LANG_PAYPAL_1['transaction']); $ipnlog->set_var('gross_payment', $LANG_PAYPAL_1['gross_payment']); $ipnlog->set_var('payment_status_label', $LANG_PAYPAL_1['payment_status']); $ipnlog->set_var('ipn_data', $LANG_PAYPAL_1['ipn_data']); $ipnlog->set_var('mc_gross', $A['mc_gross']); $ipnlog->set_var('mc_currency', $_PAY_CONF['currency']); $ipnlog->set_var('txn_id', $A['txn_id']); // Allow all serialized data to be available to the template $ipn = ''; if ($A['ipn_data'] != '') { //Diagnotic PAYPAL_check_serialization($A['ipn_data'], $errmsg); //Serialize fixer $out = preg_replace('!s:(\\d+):"(.*?)";!se', "'s:'.strlen('\$2').':\"\$2\";'", $A['ipn_data']); PAYPAL_check_serialization($out, $errmsg); if (!($ipn = unserialize($out))) { $ipn = repairSerializedArray($A['ipn_data']); $errmsg = 'IPN ' . $A['txn_id'] . ' is not complete'; $input_ipn = 1; } if (!is_array($ipn)) { $ipn = array(); } foreach ($ipn as $name => $value) { $ipnlog->set_var($name, $value); } } // Display the specified ipnlog row $ipnlog->set_var('id', $A['id']); $ipnlog->set_var('ip_addr', $A['ip_addr']); $ipnlog->set_var('time', $A['time']); if ($A['verified']) { $ipnlog->set_var('verified', $LANG_PAYPAL_1['true']); } else { $txt = $LANG_PAYPAL_1['false'] . ' | Payment status: ' . strtolower($ipn['payment_status']); //Update IPN and handle purchase if (strtolower($ipn['payment_status']) == ('complete' || 'completed')) { $txt .= ' >> <a class="paypal_handle_purchase" ipn="' . $A['txn_id'] . '" href="">' . $LANG_PAYPAL_1['handle_purchase'] . '</a>'; } $ipnlog->set_var('verified', $txt); } // Grab a raw print of the ipn data ob_start(); print_r($ipn); $raw = ob_get_contents(); ob_end_clean(); // replace \n with <br> $raw = nl2br($raw); $ipnlog->set_var('raw', stripslashes($raw)); if ($errmsg != '') { if (DEBUG) { COM_errorLog('PAYPAL: Error(s) in IPN ' . $errmsg); } $errors .= '<p><span style="color:red;">! Error(s) in IPN: ' . $errmsg . '</span></p>'; if ($input_ipn == 1) { //Display textarea for new IPN $js2 = 'jQuery(".paypal_ipn_replace").delegate(".paypal_new_ipn","click",function() { var action = jQuery(this).attr("class"); var id = jQuery(this).attr("id"); var content = jQuery("textarea#ipn_textarea").val(); content = encodeURIComponent(content); var string = \'&action=\' + action + \'&ipn=\' + id + \'&content=\' + content; jQuery.ajax({ type: "POST", url: "' . $_CONF['site_url'] . '/admin/plugins/paypal/ajax.php", data: string, cache: false, async:false, success: function(result){ jQuery("div#paypal_ipn_replace").replaceWith(result); } }); return false; });'; $_SCRIPTS->setJavaScript($js2, true); $errors .= '<div id="paypal_ipn_replace" class="paypal_ipn_replace"> <p>' . $LANG_PAYPAL_1['replace_ipn'] . '</p> <form action=""> <textarea id="ipn_textarea" class="paypal_handle_ipn"></textarea> <br' . XHTML . '><input class="paypal_new_ipn" id="' . $A['txn_id'] . '" type="submit"> <form> </div>'; } $ipnlog->set_var('errormsg', $errors); } else { $ipnlog->set_var('errormsg', ''); } $display .= $ipnlog->parse('output', 'ipnlog'); $display .= COM_endBlock(); return $display; }