git-svn-id: https://msi/svn/firstRepo/Service/branches/Slim3@40 0f545695-f87b-41b6-9a03-7f16563b5454

This commit is contained in:
2016-01-05 21:43:12 +00:00
parent 4318dd829f
commit 00d78a2ba8
46 changed files with 4960 additions and 32 deletions
+239
View File
@@ -0,0 +1,239 @@
<?php
/**
* Slim Framework (http://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2015 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Handlers;
use Exception;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Http\Body;
/**
* Default Slim application error handler
*
* It outputs the error message and diagnostic information in either JSON, XML,
* or HTML based on the Accept header.
*/
class Error
{
protected $displayErrorDetails;
/**
* Known handled content types
*
* @var array
*/
protected $knownContentTypes = [
'application/json',
'application/xml',
'text/xml',
'text/html',
];
/**
* Constructor
*
* @param boolean $displayErrorDetails Set to true to display full details
*/
public function __construct($displayErrorDetails = false)
{
$this->displayErrorDetails = (bool)$displayErrorDetails;
}
/**
* Invoke error handler
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
* @param Exception $exception The caught Exception object
*
* @return ResponseInterface
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, Exception $exception)
{
$contentType = $this->determineContentType($request);
switch ($contentType) {
case 'application/json':
$output = $this->renderJsonErrorMessage($exception);
break;
case 'text/xml':
case 'application/xml':
$output = $this->renderXmlErrorMessage($exception);
break;
case 'text/html':
$output = $this->renderHtmlErrorMessage($exception);
break;
}
$body = new Body(fopen('php://temp', 'r+'));
$body->write($output);
return $response
->withStatus(500)
->withHeader('Content-type', $contentType)
->withBody($body);
}
/**
* Render HTML error page
*
* @param Exception $exception
* @return string
*/
protected function renderHtmlErrorMessage(Exception $exception)
{
$title = 'Slim Application Error';
if ($this->displayErrorDetails) {
$html = '<p>The application could not run because of the following error:</p>';
$html .= '<h2>Details</h2>';
$html .= $this->renderHtmlException($exception);
while ($exception = $exception->getPrevious()) {
$html .= '<h2>Previous exception</h2>';
$html .= $this->renderHtmlException($exception);
}
} else {
$html = '<p>A website error has occurred. Sorry for the temporary inconvenience.</p>';
}
$output = sprintf(
"<html><head><meta http-equiv='Content-Type' content='text/html; charset=utf-8'>" .
"<title>%s</title><style>body{margin:0;padding:30px;font:12px/1.5 Helvetica,Arial,Verdana," .
"sans-serif;}h1{margin:0;font-size:48px;font-weight:normal;line-height:48px;}strong{" .
"display:inline-block;width:65px;}</style></head><body><h1>%s</h1>%s</body></html>",
$title,
$title,
$html
);
return $output;
}
/**
* Render exception as HTML.
*
* @param Exception $exception
*
* @return string
*/
protected function renderHtmlException(Exception $exception)
{
$html = sprintf('<div><strong>Type:</strong> %s</div>', get_class($exception));
if (($code = $exception->getCode())) {
$html .= sprintf('<div><strong>Code:</strong> %s</div>', $code);
}
if (($message = $exception->getMessage())) {
$html .= sprintf('<div><strong>Message:</strong> %s</div>', htmlentities($message));
}
if (($file = $exception->getFile())) {
$html .= sprintf('<div><strong>File:</strong> %s</div>', $file);
}
if (($line = $exception->getLine())) {
$html .= sprintf('<div><strong>Line:</strong> %s</div>', $line);
}
if (($trace = $exception->getTraceAsString())) {
$html .= '<h2>Trace</h2>';
$html .= sprintf('<pre>%s</pre>', htmlentities($trace));
}
return $html;
}
/**
* Render JSON error
*
* @param Exception $exception
* @return string
*/
protected function renderJsonErrorMessage(Exception $exception)
{
$error = [
'message' => 'Slim Application Error',
];
if ($this->displayErrorDetails) {
$error['exception'] = [];
do {
$error['exception'][] = [
'type' => get_class($exception),
'code' => $exception->getCode(),
'message' => $exception->getMessage(),
'file' => $exception->getFile(),
'line' => $exception->getLine(),
'trace' => explode("\n", $exception->getTraceAsString()),
];
} while ($exception = $exception->getPrevious());
}
return json_encode($error, JSON_PRETTY_PRINT);
}
/**
* Render XML error
*
* @param Exception $exception
* @return string
*/
protected function renderXmlErrorMessage(Exception $exception)
{
$xml = "<error>\n <message>Slim Application Error</message>\n";
if ($this->displayErrorDetails) {
do {
$xml .= " <exception>\n";
$xml .= " <type>" . get_class($exception) . "</type>\n";
$xml .= " <code>" . $exception->getCode() . "</code>\n";
$xml .= " <message>" . $this->createCdataSection($exception->getMessage()) . "</message>\n";
$xml .= " <file>" . $exception->getFile() . "</file>\n";
$xml .= " <line>" . $exception->getLine() . "</line>\n";
$xml .= " <trace>" . $this->createCdataSection($exception->getTraceAsString()) . "</trace>\n";
$xml .= " </exception>\n";
} while ($exception = $exception->getPrevious());
}
$xml .= "</error>";
return $xml;
}
/**
* Returns a CDATA section with the given content.
*
* @param string $content
* @return string
*/
private function createCdataSection($content)
{
return sprintf('<![CDATA[%s]]>', str_replace(']]>', ']]]]><![CDATA[>', $content));
}
/**
* Determine which content type we know about is wanted using Accept header
*
* @param ServerRequestInterface $request
* @return string
*/
private function determineContentType(ServerRequestInterface $request)
{
$acceptHeader = $request->getHeaderLine('Accept');
$selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes);
if (count($selectedContentTypes)) {
return $selectedContentTypes[0];
}
return 'text/html';
}
}
+173
View File
@@ -0,0 +1,173 @@
<?php
/**
* Slim Framework (http://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2015 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Handlers;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Body;
/**
* Default Slim application not allowed handler
*
* It outputs a simple message in either JSON, XML or HTML based on the
* Accept header.
*/
class NotAllowed
{
/**
* Known handled content types
*
* @var array
*/
protected $knownContentTypes = [
'application/json',
'application/xml',
'text/xml',
'text/html',
];
/**
* Invoke error handler
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
* @param string[] $methods Allowed HTTP methods
*
* @return ResponseInterface
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, array $methods)
{
if ($request->getMethod() === 'OPTIONS') {
$status = 200;
$contentType = 'text/plain';
$output = $this->renderPlainNotAllowedMessage($methods);
} else {
$status = 405;
$contentType = $this->determineContentType($request);
switch ($contentType) {
case 'application/json':
$output = $this->renderJsonNotAllowedMessage($methods);
break;
case 'text/xml':
case 'application/xml':
$output = $this->renderXmlNotAllowedMessage($methods);
break;
case 'text/html':
$output = $this->renderHtmlNotAllowedMessage($methods);
break;
}
}
$body = new Body(fopen('php://temp', 'r+'));
$body->write($output);
$allow = implode(', ', $methods);
return $response
->withStatus($status)
->withHeader('Content-type', $contentType)
->withHeader('Allow', $allow)
->withBody($body);
}
/**
* Determine which content type we know about is wanted using Accept header
*
* @param ServerRequestInterface $request
* @return string
*/
private function determineContentType(ServerRequestInterface $request)
{
$acceptHeader = $request->getHeaderLine('Accept');
$selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes);
if (count($selectedContentTypes)) {
return $selectedContentTypes[0];
}
return 'text/html';
}
/**
* Render PLAIN not allowed message
*
* @param array $methods
* @return string
*/
protected function renderPlainNotAllowedMessage($methods)
{
$allow = implode(', ', $methods);
return 'Allowed methods: ' . $allow;
}
/**
* Render JSON not allowed message
*
* @param array $methods
* @return string
*/
protected function renderJsonNotAllowedMessage($methods)
{
$allow = implode(', ', $methods);
return '{"message":"Method not allowed. Must be one of: ' . $allow . '"}';
}
/**
* Render XML not allowed message
*
* @param array $methods
* @return string
*/
protected function renderXmlNotAllowedMessage($methods)
{
$allow = implode(', ', $methods);
return "<root><message>Method not allowed. Must be one of: $allow</message></root>";
}
/**
* Render HTML not allowed message
*
* @param array $methods
* @return string
*/
protected function renderHtmlNotAllowedMessage($methods)
{
$allow = implode(', ', $methods);
$output = <<<END
<html>
<head>
<title>Method not allowed</title>
<style>
body{
margin:0;
padding:30px;
font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;
}
h1{
margin:0;
font-size:48px;
font-weight:normal;
line-height:48px;
}
</style>
</head>
<body>
<h1>Method not allowed</h1>
<p>Method not allowed. Must be one of: <strong>$allow</strong></p>
</body>
</html>
END;
return $output;
}
}
+157
View File
@@ -0,0 +1,157 @@
<?php
/**
* Slim Framework (http://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2015 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Handlers;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\ResponseInterface;
use Slim\Http\Body;
/**
* Default Slim application not found handler.
*
* It outputs a simple message in either JSON, XML or HTML based on the
* Accept header.
*/
class NotFound
{
/**
* Known handled content types
*
* @var array
*/
protected $knownContentTypes = [
'application/json',
'application/xml',
'text/xml',
'text/html',
];
/**
* Invoke not found handler
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
*
* @return ResponseInterface
*/
public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
{
$contentType = $this->determineContentType($request);
switch ($contentType) {
case 'application/json':
$output = $this->renderJsonNotFoundOutput($request, $response);
break;
case 'text/xml':
case 'application/xml':
$output = $this->renderXmlNotFoundOutput($request, $response);
break;
case 'text/html':
$output = $this->renderHtmlNotFoundOutput($request, $response);
}
$body = new Body(fopen('php://temp', 'r+'));
$body->write($output);
return $response->withStatus(404)
->withHeader('Content-Type', $contentType)
->withBody($body);
}
/**
* Determine which content type we know about is wanted using Accept header
*
* @param ServerRequestInterface $request
* @return string
*/
private function determineContentType(ServerRequestInterface $request)
{
$acceptHeader = $request->getHeaderLine('Accept');
$selectedContentTypes = array_intersect(explode(',', $acceptHeader), $this->knownContentTypes);
if (count($selectedContentTypes)) {
return $selectedContentTypes[0];
}
return 'text/html';
}
/**
* Return a response for application/json content not found
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
*
* @return ResponseInterface
*/
protected function renderJsonNotFoundOutput(ServerRequestInterface $request, ResponseInterface $response)
{
return '{"message":"Not found"}';
}
/**
* Return a response for xml content not found
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
*
* @return ResponseInterface
*/
protected function renderXmlNotFoundOutput(ServerRequestInterface $request, ResponseInterface $response)
{
return '<root><message>Not found</message></root>';
}
/**
* Return a response for text/html content not found
*
* @param ServerRequestInterface $request The most recent Request object
* @param ResponseInterface $response The most recent Response object
*
* @return ResponseInterface
*/
protected function renderHtmlNotFoundOutput(ServerRequestInterface $request, ResponseInterface $response)
{
$homeUrl = (string)($request->getUri()->withPath('')->withQuery('')->withFragment(''));
return <<<END
<html>
<head>
<title>Page Not Found</title>
<style>
body{
margin:0;
padding:30px;
font:12px/1.5 Helvetica,Arial,Verdana,sans-serif;
}
h1{
margin:0;
font-size:48px;
font-weight:normal;
line-height:48px;
}
strong{
display:inline-block;
width:65px;
}
</style>
</head>
<body>
<h1>Page Not Found</h1>
<p>
The page you are looking for could not be found. Check the address bar
to ensure your URL is spelled correctly. If all else fails, you can
visit our home page at the link below.
</p>
<a href='$homeUrl'>Visit the Home Page</a>
</body>
</html>
END;
}
}
@@ -0,0 +1,43 @@
<?php
/**
* Slim Framework (http://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2015 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
/**
* Default route callback strategy with route parameters as an array of arguments.
*/
class RequestResponse implements InvocationStrategyInterface
{
/**
* Invoke a route callable with request, response, and all route parameters
* as an array of arguments.
*
* @param array|callable $callable
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $routeArguments
*
* @return mixed
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
) {
foreach ($routeArguments as $k => $v) {
$request = $request->withAttribute($k, $v);
}
return call_user_func($callable, $request, $response, $routeArguments);
}
}
@@ -0,0 +1,42 @@
<?php
/**
* Slim Framework (http://slimframework.com)
*
* @link https://github.com/slimphp/Slim
* @copyright Copyright (c) 2011-2015 Josh Lockhart
* @license https://github.com/slimphp/Slim/blob/3.x/LICENSE.md (MIT License)
*/
namespace Slim\Handlers\Strategies;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Slim\Interfaces\InvocationStrategyInterface;
/**
* Route callback strategy with route parameters as individual arguments.
*/
class RequestResponseArgs implements InvocationStrategyInterface
{
/**
* Invoke a route callable with request, response and all route parameters
* as individual arguments.
*
* @param array|callable $callable
* @param ServerRequestInterface $request
* @param ResponseInterface $response
* @param array $routeArguments
*
* @return mixed
*/
public function __invoke(
callable $callable,
ServerRequestInterface $request,
ResponseInterface $response,
array $routeArguments
) {
array_unshift($routeArguments, $request, $response);
return call_user_func_array($callable, $routeArguments);
}
}