diff --git a/enrol/paypal/classes/util.php b/enrol/paypal/classes/util.php new file mode 100644 index 00000000000..a07ae24bf9b --- /dev/null +++ b/enrol/paypal/classes/util.php @@ -0,0 +1,86 @@ +. + +/** + * PayPal enrolment plugin utility class. + * + * @package enrol_paypal + * @copyright 2016 Cameron Ball + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ + +namespace enrol_paypal; + +defined('MOODLE_INTERNAL') || die(); + +/** + * PayPal enrolment plugin utility class. + * + * @package enrol_paypal + * @copyright 2016 Cameron Ball + * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later + */ +final class util { + + /** + * Alerts site admin of potential problems. + * + * @param string $subject email subject + * @param stdClass $data PayPal IPN data + */ + public static function message_paypal_error_to_admin($subject, $data) { + $admin = get_admin(); + $site = get_site(); + + $message = "$site->fullname: Transaction failed.\n\n$subject\n\n"; + + foreach ($data as $key => $value) { + $message .= "$key => $value\n"; + } + + $eventdata = new \stdClass(); + $eventdata->modulename = 'moodle'; + $eventdata->component = 'enrol_paypal'; + $eventdata->name = 'paypal_enrolment'; + $eventdata->userfrom = $admin; + $eventdata->userto = $admin; + $eventdata->subject = "PAYPAL ERROR: ".$subject; + $eventdata->fullmessage = $message; + $eventdata->fullmessageformat = FORMAT_PLAIN; + $eventdata->fullmessagehtml = ''; + $eventdata->smallmessage = ''; + message_send($eventdata); + } + + /** + * Silent exception handler. + * + * @return callable exception handler + */ + public static function get_exception_handler() { + return function($ex) { + $info = get_exception_info($ex); + + $logerrmsg = "enrol_paypal IPN exception handler: ".$info->message; + if (debugging('', DEBUG_NORMAL)) { + $logerrmsg .= ' Debug: '.$info->debuginfo."\n".format_backtrace($info->backtrace, true); + } + error_log($logerrmsg); + + exit(0); + }; + } +} diff --git a/enrol/paypal/ipn.php b/enrol/paypal/ipn.php index 197044f8f86..ba9ff5f8d1d 100644 --- a/enrol/paypal/ipn.php +++ b/enrol/paypal/ipn.php @@ -40,7 +40,7 @@ require_once($CFG->libdir . '/filelib.php'); // PayPal does not like when we return error messages here, // the custom handler just logs exceptions and stops. -set_exception_handler('enrol_paypal_ipn_exception_handler'); +set_exception_handler(\enrol_paypal\util::get_exception_handler()); /// Keep out casual intruders if (empty($_POST) or !empty($_GET)) { @@ -69,16 +69,18 @@ $data->payment_gross = $data->mc_gross; $data->payment_currency = $data->mc_currency; $data->timeupdated = time(); +// Required for message_send. +$PAGE->set_context(context_system::instance()); /// get the user and course records if (! $user = $DB->get_record("user", array("id"=>$data->userid))) { - message_paypal_error_to_admin("Not a valid user id", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Not a valid user id", $data); die; } if (! $course = $DB->get_record("course", array("id"=>$data->courseid))) { - message_paypal_error_to_admin("Not a valid course id", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Not a valid course id", $data); die; } @@ -87,8 +89,11 @@ if (! $context = context_course::instance($course->id, IGNORE_MISSING)) { die; } +// Required for message_send. +$PAGE->set_context(context_course::instance($context)); + if (! $plugin_instance = $DB->get_record("enrol", array("id"=>$data->instanceid, "status"=>0))) { - message_paypal_error_to_admin("Not a valid instance id", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Not a valid instance id", $data); die; } @@ -108,7 +113,7 @@ $result = $c->post($location, $req, $options); if (!$result) { /// Could not connect to PayPal - FAIL echo "

Error: could not access paypal.com

