Merge branch 'master' of ssh://172.20.0.1/var/git/espo/backend

This commit is contained in:
Yuri Kuznetsov
2014-05-01 11:47:56 +03:00
4 changed files with 119 additions and 65 deletions
+1 -1
View File
@@ -113,7 +113,7 @@ class Application
try {
$entryPointManager->run($entryPoint);
} catch (\Exception $e) {
$container->get('output')->processError($e->getMessage(), $e->getCode());
$container->get('output')->processError($e->getMessage(), $e->getCode(), true);
}
});
+52 -23
View File
@@ -18,7 +18,7 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
namespace Espo\Core\Utils\Api;
@@ -26,11 +26,20 @@ class Output
{
private $slim;
protected $errorDesc = array(
400 => 'Bad Request',
401 => 'Unauthorized',
403 => 'Forbidden',
404 => 'Page Not Found',
409 => 'Conflict',
500 => 'Internal Server Error',
);
public function __construct(\Espo\Core\Utils\Api\Slim $slim)
{
$this->slim = $slim;
}
public function __construct(\Espo\Core\Utils\Api\Slim $slim)
{
$this->slim = $slim;
}
protected function getSlim()
{
@@ -38,53 +47,73 @@ class Output
}
/**
* Output the result
* Output the result
*
* @param mixed $data - JSON
*/
public function render($data = null)
public function render($data = null)
{
if (is_array($data)) {
$dataArr = array_values($data);
$data = empty($dataArr[0]) ? false : $dataArr[0];
}
if (is_array($data)) {
$dataArr = array_values($data);
$data = empty($dataArr[0]) ? false : $dataArr[0];
}
ob_clean();
echo $data;
echo $data;
}
public function processError($message = 'Error', $code = 500)
public function processError($message = 'Error', $code = 500, $isPrint = false)
{
$GLOBALS['log']->error('API ['.$this->getSlim()->request()->getMethod().']:'.$this->getSlim()->router()->getCurrentRoute()->getPattern().', Params:'.print_r($this->getSlim()->router()->getCurrentRoute()->getParams(), true).', InputData: '.$this->getSlim()->request()->getBody().' - '.$message);
$this->displayError($message, $code);
ob_clean();
echo $data;
$this->getSlim()->stop();
$this->displayError($message, $code, $isPrint);
}
/**
* Output the error and stop app execution
* Output the error and stop app execution
*
* @param string $text
* @param int $statusCode
*
* @return void
*/
public function displayError($text, $statusCode = 500)
public function displayError($text, $statusCode = 500, $isPrint = false)
{
$GLOBALS['log']->info('Display Error: '.$text.', Code: '.$statusCode.' URL: '.$_SERVER['REQUEST_URI']);
$GLOBALS['log']->error('Display Error: '.$text.', Code: '.$statusCode.' URL: '.$_SERVER['REQUEST_URI']);
if (!empty( $this->slim)) {
$this->getSlim()->response()->status($statusCode);
$this->getSlim()->response()->header('X-Status-Reason', $text);
if ($isPrint) {
$status = $this->getCodeDesc($statusCode);
$status = isset($status) ? $statusCode.' '.$status : 'HTTP '.$statusCode;
$this->getSlim()->printError($text, $status);
}
$this->getSlim()->stop();
}
}
else {
$GLOBALS['log']->info('Could not get Slim instance. It looks like a direct call (bypass API). URL: '.$_SERVER['REQUEST_URI']);
die($text);
}
}
/**
* Get status code desription
*
* @param int $statusCode
* @return string | null
*/
protected function getCodeDesc($statusCode)
{
if (isset($this->errorDesc[$statusCode])) {
return $this->errorDesc[$statusCode];
}
return null;
}
}
+45 -40
View File
@@ -18,7 +18,7 @@
*
* You should have received a copy of the GNU General Public License
* along with EspoCRM. If not, see http://www.gnu.org/licenses/.
************************************************************************/
************************************************************************/
namespace Espo\Core\Utils\Api;
@@ -27,54 +27,59 @@ class Slim extends \Slim\Slim
{
/**
* Redefine the run method
*
* We no need to use a Slim handler
*/
* Redefine the run method
*
* We no need to use a Slim handler
*/
public function run()
{
//set_error_handler(array('\Slim\Slim', 'handleErrors')); //Espo: no needs to use this handler
{
//set_error_handler(array('\Slim\Slim', 'handleErrors')); //Espo: no needs to use this handler
//Apply final outer middleware layers
if ($this->config('debug')) {
//Apply pretty exceptions only in debug to avoid accidental information leakage in production
//$this->add(new \Slim\Middleware\PrettyExceptions()); //Espo: no needs to use this handler
}
//Apply final outer middleware layers
if ($this->config('debug')) {
//Apply pretty exceptions only in debug to avoid accidental information leakage in production
//$this->add(new \Slim\Middleware\PrettyExceptions()); //Espo: no needs to use this handler
}
//Invoke middleware and application stack
$this->middleware[0]->call();
//Invoke middleware and application stack
$this->middleware[0]->call();
//Fetch status, header, and body
list($status, $headers, $body) = $this->response->finalize();
//Fetch status, header, and body
list($status, $headers, $body) = $this->response->finalize();
// Serialize cookies (with optional encryption)
\Slim\Http\Util::serializeCookies($headers, $this->response->cookies, $this->settings);
// Serialize cookies (with optional encryption)
\Slim\Http\Util::serializeCookies($headers, $this->response->cookies, $this->settings);
//Send headers
if (headers_sent() === false) {
//Send status
if (strpos(PHP_SAPI, 'cgi') === 0) {
header(sprintf('Status: %s', \Slim\Http\Response::getMessageForCode($status)));
} else {
header(sprintf('HTTP/%s %s', $this->config('http.version'), \Slim\Http\Response::getMessageForCode($status)));
}
//Send headers
if (headers_sent() === false) {
//Send status
if (strpos(PHP_SAPI, 'cgi') === 0) {
header(sprintf('Status: %s', \Slim\Http\Response::getMessageForCode($status)));
} else {
header(sprintf('HTTP/%s %s', $this->config('http.version'), \Slim\Http\Response::getMessageForCode($status)));
}
//Send headers
foreach ($headers as $name => $value) {
$hValues = explode("\n", $value);
foreach ($hValues as $hVal) {
header("$name: $hVal", false);
}
}
}
//Send headers
foreach ($headers as $name => $value) {
$hValues = explode("\n", $value);
foreach ($hValues as $hVal) {
header("$name: $hVal", false);
}
}
}
//Send body, but only if it isn't a HEAD request
if (!$this->request->isHead()) {
echo $body;
}
//Send body, but only if it isn't a HEAD request
if (!$this->request->isHead()) {
echo $body;
}
//restore_error_handler();
}
//restore_error_handler(); //Espo: no needs to use this handler
}
public function printError($error, $status)
{
echo static::generateTemplateMarkup($status, '<p>'.$error.'</p><a href="' . $this->request->getRootUri() . '/">Visit the Home Page</a>');
}
}
@@ -28,6 +28,8 @@ class StreamHandler extends \Monolog\Handler\StreamHandler
{
protected $fileManager;
protected $maxErrorMessageLength = 5000;
public function __construct($url, $level = Logger::DEBUG, $bubble = true)
{
parent::__construct($url, $level, $bubble);
@@ -50,7 +52,7 @@ class StreamHandler extends \Monolog\Handler\StreamHandler
$this->errorMessage = null;
set_error_handler(array($this, 'customErrorHandler'));
$this->getFileManager()->appendContents($this->url, (string) $record['formatted']);
$this->getFileManager()->appendContents($this->url, $this->pruneMessage($record));
restore_error_handler();
if (isset($this->errorMessage)) {
@@ -63,4 +65,22 @@ class StreamHandler extends \Monolog\Handler\StreamHandler
$this->errorMessage = $msg;
}
/**
* Cut the error message depends on maxErrorMessageLength
*
* @param array $record
* @return string
*/
protected function pruneMessage(array $record)
{
$message = (string) $record['message'];
if (strlen($message) > $this->maxErrorMessageLength) {
$record['message'] = substr($message, 0, $this->maxErrorMessageLength) . '...';
$record['formatted'] = $this->getFormatter()->format($record);
}
return (string) $record['formatted'];
}
}