Extension:PayPal.php
<?php /* IpbWiki Paypal WikiMedia extension
- IpbWiki (c) 2006
- Installation Instructions: http://www.ipbwiki.com/IpbWiki_Paypal_Extension
Changes by User:Nad (1.0.3 - 2007-12-04):
- Added IPN support - Added ability to have a amount box - Change button definitions to work from LocalSettings rather than code hack - Output warnings into sitenotice in error box
- /
if (!defined('MEDIAWIKI')) die('Not an entry point.');
define('PAYPAL_VERSION','1.0.3, 2007-12-04');
$wgPayPalAmount = false; # Add an input field to enter the amount to donate
$wgPayPalIPN = false; # Use IPN notification
$wgPayPalTest = false; # Set to true if testing IPN in the PayPal sandbox site
$wgExtensionCredits['parserhook'][] = array(
'name' => 'IpbWiki PayPal',
'version' => PAYPAL_VERSION,
'author' => 'Peter De Decker, (IPN support by User:Nad)',
'url' => 'http://www.ipbwiki.com/IpbWiki_Paypal_Extension',
'description' => 'Mediawiki PayPal Extension'
);
$ipbwiki_paypal = array(); $wgExtensionFunctions[] = "wfPayPalExtension";
- Set up the extension
function wfPayPalExtension() { global $wgParser, $ipbwiki_paypal, $wgPayPalIPN;
# Register the extension with the WikiText parser $wgParser->setHook( "paypal", "wfPayPalRenderButton" );
# Set button 1 to a default value if not defined if (!isset($ipbwiki_paypal[1])) $ipbwiki_paypal[1] = '<form action="https://www.paypal.com/cgi-bin/webscr" method="post"><input type="hidden" name="cmd" value="_xclick"><input type="hidden" name="business" value="ipbwiki@gmail.com"><input type="hidden" name="item_name" value="IpbWiki PayPal"><input type="hidden" name="no_shipping" value="1"><input type="hidden" name="cn" value="Optional Comments"><input type="hidden" name="currency_code" value="EUR"><input type="hidden" name="tax" value="0"><input type="hidden" name="bn" value="PP-DonationsBF"><input type="image" src="https://www.paypal.com/en_US/i/btn/x-click-but04.gif" border="0" name="submit" alt="Make payments with PayPal - it\'s fast, free and secure!"></form>';
# IPN if ($wgPayPalIPN) {
global $wgHooks, $wgPayPalTest, $wgPayPalIPNTable, $wgUseAjax; $db = &wfGetDB(DB_MASTER);
# If using AJAX add JS updater after page rendered, and add the updater to the allowed AJAX functions if ($wgUseAjax) { $wgAjaxExportList[] = 'wfPayPalAjaxUpdater'; $wgHooks['OutputPageBeforeHTML'][] = 'wfPayPalAddAjaxUpdater'; }
# Create the IPN database table if it doesn't exist $wgPayPalIPNTable = $db->tableName('PayPalIPN'); if (!$db->tableExists($wgPayPalIPNTable)) { $query = "CREATE TABLE $wgPayPalIPNTable (id INTEGER NOT NULL, total_donated NUMERIC, total_donations INTEGER, PRIMARY KEY (id));"; $result = $db->query($query); if ($result instanceof ResultWrapper) $result = $result->result; if ($row = $db->fetchRow($result)) { #$row[0] # todo } }
# If the table couldn't be created, disable IPN and add error to site notice if (!$db->tableExists($wgPayPalIPNTable)) { global $wgSiteNotice; $wgPayPalIPN = false;
$wgSiteNotice = "
Please ensure the wiki database user has CREATE permission, or add the table manually with the following query:
$query
";
}
# If this is an IPN post from paypal, update the DB # todo: test with paypal sandbox what comes back if ($_REQUEST['something']) { $item = isset($_REQUEST['item_number']) ? $_REQUEST['item_number'] : 1; $result = $db->query("SELECT CREATE TABLE $wgPayPalIPNTable;"); if ($result instanceof ResultWrapper) $result = $result->result; if ($row = $db->fetchRow($result)) { #$row[0] # todo } } }
}
- The callback function for converting the input text to HTML output
function wfPayPalRenderButton( $input, $argv ) { global $ipbwiki_paypal, $wgAuth, $wgSiteNotice, $wgPayPalIPN;
$error = '
';
$pos_space = strpos($input,' '); if (!$pos_space) { if (is_numeric($input)) { // format <paypal>number</paypal> $part1 = $input; $part2 = ; if (!$ipbwiki_paypal[$part1]) { $wgSiteNotice .= $error; $part1 = 1; $part2 = $input; } } else { // format <paypal>text</paypal> & format <paypal></paypal> $part1 = 1; $part2 = $input; } } else { // format <paypal>number text</paypal> $part1 = substr($input,0,$pos_space); $part2 = substr($input,$pos_space+1); if (is_numeric($part1)) { if (!$ipbwiki_paypal[$part1]) { $wgSiteNotice .= $error; $part1 = 1; } } else { // format <paypal>text</paypal> $part1 = 1; $part2 = $input; } } $form = $ipbwiki_paypal[$part1]; // if the ipbwiki interface is available, then use the clean function which is defined there, otherwise just clean the necessities... if (class_exists ('ipbwiki')) { $input = $wgAuth->ipbwiki->ipbwiki->clean_value ($part2); } else { $part2 = str_replace( ">", ">", $part2 ); $part2 = str_replace( "<", "<", $part2 ); $part2 = str_replace( "\"", """, $part2 ); $part2 = str_replace( "!", "!", $part2 ); $part2 = str_replace( "'", "'", $part2 ); $input = $part2; }
# IPN if ($wgPayPalIPN) { global $wgPayPalIPNTable, $wgPayPalTest, $wgServer, $wgScript, $wgPayPalItemsRendered;
# Change the paypal URL's to sandbox site if testing if ($wgPayPalTest) $form = str_replace('www.paypal.com','www.sandbox.paypal.com',$form);
# Add a notify_url value in the form to tell paypal to post account changes to this script $form = str_replace('</form>',"<input type=\"hidden\" name=\"notify_url\" value=\"$wgServer$wgScript\" /></form>",$form);
# Replace $1 and $2 in the text with the total amount donated and the total number of donations # - these values are surrounded by div's endowed with id's so that the AJAX updater can access them $db = &wfGetDB(DB_SLAVE); $result = $db->query("SELECT id,total_donated,total_donations FROM $wgPayPalIPNTable WHERE id = '$part1'"); if ($result instanceof ResultWrapper) $result = $result->result; if ($row = $db->fetchRow($result)) {
$total_donated = "
"; $total_donations = "
";
} $input = wfMsgReplaceArgs($input,array($total_donated,$total_donations)); }
$output = '
'.$form.' | '.$input.' |
';
return $output; }
- Adds a JS function to poll for changes to any of the button's totals
function wfPayPalAddAjaxUpdater(&$out) { global $wgJsMimeType; $out->addScript("<script type='$wgJsMimeType'> function workflowUpdateState(name) { clearTimeout(workflowUpdate); workflowLastState = workflowData[name][0]; var state = workflowData[name][workflowLastState]; sajax_do_call('wfPayPalAjaxUpdater',[wgPageName,name,state],document.getElementById('catlinks')); } function workflowSwitchState(name,dir) { clearTimeout(workflowUpdate); document.getElementById('workflow-'+name+'-'+state).setAttribute('style',); if (workflowLastState != state) workflowUpdate = setTimeout('workflowUpdateState(\"'+name+'\")',$wgWorkflowUpdateDelay); } </script>"); return true; }
- The function called by the AJAX dispatcher to return the current totals of all buttons
function wfPayPalAjaxUpdater() { # todo: just return all the items in the db return $something; }