Example #1
0
 /**
  * Pode ser chamado diretamente por um throw ou quando o PHP dispara um erro (WARNING, PARSE ou FATAL).
  * No segundo caso um próprio método erro() dessa clase dispara a exceção.
  * 
  * @param String $message Texto descritivo sobre o que pode ter acontecido na rotina que disparou o erro.
  * @param int $gravidade Valor inteiro para indicar a gravidade (0 a 3) da exceção. No caso de ser disparada por um
  *        	erro do PHP esse campo é um valor constante que indica qual tipo de erro.
  * @param array $contexto Array com valores do debug_backtrace() (nativo do PHP), pode não ser enviado ou ignorado
  *        	com valor false. No caso de erros no PHP tráz informações sobre linha, arquivo e contexto (veja doc
  *        	set_error_handler)
  * @param bool $erro_php É usado apenas pelo método erro() da classe para indicar que não é uma exceção do sistema,
  *        	mas sim um erro no PHP. O método erro() está sendo usado como handle dos erros no PHP para que os
  *        	usuários não vejam mensagens de erros.
  * @return void
  */
 public function __construct($message, $gravidade = __CLASS__, $contexto = false, $erro_php = false)
 {
     if (!self::$identificador_execucao) {
         self::$identificador_execucao = str_pad(rand(1, 9999), 4, '0', STR_PAD_LEFT);
     }
     $this->message = $message;
     $this->erro_nome = self::$identificador_execucao . '-' . ++self::$cont_erros . '-' . $gravidade . "-" . date('Y-m-d-H-i-s') . ".json";
     $this->erros['level'] = $gravidade;
     $this->erros['datetime'] = date("H:i:s Y-m-d", time());
     $this->erros['mensagem'] = $message;
     $this->erros['db_error'] = DB::error();
     if ($erro_php) {
         $erro_linha = $contexto['linha'];
         $erro_arquivo = $contexto['arquivo'];
         $message = strip_tags($message);
         /*
          * Não sei porque diabos esta chave as vezes vem com valores recursivos infinitos que causam erro no
          * sistema.
          */
         $contexto['contexto']["GLOBALS"] = " ";
         // muitas vezes o erro do php não traz o debug_backtrace
         $contexto['Backtrace'] = debug_backtrace();
     } else {
         $erro_linha = self::getLine();
         $erro_arquivo = self::getFile();
         if (SYS_MODO_DEVEL) {
             echo "<pre><br /><b>{$gravidade}</b> {$message}\n\nno arquivo {$erro_arquivo} Linha: {$erro_linha}<br /><br /></pre>";
         }
     }
     $this->id_unico = basename($erro_arquivo, '.php') . '.' . $erro_linha;
     $this->erros['PHP']['Arquivo'] = $erro_arquivo;
     $this->erros['PHP']['Linha'] = $erro_linha;
     $this->erros['PHP']['Codigo'] = $this->id_unico;
     /*
      * Caso tenha sido passado um array com o contexto do erro/exceção.
      */
     if ($contexto) {
         $this->erros['Contexto'] = $contexto;
     } else {
         $this->erros['Backtrace'] = debug_backtrace();
     }
     $this->erros["GET"] = $_GET;
     $this->erros["POST"] = $_POST;
     $this->erros["REQUEST"] = $_REQUEST;
     if (isset($_SESSION)) {
         $this->erros["Sessao"] = $_SESSION;
     }
     $this->erros["Cookies"] = $_COOKIE;
     $this->erros["Arquivos"] = $_FILES;
     $this->erros["Servidor"] = $_SERVER;
     $this->erros["APPS"] = (array) System::getInstance();
     foreach (SysDebug::getErros() as $err) {
         $this->erros['user_erros'][] = ['Label' => $err['Label'], 'VAR' => $err['VAR'], 'file' => $err['file'], 'line' => $err['line'], 'stringy' => $err['stringy']];
     }
     $json = utf8_decode(json_encode($this->erros, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
     $tam_file = file_put_contents(PATH_LOG_ERRO . $this->erro_nome, $json);
     if (SYS_MODO_DEVEL) {
         echo "<br/>Erro: " . $this->erro_nome;
         echo "<br/><pre>{$json}</pre>";
     }
     /*
      * Verifica se o sistema está configurado para enviar um e-mail para o administrador com o json.
      */
     if (ERROS_ENVIAR_EMAIL && !self::$erro_pai_enviado) {
         $largura_coluna = 20;
         $msg = '<code><pre>' . SYS_NAME . " Disse:\n" . $message;
         $msg .= "\n\n" . str_pad('Arquivo: ', $largura_coluna) . $erro_arquivo;
         $msg .= "\n" . str_pad('Codigo: ', $largura_coluna) . $this->id_unico;
         $msg .= "\n" . str_pad('Linha: ', $largura_coluna) . $erro_linha;
         $msg .= "\n" . str_pad('Erro banco: ', $largura_coluna) . DB::error();
         $msg .= "\n----------------------------------------------------------------------------------\n";
         $msg .= "\n" . str_pad("Horario:", $largura_coluna) . date('H:i:s d/m/Y');
         if (array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
             $msg .= "\n" . str_pad("IP:", $largura_coluna) . $_SERVER['HTTP_X_FORWARDED_FOR'];
             $msg .= "\n" . str_pad("Proxy:", $largura_coluna) . '<a href="http://www.geoiptool.com/?IP=' . $_SERVER['REMOTE_ADDR'] . '" target="_blank">' . $_SERVER['REMOTE_ADDR'] . '</a>';
         } else {
             $msg .= "\n" . str_pad("IP:", $largura_coluna) . '<a href="http://www.geoiptool.com/?IP=' . $_SERVER['REMOTE_ADDR'] . '" target="_blank">' . $_SERVER['REMOTE_ADDR'] . '</a>';
         }
         $msg .= "\n" . str_pad("Navegador:", $largura_coluna) . $_SERVER['HTTP_USER_AGENT'];
         $msg .= "\n" . str_pad("URL requisitada:", $largura_coluna) . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
         $msg .= "\n" . str_pad("POST:", $largura_coluna) . count($_POST);
         $msg .= "\n" . str_pad("GET:", $largura_coluna) . count($_GET);
         $msg .= "\n" . str_pad("FILES:", $largura_coluna) . count($_FILES);
         $msg .= "\n" . str_pad("URL raiz:", $largura_coluna) . URL_ROOT;
         $msg .= "\n\n\n" . str_pad("JSON", $largura_coluna) . $json;
         if ($tam_file) {
             $msg .= "\n----------------------------------------------------------------------------------\n";
             $msg .= "\n" . str_pad("Arquivo em:", $largura_coluna) . PATH_LOG_ERRO . $this->erro_nome;
         } else {
             $msg .= "\n\nNÃO FOI POSSÍVEL ESCREVER O ARQUIVO EM DISCO!";
         }
         $msg .= "</pre></code>";
         if (ERROS_ANEXAR) {
             $anexo_codificado = chunk_split(base64_encode($json));
             $mailheaders = "\nMIME-version: 1.0\n";
             $mailheaders .= "Content-type: multipart/mixed; ";
             $mailheaders .= "boundary=\"Message-Boundary\"\n";
             $mailheaders .= "Content-transfer-encoding: 7BIT\n";
             $mailheaders .= "X-attachments: {$this->erro_nome}";
             $body_top = "--Message-Boundary\n";
             $body_top .= "Content-type: text/html; charset=utf8\n";
             $body_top .= "Content-transfer-encoding: 7BIT\n";
             $body_top .= "Content-description: Mail message body\n\n";
             $msg = $body_top . $msg;
             $msg .= "\n\n--Message-Boundary\n";
             $msg .= "Content-type: application/json; name=\"{$this->erro_nome}\"\n";
             $msg .= "Content-Transfer-Encoding: BASE64\n";
             $msg .= "Content-disposition: attachment; filename=\"{$this->erro_nome}\"\n\n";
             $msg .= "{$anexo_codificado}\n";
             $msg .= "--Message-Boundary--\n";
         }
         $mailheaders .= "\nReferences: <" . $this->id_unico . "@" . parse_url(URL_ROOT, PHP_URL_HOST) . ">\n";
         $msg .= "\n\nAtt, " . SYS_NAME . " (" . SIS_EMAIL . ")";
         $assunto = "[" . $gravidade . "][" . str_replace("http://", '', URL_ROOT) . '] ' . utf8_decode(substr($this->id_unico, 0, 30));
         if (mail(ERROS_EMAIL, $assunto, $msg, "From: " . SYS_NAME . " <" . SIS_EMAIL . ">" . $mailheaders)) {
             self::$erro_pai_enviado = true;
         } else {
             file_put_contents(PATH_LOG_ERRO . "EMAIL_{$this->erro_nome}", "Erro ao enviar e-mail do erro {$this->erro_nome}");
         }
     }
 }