Completed
Push — master ( 625e32...22cdbd )
by Michael
02:37
created

ipnppd.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/************************************************************************/
3
/* Donations - Paypal financial management module for Xoops 2           */
4
/* Copyright (c) 2004 by Xoops2 Donations Module Dev Team			    */
5
/* http://dev.xoops.org/modules/xfmod/project/?group_id=1060			*/
6
/* $Id: ipnppd.php 8193 2011-11-07 02:42:53Z beckmi $      */
0 ignored issues
show
Unused Code Comprehensibility introduced by
47% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
7
/************************************************************************/
8
/*                                                                      */
9
/* Based on NukeTreasury for PHP-Nuke - by Dave Lawrence AKA Thrash     */
10
/* NukeTreasury - Financial management for PHP-Nuke                     */
11
/* Copyright (c) 2004 by Dave Lawrence AKA Thrash                       */
12
/*                       [email protected]                         */
13
/*                       [email protected]                          */
14
/*                                                                      */
15
/************************************************************************/
16
/*                                                                      */
17
/* This program is free software; you can redistribute it and/or modify */
18
/* it under the terms of the GNU General Public License as published by */
19
/* the Free Software Foundation; either version 2 of the License.       */
20
/*                                                                      */
21
/* This program is distributed in the hope that it will be useful, but  */
22
/* WITHOUT ANY WARRANTY; without even the implied warranty of           */
23
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU     */
24
/* General Public License for more details.                             */
25
/*                                                                      */
26
/* You should have received a copy of the GNU General Public License    */
27
/* along with this program; if not, write to the Free Software          */
28
/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  */
29
/* USA                                                                  */
30
/************************************************************************/
31
32
//$xoopsOption['nocommon'] = 1;
33
include 'header.php';
34
include_once 'include' . DIRECTORY_SEPARATOR . 'functions.php';
35
include_once XOOPS_ROOT_PATH . DIRECTORY_SEPARATOR . 'class' . DIRECTORY_SEPARATOR . 'xoopsformloader.php';
36
37
$tr_config = configInfo();
38
$paypal_url = explode('|',$tr_config['paypal_url']);
39
$paypal_url = $paypal_url[0];
40
//determine the currency
41
$PP_CURR_CODE = explode('|',$tr_config['pp_curr_code']); // [USD,GBP,JPY,CAD,EUR]
42
$PP_CURR_CODE = $PP_CURR_CODE[0];
43
$curr_sign = define_curr($PP_CURR_CODE);
44
45
$pp_varlist=simple_query($xoopsDB->prefix('donations_transactions'),'','',array('id'));
46
47
define('_ERR', 1);
48
define('_INF', 2);
49
$ERR = 0;
50
$log = '';
51
$loglvl = $tr_config['ipn_dbg_lvl'];
52
53
// creates a log file in the XOOPS uploads directory
54
$lpFile = XOOPS_UPLOAD_PATH . DIRECTORY_SEPARATOR . 'xdonations_ipn.log';
55
if ( $lp = fopen($lpFile, 'w+') ) {
56
    dprt(_MD_DON_LOGFILE_CREATED, _INF);
57
} else {
58
    dprt(_MD_DON_LOGFILE_NOT_CREATED, _ERR);
59
}
60
dprt(date('r'), _INF);
61
$dbg = (isset($_GET['dbg']) && $_GET['dbg'] ) ? TRUE : FALSE ;
62
63
if( $dbg ) {
64
    dprt(_MD_DON_DEBUGACTIVE, _INF);
65
    echo _MD_DON_DEBUGHEADER;
66
    $pp_varlist['receiver_email'] = $tr_config['receiver_email'];
67
}
68
69
// read the post from PayPal system and add 'cmd'
70
$req = 'cmd=_notify-validate';
71
72
foreach ($_POST as $key => $value) {
73
    $value = urlencode(stripslashes($value));
74
    $req .= "&$key=$value";
75
}
76
77
// post back to PayPal system to validate
78
dprt(_MD_DON_OPENCONN, _INF);
79
$fp = fsockopen ($paypal_url, 80, $errno, $errstr, 30);
80
81
if (!$fp) { // HTTP ERROR
82
    //TODO: use CURL if fsockopen fails
83
    dprt("<style=\"color: #00CC00;\">" . _MD_DON_CONNFAIL . "</span>", _ERR);
84
    die( sprintf(_MD_DON_POSTBACK_FAIL, $errno, $errstr) );
85
} else {
86
    dprt(_MD_DON_POSTBACK_OK, _INF);
87
    $header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
88
    $header .= "Content-Type: application/x-www-form-urlencoded\r\n";
89
    $header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
90
}
91
92
// assign posted variables to local variables
93
$pp_varname = array_values(array_intersect(array_keys($pp_varlist), array_keys($_POST)));
94
for ($i = 0; $i < count($pp_varname); $i++) {
95
    $pp_varlist[$pp_varname[$i]] = $_POST[$pp_varname[$i]];
96
}
97
98
if ( '' == $pp_varlist['payment_date'] ) { //set blank date to proper format
99
    $pp_varlist['payment_date'] = '0000-00-00 00:00:00';
100
}
101
102
$writeOk = fputs ($fp, $header . $req);
103
if (!$writeOk) { // HTTP ERROR
104
    dprt("<style=\"font-weight: bold; color: #00CC00;\">" . _MD_DON_WRITEFAIL . "</span>", _ERR);
105
    die(sprintf(_MD_DON_ERR_FAILED_WRITE, $errno, $errstr));
106
} else {
107
    dprt(_MD_DON_WRITEOK, _INF);
108
}
109
110
// Perform PayPal email account verification
111
if ( !$dbg && (strcasecmp( $pp_varlist['business'], $tr_config['receiver_email']) != 0) ) {
112
    dprt(sprintf(_MD_DON_BUSINVALID,$pp_varlist['business']), _ERR) ;
113
    dprt(sprintf(_MD_DON_RCVINVALID,$pp_varlist['receiver_email']), _ERR) ;
114
    $ERR = 1;
115
}
116
117
$insertSQL = '';
118
// Look for duplicate txn_id's
119
if( $pp_varlist['txn_id'] ) {
120
    $sql = "SELECT COUNT(*) FROM ".$xoopsDB->prefix("donations_transactions")." WHERE txn_id = '" . addslashes($pp_varlist['txn_id']) . "'";
121
    $Recordset1 = $xoopsDB->query($sql);
122
    list($NumDups) = $xoopsDB->fetchRow($Recordset1);
123
}
124
if ( $pp_varlist['parent_txn_id'] ) {
125
    $parent_sql = "SELECT * FROM ".$xoopsDB->prefix("donations_transactions")." WHERE txn_id = '" . addslashes($pp_varlist['parent_txn_id']) . "'";
126
    $parent_Recordset1 = $xoopsDB->query($parent_sql);
127
    $parent_row_Recordset1 = $xoopsDB->fetchArray($parent_Recordset1);
128
    $parent_NumDups = $xoopsDB->getRowsNum($parent_Recordset1);
129
}
130
131
while (!$dbg && !$ERR && !feof($fp)) {
132
    $res = fgets ($fp, 1024);
133
    if (strcmp ($res, "VERIFIED") == 0) {
134
        // Ok - PayPal has told us we have a valid IPN here
135
        dprt(_MD_DON_VERIFIED, _INF);
136
137
        // Check for a reversal for a refund
138
        if( strcmp($pp_varlist['payment_status'], "Refunded") == 0 || strcmp($pp_varlist['txn_type'], "Reversal") == 0) {
139
            // Verify the reversal
140
            dprt(_MD_DON_REFUND, _INF);
141
            if ( ($parent_NumDups == 0) || strcmp($parent_row_Recordset1['payment_status'], "Completed") ||
142
            (strcmp($parent_row_Recordset1['txn_type'], "web_accept") != 0 && strcmp($parent_row_Recordset1['txn_type'], "send_money") != 0) ) {
143
                // This is an error.  A reversal implies a pre-existing completed transaction
144
                dprt(_MD_DON_TRANSMISSING, _ERR);
145
                foreach( $_POST as $key => $val ) {
146
                    dprt("$key => $val", _ERR);
147
                }
148
                break;
149
            }
150
            if ( 1 != $parent_NumDups  ) {
151
                dprt(_MD_DON_MULTITXNS, _ERR);
152
                foreach ( $_POST as $key => $val ) {
153
                    dprt("$key => $val", _ERR);
154
                }
155
                break;
156
            }
157
158
            /* TODO: Need to add info to database.  If user donates, then cancels a subsequent
159
             * donation then they are removed from group - need a counter to see how many times a
160
             * user has donated and only remove from group if 'everything' donated has been reversed.
161
             */
162
163
            // remove xoopsUsers (not anon) from group selected by Admin in config
164
            if ( !empty($pp_varlist['custom']) ){
165
                $member_handler =& xoops_gethandler('member');
166
                $edituser =& $member_handler->getUser($pp_varlist['custom']);
167
168
                // remove the user from the specified group
169
                if ($tr_config['assign_group']) {  // admin has selected a group in admin
170
                    $group_handler =& xoops_gethandler('group');
171
                    $validGroup = $group_handler->get(intval($tr_config['assign_group'])); // make sure this is a valid group id
172
                    if ($validGroup) {
173
                        $thisUserGroups = $member_handler->getGroupsByUser(intval($edituser->getVar('uid')));
174
                        if (!in_array($validGroup->getVar('groupid'), $thisUserGroups)) {
175
176
                            // now find out if user is in the group
177
                            $isMember = $member_handler->getGroupsByUser($edituser->getVar('uid'));
178
                            if ($isMember) {
179
                                $success = $member_handler->removeUserFromGroup($tr_config['assign_group'], $edituser->getVar('uid'));
180 View Code Duplication
                                if ($success) {
181
                                    dprt("User " . $edituser->getVar('uname') . " was removed from the " . $validGroup->getVar('name') . " group", _INF);
182
                                } else {
183
                                    dprt ("User " . $edituser->getVar('uname') . " could not be removed from the " . $validGroup->getVar('name') ." group", _ERR);
184
                                }
185
                            }
186
                        } else {
187
                            dprt ($edituser->getVar('uname') . " was not in the " . $validGroup->getVar('name') . " group", _INF);
188
                        }
189
                    } else {
190
                        dprt ('Group isn\'t valid - change Admin configs option<br />', _ERR);
191
                    }
192
                }
193
                /*
194
                 * TODO: Need to add a db table variable to 'demote' the user's rank back to where
195
                 * it was prior to the reversal
196
                 */
197
            }
198
            $pp_varlist['payment_date'] = strftime('%Y-%m-%d %H:%M:%S',strtotime($pp_varlist['payment_date']));
199
            $field_values=$field_names='';
200 View Code Duplication
            for ($i = 0; $i < count($pp_varname); $i++) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
201
                if ( 0 != $i ){
202
                    $field_names .= ',';
203
                    $field_values .= ',';
204
                }
205
                $field_names .= '`' . $pp_varname[$i] . '`';
206
                $field_values .= "'" . $pp_varlist[$pp_varname[$i]] . "'";
207
            }
208
            $insertSQL = "INSERT INTO ".$xoopsDB->prefix("donations_transactions")." ($field_names) VALUES ($field_values)";
209
210
            // We're cleared to add this record
211
            dprt($insertSQL, _INF);
212
            $Result1 = $xoopsDB->queryF($insertSQL);
213
            dprt("SQL result = " . $Result1, _INF);
214
215
            break;
216
            // Look for a normal payment
217
        } elseif ( (strcmp($pp_varlist['payment_status'], "Completed") == 0) && ((strcmp($pp_varlist['txn_type'], "web_accept")== 0) || (strcmp($pp_varlist['txn_type'], "send_money")== 0)) ) {
218
            dprt(_MD_DON_NORMAL_TXN, _INF);
219
            if( $lp ) {
220
                fputs($lp, $pp_varlist['payer_email'] . " " . $pp_varlist['payment_status'] . " " . $pp_varlist['payment_date'] . "\n");
221
            }
222
223
            if ( $NumDups != 0 ) { // Check for a duplicate txn_id
224
                dprt(_MD_DON_DUPLICATETXN, _ERR);
225
                foreach ( $_POST as $key => $val ) {
226
                    dprt("$key => $val", _ERR);
227
                }
228
                break;
229
            }
230
231
            $pp_varlist['payment_date'] = strftime('%Y-%m-%d %H:%M:%S', strtotime($pp_varlist['payment_date']));
232
            $field_values = $field_names = '';
233 View Code Duplication
            for ($i = 0; $i < count($pp_varname); $i++) {
0 ignored issues
show
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
234
                if ( $i != 0 ) {
235
                    $field_names .= ',';
236
                    $field_values .= ',';
237
                }
238
                $field_names .= '`'.$pp_varname[$i].'`';
239
                $field_values .= "'".$pp_varlist[$pp_varname[$i]]."'";
240
            }
241
            $insertSQL = "INSERT INTO ".$xoopsDB->prefix("donations_transactions")." ($field_names) VALUES ($field_values)";
242
243
            // We're cleared to add this record
244
            dprt($insertSQL, _INF);
245
            $Result1 = $xoopsDB->queryF($insertSQL);
246
            dprt("SQL result = " . $Result1, _INF);
247
248
            // add xoopsUsers (not anon) to group if selected by Admin in config
249
            if ( !empty($pp_varlist['custom']) && ( ($pp_varlist['option_selection1'] == 'Yes') || ($tr_config['don_forceadd'] == '1') ) ) {
250
                $member_handler =& xoops_gethandler('member');
251
                $edituser =& $member_handler->getUser($pp_varlist['custom']);
252
253
                // add the user to specified group
254
                if ( $tr_config['assign_group'] ) {  // config option set to add users to a group
255
                    $group_handler =& xoops_gethandler('group');
256
                    $validGroup = $group_handler->get(intval($tr_config['assign_group'])); // make sure this is a valid group id
257
                    if ($validGroup) {
258
                        $thisUserGroups = $member_handler->getGroupsByUser(intval($edituser->getVar('uid')));
259
                        if (!in_array($validGroup->getVar('groupid'), $thisUserGroups)) {
260
                            $success = $member_handler->addUserToGroup($validGroup->getVar('groupid'), $edituser->getVar('uid'));
261 View Code Duplication
                            if ($success) {
262
                                dprt("User " . $edituser->getVar('uname') . " was added to the " . $validGroup->getVar('name') . " group", _INF);
263
                            } else {
264
                                dprt ("User " . $edituser->getVar('uname') . " could not be addded to the " . $validGroup->getVar('name') ." group", _ERR);
265
                            }
266
                        } else {
267
                            dprt ($edituser->getVar('uname') . " is already in the " . $validGroup->getVar('name') . " group", _INF);
268
                        }
269
                    } else {
270
                        dprt ('Group isn\'t valid - change Admin configs option<br />', _ERR);
271
                    }
272
                }
273
274
                // add the user to a specific rank
275
                if ( $tr_config['assign_rank'] ) {  // config option set to add users to a rank
276
                    $urank = $edituser->rank();
277
                    if ( 0 != $urank['id'] ) {
278
                        $result = $xoopsDB->query("SELECT COUNT(*) FROM ".$xoopsDB->prefix('ranks')." WHERE rank_id='".$urank['id']."' AND rank_special=0");
279
                        list($rank_check) = $xoopsDB->fetchRow($result);
280
                        $xoopsDB->freeRecordSet($result);
281
                    } else {
282
                        $rank_check = 1;
283
                    }
284
                    if ( $rank_check > 0 ) {
285
                        // set user's new rank
286
                        $edituser->setVar('rank', $tr_config['assign_rank']);
287
                        $member_handler->insertUser($edituser);
288
                    }
289
                }
290
            }
291
            break;
292
        } else  { // We're not interested in this transaction, so we're done
293
            dprt(_MD_DON_NOTINTERESTED, _ERR);
294
            foreach ( $_POST as $key => $val ) {
295
                dprt("$key => $val", _ERR);
296
            }
297
            dprt('pp_varlist:',_ERR);
298
            foreach ( $pp_varlist as $key => $val ) {
299
                dprt("$key => $val", _ERR);
300
            }
301
            dprt('strcmp payment_status: '.strcmp($pp_varlist['payment_status'], "Completed"),_ERR);
302
            dprt('strcmp txn_type: '.strcmp($pp_varlist['txn_type'], "web_accept"),_ERR);
303
            dprt('strcmp txn_type: '.strcmp($pp_varlist['txn_type'], "send_money"),_ERR);
304
            break;
305
        }
306
    } elseif (strcmp ($res, "INVALID") == 0) {
307
        // log for manual investigation
308
        dprt(_MD_DON_INVALIDIPN, _ERR);
309
        foreach( $_POST as $key => $val ) {
310
            dprt("$key => $val", _ERR);
311
        }
312
        break;
313
    } else {
314
        dprt(_MD_DON_ERR_UNKNOWN_IPN_STAT, _ERR);
315
    }
