/**
  * Send error emails.
  * Requires yii-email-module
  */
 public function actionIndex()
 {
     /** @var AuditModule $audit */
     $audit = Yii::app()->getModule('audit');
     $data = $audit->getDbConnection()->createCommand("SELECT id FROM " . AuditError::model()->tableName() . " WHERE status=:new_status")->query(array(':new_status' => 'new'));
     while ($data && ($row = $data->read()) !== false) {
         $auditError = AuditError::model()->findByPk($row['id']);
         $message = Yii::t('app', '<b>:message</b><br />in <i>:file</i> on line <i>:line</i>.<br/>:link.', array(':message' => $auditError->message, ':file' => $auditError->file, ':line' => $auditError->line, ':link' => CHtml::link(Yii::t('audit', 'view'), Yii::app()->createAbsoluteUrl('audit/error/view', array('id' => $auditError->id), $this->secureUrl ? 'https' : 'http'))));
         Yii::app()->emailManager->email($this->email, $auditError->type . ' (' . $auditError->hash . ')', $message);
         $auditError->status = 'emailed';
         $auditError->save(false, array('status'));
     }
 }
 /**
  * Log an exception.
  * @param $exception Exception
  * @param null|string $extra
  * @return AuditError
  */
 public function logException($exception, $extra = null)
 {
     // create a new AuditError
     $auditError = new AuditError();
     $auditError->created = time();
     $auditError->status = 'new';
     $auditError->code = $exception instanceof CHttpException ? $exception->statusCode : 500;
     $auditError->error_code = $exception->getCode();
     $auditError->type = get_class($exception);
     $auditError->message = $exception->getMessage();
     $auditError->trace = $exception->getTraceAsString();
     if ($extra) {
         $auditError->extra = AuditHelper::pack($extra);
     }
     // get file and line
     $exactTrace = $this->getExactTrace($exception);
     if (!$exactTrace) {
         $auditError->file = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $exception->getFile());
         $auditError->line = $exception->getLine();
     } else {
         $auditError->file = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $exactTrace['file']);
         $auditError->line = $exactTrace['line'];
     }
     $auditError->source_code = AuditHelper::pack($this->renderSourceCode($auditError->file, $auditError->line, $this->maxSourceLines));
     // get traces
     $trace = $exception->getTrace();
     if ($trace) {
         foreach ($trace as $i => $t) {
             if (!isset($t['file'])) {
                 $trace[$i]['file'] = 'unknown';
             }
             $trace[$i]['file'] = str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $trace[$i]['file']);
             if (!isset($t['line'])) {
                 $trace[$i]['line'] = 0;
             }
             if (!isset($t['function'])) {
                 $trace[$i]['function'] = 'unknown';
             }
             if (isset($t['object'])) {
                 unset($trace[$i]['object']);
             }
         }
     }
     $auditError->traces = json_encode($trace);
     $auditError->stack_trace = AuditHelper::pack($this->renderStackTrace($trace));
     // get the AuditRequest
     $auditRequest = $this->getAuditRequest();
     $auditError->audit_request_id = $auditRequest ? $auditRequest->id : 0;
     // generate a hash of the error
     $auditError->hash = $this->hash($auditError->message . $auditError->file . $auditError->line);
     // save the AuditError
     $auditError->save(false);
     return $auditError;
 }