XoopsModules25x /
xdonations
This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include, or for example
via PHP's auto-loading mechanism.
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) 2016 XOOPS Project */ |
||
| 5 | /* http://dev.xoops.org/modules/xfmod/project/?group_id=1060 */ |
||
| 6 | /* |
||
| 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 __DIR__ . '/header.php'; |
||
| 34 | include_once 'include/functions.php'; |
||
| 35 | include_once XOOPS_ROOT_PATH . '/class/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 | $currencySign = defineCurrency($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 . '/xdonations_ipn.log'; |
||
| 55 | if ( false!=($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, $iMax = count($pp_varname); $i < $iMax; ++$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 = fwrite($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') || (strcmp($parent_row_Recordset1['txn_type'], 'web_accept') != 0 && strcmp($parent_row_Recordset1['txn_type'], 'send_money') != 0)) { |
||
| 142 | // This is an error. A reversal implies a pre-existing completed transaction |
||
| 143 | dprt(_MD_DON_TRANSMISSING, _ERR); |
||
| 144 | foreach ($_POST as $key => $val) { |
||
| 145 | dprt("$key => $val", _ERR); |
||
| 146 | } |
||
| 147 | break; |
||
| 148 | } |
||
| 149 | if (1 != $parent_NumDups) { |
||
| 150 | dprt(_MD_DON_MULTITXNS, _ERR); |
||
| 151 | foreach ($_POST as $key => $val) { |
||
| 152 | dprt("$key => $val", _ERR); |
||
| 153 | } |
||
| 154 | break; |
||
| 155 | } |
||
| 156 | |||
| 157 | /* TODO: Need to add info to database. If user donates, then cancels a subsequent |
||
| 158 | * donation then they are removed from group - need a counter to see how many times a |
||
| 159 | * user has donated and only remove from group if 'everything' donated has been reversed. |
||
| 160 | */ |
||
| 161 | |||
| 162 | // remove xoopsUsers (not anon) from group selected by Admin in config |
||
| 163 | if (!empty($pp_varlist['custom'])) { |
||
| 164 | $member_handler = xoops_getHandler('member'); |
||
| 165 | $edituser =& $member_handler->getUser($pp_varlist['custom']); |
||
| 166 | |||
| 167 | // remove the user from the specified group |
||
| 168 | if ($tr_config['assign_group']) { // admin has selected a group in admin |
||
| 169 | $group_handler = xoops_getHandler('group'); |
||
| 170 | $validGroup = $group_handler->get((int)$tr_config['assign_group']); // make sure this is a valid group id |
||
| 171 | if ($validGroup) { |
||
| 172 | $thisUserGroups = $member_handler->getGroupsByUser((int)$edituser->getVar('uid')); |
||
| 173 | if (!in_array($validGroup->getVar('groupid'), $thisUserGroups)) { |
||
| 174 | |||
| 175 | // now find out if user is in the group |
||
| 176 | $isMember = $member_handler->getGroupsByUser($edituser->getVar('uid')); |
||
| 177 | if ($isMember) { |
||
| 178 | $success = $member_handler->removeUserFromGroup($tr_config['assign_group'], $edituser->getVar('uid')); |
||
| 179 | View Code Duplication | if ($success) { |
|
| 180 | dprt('User ' . $edituser->getVar('uname') . ' was removed from the ' . $validGroup->getVar('name') . ' group', _INF); |
||
| 181 | } else { |
||
| 182 | dprt('User ' . $edituser->getVar('uname') . ' could not be removed from the ' . $validGroup->getVar('name') . ' group', _ERR); |
||
| 183 | } |
||
| 184 | } |
||
| 185 | } else { |
||
| 186 | dprt($edituser->getVar('uname') . ' was not in the ' . $validGroup->getVar('name') . ' group', _INF); |
||
| 187 | } |
||
| 188 | } else { |
||
| 189 | dprt('Group isn\'t valid - change Admin configs option<br />', _ERR); |
||
| 190 | } |
||
| 191 | } |
||
| 192 | /* |
||
| 193 | * TODO: Need to add a db table variable to 'demote' the user's rank back to where |
||
| 194 | * it was prior to the reversal |
||
| 195 | */ |
||
| 196 | } |
||
| 197 | $pp_varlist['payment_date'] = strftime('%Y-%m-%d %H:%M:%S', strtotime($pp_varlist['payment_date'])); |
||
| 198 | $field_values = $field_names = ''; |
||
| 199 | View Code Duplication | for ($i = 0, $iMax = count($pp_varname); $i < $iMax; ++$i) { |
|
| 200 | if (0 != $i) { |
||
| 201 | $field_names .= ','; |
||
| 202 | $field_values .= ','; |
||
| 203 | } |
||
| 204 | $field_names .= '`' . $pp_varname[$i] . '`'; |
||
| 205 | $field_values .= "'" . $pp_varlist[$pp_varname[$i]] . "'"; |
||
| 206 | } |
||
| 207 | $insertSQL = 'INSERT INTO ' . $xoopsDB->prefix('donations_transactions') . " ($field_names) VALUES ($field_values)"; |
||
| 208 | |||
| 209 | // We're cleared to add this record |
||
| 210 | dprt($insertSQL, _INF); |
||
| 211 | $Result1 = $xoopsDB->queryF($insertSQL); |
||
| 212 | dprt('SQL result = ' . $Result1, _INF); |
||
| 213 | |||
| 214 | break; |
||
| 215 | // Look for a normal payment |
||
| 216 | } elseif ((strcmp($pp_varlist['payment_status'], 'Completed') == 0) && ((strcmp($pp_varlist['txn_type'], 'web_accept') == 0) || (strcmp($pp_varlist['txn_type'], 'send_money') == 0))) { |
||
| 217 | dprt(_MD_DON_NORMAL_TXN, _INF); |
||
| 218 | if ($lp) { |
||
| 219 | fwrite($lp, $pp_varlist['payer_email'] . ' ' . $pp_varlist['payment_status'] . ' ' . $pp_varlist['payment_date'] . "\n"); |
||
| 220 | } |
||
| 221 | |||
| 222 | if ($NumDups != 0) { // Check for a duplicate txn_id |
||
| 223 | dprt(_MD_DON_DUPLICATETXN, _ERR); |
||
| 224 | foreach ($_POST as $key => $val) { |
||
| 225 | dprt("$key => $val", _ERR); |
||
| 226 | } |
||
| 227 | break; |
||
| 228 | } |
||
| 229 | |||
| 230 | $pp_varlist['payment_date'] = strftime('%Y-%m-%d %H:%M:%S', strtotime($pp_varlist['payment_date'])); |
||
| 231 | $field_values = $field_names = ''; |
||
| 232 | View Code Duplication | for ($i = 0, $iMax = count($pp_varname); $i < $iMax; ++$i) { |
|
| 233 | if ($i != 0) { |
||
| 234 | $field_names .= ','; |
||
| 235 | $field_values .= ','; |
||
| 236 | } |
||
| 237 | $field_names .= '`' . $pp_varname[$i] . '`'; |
||
| 238 | $field_values .= "'" . $pp_varlist[$pp_varname[$i]] . "'"; |
||
| 239 | } |
||
| 240 | $insertSQL = 'INSERT INTO ' . $xoopsDB->prefix('donations_transactions') . " ($field_names) VALUES ($field_values)"; |
||
| 241 | |||
| 242 | // We're cleared to add this record |
||
| 243 | dprt($insertSQL, _INF); |
||
| 244 | $Result1 = $xoopsDB->queryF($insertSQL); |
||
| 245 | dprt('SQL result = ' . $Result1, _INF); |
||
| 246 | |||
| 247 | // add xoopsUsers (not anon) to group if selected by Admin in config |
||
| 248 | if (!empty($pp_varlist['custom']) && (($pp_varlist['option_selection1'] === 'Yes') || ($tr_config['don_forceadd'] == '1'))) { |
||
| 249 | $member_handler = xoops_getHandler('member'); |
||
| 250 | $edituser =& $member_handler->getUser($pp_varlist['custom']); |
||
| 251 | |||
| 252 | // add the user to specified group |
||
| 253 | if ($tr_config['assign_group']) { // config option set to add users to a group |
||
| 254 | $group_handler = xoops_getHandler('group'); |
||
| 255 | $validGroup = $group_handler->get((int)$tr_config['assign_group']); // make sure this is a valid group id |
||
| 256 | if ($validGroup) { |
||
| 257 | $thisUserGroups = $member_handler->getGroupsByUser((int)$edituser->getVar('uid')); |
||
| 258 | if (!in_array($validGroup->getVar('groupid'), $thisUserGroups)) { |
||
| 259 | $success = $member_handler->addUserToGroup($validGroup->getVar('groupid'), $edituser->getVar('uid')); |
||
| 260 | View Code Duplication | if ($success) { |
|
| 261 | dprt('User ' . $edituser->getVar('uname') . ' was added to the ' . $validGroup->getVar('name') . ' group', _INF); |
||
| 262 | } else { |
||
| 263 | dprt('User ' . $edituser->getVar('uname') . ' could not be addded to the ' . $validGroup->getVar('name') . ' group', _ERR); |
||
| 264 | } |
||
| 265 | } else { |
||
| 266 | dprt($edituser->getVar('uname') . ' is already in the ' . $validGroup->getVar('name') . ' group', _INF); |
||
| 267 | } |
||
| 268 | } else { |
||
| 269 | dprt('Group isn\'t valid - change Admin configs option<br />', _ERR); |
||
| 270 | } |
||
| 271 | } |
||
| 272 | |||
| 273 | // add the user to a specific rank |
||
| 274 | if ($tr_config['assign_rank']) { // config option set to add users to a rank |
||
| 275 | $urank = $edituser->rank(); |
||
| 276 | if (0 != $urank['id']) { |
||
| 277 | $result = $xoopsDB->query('SELECT COUNT(*) FROM ' . $xoopsDB->prefix('ranks') . " WHERE rank_id='" . $urank['id'] . "' AND rank_special=0"); |
||
| 278 | list($rank_check) = $xoopsDB->fetchRow($result); |
||
| 279 | $xoopsDB->freeRecordSet($result); |
||
| 280 | } else { |
||
| 281 | $rank_check = 1; |
||
| 282 | } |
||
| 283 | if ($rank_check > 0) { |
||
| 284 | // set user's new rank |
||
| 285 | $edituser->setVar('rank', $tr_config['assign_rank']); |
||
| 286 | $member_handler->insertUser($edituser); |
||
| 287 | } |
||
| 288 | } |
||
| 289 | } |
||
| 290 | break; |
||
| 291 | } else { // We're not interested in this transaction, so we're done |
||
| 292 | dprt(_MD_DON_NOTINTERESTED, _ERR); |
||
| 293 | foreach ($_POST as $key => $val) { |
||
| 294 | dprt("$key => $val", _ERR); |
||
| 295 | } |
||
| 296 | dprt('pp_varlist:', _ERR); |
||
| 297 | foreach ($pp_varlist as $key => $val) { |
||
|
0 ignored issues
–
show
|
|||
| 298 | dprt("$key => $val", _ERR); |
||
| 299 | } |
||
| 300 | dprt('strcmp payment_status: ' . strcmp($pp_varlist['payment_status'], 'Completed'), _ERR); |
||
| 301 | dprt('strcmp txn_type: ' . strcmp($pp_varlist['txn_type'], 'web_accept'), _ERR); |
||
| 302 | dprt('strcmp txn_type: ' . strcmp($pp_varlist['txn_type'], 'send_money'), _ERR); |
||
| 303 | break; |
||
| 304 | } |
||
| 305 | } elseif (strcmp($res, 'INVALID') == 0) { |
||
| 306 | // log for manual investigation |
||
| 307 | dprt(_MD_DON_INVALIDIPN, _ERR); |
||
| 308 | foreach ($_POST as $key => $val) { |
||
| 309 | dprt("$key => $val", _ERR); |
||
| 310 | } |
||
| 311 | break; |
||
| 312 | } else { |
||
| 313 | dprt(_MD_DON_ERR_UNKNOWN_IPN_STAT, _ERR); |
||
| 314 | } |
||
| 315 | } |
||
| 316 | |||
| 317 | if ($dbg) { |
||
| 318 | $sql = 'SELECT * FROM ' . $xoopsDB->prefix('donations_transactions') . ' LIMIT 10'; |
||
| 319 | dprt(_MD_DON_EXECUTING_QUERY, _INF); |
||
| 320 | $Result1 = $xoopsDB->query($sql); |
||
| 321 | if ($Result1) { |
||
| 322 | dprt("<span style=\"font-weight: bold; color: #00CC00;\">" . _MD_DON_DEBUGPASS . '</span>', _INF); |
||
| 323 | } else { |
||
| 324 | dprt("<span style=\"font-weight: bold; color: #CC0000;\">" . _MD_DON_DEBUGFAIL . '</span>', _ERR); |
||
| 325 | } |
||
| 326 | dprt(sprintf(_MD_DON_RCVEMAIL, $tr_config['receiver_email']), _INF); |
||
| 327 | } |
||
| 328 | |||
| 329 | if ($log) { |
||
| 330 | dprt('<br />' . _MD_DON_LOGBEGIN . "<br />\n", _INF); |
||
| 331 | // Insert the log entry |
||
| 332 | $currentDate = strftime('%Y-%m-%d %H:%M:%S', time()); |
||
| 333 | $paymentDate = isset($_POST['payment_date']) ? strftime('%Y-%m-%d %H:%M:%S', strtotime($_POST['payment_date'])) : $currentDate; |
||
| 334 | $sql = 'INSERT INTO ' . $xoopsDB->prefix('donations_translog') . " VALUES (NULL,'{$currentDate}', '{$paymentDate}','" . addslashes($log) . "')"; |
||
| 335 | $Result1 = $xoopsDB->queryF($sql); |
||
| 336 | |||
| 337 | // Clear out old log entries |
||
| 338 | $sql = 'SELECT COUNT(*) FROM ' . $xoopsDB->prefix('donations_translog'); |
||
| 339 | $Result1 = $xoopsDB->query($sql); |
||
| 340 | list($countLogs) = $xoopsDB->fetchRow($Result1); |
||
| 341 | if ($countLogs == $tr_config['ipn_log_entries']) { |
||
| 342 | $sql = 'DELETE FROM ' . $xoopsDB->prefix('donations_translog'); |
||
| 343 | $Result1 = $xoopsDB->queryF($sql); |
||
| 344 | if (false === $Result1) { |
||
| 345 | dprt(_MD_DON_ERR_TXN_NOCLEAR, _ERR); |
||
| 346 | } else { |
||
| 347 | dprt(_MD_DON_ERR_TXN_CLEAR, _INF); |
||
| 348 | } |
||
| 349 | } |
||
| 350 | } |
||
| 351 | |||
| 352 | fclose($fp); |
||
| 353 | if ($lp) { |
||
| 354 | fwrite($lp, _MD_DON_EXITING . "\n"); |
||
| 355 | fclose($lp); |
||
| 356 | } |
||
| 357 | |||
| 358 | if ($dbg) { |
||
| 359 | echo '<hr />'; |
||
| 360 | echo _MD_DON_IFNOERROR . "<br />\n"; |
||
| 361 | echo "<a href='javascript:window.close();'>Close Window</a>"; |
||
| 362 | } |
||
| 363 | |||
| 364 | /** |
||
| 365 | * |
||
| 366 | * Debug Message Store/Display |
||
| 367 | * @param string $str string to store/display |
||
| 368 | * @param int $clvl error reporting level (1 = error, 2= info) |
||
| 369 | */ |
||
| 370 | function dprt($str, $clvl) |
||
| 371 | { |
||
| 372 | global $dbg, $lp, $log, $loglvl; |
||
| 373 | |||
| 374 | if (isset($dbg) && $dbg) { |
||
| 375 | echo $str . '<br />'; |
||
| 376 | } |
||
| 377 | |||
| 378 | if (isset($loglvl) && ($clvl <= $loglvl)) { |
||
| 379 | $log .= $str . "\n"; |
||
| 380 | if (isset($lp) && $lp) { |
||
| 381 | fwrite($lp, strip_tags($str) . "\r\n"); |
||
| 382 | } |
||
| 383 | } |
||
| 384 | } |
||
| 385 |
There are different options of fixing this problem.
If you want to be on the safe side, you can add an additional type-check:
If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:
Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.