316
}
317
318
if( $dbg ) {
319
    $sql = "SELECT * FROM ".$xoopsDB->prefix("donations_transactions") . " LIMIT 10";
320
    dprt(_MD_DON_EXECUTING_QUERY, _INF);
321
    $Result1 = $xoopsDB->query($sql);
322
    if ( $Result1 ) {
323
        dprt("<span style=\"font-weight: bold; color: #00CC00;\">" . _MD_DON_DEBUGPASS . "</span>", _INF);
324
    } else {
325
        dprt("<span style=\"font-weight: bold; color: #CC0000;\">" . _MD_DON_DEBUGFAIL . "</span>", _ERR);
326
    }
327
    dprt(sprintf(_MD_DON_RCVEMAIL,$tr_config['receiver_email']), _INF);
328
}
329
330
if( $log ) {
331
    dprt("<br />" . _MD_DON_LOGBEGIN . "<br />\n", _INF);
332
    // Insert the log entry
333
    $currentDate = strftime('%Y-%m-%d %H:%M:%S',mktime());
334
    $paymentDate = isset($_POST['payment_date']) ? strftime('%Y-%m-%d %H:%M:%S',strtotime($_POST['payment_date'])) : $currentDate;
335
    $sql = "INSERT INTO " . $xoopsDB->prefix("donations_translog") . " VALUES (NULL,'{$currentDate}', '{$paymentDate}','" . addslashes($log) . "')";
336
    $Result1 = $xoopsDB->queryF($sql);
337
338
    // Clear out old log entries
339
    $sql = "SELECT COUNT(*) FROM ".$xoopsDB->prefix("donations_translog");
340
    $Result1 = $xoopsDB->query($sql);
341
    list($countLogs) = $xoopsDB->fetchRow($Result1);
342
    if( $countLogs == $tr_config['ipn_log_entries'] ) {
343
        $sql =  "DELETE FROM " . $xoopsDB->prefix("donations_translog");
344
        $Result1 = $xoopsDB->queryF($sql);
345
        if ( FALSE === $Result1 ) {
346
            dprt(_MD_DON_ERR_TXN_NOCLEAR, _ERR);
347
        } else {
348
            dprt(_MD_DON_ERR_TXN_CLEAR, _INF);
349
        }
350
    }
351
}
352
353
fclose ($fp);
354
if( $lp ) {
355
    fputs($lp, _MD_DON_EXITING . "\n");
356
    fclose ($lp);
357
}
358
359
if( $dbg) {
360
    echo "<hr />";
361
    echo _MD_DON_IFNOERROR . "<br />\n";
362
    echo "<a href='javascript:window.close();'>Close Window</a>";
363
}
364
365
/**
366
 *
367
 * Debug Message Store/Display
368
 * @param string $str string to store/display
369
 * @param int $clvl error reporting level (1 = error, 2= info)
370
 */
371
function dprt($str, $clvl)
372
{
373
    global $dbg, $lp, $log, $loglvl;
374
375
    if ( isset($dbg) && $dbg ) {
376
        echo $str . "<br />";
377
    }
378
379
    if ( isset($loglvl) && ($clvl <= $loglvl) ) {
380
        $log .= $str . "\n";
381
        if ( isset($lp) && $lp ) {
382
            fputs($lp, strip_tags($str) . "\r\n");
383
        }
384
    }
385
}
386