/** * Create a new user * * @access public * @param string $data An array of data to use for creating the user * @param boolean $send_welcome Whether or not to send the welcome email or not * @return boolean **/ public function create($data = FALSE, $send_welcome = TRUE) { // Has an email or a suername been submitted? if (APP_NATIVE_LOGIN_USING == 'EMAIL') { // Email defined? if (empty($data['email'])) { $this->_set_error('An email address must be supplied.'); return FALSE; } // Check email against DB $this->db->where('email', $data['email']); if ($this->db->count_all_results(NAILS_DB_PREFIX . 'user_email')) { $this->_set_error('This email is already in use.'); return FALSE; } } elseif (APP_NATIVE_LOGIN_USING == 'USERNAME') { // Username defined? if (empty($data['username'])) { $this->_set_error('A username must be supplied.'); return FALSE; } // Check username against DB $this->db->where('username', $data['username']); if ($this->db->count_all_results(NAILS_DB_PREFIX . 'user')) { $this->_set_error('This username is already in use.'); return FALSE; } } else { // Either a username or an email must be supplied if (empty($data['email']) && empty($data['username'])) { $this->_set_error('An email address or a username must be supplied.'); return FALSE; } if (!empty($data['email'])) { // Check email against DB $this->db->where('email', $data['email']); if ($this->db->count_all_results(NAILS_DB_PREFIX . 'user_email')) { $this->_set_error('This email is already in use.'); return FALSE; } } if (!empty($data['username'])) { // Check username against DB $this->db->where('username', $data['username']); if ($this->db->count_all_results(NAILS_DB_PREFIX . 'user')) { $this->_set_error('This username is already in use.'); return FALSE; } } } // -------------------------------------------------------------------------- // All should be ok, go ahead and create the account $_user_data = array(); // -------------------------------------------------------------------------- // If a password has been passed then generate the encrypted strings, otherwise // just generate a salt. if (empty($data['password'])) { $_password[] = NULL; $_password[] = $this->user_password_model->salt(); } else { $_password = $this->user_password_model->generate_hash($data['password']); if (!$_password) { $this->_set_error($this->user_password_model->last_error()); return FALSE; } } // Do we need to inform the user of their password? This might be set // if an admin created the account, or if the system generated a new password $_inform_user_pw = !empty($data['inform_user_pw']) ? TRUE : FALSE; // -------------------------------------------------------------------------- // Check that we're dealing with a valid group if (empty($data['group_id'])) { $_user_data['group_id'] = $this->user_group_model->get_default_group_id(); } else { $_user_data['group_id'] = $data['group_id']; } $_group = $this->user_group_model->get_by_id($_user_data['group_id']); if (!$_group) { $this->_set_error('Invalid Group ID specified.'); return FALSE; } else { $_user_data['group_id'] = $_group->id; } // -------------------------------------------------------------------------- // Check we're dealing with a valid auth_method if (!empty($data['auth_method_id'])) { if (is_numeric($data['auth_method_id'])) { $this->db->where('id', (int) $data['auth_method_id']); } else { // TODO: Change this column to be called `slug` $this->db->where('type', $data['auth_method_id']); } $_auth_method = $this->db->get(NAILS_DB_PREFIX . 'user_auth_method')->row(); if (!$_auth_method) { // Define a use friendly error (this may be shown to them) $this->_set_error('There was an error creating the user account - Error #001'); // This is a problem, email devs send_developer_mail('No auth method available for the supplied auth_method_id', 'The user_model->create() method was called with an invalid auth_method_id ("' . $data['auth_method_id'] . '"). This needs investigated and corrected.'); return FALSE; } } else { // TODO: this column should be `slug` $this->db->where('type', 'native'); $_auth_method = $this->db->get(NAILS_DB_PREFIX . 'user_auth_method')->row(); if (!$_auth_method) { // Define a use friendly error (this may be shown to them) $this->_set_error('There was an error creating the user account - Error #002'); // This is a problem, email devs send_developer_mail('No Native Authentication Method', 'There is no authentication method defined in the database for native registrations.'); return FALSE; } } $_user_data['auth_method_id'] = $_auth_method->id; // -------------------------------------------------------------------------- if (!empty($data['username'])) { $_user_data['username'] = $data['username']; } if (!empty($data['email'])) { $_email = $data['email']; $_email_is_verified = !empty($data['email_is_verified']); } $_user_data['password'] = $_password->password; $_user_data['password_md5'] = $_password->password_md5; $_user_data['password_engine'] = $_password->engine; $_user_data['salt'] = $_password->salt; $_user_data['ip_address'] = $this->input->ip_address(); $_user_data['last_ip'] = $_user_data['ip_address']; $_user_data['created'] = date('Y-m-d H:i:s'); $_user_data['last_update'] = date('Y-m-d H:i:s'); $_user_data['is_suspended'] = !empty($data['is_suspended']); $_user_data['temp_pw'] = !empty($data['temp_pw']); $_user_data['auth_method_id'] = $_auth_method->id; // Facebook oauth details $_user_data['fb_token'] = !empty($data['fb_token']) ? $data['fb_token'] : NULL; $_user_data['fb_id'] = !empty($data['fb_id']) ? $data['fb_id'] : NULL; // Twitter oauth details $_user_data['tw_id'] = !empty($data['tw_id']) ? $data['tw_id'] : NULL; $_user_data['tw_token'] = !empty($data['tw_token']) ? $data['tw_token'] : NULL; $_user_data['tw_secret'] = !empty($data['tw_secret']) ? $data['tw_secret'] : NULL; // Linkedin oauth details $_user_data['li_id'] = !empty($data['li_id']) ? $data['li_id'] : NULL; $_user_data['li_token'] = !empty($data['li_token']) ? $data['li_token'] : NULL; // Referral code $_user_data['referral'] = $this->_generate_referral(); // Other data $_user_data['salutation'] = !empty($data['salutation']) ? $data['salutation'] : NULL; $_user_data['first_name'] = !empty($data['first_name']) ? $data['first_name'] : NULL; $_user_data['last_name'] = !empty($data['last_name']) ? $data['last_name'] : NULL; if (isset($data['gender'])) { $_user_data['gender'] = $data['gender']; } if (isset($data['timezone'])) { $_user_data['timezone'] = $data['timezone']; } if (isset($data['datetime_format_date'])) { $_user_data['datetime_format_date'] = $data['datetime_format_date']; } if (isset($data['datetime_format_time'])) { $_user_data['datetime_format_time'] = $data['datetime_format_time']; } if (isset($data['language'])) { $_user_data['language'] = $data['language']; } // -------------------------------------------------------------------------- // Set Meta data $_meta_cols = $this->_get_meta_columns(); $_meta_data = array(); foreach ($data as $key => $val) { if (array_search($key, $_meta_cols) !== FALSE) { $_meta_data[$key] = $val; } } // -------------------------------------------------------------------------- $this->db->trans_begin(); $this->db->set($_user_data); if (!$this->db->insert(NAILS_DB_PREFIX . 'user')) { $this->_set_error('Failed to create base user object.'); $this->db->trans_rollback(); return FALSE; } $_id = $this->db->insert_id(); // -------------------------------------------------------------------------- // Update the user table with an MD5 hash of the user ID; a number of functions // make use of looking up this hashed information; this should be quicker. $this->db->set('id_md5', md5($_id)); $this->db->where('id', $_id); if (!$this->db->update(NAILS_DB_PREFIX . 'user')) { $this->_set_error('Failed to update base user object.'); $this->db->trans_rollback(); return FALSE; } // -------------------------------------------------------------------------- // Create the user_meta record, add any extra data if needed $this->db->set('user_id', $_id); if ($_meta_data) { $this->db->set($_meta_data); } if (!$this->db->insert(NAILS_DB_PREFIX . 'user_meta')) { $this->_set_error('Failed to create user meta data object.'); $this->db->trans_rollback(); return FALSE; } // -------------------------------------------------------------------------- // Finally add the email address to the user_email table if (!empty($_email)) { $_code = $this->email_add($_email, $_id, TRUE, $_email_is_verified, FALSE); if (!$_code) { // Error will be set by email_add(); $this->db->trans_rollback(); return FALSE; } // Send the user the welcome email if ($send_welcome) { $this->load->library('emailer'); $_email = new stdClass(); $_email->type = 'new_user_' . $_group->id; $_email->to_id = $_id; $_email->data = array(); $_email->data['method'] = $_auth_method; // If this user is created by an admin then take note of that. if ($this->is_admin()) { $_email->data['admin'] = new stdClass(); $_email->data['admin']->id = active_user('id'); $_email->data['admin']->first_name = active_user('first_name'); $_email->data['admin']->last_name = active_user('last_name'); $_email->data['admin']->group = new stdClass(); $_email->data['admin']->group->id = $_group->id; $_email->data['admin']->group->name = $_group->label; } if (!empty($data['password']) && !empty($_inform_user_pw)) { $_email->data['password'] = $data['password']; // Is this a temp password? We should let them know that too if ($_user_data['temp_pw']) { $_email->data['temp_pw'] = !empty($_user_data['temp_pw']); } } // If the email isn't verified we'll want to include a note asking them to do so if (!$_email_is_verified) { $_email->data['verification_code'] = $_code; } if (!$this->emailer->send($_email, TRUE)) { // Failed to send using the group email, try using the generic email template $_email->type = 'new_user'; if (!$this->emailer->send($_email, TRUE)) { // Email failed to send, musn't exist, oh well. $_error = 'Failed to send welcome email.'; $_error .= !empty($_inform_user_pw) ? ' Inform the user their password is <strong>' . $data['password'] . '</strong>' : ''; $this->_set_error($_error); } } } } // -------------------------------------------------------------------------- // commit the transaction and return new user object if ($this->db->trans_status() !== FALSE) { $this->db->trans_commit(); return $this->get_by_id($_id); } else { return FALSE; } }
public function send_order_notification($order) { // If an ID has been passed, look it up if (is_numeric($order)) { _LOG('Looking up order #' . $order); $order = $this->get_by_id($order); if (!$order) { _LOG('Invalid order ID'); $this->_set_error('Invalid order ID.'); return FALSE; } } // -------------------------------------------------------------------------- $this->load->library('emailer'); $this->load->helper('email'); $_email = new stdClass(); $_email->type = 'shop_notify'; $_email->data = array(); $_email->data['order'] = $order; $_recipients = explode(',', notification('notify_order', 'shop')); foreach ($_recipients as $recipient) { $_email->to_email = $recipient; if (!$this->emailer->send($_email, TRUE)) { // Email failed to send, alert developers _LOG('!! Failed to send order notification to ' . $_email->to_email . ', alerting developers.'); _LOG(implode("\n", $this->emailer->get_errors())); send_developer_mail('Unable to send order notification email', 'Unable to send the order notification to ' . $_email->to_email . '; order: #' . $order->id . "\n\nEmailer errors:\n\n" . print_r($this->emailer->get_errors(), TRUE)); } } }
protected function _notify_paypal() { // Configure log _LOG_FILE(app_setting('url', 'shop') . 'notify/paypal/ipn-' . date('Y-m-d') . '.php'); _LOG(); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG('Waking up IPN responder; handling with PayPal'); // -------------------------------------------------------------------------- // POST data? // Want to test a previous IPN message? // Paste the IPN message into the following and uncomment the following lines // $_message = ''; // $_message = str_replace( '+', '%2B', $_message ); // parse_str( $_message, $_POST ); if (!$this->data['testing'] && !$this->input->post()) { _LOG('No POST data, going back to sleep...'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); return; } // -------------------------------------------------------------------------- // Are we testing? if ($this->data['testing']) { $_ipn = TRUE; _LOG(); _LOG('**TESTING**'); _LOG('**Simulating data sent from PayPal**'); _LOG(); // Check order exists $_order = $this->shop_order_model->get_by_ref($this->input->get('ref')); if (!$_order) { _LOG('Invalid order reference, aborting.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); return; } // -------------------------------------------------------------------------- $_paypal = array(); $_paypal['payment_type'] = 'instant'; $_paypal['invoice'] = $_order->ref; $_paypal['custom'] = $this->encrypt->encode(md5($_order->ref . ':' . $_order->code), APP_PRIVATE_KEY); $_paypal['txn_id'] = 'TEST:' . random_string('alpha', 6); $_paypal['txn_type'] = 'cart'; $_paypal['payment_status'] = 'Completed'; $_paypal['pending_reason'] = 'PaymentReview'; $_paypal['mc_fee'] = 0.0; } else { _LOG('Validating the IPN call'); $this->load->library('paypal'); $_ipn = $this->paypal->validate_ipn(); $_paypal = $this->input->post(); $_order = $this->shop_order_model->get_by_ref($this->input->post('invoice')); if (!$_order) { _LOG('Invalid order ID, aborting. Likely a transaction not initiated by the site.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); return; } } // -------------------------------------------------------------------------- // Did the IPN validate? if ($_ipn) { _LOG('IPN Verified with PayPal'); _LOG(); // -------------------------------------------------------------------------- // Extra verification step, check the 'custom' variable decodes appropriately _LOG('Verifying data'); _LOG(); $_verification = $this->encrypt->decode($_paypal['custom'], APP_PRIVATE_KEY); if ($_verification != md5($_order->ref . ':' . $_order->code)) { $_data = array('pp_txn_id' => $_paypal['txn_id']); $this->shop_order_model->fail($_order->id, $_data); _LOG('Order failed secondary verification, aborting.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); // -------------------------------------------------------------------------- // Inform developers send_developer_mail('An IPN request failed', 'An IPN request was made which failed secondary verification, Order: ' . $_paypal['invoice']); return; } // -------------------------------------------------------------------------- // Only bother to handle certain types // TODO: handle refunds _LOG('Checking txn_type is supported'); _LOG(); if ($_paypal['txn_type'] != 'cart') { _LOG('"' . $_paypal['txn_type'] . '" is not a supported PayPal txn_type, gracefully aborting.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); return; } // -------------------------------------------------------------------------- // Check if order has already been processed _LOG('Checking if order has already been processed'); _LOG(); if (ENVIRONMENT == 'production' && $_order->status != 'UNPAID') { _LOG('Order has already been processed, aborting.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); return; } elseif (ENVIRONMENT != 'production' && $_order->status != 'UNPAID') { _LOG('Order has already been processed, but not on production so continuing anyway.'); _LOG(); } // -------------------------------------------------------------------------- // Check the status of the payment _LOG('Checking the status of the payment'); _LOG(); switch (strtolower($_paypal['payment_status'])) { case 'completed': // Do nothing, this transaction is OK _LOG('Payment status is "completed"; continuing...'); break; // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- case 'reversed': // Transaction was cancelled, mark order as FAILED _LOG('Payment was reversed, marking as failed and aborting'); $_data = array('pp_txn_id' => $_paypal['txn_id']); $this->shop_order_model->fail($_order->id, $_data); break; // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- case 'pending': // Check the pending_reason, if it's 'paymentreview' then gracefully stop // processing; PayPal will send a further IPN once the payment is complete _LOG('Payment status is "pending"; check the reason.'); if (strtolower($_paypal['pending_reason']) == 'paymentreview') { // The transaction is pending review, gracefully stop proicessing, but don't cancel the order _LOG('Payment is pending review by PayPal, gracefully aborting just now.'); $this->shop_order_model->pending($_order->id); return; } else { _LOG('Unsupported payment reason "' . $_paypal['pending_reason'] . '", aborting.'); // -------------------------------------------------------------------------- $_data = array('pp_txn_id' => $_paypal['txn_id']); $this->shop_order_model->fail($_order->id, $_data); // -------------------------------------------------------------------------- // Inform developers send_developer_mail('A PayPal payment failed', '<strong>' . $_order->user->first_name . ' ' . $_order->user->last_name . ' (' . $_order->user->email . ')</strong> has just attempted to pay for order ' . $_order->ref . '. The payment failed with status "' . $_paypal['payment_status'] . '" and reason "' . $_paypal['pending_reason'] . '".'); return; } // -------------------------------------------------------------------------- return; break; // -------------------------------------------------------------------------- // -------------------------------------------------------------------------- default: // Unknown/invalid payment status _LOG('Invalid payment status'); $_data = array('pp_txn_id' => $_paypal['txn_id']); $this->shop_order_model->fail($_order->id, $_data); // -------------------------------------------------------------------------- // Inform developers send_developer_mail('A PayPal payment failed', '<strong>' . $_order->user->first_name . ' ' . $_order->user->last_name . ' (' . $_order->user->email . ')</strong> has just attempted to pay for order ' . $_order->ref . '. The payment failed with status "' . $_paypal['payment_status'] . '" and reason "' . $_paypal['pending_reason'] . '".'); return; break; } // -------------------------------------------------------------------------- // All seems good, continue with order processing _LOG('All seems well, continuing...'); _LOG(); _LOG('Setting txn_id (' . $_paypal['txn_id'] . ') and fees_deducted (' . $_paypal['mc_fee'] . ').'); _LOG(); $_data = array('pp_txn_id' => $_paypal['txn_id'], 'fees_deducted' => $_paypal['mc_fee']); $this->shop_order_model->paid($_order->id, $_data); // -------------------------------------------------------------------------- // PROCESSSSSS... $this->shop_order_model->process($_order); _LOG(); // -------------------------------------------------------------------------- // Send a receipt to the customer _LOG('Sending receipt to customer: ' . $_order->user->email); $this->shop_order_model->send_receipt($_order); _LOG(); // -------------------------------------------------------------------------- // Send a notification to the store owner(s) _LOG('Sending notification to store owner(s): ' . notification('notify_order', 'shop')); $this->shop_order_model->send_order_notification($_order); // -------------------------------------------------------------------------- if ($_order->voucher) { // Redeem the voucher, if it's there _LOG('Redeeming voucher: ' . $_order->voucher->code . ' - ' . $_order->voucher->label); $this->shop_voucher_model->redeem($_order->voucher->id, $_order); } // -------------------------------------------------------------------------- _LOG(); // -------------------------------------------------------------------------- _LOG('All done here, going back to sleep...'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); if ($this->data['testing']) { echo anchor(app_setting('url', 'shop') . 'checkout/processing?ref=' . $_order->ref, 'Continue to Processing Page'); } } else { _LOG('PayPal did not verify this IPN call, aborting.'); _LOG('- - - - - - - - - - - - - - - - - - -'); _LOG(); } }
protected function _check_cache($file) { // Check cache for $file if (!is_file(DEPLOY_CACHE_DIR . $file)) { // If not found, generate $this->load->model('sitemap/sitemap_model'); if (!$this->sitemap_model->generate()) { // Failed to generate sitemap _LOG('Failed to generate sitemap: ' . $this->sitemap_model->last_error()); // Let the dev's know too, this could be serious send_developer_mail('Failed to generate sitemap', 'There was no ' . $file . ' data in the cache and I failed to recreate it.'); // Send a temporarily unavailable header, we don't want search engines unlisting us because of this. $this->output->set_header($this->input->server('SERVER_PROTOCOL') . ' 503 Service Temporarily Unavailable'); $this->output->set_header('Status: 503 Service Temporarily Unavailable'); $this->output->set_header('Retry-After: 7200'); $this->load->view('sitemap/error'); return FALSE; } } return TRUE; }
/** * Send a templated email immediately * * @access private * @param object $input The input object * @param boolean $graceful Whether to fail gracefully or not * @return boolean **/ private function _send($email_id = FALSE, $graceful = FALSE) { // Get the email if $email_id is not an object if (!is_object($email_id)) { $_email = $this->get_by_id($email_id); } else { $_email = $email_id; } // -------------------------------------------------------------------------- if (!$_email) { $this->_set_error('EMAILER: Unable to fetch email object'); return FALSE; } // -------------------------------------------------------------------------- $_send = new stdClass(); $_send->to = new stdClass(); $_send->to->email = $_email->user->email; $_send->to->email_verified = (bool) $_email->email_verified; $_send->to->email_verified_code = $_email->email_verified_code; $_send->to->first = $_email->user->first_name; $_send->to->last = $_email->user->last_name; $_send->to->id = (int) $_email->user->id; $_send->to->username = $_email->user->username; $_send->to->group_id = $_email->user->group_id; $_send->to->login_url = $_email->user->id ? site_url('auth/login/with_hashes/' . md5($_email->user->id) . '/' . md5($_email->user->password)) : NULL; $_send->email_type_id = $_email->type_id; $_send->subject = $_email->subject; $_send->template = $_email->template_file; $_send->template_pt = $_email->template_file . '_plaintext'; $_send->data = $_email->email_vars; $_send->data['ci'] =& get_instance(); // Check login URLs are allowed get_instance()->config->load('auth'); if (!get_instance()->config->item('auth_enable_hashed_login')) { $_send->to->login_url = ''; } if (!is_array($_send->data)) { $_send->data = array(); } // -------------------------------------------------------------------------- // From user $_send->from = new stdClass(); if (!empty($_send->data['email_from_email'])) { $_send->from->email = $_send->data['email_from_email']; $_send->from->name = !empty($_send->data['email_from_name']) ? $_send->data['email_from_name'] : $_send->data['email_from_email']; } else { $_send->from->email = $this->from->email; $_send->from->name = $this->from->name; } // -------------------------------------------------------------------------- // Fresh start please $this->ci->email->clear(TRUE); // -------------------------------------------------------------------------- // Add some extra, common variables for the template $_send->data['email_type_id'] = $_email->type_id; $_send->data['email_ref'] = $_email->ref; $_send->data['sent_from'] = $_send->from; $_send->data['sent_to'] = $_send->to; $_send->data['email_subject'] = $_send->subject; $_send->data['site_url'] = site_url(); $_send->data['secret'] = APP_PRIVATE_KEY; // -------------------------------------------------------------------------- // If we're not on a production server, never send out to any live addresses $_send_to = $_send->to->email; if (ENVIRONMENT != 'production' || EMAIL_OVERRIDE) { if (EMAIL_OVERRIDE) { $_send_to = EMAIL_OVERRIDE; } elseif (APP_DEVELOPER_EMAIL) { $_send_to = APP_DEVELOPER_EMAIL; } else { // Not sure where this is going; fall over *waaaa* show_error('EMAILER: Non production environment and neither EMAIL_OVERRIDE nor APP_DEVELOPER_EMAIL is set.'); return FALSE; } } // -------------------------------------------------------------------------- // Start prepping the email $this->ci->email->from($this->from->email, $_send->from->name); $this->ci->email->reply_to($_send->from->email, $_send->from->name); $this->ci->email->to($_send_to); $this->ci->email->subject($_send->subject); // -------------------------------------------------------------------------- // Clear any errors which might have happened previously $_error =& load_class('Exceptions', 'core'); $_error->clear_errors(); // Load the template $body = $this->ci->load->view('email/structure/header', $_send->data, TRUE); $body .= $this->ci->load->view('email/' . $_send->template, $_send->data, TRUE); $body .= $this->ci->load->view('email/structure/footer', $_send->data, TRUE); // If any errors occurred while attempting to generate the body of this email // then abort the sending and log it if (EMAIL_DEBUG && APP_DEVELOPER_EMAIL && $_error->error_has_occurred()) { // The templates error'd, abort the send and let dev know $_subject = 'Email #' . $_email->id . ' failed to send due to errors occurring in the templates'; $_message = 'Hi,' . "\n"; $_message .= '' . "\n"; $_message .= 'Email #' . $_email->id . ' was aborted due to errors occurring while building the template' . "\n"; $_message .= '' . "\n"; $_message .= 'Please take a look as a matter of urgency; the errors are noted below:' . "\n"; $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_errors = $_error->recent_errors(); foreach ($_errors as $error) { $_message .= 'Severity: ' . $_error->levels[$error->severity] . "\n"; $_message .= 'Message: ' . $error->message . "\n"; $_message .= 'File: ' . $error->filepath . "\n"; $_message .= 'Line: ' . $error->line . "\n"; $_message .= '' . "\n"; } $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_message .= 'Additional debugging information:' . "\n"; $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_message .= print_r($_send, TRUE) . "\n"; send_developer_mail($_subject, $_message); // -------------------------------------------------------------------------- $this->_set_error('EMAILER: Errors in email template, developers informed'); // --------------------------------------------------------------------------] return FALSE; } // -------------------------------------------------------------------------- // Parse the body for <a> links and replace with a tracking URL // First clear out any previous link caches (production only) $this->track_link_cache = array(); if (ENVIRONMENT == 'production') { if ($_send->to->id && !$_send->to->email_verified) { $_needs_verified = array('id' => $_send->to->id, 'code' => $_send->to->email_verified_code); } else { $_needs_verified = FALSE; } $body = $this->_parse_links($body, $_email->id, $_email->ref, TRUE, $_needs_verified); } // -------------------------------------------------------------------------- // Set the email body $this->ci->email->message($body); // -------------------------------------------------------------------------- // Set the plain text version $plaintext = $this->ci->load->view('email/structure/header_plaintext', $_send->data, TRUE); $plaintext .= $this->ci->load->view('email/' . $_send->template_pt, $_send->data, TRUE); $plaintext .= $this->ci->load->view('email/structure/footer_plaintext', $_send->data, TRUE); // -------------------------------------------------------------------------- // Parse the body for URLs and replace with a tracking URL (production only) if (ENVIRONMENT == 'production') { $plaintext = $this->_parse_links($plaintext, $_email->id, $_email->ref, FALSE, $_needs_verified); } // -------------------------------------------------------------------------- $this->ci->email->set_alt_message($plaintext); // -------------------------------------------------------------------------- // Add any attachments if (isset($_send->data['attachments']) && is_array($_send->data['attachments']) && $_send->data['attachments']) { foreach ($_send->data['attachments'] as $file) { if (!$this->_add_attachment($file)) { if (!$graceful) { show_error('EMAILER: Failed to add attachment: ' . $file); } else { $this->_set_error('EMAILER: Insert Failed.'); return FALSE; } } } } // -------------------------------------------------------------------------- // Debugging? if (EMAIL_DEBUG) { $this->_debugger($_send, $body, $plaintext, $_error->recent_errors()); return FALSE; } // -------------------------------------------------------------------------- // Send! Turn off error reporting, if it fails we should handle it gracefully $_previous_error_reporting = error_reporting(); error_reporting(0); if ($this->ci->email->send()) { // Put error reporting back as it was error_reporting($_previous_error_reporting); // -------------------------------------------------------------------------- // Mail sent, mark the time $this->db->set('time_sent', 'NOW()', FALSE); $this->db->where('id', $_email->id); $this->db->update(NAILS_DB_PREFIX . 'email_archive'); return TRUE; } else { // Put error reporting back as it was error_reporting($_previous_error_reporting); // -------------------------------------------------------------------------- // Failed to send, notify developers $_subject = 'Email #' . $_email->id . ' failed to send at SMTP time'; $_message = 'Hi,' . "\n"; $_message .= '' . "\n"; $_message .= 'Email #' . $_email->id . ' failed to send at SMTP time' . "\n"; $_message .= '' . "\n"; $_message .= 'Please take a look as a matter of urgency; debugging data is below:' . "\n"; $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_message .= $this->ci->email->print_debugger(); $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_message .= 'Additional debugging information:' . "\n"; $_message .= '' . "\n"; $_message .= '- - - - - - - - - - - - - - - - - - - - - -' . "\n"; $_message .= '' . "\n"; $_message .= print_r($_send, TRUE) . "\n"; if (ENVIRONMENT == 'production') { $this->_set_error('Email failed to send at SMTP time, developers informed'); send_developer_mail($_subject, $_message); } else { // On non-production environments halt execution, this is an error with the configs // and should probably be addressed if (!$graceful) { show_error('Email failed to send at SMTP time. Potential configuration error. Investigate, debugging data below: <div style="padding:20px;background:#EEE">' . $this->ci->email->print_debugger() . '</div>'); } else { $this->_set_error('Email failed to send at SMTP time.'); } } // -------------------------------------------------------------------------- return FALSE; } }