public function send() { $mail = new PHPMailer(); foreach ($this->to as $to) { $mail->AddAddress($to); } $mail->IsMail(); $mail->Subject = $this->subject; $mail->From = MAIL_REPLY_TO; $mail->FromName = $this->fromName ?: MAIL_FROM_NAME; $mail->Sender = MAIL_REPLY_TO; if ($this->replyTo) { $mail->AddReplyTo($this->replyTo); } $mail->Body = $this->body; if (substr(trim($this->body), 0, 1) == '<') { $mail->IsHTML(true); if (isset($this->plain_body)) { $mail->AltBody = html_entity_decode($this->plain_body); } } else { $mail->Body = html_entity_decode($this->body); $mail->IsHTML(false); } if (IS_PRODUCTION) { return $mail->Send(); } else { \jmvc::log(print_r($mail, true), 'mail'); } }
public static function end() { if (self::$checksum == md5(serialize(self::$d))) { return; } if (empty(self::$d)) { // session is empty; we can abandon it setcookie(self::COOKIE_NAME, '', time() - 3600, '/'); return; } if (!self::$sessionModel && !self::$driver) { if (isset($GLOBALS['_CONFIG']['cache_driver'])) { self::$driver = \jmvc::cache(); } else { self::$sessionModel = new \jmvc\models\Session(); } } $key = self::id() ?: self::generate_id(); if (self::$driver) { self::$driver->set($key, self::$d, ONE_DAY); } else { if (self::$sessionModel) { self::$sessionModel->id = $key; self::$sessionModel->data = serialize(self::$d); self::$sessionModel->save(); } } }
/** * Object ID based routing. URLs like /controller_name/object_id/method_name/ where object_id is numeric. * Call from index() like this: * if ($this->route_object(args...)) { * return; * } * @param string $model Model class to attempt to load * @param string $default Default method to run if URL is /controller_name/object_id/ * @param \jmvc\Model &$obj Reference return of found object * @param function $filter_callback Object will be passed to this function; if the function returns false, a 404 will be triggered * @return bool Whether an object was found or not */ public function route_object($model, $default = false, &$obj = null, $filter_callback = null) { if (!is_numeric($this->args[0])) { return false; } $method = $this->args[1] ?: $default; if (!method_exists($this, $method)) { \jmvc::do404(); } $obj = $model::factory($this->args[0]); if (!$obj) { \jmvc::do404(); } if ($filter_callback && !$filter_callback($obj)) { \jmvc::do404(); } $this->view_override(array('view' => $method)); $this->{$method}($obj); return true; }
protected function __construct() { $this->m = \jmvc::redis(); self::$stats = array('hits' => 0, 'misses' => 0, 'writes' => 0, 'keys' => array()); }
/** * Render a view without attempting to call a controller. Similar to render(). * @param mixed $view_name * @param array $args * @return void */ public static function render_static($view_name = null, $args = array()) { $context = self::push_context($view_name, $parent); if (method_exists('jmvc\\Controller', $context['view'])) { \jmvc::do404(); } if (!empty($parent)) { $args['parent'] = $parent; } if ($view_file = self::exists($context)) { ob_start(); include $view_file; $output = ob_get_clean(); } else { throw new \ErrorException('Can\'t find view. View: ' . $context['view'] . ', Controller: ' . $context['controller'] . ', Template: ' . $context['template'] . ', Site: ' . $context['site']); } self::pop_context($view_name); return $output; }
<?php // Instructions: set this to be run by cron once per minute, and use Solo to prevent more than 1 instance from running // http://timkay.com/solo/ include 'cron_helper.php'; $redis = \jmvc::Redis(); $job_count = 0; while ($job = $redis->blpop('JMVC:jobs:high', 'JMVC:jobs:low', 0)) { $job_count++; $job = json_decode($job[1]); if ($job->obj_id) { // instantiate object $classname = $job->class; $obj = $classname::factory($job->obj_id); if (!$obj) { throw new \Exception($job->class . ' #' . $job->obj_id . ' not found!'); } $callback = array($obj, $job->method); } else { // call static method $callback = array($job->class, $job->method); } if (!is_callable($callback)) { throw new \Exception('Method ' . $job->class . ':' . $job->method . ' not found!'); } call_user_func_array($callback, $job->args); if ($job_count > 100) { // die and let cron restart the script, just in case PHP is leaking memory die; } }
/** * Place a job in the JMVC job queue. Requires job-worker.php to be running * @param $class The model name to call or instantiate * @param $method The model class method to call * @param $obj_id Optional; if provided, the object with that ID will be instantiated, otherwise $method will be called statically. * @param $args Arguments to be passed to $method * @param $priority Can be either 'high' or 'low' */ public static function defer($class, $method, $obj_id = null, $args = array(), $priority = 'low') { if (!in_array($priority, array('high', 'low'))) { throw new \Exception('Invalid priority type: ' . $priority); } $r = \jmvc::redis(); $job = array('class' => $class, 'method' => $method, 'obj_id' => $obj_id, 'args' => $args, 'created' => time()); $r->rpush('JMVC:jobs:' . $priority, json_encode($job)); }
/** * Sends the e-mail. Prints debug output if debug mode is turned on * @return Mail_Postmark */ public function &send() { $this->preSendCheck(); if (!IS_PRODUCTION) { static $sent = false; if (!defined('TEST_EMAIL_ADDRESS') || $sent) { return; } $this->_toAddress = array(TEST_EMAIL_ADDRESS); $sent = true; } $data = $this->_prepareData(); $headers = array('Accept: application/json', 'Content-Type: application/json', 'X-Postmark-Server-Token: ' . POSTMARKAPP_API_KEY); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'http://api.postmarkapp.com/email'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST'); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); $return = curl_exec($ch); if ($this->_debugMode == self::DEBUG_VERBOSE) { echo "JSON: " . json_encode($data) . "\nHeaders: \n\t" . implode("\n\t", $headers) . "\nReturn:\n{$return}"; } else { if ($this->_debugMode == self::DEBUG_RETURN) { return array('json' => json_encode($data), 'headers' => $headers, 'return' => $return); } } if (curl_error($ch) != '') { \jmvc::log(date('r') . "\nPostmark CURL error: " . curl_error($ch), 'postmark'); return $this; } $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if (!self::_isTwoHundred($httpCode)) { $message = json_decode($return)->Message; \jmvc::log(date('r') . "\nPostmark Error {$httpCode}:" . $message, 'postmark'); } return $this; }
public static function make_toolbar() { $content = ''; $infowindows = ''; ob_start(); if (!empty(self::$links)) { echo '<ul class="panel links">'; foreach (self::$links as $link) { echo '<li>' . $link['label'] . ': <a href="' . $link['url'] . '">' . $link['link_text'] . '</a></li>'; } echo '</ul>'; } $stats = \jmvc\Db::$stats; if (is_array($stats)) { $total = $stats['select'] + $stats['insert'] + $stats['update'] + $stats['delete']; echo '<div class="panel"> <h3>Database Stats</h3> <table class="data"> <tr> <td><strong>Total</strong></td> <td class="num"><strong>' . $total . '</strong></td> </tr> <tr> <td>Select</td> <td class="num">' . $stats['select'] . '</td> </tr> <tr> <td>Insert</td> <td class="num">' . $stats['insert'] . '</td> </tr> <tr> <td>Update</td> <td class="num">' . $stats['update'] . '</td> </tr> <tr> <td>Delete</td> <td class="num">' . $stats['delete'] . '</td> </tr> </table>'; $queries = \jmvc\Db::$queries; if (is_array($queries) && !empty($queries)) { $rows = ''; foreach ($queries as $query) { $rows .= '<tr> <td class="num">' . round($query['time'] * 1000) . 'ms</td> <td>' . self::table_names($query['query']) . ' </td> <td><a href="#" class="showquery">Show Query</a> <div class="query">' . nl2br($query['query']) . '</div></td> </tr>'; } $infoWindows .= '<div id="jmvc-debug-dbqueries"> <table class="data"> ' . $rows . ' </table> </div>'; echo '<a href="#" rel="jmvc-debug-dbqueries" class="jmvc-debug-infoWindowLink">Show DB Queries</a>'; } echo '</div>'; } $stats = \jmvc\classes\Cache_Interface::$stats; if (is_array($stats)) { echo '<div class="panel"> <h3>Cache Stats</h3> <table class="data"> <tr> <td>Hits</td> <td class="num">' . $stats['hits'] . '</td> </tr> <tr> <td>Misses</td> <td class="num">' . $stats['misses'] . '</td> </tr> <tr> <td>Writes</td> <td class="num">' . $stats['writes'] . '</td> </tr> </table>'; if (!empty($stats['keys'])) { $rows = ''; foreach ($stats['keys'] as $key) { $rows .= '<tr> <td>' . $key[0] . '</td> <td>' . $key[1] . '</td> </tr>'; } $infoWindows .= '<div id="jmvc-debug-cache-keys"> <table class="data"> ' . $rows . ' </table> </div>'; echo '<a href="#" rel="jmvc-debug-cache-keys" class="jmvc-debug-infoWindowLink">Show Keys</a>'; } echo '</div>'; } if (isset($GLOBALS['_CONFIG']['redis'])) { $r = new \Redis(); $r->connect($GLOBALS['_CONFIG']['redis']['host'], $GLOBALS['_CONFIG']['redis']['port']); $mail_count = $r->llen('jmvc:rmail'); if (IS_PRODUCTION && $mail_count) { $encoded_message = $r->lindex('jmvc:rmail', 0); if ($encoded_message) { $message = json_decode($encoded_message); if (time() - $message->created > 1800) { \jmvc::notify_admin(new \Exception('Mail queue: stale message from ' . date('r', $message->created))); } } } $jobs_count = $r->llen('JMVC:jobs:low') + $r->llen('JMVC:jobs:high'); if (IS_PRODUCTION && $jobs_count) { $encoded_message = $r->lindex('JMVC:jobs:high', 0); if (!$encoded_message) { $encoded_message = $r->lindex('JMVC:jobs:low', 0); } if ($encoded_message) { $message = json_decode($encoded_message); if (time() - $message->created > 1800) { \jmvc::notify_admin(new \Exception('Job queue: stale job from ' . date('r', $message->created))); } } } } $end = array_pop(\jmvc::$traces); \jmvc::$traces[] = $end; $rows = ''; foreach (\jmvc::$traces as $trace) { $rows .= '<tr> <td class="num">' . round($trace['time']) . 'ms</td> <td>' . $trace['message'] . '</td> </tr>'; } $infoWindows .= '<div id="jmvc-debug-traces"> <table class="data"> ' . $rows . ' </table> </div>'; $content = ob_get_clean(); $display = isset($_COOKIE['jmvc-debug-toolbar']) ? '' : 'style="display:none;"'; return '<div id="jmvc-debug-container"> <div id="jmvc-debug-toolbar" ' . $display . '> ' . $content . ' <ul class="panel"> <li class="jmvc-debug-toggle-option" id="jmvc-bust-cache">Cache Buster</li> <li><a href="#" rel="jmvc-debug-traces" class="jmvc-debug-infoWindowLink">' . round($end['time']) . 'ms</a></li> <li>' . ($mail_count ?: 0) . ' unsent emails</li> <li>' . ($jobs_count ?: 0) . ' pending jobs</li> </ul> <div style="clear: both"></div> </div> <div class="jmvc-debug-toggle">X</div> </div> <div id="jmvc-debug-infoWindows">' . $infoWindows . '</div> <script type="text/javascript" src="/js/debug.js"></script> '; }