Browse Source

merged changes from Signio module by John Donagher <john@webmeta.com>

PHP-4.0.5
David Croft 26 years ago
parent
commit
09c9d44399
  1. 53
      ext/pfpro/config.m4
  2. 184
      ext/pfpro/pfpro.c
  3. 26
      ext/pfpro/php_pfpro.h

53
ext/pfpro/config.m4

@ -1,36 +1,43 @@
dnl $Id$
dnl config.m4 for extension pfpro
AC_MSG_CHECKING(for Payflow Pro support)
PHP_ARG_WITH(pfpro, for pfpro support,
[ --with-pfpro=[DIR] Include Payflow Pro support])
PHP_ARG_WITH(pfpro, whether to include Verisign Payflow Pro support,
[ --with-pfpro[=DIR] Include Verisign Payflow Pro support])
if test "$PHP_PFPRO" != "no"; then
if test -r $PHP_PFPRO/lib/libpfpro.so; then
PFPRO_DIR=$PHP_PFPRO
else
AC_MSG_CHECKING(for libpfpro in default path)
for i in /usr/local /usr; do
if test -r $i/lib/libpfpro.so; then
PFPRO_DIR=$i
AC_MSG_RESULT(found in $i)
fi
done
for i in /usr/local /usr $PHP_PFPRO; do
if test -r $i/pfpro.h; then
PFPRO_INC_DIR=$i
elif test -r $i/include/pfpro.h; then
PFPRO_INC_DIR=$i/include
fi
if test -r $i/libpfpro.so; then
PFPRO_LIB_DIR=$i
elif test -r $i/lib/libpfpro.so; then
PFPRO_LIB_DIR=$i/lib
fi
done
if test -z "$PFPRO_INC_DIR"; then
AC_MSG_ERROR(Could not find pfpro.h. Please make sure you have the
Verisign Payflow Pro SDK installed. Use
./configure --with-pfpro=<pfpro-dir> if necessary)
fi
if test -z "$PFPRO_DIR"; then
AC_MSG_RESULT(not found)
AC_MSG_ERROR(Please install the payflow pro SDK distribution -
pfpro.h should be in <pfpro-dir>/include and
libpfpro.so should be in <pfpro-dir>/lib)
Use ./configure --with-pfpro=<pfpro-dir> if necessary
if test -z "$PFPRO_LIB_DIR"; then
AC_MSG_ERROR(Could not find libpfpro.so. Please make sure you have the
Verisign Payflow Pro SDK installed. Use
./configure --with-pfpro=<pfpro-dir> if necessary)
fi
AC_ADD_INCLUDE($PFPRO_DIR/include)
AC_MSG_RESULT(found in $PFPRO_LIB_DIR)
PHP_SUBST(PFPRO_SHARED_LIBADD)
AC_ADD_INCLUDE($PFPRO_INC_DIR)
AC_ADD_LIBRARY_WITH_PATH(pfpro, $PFPRO_DIR, PFPRO_SHARED_LIBADD)
PHP_SUBST(PFPRO_SHARED_LIBADD)
AC_ADD_LIBRARY_WITH_PATH(pfpro, $PFPRO_LIB_DIR, PFPRO_SHARED_LIBADD)
AC_DEFINE(HAVE_PFPRO, 1, [ ])

184
ext/pfpro/pfpro.c

