public function daily() { $this->_start('maintenance', 'daily', 'Daily Maintenance Tasks'); // -------------------------------------------------------------------------- // Daily Tasks // Shop related tasks if (module_is_enabled('shop')) { _LOG('Shop Module Enabled. Beginning Shop Tasks.'); // -------------------------------------------------------------------------- // Load models $this->load->model('shop/shop_model'); $this->load->model('shop/shop_currency_model'); // -------------------------------------------------------------------------- // Sync Currencies _LOG('... Synching Currencies'); if (!$this->shop_currency_model->sync()) { _LOG('... ... FAILED: ' . $this->shop_currency_model->last_error()); } // -------------------------------------------------------------------------- _LOG('Finished Shop Tasks'); } // Site map related tasks, makes sense for this one to come last in case any of // the previous have an impact if (module_is_enabled('sitemap')) { _LOG('Sitemap Module Enabled. Beginning Sitemap Tasks.'); // -------------------------------------------------------------------------- // Load models $this->load->model('sitemap/sitemap_model'); // -------------------------------------------------------------------------- // Generate sitemap _LOG('... Generating Sitemap data'); if (!$this->sitemap_model->generate()) { _LOG('... ... FAILED: ' . $this->sitemap_model->last_error()); } // -------------------------------------------------------------------------- _LOG('Finished Site Tasks'); } // -------------------------------------------------------------------------- $this->_end(); }
protected function _end($log_message = NULL) { // How'd we do? $_end = microtime(TRUE) * 10000; $_duration = ($_end - $this->start) / 10000; // -------------------------------------------------------------------------- _LOG(); _LOG('Finished job [' . $this->task . ']'); _LOG('Job took ' . number_format($_duration, 5) . ' seconds'); _LOG(); _LOG('----------------------------------------'); _LOG(); // -------------------------------------------------------------------------- // Write this to the DB log $_data = array(); $_data['task'] = $this->task; $_data['duration'] = $_duration; $_data['message'] = $log_message; $this->db->set($_data); $this->db->set('created', 'NOW()', FALSE); $this->db->insert(NAILS_DB_PREFIX . 'log_cron'); }
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 _end() { // Note End $this->benchmark->mark('deploy_end'); _LOG('-----------------------------------------'); _LOG(ucfirst($this->uri->segment(2)) . ' Deployment Tasks took ' . $this->benchmark->elapsed_time('deploy_start', 'deploy_end') . ' seconds'); // -------------------------------------------------------------------------- if (strtoupper(ENVIRONMENT) !== 'PRODUCTION' && !$this->input->is_cli_request()) { echo '</pre>'; echo $this->load->view('deploy/footer', NULL, TRUE); } }
public function sync() { if (defined('NAILS_SHOP_OPENEXCHANGERATES_APP_ID') && NAILS_SHOP_OPENEXCHANGERATES_APP_ID) { // Make sure we know what the base currency is if (defined('SHOP_BASE_CURRENCY_CODE')) { $this->load->model('shop/shop_model'); } _LOG('... Base Currency is ' . SHOP_BASE_CURRENCY_CODE); // Set up the cURL request $this->load->library('curl'); $_url = 'http://openexchangerates.org/api/latest.json?app_id=' . NAILS_SHOP_OPENEXCHANGERATES_APP_ID; $_params = array('app_id' => NAILS_SHOP_OPENEXCHANGERATES_APP_ID); $this->curl->create($_url); $this->curl->option(CURLOPT_FAILONERROR, FALSE); $_result = json_decode($this->curl->execute()); if (!isset($_result->error)) { // Ok, now we know the rates we need to work out what the base_exchange rate is. // If the store's base rate is the same as the API's base rate then we're golden, // if it's not then we'll need to do some calculations. if (SHOP_BASE_CURRENCY_CODE == $_result->base) { foreach ($_result->rates as $code => $rate) { $_data = array('base_exchange' => $rate); $this->update($code, $_data); _LOG('... ' . $code . ' > ' . $rate); } } else { _LOG('... API base is ' . $_result->base . '; calculating differences...'); $_base = 1; foreach ($_result->rates as $code => $rate) { if ($code == SHOP_BASE_CURRENCY_CODE) { $_base = $rate; break; } } foreach ($_result->rates as $code => $rate) { // We calculate the new exchange rate as so: $rate / $_base // See here: http://stackoverflow.com/a/17452753/789224 // PS. Haters gonna hate. $_new_rate = $rate / $_base; $_data = array('base_exchange' => $_new_rate); $this->update($code, $_data); _LOG('... Calculating and saving new exchange rate for ' . SHOP_BASE_CURRENCY_CODE . ' > ' . $code . ' (' . $_new_rate . ')'); } } // -------------------------------------------------------------------------- return TRUE; } else { _LOG('... An error occurred when querying the API:'); _LOG('... ' . $_result->status . ' ' . $_result->message . ' - ' . $_result->description); return FALSE; } } else { _LOG('... NAILS_SHOP_OPENEXCHANGERATES_APP_ID is not defined. Sync aborted.'); return FALSE; } }
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; }
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(); } }
function checkoutProject() { global $REPO, $CONFIG, $PROJECTS; // Compose current repository path $repoPath = $CONFIG['repositoriesPath'] . $REPO . '.git/'; // Checkout project files $branch = !empty($PROJECTS[$REPO]['branch']) ? $PROJECTS[$REPO]['branch'] : DEFAULT_BRANCH; $command = 'cd ' . $repoPath . ' && GIT_WORK_TREE=' . $PROJECTS[$REPO]['projPath'] . ' ' . $CONFIG['gitCommand'] . ' checkout -f ' . $branch; _LOG('Command: ' . $command); $exec = shell_exec($command); _LOG("Result: " . $exec); if (!empty($PROJECTS[$REPO]['postHookCmd'])) { $command = 'cd ' . $PROJECTS[$REPO]['projPath'] . ' && ' . $PROJECTS[$REPO]['postHookCmd']; _LOG("Command: " . $command); $exec = shell_exec($command); _LOG("Result: " . $exec); } // Log the deployment $hash = rtrim(shell_exec('cd ' . $repoPath . ' && ' . $CONFIG['gitCommand'] . ' rev-parse --short HEAD')); _LOG("Done, commit #" . $hash); }
function _ERROR($s) { _LOG('ERROR: ' . $s); }