function pmprodev_checkout_debug_email($level) { global $pmprodev_options, $current_user, $wpdb; if (empty($pmprodev_options['checkout_debug_email'])) { return $level; } $email = new PMProEmail(); if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') { $http = 'https://'; } else { $http = 'http://'; } $email->subject = sprintf('%s Checkout Page Debug Log', get_bloginfo('name')); $email->recipient = $pmprodev_options['checkout_debug_email']; $email->template = 'checkout_debug'; $email->body = file_get_contents(plugin_dir_path(__FILE__) . '/email/checkout_debug.html'); $email->data = array('sitename' => get_bloginfo('sitename'), 'checkout_url' => $http . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'], 'submit' => print_r($_REQUEST['submit-checkout'], true), 'level' => print_r($level, true), 'user' => print_r($current_user->data, true), 'request' => print_r($_REQUEST, true)); $order = new MemberOrder(); $order->getLastMemberOrder($current_user->user_id); if (!empty($order)) { $email->data['order'] = print_r($order, true); } $email->sendEmail(); return $level; }
function pmproeewe_extra_emails() { global $wpdb; //make sure we only run once a day $today = date("Y-m-d 00:00:00"); /* Here is where you set how many emails you want to send, how early, and which template files to e-mail. If you set the template file to an empty string '' then it will send the default PMPro expiring e-mail. Place your email templates in a subfolder of your active theme. Create a paid-memberships-pro folder in your theme folder, and then create an email folder within that. Your template files should have a suffix of .html, but you don't put it below. So if you create a file in there called myexpirationemail.html, then you'd just put 'myexpirationemail' in the array below. (PMPro will fill in the .html for you.) */ $emails = array(30 => 'mem_expiring_30days', 60 => 'mem_expiring_60days', 90 => 'mem_expiring_90days'); //<--- !!! UPDATE THIS ARRAY TO CHANGE WHEN EMAILS GO OUT AND THEIR TEMPLATE FILES !!! --> ksort($emails, SORT_NUMERIC); //array to store ids of folks we sent emails to so we don't email them twice $sent_emails = array(); foreach (array_keys($emails) as $days) { //look for memberships that are going to expire within one week (but we haven't emailed them within a week) $sqlQuery = "SELECT mu.user_id, mu.membership_id, mu.startdate, mu.enddate FROM {$wpdb->pmpro_memberships_users} mu LEFT JOIN {$wpdb->usermeta} um ON um.user_id = mu.user_id AND um.meta_key = 'pmpro_expiration_notice_" . $days . "' WHERE mu.status = 'active' AND mu.enddate IS NOT NULL AND mu.enddate <> '' AND mu.enddate <> '0000-00-00 00:00:00' AND DATE_SUB(mu.enddate, INTERVAL " . $days . " Day) <= '" . $today . "' AND (um.meta_value IS NULL OR DATE_ADD(um.meta_value, INTERVAL " . $days . " Day) <= '" . $today . "') ORDER BY mu.enddate"; $expiring_soon = $wpdb->get_results($sqlQuery); foreach ($expiring_soon as $e) { if (!in_array($e->user_id, $sent_emails)) { //send an email $pmproemail = new PMProEmail(); $euser = get_userdata($e->user_id); if ($euser) { $euser->membership_level = pmpro_getMembershipLevelForUser($euser->ID); $pmproemail->email = $euser->user_email; $pmproemail->subject = sprintf(__("Your membership at %s will end soon", "pmpro"), get_option("blogname")); if (strlen($emails[$days]) > 0) { $pmproemail->template = $emails[$days]; } else { $pmproemail->template = "membership_expiring"; } $pmproemail->data = array("subject" => $pmproemail->subject, "name" => $euser->display_name, "user_login" => $euser->user_login, "sitename" => get_option("blogname"), "membership_id" => $euser->membership_level->id, "membership_level_name" => $euser->membership_level->name, "siteemail" => pmpro_getOption("from_email"), "login_link" => wp_login_url(), "enddate" => date(get_option('date_format'), $euser->membership_level->enddate), "display_name" => $euser->display_name, "user_email" => $euser->user_email); $pmproemail->sendEmail(); printf(__("Membership expiring email sent to %s. ", "pmpro"), $euser->user_email); $sent_emails[] = $e->user_id; } } //update user meta so we don't email them again update_user_meta($e->user_id, "pmpro_expiration_notice_" . $days, $today); } } }
function pmpro_delete_user($user_id = NULL) { global $wpdb; //changing their membership level to 0 will cancel any subscription and remove their membership level entry //we don't remove the orders because it would affect reporting if (pmpro_changeMembershipLevel(0, $user_id)) { //okay } else { //couldn't delete the subscription //we should probably notify the admin global $pmpro_error; if (!empty($pmpro_error)) { $pmproemail = new PMProEmail(); $pmproemail->data = array("body" => "<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", "pmpro"), strval($user_id)) . "</p><p>Error: " . $pmpro_error . "</p>"); $last_order = $wpdb->get_row("SELECT * FROM {$wpdb->pmpro_membership_orders} WHERE user_id = '" . $user_id . "' ORDER BY timestamp DESC LIMIT 1"); if (!empty($last_order)) { $pmproemail->data["body"] .= "<p>Last Invoice:<br />" . nl2br(var_export($last_order, true)) . "</p>"; } $pmproemail->sendEmail(get_bloginfo("admin_email")); } } }
pmpro_stripeWebhookExit(); } else { $logstr .= "Could not find the related subscription for event with ID #" . $event->id . "."; if (!empty($event->data->object->customer)) { $logstr .= " Customer ID #" . $event->data->object->customer . "."; } pmpro_stripeWebhookExit(); } } elseif ($event->type == "customer.subscription.deleted") { //for one of our users? if they still have a membership, notify the admin $user = getUserFromCustomerEvent($event, "success", true); if (!empty($user->ID)) { do_action("pmpro_stripe_subscription_deleted", $user->ID); $pmproemail = new PMProEmail(); $pmproemail->data = array("body" => "<p>" . sprintf(__("%s has had their payment subscription cancelled by Stripe. Please check that this user's membership is cancelled on your site if it should be.", "pmpro"), $user->display_name . " (" . $user->user_login . ", " . $user->user_email . ")") . "</p>"); $pmproemail->sendEmail(get_bloginfo("admin_email")); $logstr .= "Subscription deleted for user ID #" . $user->ID . ". Event ID #" . $event->id . "."; pmpro_stripeWebhookExit(); } else { //check for any user at all $user = getUserFromCustomerEvent($event); if (!empty($user->ID)) { $logstr .= "Stripe tells us a subscription is deleted. This was probably initiated from PMPro and the membership/order is already cancelled. Event ID #" . $event->id . "."; } else { $logstr .= "Stripe tells us a subscription is deleted, but we could not find a user here for that subscription. Could be a subscription managed by a different app or plugin. Event ID #" . $event->id . "."; } pmpro_stripeWebhookExit(); } } } else { if (!empty($event_id)) {
/** * Cancel an order and call the cancel step of the gateway class if needed. */ function cancel() { //only need to cancel on the gateway if there is a subscription id if (empty($this->subscription_transaction_id)) { //just mark as cancelled $this->updateStatus("cancelled"); return true; } else { //cancel the gateway subscription first $result = $this->Gateway->cancel($this); if ($result == false) { //there was an error, but cancel the order no matter what $this->updateStatus("cancelled"); //we should probably notify the admin $pmproemail = new PMProEmail(); $pmproemail->template = "subscription_cancel_error"; $pmproemail->data = array("body" => "<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", "pmpro"), strval($this->user_id)) . "</p><p>Error: " . $this->error . "</p>"); $pmproemail->data["body"] .= "<p>Associated Order:<br />" . nl2br(var_export($this, true)) . "</p>"; $pmproemail->sendEmail(get_bloginfo("admin_email")); return false; } else { //would have been cancelled by the gateway class return $result; } } }
function sendEmail($post_ids, $user_id) { if (!class_exists("PMProEmail")) { return; } $email = new PMProEmail(); $user = get_user_by('id', $user_id); //build list of posts $post_list = "<ul>\n"; foreach ($post_ids as $post_id) { $post_list .= '<li><a href="' . get_permalink($post_id) . '">' . get_the_title($post_id) . '</a></li>' . "\n"; } $post_list .= "</ul>\n"; $email->email = $user->user_email; $email->subject = sprintf(__("New content is available at %s", "pmpro"), get_option("blogname")); $email->template = "new_content"; //check for custom email template if (file_exists(get_stylesheet_directory() . '/paid-memberships-pro/series/new_content.html')) { $template_path = get_stylesheet_directory() . '/paid-memberships-pro/series/new_content.html'; } elseif (file_exists(get_template_directory() . '/paid-memberships-pro/series/new_content.html')) { $template_path = get_template_directory() . '/paid-memberships-pro/series/new_content.html'; } else { $template_path = plugins_url('email/new_content.html', dirname(__FILE__)); } $email->body = file_get_contents($template_path); $email->data = array("name" => $user->display_name, "sitename" => get_option("blogname"), "post_list" => $post_list, "login_link" => wp_login_url()); if (!empty($post->post_excerpt)) { $email->data['excerpt'] = '<p>An excerpt of the post is below.</p><p>' . $post->post_excerpt . '</p>'; } else { $email->data['excerpt'] = ''; } $email->sendEmail(); }
/** * Cancel an order and call the cancel step of the gateway class if needed. */ function cancel() { //only need to cancel on the gateway if there is a subscription id if (empty($this->subscription_transaction_id)) { //just mark as cancelled $this->updateStatus("cancelled"); return true; } else { //cancel the gateway subscription first $result = $this->Gateway->cancel($this); if ($result == false) { //there was an error, but cancel the order no matter what $this->updateStatus("cancelled"); //we should probably notify the admin $pmproemail = new PMProEmail(); $pmproemail->template = "subscription_cancel_error"; $pmproemail->data = array("body" => "<p>" . sprintf(__("There was an error canceling the subscription for user with ID=%s. You will want to check your payment gateway to see if their subscription is still active.", "pmpro"), strval($this->user_id)) . "</p><p>Error: " . $this->error . "</p>"); $pmproemail->data["body"] .= "<p>Associated Order:<br />" . nl2br(var_export($this, true)) . "</p>"; $pmproemail->sendEmail(get_bloginfo("admin_email")); return false; } else { //Note: status would have been set to cancelled by the gateway class. So we don't have to update it here. //remove billing numbers in pmpro_memberships_users if the membership is still active global $wpdb; $sqlQuery = "UPDATE {$wpdb->pmpro_memberships_users} SET initial_payment = 0, billing_amount = 0, cycle_number = 0 WHERE user_id = '" . $this->user_id . "' AND membership_id = '" . $this->membership_id . "' AND status = 'active'"; $wpdb->query($sqlQuery); return $result; } } }
function pmpropbc_reminder_emails() { global $wpdb; //make sure we only run once a day $now = current_time('timestamp'); $today = date("Y-m-d", $now); //have to run for each level, so get levels $levels = pmpro_getAllLevels(true, true); if (empty($levels)) { return; } foreach ($levels as $level) { //get options $options = pmpropbc_getOptions($level->id); if (!empty($options['reminder_days'])) { $date = date("Y-m-d", strtotime("+ " . $options['reminder_days'] . " days", $now)); } else { $date = $today; } //need to get all combos of pay cycle and period $sqlQuery = "SELECT DISTINCT(CONCAT(cycle_number, ' ', cycle_period)) FROM {$wpdb->pmpro_memberships_users} WHERE membership_id = '" . $level->id . "' AND cycle_number > 0 AND status = 'active'"; $combos = $wpdb->get_col($sqlQuery); if (empty($combos)) { continue; } foreach ($combos as $combo) { //get all check orders still pending after X days $sqlQuery = "\r\n\t\t\t\tSELECT id \r\n\t\t\t\tFROM {$wpdb->pmpro_membership_orders} \r\n\t\t\t\tWHERE membership_id = {$level->id} \r\n\t\t\t\t\tAND gateway = 'check' \r\n\t\t\t\t\tAND status = 'pending' \r\n\t\t\t\t\tAND DATE_ADD(timestamp, INTERVAL {$combo}) <= '" . $date . "'\r\n\t\t\t\t\tAND notes NOT LIKE '%Reminder Sent:%' AND notes NOT LIKE '%Reminder Skipped:%'\r\n\t\t\t\tORDER BY id\r\n\t\t\t"; if (defined('PMPRO_CRON_LIMIT')) { $sqlQuery .= " LIMIT " . PMPRO_CRON_LIMIT; } $orders = $wpdb->get_col($sqlQuery); if (empty($orders)) { continue; } foreach ($orders as $order_id) { //get some data $order = new MemberOrder($order_id); $user = get_userdata($order->user_id); $user->membership_level = pmpro_getMembershipLevelForUser($order->user_id); //if they are no longer a member, let's not send them an email if (empty($user->membership_level) || empty($user->membership_level->ID) || $user->membership_level->id != $order->membership_id) { //note when we send the reminder $new_notes = $order->notes . "Reminder Skipped:" . $today . "\n"; $wpdb->query("UPDATE {$wpdb->pmpro_membership_orders} SET notes = '" . esc_sql($new_notes) . "' WHERE id = '" . $order_id . "' LIMIT 1"); continue; } //note when we send the reminder $new_notes = $order->notes . "Reminder Sent:" . $today . "\n"; $wpdb->query("UPDATE {$wpdb->pmpro_membership_orders} SET notes = '" . esc_sql($new_notes) . "' WHERE id = '" . $order_id . "' LIMIT 1"); //setup email to send $email = new PMProEmail(); $email->template = "check_pending_reminder"; $email->email = $user->user_email; $email->subject = sprintf(__("Reminder: New Invoice for %s at %s", "pmpropbc"), $user->membership_level->name, get_option("blogname")); //get body from template $email->body = file_get_contents(PMPRO_PAY_BY_CHECK_DIR . "/email/" . $email->template . ".html"); //setup more data $email->data = array("name" => $user->display_name, "user_login" => $user->user_login, "sitename" => get_option("blogname"), "siteemail" => pmpro_getOption("from_email"), "membership_id" => $user->membership_level->id, "membership_level_name" => $user->membership_level->name, "membership_cost" => pmpro_getLevelCost($user->membership_level), "login_link" => wp_login_url(pmpro_url("account")), "display_name" => $user->display_name, "user_email" => $user->user_email); $email->data["instructions"] = pmpro_getOption('instructions'); $email->data["invoice_id"] = $order->code; $email->data["invoice_total"] = pmpro_formatPrice($order->total); $email->data["invoice_date"] = date(get_option('date_format'), $order->timestamp); $email->data["billing_name"] = $order->billing->name; $email->data["billing_street"] = $order->billing->street; $email->data["billing_city"] = $order->billing->city; $email->data["billing_state"] = $order->billing->state; $email->data["billing_zip"] = $order->billing->zip; $email->data["billing_country"] = $order->billing->country; $email->data["billing_phone"] = $order->billing->phone; $email->data["cardtype"] = $order->cardtype; $email->data["accountnumber"] = hideCardNumber($order->accountnumber); $email->data["expirationmonth"] = $order->expirationmonth; $email->data["expirationyear"] = $order->expirationyear; $email->data["billing_address"] = pmpro_formatAddress($order->billing->name, $order->billing->street, "", $order->billing->city, $order->billing->state, $order->billing->zip, $order->billing->country, $order->billing->phone); if ($order->getDiscountCode()) { $email->data["discount_code"] = "<p>" . __("Discount Code", "pmpro") . ": " . $order->discount_code->code . "</p>\n"; } else { $email->data["discount_code"] = ""; } //send the email $email->sendEmail(); } } } }