@ -12,7 +12,8 @@
| obtain it through the world-wide-web, please send a note to |
| license@php.net so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
| Author: David Croft <david@infotrek.co.uk> |
| Authors: David Croft <david@infotrek.co.uk>, |
| John Donagher <john@webmeta.com> |
+----------------------------------------------------------------------+
*/
@ -22,8 +23,7 @@
as I've yet to decide whether this is a good way to place "default"
stuff like hosts and proxies */
/* Status: Working. Awaiting comments from Signio as to whether
PNInit and ProcessPNTransaction have any meaningful return value */
/* Status: Working. */
#include "php.h"
#include "php_ini.h"
@ -55,8 +55,8 @@ zend_module_entry pfpro_module_entry = {
pfpro_functions,
PHP_MINIT(pfpro),
PHP_MSHUTDOWN(pfpro),
NULL, /* request start */
NULL, /* request end */
PHP_RINIT(pfpro), /* request start */
PHP_RSHUTDOWN(pfpro), /* request end */
PHP_MINFO(pfpro),
STANDARD_MODULE_PROPERTIES
};
@ -86,10 +86,21 @@ PHP_MSHUTDOWN_FUNCTION(pfpro)
return SUCCESS;
}
PHP_RINIT_FUNCTION(pfpro)
{
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(pfpro)
{
return SUCCESS;
}
PHP_MINFO_FUNCTION(pfpro)
{
php_info_print_table_start();
php_info_print_table_header(2, "Signio Payflow Pro support", "enabled");
php_info_print_table_header(2, "Verisign Payflow Pro support", "enabled");
php_info_print_table_end();
/*
@ -165,7 +176,7 @@ PHP_FUNCTION(pfpro_process_raw)
/* No, I don't like that Signio tell you to use a
fixed length buffer either */
char response[512];
char response[512] = "";
if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
WRONG_PARAM_COUNT;
@ -263,8 +274,8 @@ PHP_FUNCTION(pfpro_process)
pval ***args;
HashTable *target_hash;
ulong lkey;
char *varname;
ulong num_key;
char *string_key;
zval **entry;
int pass;
@ -283,11 +294,16 @@ PHP_FUNCTION(pfpro_process)
/* No, I don't like that Signio tell you to use a
fixed length buffer either */
char response[512];
char response[512] = "";
char tmpbuf[128];
char *rsppos, *valpos;
char buf[128], sbuf[128];
char *p1, *p2, *p_end, /* Pointers for string manipulation */
*sp1, *sp2, *sp_end,
*pdelim1="&", *pdelim2="=";
if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 8) {
WRONG_PARAM_COUNT;
@ -296,13 +312,13 @@ PHP_FUNCTION(pfpro_process)
args = (pval ***) emalloc(sizeof(pval **) * ZEND_NUM_ARGS());
if (zend_get_parameters_array_ex(ZEND_NUM_ARGS(), args) == FAILURE) {
php_error(E_WARNING, "Unable to read parameters in pfpro_process()");
php_error(E_ERROR, "Unable to read parameters in pfpro_process()");
efree(args);
RETURN_FALSE;
}
if ((*args[0])->type != IS_ARRAY) {
php_error(E_WARNING, "First parameter to pfpro_process() must be an array");
php_error(E_ERROR, "First parameter to pfpro_process() must be an array");
efree(args);
RETURN_FALSE;
}
@ -359,20 +375,48 @@ PHP_FUNCTION(pfpro_process)
zend_hash_internal_pointer_reset(target_hash);
while (zend_hash_get_current_data(target_hash, (void **)&entry) == SUCCESS) {
if (zend_hash_get_current_key(target_hash, &varname, &lkey) == HASH_KEY_IS_STRING) {
if (parmlength > 0) {
if (pass == 1)
strcpy(parmlist + parmlength, "&");
parmlength += 1;
}
if (parmlength > 0) {
if (pass == 1)
strcpy(parmlist + parmlength, varname);
parmlength += strlen(varname);
strcpy(parmlist + parmlength, "&");
parmlength += 1;
}
/* John I don't see any need to put the key in a zval
if it's not used as such and is pulled straight out */
switch (zend_hash_get_current_key(target_hash, &string_key, &num_key)) {
case HASH_KEY_IS_STRING:
if (pass == 1)
strcpy(parmlist + parmlength, string_key);
parmlength += strlen(string_key);
efree(string_key);
break;
case HASH_KEY_IS_LONG:
sprintf(tmpbuf, "%d", num_key);
if (pass == 1)
strcpy(parmlist + parmlength, tmpbuf);
parmlength += strlen(tmpbuf);
if ((*entry)->type == IS_STRING) {
if (strchr((*entry)->value.str.val, '&') ||
strchr((*entry)->value.str.val, '=')) {
break;
default:
php_error(E_ERROR, "pfpro_process() array keys must be strings or integers");
efree(args);
RETURN_FALSE;
}
switch ((*entry)->type) {
case IS_STRING:
if (strchr((*entry)->value.str.val, '&')
|| strchr((*entry)->value.str.val, '=')) {
sprintf(tmpbuf, "[%d]=", (*entry)->value.str.len);
if (pass == 1)
strcpy(parmlist + parmlength, tmpbuf);
@ -383,31 +427,33 @@ PHP_FUNCTION(pfpro_process)
strcpy(parmlist + parmlength, "=");
parmlength += 1;
}
if (pass == 1)
strcpy(parmlist + parmlength, (*entry)->value.str.val);
parmlength += (*entry)->value.str.len;
}
else if ((*entry)->type == IS_LONG) {
break;
case IS_LONG:
sprintf(tmpbuf, "=%d", (*entry)->value.lval);
if (pass == 1)
strcpy(parmlist + parmlength, tmpbuf);
parmlength += strlen(tmpbuf);
}
else if ((*entry)->type == IS_DOUBLE) {
break;
case IS_DOUBLE:
sprintf(tmpbuf, "=%.2f", (*entry)->value.dval);
if (pass == 1)
strcpy(parmlist + parmlength, tmpbuf);
parmlength += strlen(tmpbuf);
}
else {
php_error(E_WARNING, "pfpro_process() array values should be strings, ints or floats");
}
efree(varname);
}
else {
php_error(E_WARNING, "pfpro_process() array keys must be strings");
efree(args);
RETURN_FALSE;
break;
default:
php_error(E_ERROR, "pfpro_process() array values must be strings, ints or floats");
efree(args);
RETURN_FALSE;
}
zend_hash_move_forward(target_hash);
}
@ -442,7 +488,7 @@ PHP_FUNCTION(pfpro_process)
from this BEFORE we knock it off to the bank */
if (array_init(return_value) == FAILURE) {
php_error(E_WARNING, "pfpro_process() unable to create array");
php_error(E_ERROR, "pfpro_process() unable to create array");
RETURN_FALSE;
}
@ -458,6 +504,8 @@ PHP_FUNCTION(pfpro_process)
efree(address);
}
#if 0
/* Decode the response back into a PHP array */
rsppos = strtok(response, "&");
@ -471,6 +519,66 @@ PHP_FUNCTION(pfpro_process)
}
} while (rsppos = strtok(NULL, "&"));
#else
/* This final chunk of code is to walk the string returned by Signio
and build a string array to return to the user */
/* John, I suspect this code will fall over if there are less than
3 items in the response string -- david */
/* Clean our str[n]cpy buffers */
memset(buf, 0, sizeof(buf));
memset(sbuf, 0, sizeof(sbuf));
p_end = response + strlen(response);
p1 = response;
p2 = (char*)php_memnstr(response, pdelim1, 1, p_end);
sp1 = (char*)php_memnstr(response, pdelim2, 1, p2);
strncpy(buf, p1, sp1-p1);
sp1++;
strncpy(sbuf, sp1, p2-sp1);
add_assoc_string(return_value, &buf[0], &sbuf[0], 1);
do {
memset(buf, 0, sizeof(buf));
memset(sbuf, 0, sizeof(sbuf));
p1 = p2+1;
if ((sp2 = (char*)php_memnstr(p1, pdelim1, 1, p_end)) != NULL) {
sp1 = (char*)php_memnstr(p1, pdelim2, 1, sp2);
strncpy(buf, p1, sp1-p1);
sp1++;
strncpy(sbuf, sp1, sp2-sp1);
add_assoc_string(return_value, &buf[0], &sbuf[0], 1);
}
} while ((p2 = (char*)php_memnstr(p1, pdelim1, 1, p_end)) != NULL);
if (p1 <= p_end) {
memset(buf, 0, sizeof(buf));
memset(sbuf, 0, sizeof(sbuf));
sp1 = (char*)php_memnstr(p1, pdelim2, 1, p_end);
strncpy(buf, p1, sp1-p1);
sp1++;
strncpy(sbuf, sp1, p_end-sp1);
add_assoc_string(return_value, &buf[0], &sbuf[0], 1);
}
#endif
}
/* }}} */