"; - message_paypal_error_to_admin("Could not access paypal.com to verify payment", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Could not access paypal.com to verify payment", $data); die; } @@ -127,14 +132,17 @@ if (strlen($result) > 0) { if ($data->payment_status != "Completed" and $data->payment_status != "Pending") { $plugin->unenrol_user($plugin_instance, $data->userid); - message_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Status not completed or pending. User unenrolled from course", + $data); die; } // If currency is incorrectly set then someone maybe trying to cheat the system if ($data->mc_currency != $plugin_instance->currency) { - message_paypal_error_to_admin("Currency does not match course settings, received: ".$data->mc_currency, $data); + \enrol_paypal\util::message_paypal_error_to_admin( + "Currency does not match course settings, received: ".$data->mc_currency, + $data); die; } @@ -155,7 +163,7 @@ if (strlen($result) > 0) { $eventdata->smallmessage = ''; message_send($eventdata); - message_paypal_error_to_admin("Payment pending", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Payment pending", $data); die; } @@ -172,25 +180,25 @@ if (strlen($result) > 0) { if ($existing = $DB->get_record("enrol_paypal", array("txn_id"=>$data->txn_id))) { // Make sure this transaction doesn't exist already - message_paypal_error_to_admin("Transaction $data->txn_id is being repeated!", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Transaction $data->txn_id is being repeated!", $data); die; } if (core_text::strtolower($data->business) !== core_text::strtolower($plugin->get_config('paypalbusiness'))) { // Check that the email is the one we want it to be - message_paypal_error_to_admin("Business email is {$data->business} (not ". + \enrol_paypal\util::message_paypal_error_to_admin("Business email is {$data->business} (not ". $plugin->get_config('paypalbusiness').")", $data); die; } if (!$user = $DB->get_record('user', array('id'=>$data->userid))) { // Check that user exists - message_paypal_error_to_admin("User $data->userid doesn't exist", $data); + \enrol_paypal\util::message_paypal_error_to_admin("User $data->userid doesn't exist", $data); die; } if (!$course = $DB->get_record('course', array('id'=>$data->courseid))) { // Check that course exists - message_paypal_error_to_admin("Course $data->courseid doesn't exist", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Course $data->courseid doesn't exist", $data); die; } @@ -207,7 +215,7 @@ if (strlen($result) > 0) { $cost = format_float($cost, 2, false); if ($data->payment_gross < $cost) { - message_paypal_error_to_admin("Amount paid is not enough ($data->payment_gross < $cost))", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Amount paid is not enough ($data->payment_gross < $cost))", $data); die; } @@ -304,55 +312,9 @@ if (strlen($result) > 0) { } else if (strcmp ($result, "INVALID") == 0) { // ERROR $DB->insert_record("enrol_paypal", $data, false); - message_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data); + \enrol_paypal\util::message_paypal_error_to_admin("Received an invalid payment notification!! (Fake payment?)", $data); } } exit; - -//--- HELPER FUNCTIONS -------------------------------------------------------------------------------------- - - -function message_paypal_error_to_admin($subject, $data) { - echo $subject; - $admin = get_admin(); - $site = get_site(); - - $message = "$site->fullname: Transaction failed.\n\n$subject\n\n"; - - foreach ($data as $key => $value) { - $message .= "$key => $value\n"; - } - - $eventdata = new stdClass(); - $eventdata->modulename = 'moodle'; - $eventdata->component = 'enrol_paypal'; - $eventdata->name = 'paypal_enrolment'; - $eventdata->userfrom = $admin; - $eventdata->userto = $admin; - $eventdata->subject = "PAYPAL ERROR: ".$subject; - $eventdata->fullmessage = $message; - $eventdata->fullmessageformat = FORMAT_PLAIN; - $eventdata->fullmessagehtml = ''; - $eventdata->smallmessage = ''; - message_send($eventdata); -} - -/** - * Silent exception handler. - * - * @param Exception $ex - * @return void - does not return. Terminates execution! - */ -function enrol_paypal_ipn_exception_handler($ex) { - $info = get_exception_info($ex); - - $logerrmsg = "enrol_paypal IPN exception handler: ".$info->message; - if (debugging('', DEBUG_NORMAL)) { - $logerrmsg .= ' Debug: '.$info->debuginfo."\n".format_backtrace($info->backtrace, true); - } - error_log($logerrmsg); - - exit(0); -}