26
ext/pfpro/php_pfpro.h

@ -38,31 +38,17 @@ PHP_RINIT_FUNCTION(pfpro);
PHP_RSHUTDOWN_FUNCTION(pfpro);
PHP_MINFO_FUNCTION(pfpro);
PHP_FUNCTION(pfpro_version); /* Return library version */
PHP_FUNCTION(pfpro_init);
PHP_FUNCTION(pfpro_cleanup);
PHP_FUNCTION(pfpro_process_raw);
PHP_FUNCTION(pfpro_process);
PHP_FUNCTION(pfpro_version); /* Return library version */
PHP_FUNCTION(pfpro_init); /* Initialise pfpro gateway */
PHP_FUNCTION(pfpro_cleanup); /* Shut down cleanly */
PHP_FUNCTION(pfpro_process_raw); /* Raw transaction processing */
PHP_FUNCTION(pfpro_process); /* Transaction processing */
/* Fill in this structure and use entries in it
for thread safety instead of using true globals.
*/
typedef struct {
/* You can use the next one as type if your module registers any
resources. Oh, you can of course rename it to something more
suitable, add list entry types or remove it if it not needed.
It's just an example.
*/
int le_pfpro;
int initialised;
} php_pfpro_globals;
/* In every function that needs to use variables in php_pfpro_globals,
do call PFPROLS_FETCH(); after declaring other variables used by
that function, and always refer to them as PFPROG(variable).
You are encouraged to rename these macros something shorter, see
examples in any other php module directory.
*/
#ifdef ZTS
#define PFPROG(v) (pfpro_globals->v)
#define PFPROLS_FETCH() php_pfpro_globals *pfpro_globals = ts_resource(gd_pfpro_id)

Loading…
Cancel
Save