diff --git a/- Copy.htaccess b/- Copy.htaccess
new file mode 100644
index 0000000..0a1d946
--- /dev/null
+++ b/- Copy.htaccess
@@ -0,0 +1,5 @@
+
+ RewriteEngine On
+ RewriteCond %{REQUEST_FILENAME} !-f
+ RewriteRule ^(.*)$ serviceapp.php [QSA,L]
+
\ No newline at end of file
diff --git a/Middleware/CheckFrom.php b/Middleware/CheckFrom.php
new file mode 100644
index 0000000..c79061e
--- /dev/null
+++ b/Middleware/CheckFrom.php
@@ -0,0 +1,33 @@
+getHost();
+ $currentRefererRequest = substr($currentRefererRequest, 7); //Senza http://
+ $indexDoublePoint = strpos($currentRefererRequest, ':');
+ $indexFirstSlash = strpos($currentRefererRequest, '/');
+ $currentRefererRequest = substr($currentRefererRequest, 0, $indexDoublePoint > 0 && $indexDoublePoint < $indexFirstSlash ? $indexDoublePoint : $indexFirstSlash );
+ if(!in_array($currentRefererRequest, $allowedHost))
+ {
+ return $response->withStatus(500)->write('Generic error occurred');
+ }
+ */
+ $currentHostRequest = $app->request()->getHost();
+ if(!in_array($currentHostRequest, $allowedHost))
+ {
+ return $response->withStatus(403)->write('Request arrive from host not allowed');
+ }
+
+ return $next($request, $response);
+ }
+}
\ No newline at end of file
diff --git a/MySqlClass - Copy.php b/MySqlClass - Copy.php
new file mode 100644
index 0000000..537275a
--- /dev/null
+++ b/MySqlClass - Copy.php
@@ -0,0 +1,89 @@
+attiva)
+ {
+ $this->connessione = mysql_connect($this->nomehost,$this->nomeuser,$this->password);
+ if ($this->connessione == FALSE)
+ die(mysql_error());
+ mysql_select_db($this->mydb, $this->connessione) or die ("Errore nella selezione del database. Verificare i parametri nel file config.inc.php");
+ $this->attiva = true;
+ }
+ else{
+ return true;
+ }
+
+ }
+
+ public function executeQuery($queryStr)
+ {
+ $this->connetti();
+
+ if (!$res = mysql_query($queryStr, $this->connessione)) die(mysql_error());
+ return true;
+ return false;
+ }
+
+ public function insertRecord($queryStr)
+ {
+ $this->connetti();
+
+ if (!$res = mysql_query($queryStr, $this->connessione)) die(mysql_error());
+ return mysql_insert_id();
+ }
+
+ public function queryToObject($queryStr)
+ {
+ $this->connetti();
+
+ $sth = mysql_query($queryStr, $this->connessione) or die(mysql_error());
+
+ $rows = array();
+ while($r = mysql_fetch_assoc($sth)) {
+ array_push($rows,array_map('utf8_encode', $r));
+ }
+ mysql_free_result($sth);
+ return $rows;
+ }
+
+ // funzione per la chiusura della connessione
+ public function disconnetti()
+ {
+ if($this->attiva)
+ {
+ if(mysql_close($this->connessione))
+ {
+ $this->attiva = false;
+ return true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ public function __destruct()
+ {
+ $this->disconnetti();
+ }
+ }
+?>
\ No newline at end of file
diff --git a/SimpleImage.php b/SimpleImage.php
new file mode 100644
index 0000000..bb471ec
--- /dev/null
+++ b/SimpleImage.php
@@ -0,0 +1,104 @@
+image_type = $image_info[2];
+ if ($this->image_type == IMAGETYPE_JPEG) {
+ $this->image = imagecreatefromjpeg($filename);
+ } elseif ($this->image_type == IMAGETYPE_GIF) {
+ $this->image = imagecreatefromgif($filename);
+ } elseif ($this->image_type == IMAGETYPE_PNG) {
+ $this->image = imagecreatefrompng($filename);
+ }
+ }
+
+ function saveas($filename, $image_type = IMAGETYPE_JPEG, $compression = 75, $permissions = null) {
+ if ($image_type == IMAGETYPE_JPEG) {
+ imagejpeg($this->image, $filename, $compression);
+ } elseif ($image_type == IMAGETYPE_GIF) {
+ imagegif($this->image, $filename);
+ } elseif ($image_type == IMAGETYPE_PNG) {
+ imagepng($this->image, $filename);
+ } if ($permissions != null) {
+ chmod($filename, $permissions);
+ }
+ }
+
+ function save($filename) {
+ if ($this->image_type == IMAGETYPE_JPEG) {
+ imagejpeg($this->image, $filename);
+ } elseif ($this->image_type == IMAGETYPE_GIF) {
+ imagegif($this->image, $filename);
+ } elseif ($this->image_type == IMAGETYPE_PNG) {
+ imagepng($this->image, $filename);
+ }
+ }
+
+ function output($image_type = IMAGETYPE_JPEG) {
+ if ($image_type == IMAGETYPE_JPEG) {
+ imagejpeg($this->image);
+ } elseif ($image_type == IMAGETYPE_GIF) {
+ imagegif($this->image);
+ } elseif ($image_type == IMAGETYPE_PNG) {
+ imagepng($this->image);
+ }
+ }
+
+ function getWidth() {
+ return imagesx($this->image);
+ }
+
+ function getHeight() {
+ return imagesy($this->image);
+ }
+
+ function resizeToHeight($height) {
+ $ratio = $height / $this->getHeight();
+ $width = $this->getWidth() * $ratio;
+ $this->resize($width, $height);
+ }
+
+ function resizeToWidth($width) {
+ $ratio = $width / $this->getWidth();
+ $height = $this->getheight() * $ratio;
+ $this->resize($width, $height);
+ }
+
+ function scale($scale) {
+ $width = $this->getWidth() * $scale / 100;
+ $height = $this->getheight() * $scale / 100;
+ $this->resize($width, $height);
+ }
+
+ function resize($width, $height) {
+ $new_image = imagecreatetruecolor($width, $height);
+ if ($this->image_type == IMAGETYPE_GIF || $this->image_type == IMAGETYPE_PNG) {
+ $current_transparent = imagecolortransparent($this->image);
+ if ($current_transparent != -1) {
+ $transparent_color = imagecolorsforindex($this->image, $current_transparent);
+ $current_transparent = imagecolorallocate($new_image, $transparent_color['red'], $transparent_color['green'], $transparent_color['blue']);
+ imagefill($new_image, 0, 0, $current_transparent);
+ imagecolortransparent($new_image, $current_transparent);
+ } elseif ($this->image_type == IMAGETYPE_PNG) {
+ imagealphablending($new_image, false);
+ $color = imagecolorallocatealpha($new_image, 0, 0, 0, 127);
+ imagefill($new_image, 0, 0, $color);
+ imagesavealpha($new_image, true);
+ }
+ }
+ imagecopyresampled($new_image, $this->image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
+ $this->image = $new_image;
+ }
+
+ function close()
+ {
+ imagedestroy($this->image);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/Slim/App.php b/Slim/App.php
new file mode 100644
index 0000000..641270c
--- /dev/null
+++ b/Slim/App.php
@@ -0,0 +1,555 @@
+container = $container;
+ }
+
+ /**
+ * Enable access to the DI container by consumers of $app
+ *
+ * @return ContainerInterface
+ */
+ public function getContainer()
+ {
+ return $this->container;
+ }
+
+ /**
+ * Add middleware
+ *
+ * This method prepends new middleware to the app's middleware stack.
+ *
+ * @param mixed $callable The callback routine
+ *
+ * @return static
+ */
+ public function add($callable)
+ {
+ $callable = $this->resolveCallable($callable);
+ if ($callable instanceof Closure) {
+ $callable = $callable->bindTo($this->container);
+ }
+
+ return $this->addMiddleware($callable);
+ }
+
+ /**
+ * Calling a non-existant method on App checks to see if there's an item
+ * in the container than is callable and if so, calls it.
+ *
+ * @param string $method
+ * @param array $args
+ * @return mixed
+ */
+ public function __call($method, $args)
+ {
+ if ($this->container->has($method)) {
+ $obj = $this->container->get($method);
+ if (is_callable($obj)) {
+ return call_user_func_array($obj, $args);
+ }
+ }
+ }
+
+ /********************************************************************************
+ * Router proxy methods
+ *******************************************************************************/
+
+ /**
+ * Add GET route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function get($pattern, $callable)
+ {
+ return $this->map(['GET'], $pattern, $callable);
+ }
+
+ /**
+ * Add POST route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function post($pattern, $callable)
+ {
+ return $this->map(['POST'], $pattern, $callable);
+ }
+
+ /**
+ * Add PUT route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function put($pattern, $callable)
+ {
+ return $this->map(['PUT'], $pattern, $callable);
+ }
+
+ /**
+ * Add PATCH route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function patch($pattern, $callable)
+ {
+ return $this->map(['PATCH'], $pattern, $callable);
+ }
+
+ /**
+ * Add DELETE route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function delete($pattern, $callable)
+ {
+ return $this->map(['DELETE'], $pattern, $callable);
+ }
+
+ /**
+ * Add OPTIONS route
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function options($pattern, $callable)
+ {
+ return $this->map(['OPTIONS'], $pattern, $callable);
+ }
+
+ /**
+ * Add route for any HTTP method
+ *
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return \Slim\Interfaces\RouteInterface
+ */
+ public function any($pattern, $callable)
+ {
+ return $this->map(['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'], $pattern, $callable);
+ }
+
+ /**
+ * Add route with multiple methods
+ *
+ * @param string[] $methods Numeric array of HTTP method names
+ * @param string $pattern The route URI pattern
+ * @param mixed $callable The route callback routine
+ *
+ * @return RouteInterface
+ */
+ public function map(array $methods, $pattern, $callable)
+ {
+ if ($callable instanceof Closure) {
+ $callable = $callable->bindTo($this->container);
+ }
+
+ $route = $this->container->get('router')->map($methods, $pattern, $callable);
+ if (is_callable([$route, 'setContainer'])) {
+ $route->setContainer($this->container);
+ }
+
+ if (is_callable([$route, 'setOutputBuffering'])) {
+ $route->setOutputBuffering($this->container->get('settings')['outputBuffering']);
+ }
+
+ return $route;
+ }
+
+ /**
+ * Route Groups
+ *
+ * This method accepts a route pattern and a callback. All route
+ * declarations in the callback will be prepended by the group(s)
+ * that it is in.
+ *
+ * @param string $pattern
+ * @param callable $callable
+ *
+ * @return RouteGroupInterface
+ */
+ public function group($pattern, $callable)
+ {
+ /** @var RouteGroup $group */
+ $group = $this->container->get('router')->pushGroup($pattern, $callable);
+ $group->setContainer($this->container);
+ $group($this);
+ $this->container->get('router')->popGroup();
+ return $group;
+ }
+
+ /********************************************************************************
+ * Runner
+ *******************************************************************************/
+
+ /**
+ * Run application
+ *
+ * This method traverses the application middleware stack and then sends the
+ * resultant Response object to the HTTP client.
+ *
+ * @param bool|false $silent
+ * @return ResponseInterface
+ *
+ * @throws Exception
+ * @throws MethodNotAllowedException
+ * @throws NotFoundException
+ */
+ public function run($silent = false)
+ {
+ $request = $this->container->get('request');
+ $response = $this->container->get('response');
+
+ // Ensure basePath is set
+ $router = $this->container->get('router');
+ if (is_callable([$request->getUri(), 'getBasePath']) && is_callable([$router, 'setBasePath'])) {
+ $router->setBasePath($request->getUri()->getBasePath());
+ }
+
+
+ // Dispatch the Router first if the setting for this is on
+ if ($this->container->get('settings')['determineRouteBeforeAppMiddleware'] === true) {
+ // Dispatch router (note: you won't be able to alter routes after this)
+ $request = $this->dispatchRouterAndPrepareRoute($request, $router);
+ }
+
+ // Traverse middleware stack
+ try {
+ $response = $this->callMiddlewareStack($request, $response);
+ } catch (MethodNotAllowedException $e) {
+ if (!$this->container->has('notAllowedHandler')) {
+ throw $e;
+ }
+ /** @var callable $notAllowedHandler */
+ $notAllowedHandler = $this->container->get('notAllowedHandler');
+ $response = $notAllowedHandler($e->getRequest(), $e->getResponse(), $e->getAllowedMethods());
+ } catch (NotFoundException $e) {
+ if (!$this->container->has('notFoundHandler')) {
+ throw $e;
+ }
+ /** @var callable $notFoundHandler */
+ $notFoundHandler = $this->container->get('notFoundHandler');
+ $response = $notFoundHandler($e->getRequest(), $e->getResponse());
+ } catch (SlimException $e) {
+ $response = $e->getResponse();
+ } catch (Exception $e) {
+ if (!$this->container->has('errorHandler')) {
+ throw $e;
+ }
+ /** @var callable $errorHandler */
+ $errorHandler = $this->container->get('errorHandler');
+ $response = $errorHandler($request, $response, $e);
+ }
+
+ $response = $this->finalize($response);
+
+ if (!$silent) {
+ $this->respond($response);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Send the response the client
+ *
+ * @param ResponseInterface $response
+ */
+ public function respond(ResponseInterface $response)
+ {
+ // Send response
+ if (!headers_sent()) {
+ // Status
+ header(sprintf(
+ 'HTTP/%s %s %s',
+ $response->getProtocolVersion(),
+ $response->getStatusCode(),
+ $response->getReasonPhrase()
+ ));
+
+ // Headers
+ foreach ($response->getHeaders() as $name => $values) {
+ foreach ($values as $value) {
+ header(sprintf('%s: %s', $name, $value), false);
+ }
+ }
+ }
+
+ // Body
+ if (!$this->isEmptyResponse($response)) {
+ $body = $response->getBody();
+ if ($body->isSeekable()) {
+ $body->rewind();
+ }
+ $settings = $this->container->get('settings');
+ $chunkSize = $settings['responseChunkSize'];
+ $contentLength = $response->getHeaderLine('Content-Length');
+ if (!$contentLength) {
+ $contentLength = $body->getSize();
+ }
+ $totalChunks = ceil($contentLength / $chunkSize);
+ $lastChunkSize = $contentLength % $chunkSize;
+ $currentChunk = 0;
+ while (!$body->eof() && $currentChunk < $totalChunks) {
+ if (++$currentChunk == $totalChunks && $lastChunkSize > 0) {
+ $chunkSize = $lastChunkSize;
+ }
+ echo $body->read($chunkSize);
+ if (connection_status() != CONNECTION_NORMAL) {
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Invoke application
+ *
+ * This method implements the middleware interface. It receives
+ * Request and Response objects, and it returns a Response object
+ * after compiling the routes registered in the Router and dispatching
+ * the Request object to the appropriate Route callback routine.
+ *
+ * @param ServerRequestInterface $request The most recent Request object
+ * @param ResponseInterface $response The most recent Response object
+ *
+ * @return ResponseInterface
+ * @throws MethodNotAllowedException
+ * @throws NotFoundException
+ */
+ public function __invoke(ServerRequestInterface $request, ResponseInterface $response)
+ {
+ // Get the route info
+ $routeInfo = $request->getAttribute('routeInfo');
+
+ /** @var \Slim\Interfaces\RouterInterface $router */
+ $router = $this->container->get('router');
+
+ // If router hasn't been dispatched or the URI changed then dispatch
+ if (null === $routeInfo || ($routeInfo['request'] !== [$request->getMethod(), (string) $request->getUri()])) {
+ $request = $this->dispatchRouterAndPrepareRoute($request, $router);
+ $routeInfo = $request->getAttribute('routeInfo');
+ }
+
+ if ($routeInfo[0] === Dispatcher::FOUND) {
+ $route = $router->lookupRoute($routeInfo[1]);
+ return $route->run($request, $response);
+ } elseif ($routeInfo[0] === Dispatcher::METHOD_NOT_ALLOWED) {
+ if (!$this->container->has('notAllowedHandler')) {
+ throw new MethodNotAllowedException($request, $response, $routeInfo[1]);
+ }
+ /** @var callable $notAllowedHandler */
+ $notAllowedHandler = $this->container->get('notAllowedHandler');
+ return $notAllowedHandler($request, $response, $routeInfo[1]);
+ }
+
+ if (!$this->container->has('notFoundHandler')) {
+ throw new NotFoundException($request, $response);
+ }
+ /** @var callable $notFoundHandler */
+ $notFoundHandler = $this->container->get('notFoundHandler');
+ return $notFoundHandler($request, $response);
+ }
+
+ /**
+ * Perform a sub-request from within an application route
+ *
+ * This method allows you to prepare and initiate a sub-request, run within
+ * the context of the current request. This WILL NOT issue a remote HTTP
+ * request. Instead, it will route the provided URL, method, headers,
+ * cookies, body, and server variables against the set of registered
+ * application routes. The result response object is returned.
+ *
+ * @param string $method The request method (e.g., GET, POST, PUT, etc.)
+ * @param string $path The request URI path
+ * @param string $query The request URI query string
+ * @param array $headers The request headers (key-value array)
+ * @param array $cookies The request cookies (key-value array)
+ * @param string $bodyContent The request body
+ * @param ResponseInterface $response The response object (optional)
+ * @return ResponseInterface
+ */
+ public function subRequest($method, $path, $query = '', array $headers = [], array $cookies = [], $bodyContent = '', ResponseInterface $response = null)
+ {
+ $env = $this->container->get('environment');
+ $uri = Uri::createFromEnvironment($env)->withPath($path)->withQuery($query);
+ $headers = new Headers($headers);
+ $serverParams = $env->all();
+ $body = new Body(fopen('php://temp', 'r+'));
+ $body->write($bodyContent);
+ $body->rewind();
+ $request = new Request($method, $uri, $headers, $cookies, $serverParams, $body);
+
+ if (!$response) {
+ $response = $this->container->get('response');
+ }
+
+ return $this($request, $response);
+ }
+
+ /**
+ * Dispatch the router to find the route. Prepare the route for use.
+ *
+ * @param ServerRequestInterface $request
+ * @param RouterInterface $router
+ * @return ServerRequestInterface
+ */
+ protected function dispatchRouterAndPrepareRoute(ServerRequestInterface $request, RouterInterface $router)
+ {
+ $routeInfo = $router->dispatch($request);
+
+ if ($routeInfo[0] === Dispatcher::FOUND) {
+ $routeArguments = [];
+ foreach ($routeInfo[2] as $k => $v) {
+ $routeArguments[$k] = urldecode($v);
+ }
+
+ $route = $router->lookupRoute($routeInfo[1]);
+ $route->prepare($request, $routeArguments);
+
+ // add route to the request's attributes in case a middleware or handler needs access to the route
+ $request = $request->withAttribute('route', $route);
+ }
+
+ $routeInfo['request'] = [$request->getMethod(), (string) $request->getUri()];
+
+ return $request->withAttribute('routeInfo', $routeInfo);
+ }
+
+ /**
+ * Finalize response
+ *
+ * @param ResponseInterface $response
+ * @return ResponseInterface
+ */
+ protected function finalize(ResponseInterface $response)
+ {
+ // stop PHP sending a Content-Type automatically
+ ini_set('default_mimetype', '');
+
+ if ($this->isEmptyResponse($response)) {
+ return $response->withoutHeader('Content-Type')->withoutHeader('Content-Length');
+ }
+
+ $size = $response->getBody()->getSize();
+ if ($size !== null && !$response->hasHeader('Content-Length')) {
+ $response = $response->withHeader('Content-Length', (string) $size);
+ }
+
+ return $response;
+ }
+
+ /**
+ * Helper method, which returns true if the provided response must not output a body and false
+ * if the response could have a body.
+ *
+ * @see https://tools.ietf.org/html/rfc7231
+ *
+ * @param ResponseInterface $response
+ * @return bool
+ */
+ protected function isEmptyResponse(ResponseInterface $response)
+ {
+ if (method_exists($response, 'isEmpty')) {
+ return $response->isEmpty();
+ }
+ return in_array($response->getStatusCode(), [204, 205, 304]);
+ }
+}
diff --git a/Slim/CallableResolver.php b/Slim/CallableResolver.php
new file mode 100644
index 0000000..4dc671e
--- /dev/null
+++ b/Slim/CallableResolver.php
@@ -0,0 +1,87 @@
+container = $container;
+ }
+
+ /**
+ * Resolve toResolve into a closure that that the router can dispatch.
+ *
+ * If toResolve is of the format 'class:method', then try to extract 'class'
+ * from the container otherwise instantiate it and then dispatch 'method'.
+ *
+ * @param mixed $toResolve
+ *
+ * @return callable
+ *
+ * @throws RuntimeException if the callable does not exist
+ * @throws RuntimeException if the callable is not resolvable
+ */
+ public function resolve($toResolve)
+ {
+ $resolved = $toResolve;
+
+ if (!is_callable($toResolve) && is_string($toResolve)) {
+ // check for slim callable as "class:method"
+ $callablePattern = '!^([^\:]+)\:([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)$!';
+ if (preg_match($callablePattern, $toResolve, $matches)) {
+ $class = $matches[1];
+ $method = $matches[2];
+
+ if ($this->container->has($class)) {
+ $resolved = [$this->container->get($class), $method];
+ } else {
+ if (!class_exists($class)) {
+ throw new RuntimeException(sprintf('Callable %s does not exist', $class));
+ }
+ $resolved = [new $class($this->container), $method];
+ }
+ } else {
+ // check if string is something in the DIC that's callable or is a class name which
+ // has an __invoke() method
+ $class = $toResolve;
+ if ($this->container->has($class)) {
+ $resolved = $this->container->get($class);
+ } else {
+ if (!class_exists($class)) {
+ throw new RuntimeException(sprintf('Callable %s does not exist', $class));
+ }
+ $resolved = new $class($this->container);
+ }
+ }
+ }
+
+ if (!is_callable($resolved)) {
+ throw new RuntimeException(sprintf('%s is not resolvable', $toResolve));
+ }
+
+ return $resolved;
+ }
+}
diff --git a/Slim/CallableResolverAwareTrait.php b/Slim/CallableResolverAwareTrait.php
new file mode 100644
index 0000000..e6bae51
--- /dev/null
+++ b/Slim/CallableResolverAwareTrait.php
@@ -0,0 +1,47 @@
+container instanceof ContainerInterface) {
+ return $callable;
+ }
+
+ /** @var CallableResolverInterface $resolver */
+ $resolver = $this->container->get('callableResolver');
+
+ return $resolver->resolve($callable);
+ }
+}
diff --git a/Slim/Collection.php b/Slim/Collection.php
new file mode 100644
index 0000000..9540d46
--- /dev/null
+++ b/Slim/Collection.php
@@ -0,0 +1,204 @@
+ $value) {
+ $this->set($key, $value);
+ }
+ }
+
+ /********************************************************************************
+ * Collection interface
+ *******************************************************************************/
+
+ /**
+ * Set collection item
+ *
+ * @param string $key The data key
+ * @param mixed $value The data value
+ */
+ public function set($key, $value)
+ {
+ $this->data[$key] = $value;
+ }
+
+ /**
+ * Get collection item for key
+ *
+ * @param string $key The data key
+ * @param mixed $default The default value to return if data key does not exist
+ *
+ * @return mixed The key's value, or the default value
+ */
+ public function get($key, $default = null)
+ {
+ return $this->has($key) ? $this->data[$key] : $default;
+ }
+
+ /**
+ * Add item to collection
+ *
+ * @param array $items Key-value array of data to append to this collection
+ */
+ public function replace(array $items)
+ {
+ foreach ($items as $key => $value) {
+ $this->set($key, $value);
+ }
+ }
+
+ /**
+ * Get all items in collection
+ *
+ * @return array The collection's source data
+ */
+ public function all()
+ {
+ return $this->data;
+ }
+
+ /**
+ * Get collection keys
+ *
+ * @return array The collection's source data keys
+ */
+ public function keys()
+ {
+ return array_keys($this->data);
+ }
+
+ /**
+ * Does this collection have a given key?
+ *
+ * @param string $key The data key
+ *
+ * @return bool
+ */
+ public function has($key)
+ {
+ return array_key_exists($key, $this->data);
+ }
+
+ /**
+ * Remove item from collection
+ *
+ * @param string $key The data key
+ */
+ public function remove($key)
+ {
+ unset($this->data[$key]);
+ }
+
+ /**
+ * Remove all items from collection
+ */
+ public function clear()
+ {
+ $this->data = [];
+ }
+
+ /********************************************************************************
+ * ArrayAccess interface
+ *******************************************************************************/
+
+ /**
+ * Does this collection have a given key?
+ *
+ * @param string $key The data key
+ *
+ * @return bool
+ */
+ public function offsetExists($key)
+ {
+ return $this->has($key);
+ }
+
+ /**
+ * Get collection item for key
+ *
+ * @param string $key The data key
+ *
+ * @return mixed The key's value, or the default value
+ */
+ public function offsetGet($key)
+ {
+ return $this->get($key);
+ }
+
+ /**
+ * Set collection item
+ *
+ * @param string $key The data key
+ * @param mixed $value The data value
+ */
+ public function offsetSet($key, $value)
+ {
+ $this->set($key, $value);
+ }
+
+ /**
+ * Remove item from collection
+ *
+ * @param string $key The data key
+ */
+ public function offsetUnset($key)
+ {
+ $this->remove($key);
+ }
+
+ /**
+ * Get number of items in collection
+ *
+ * @return int
+ */
+ public function count()
+ {
+ return count($this->data);
+ }
+
+ /********************************************************************************
+ * IteratorAggregate interface
+ *******************************************************************************/
+
+ /**
+ * Get collection iterator
+ *
+ * @return \ArrayIterator
+ */
+ public function getIterator()
+ {
+ return new ArrayIterator($this->data);
+ }
+}
diff --git a/Slim/Container.php b/Slim/Container.php
new file mode 100644
index 0000000..fb08a93
--- /dev/null
+++ b/Slim/Container.php
@@ -0,0 +1,296 @@
+ '1.1',
+ 'responseChunkSize' => 4096,
+ 'outputBuffering' => 'append',
+ 'determineRouteBeforeAppMiddleware' => false,
+ 'displayErrorDetails' => false,
+ ];
+
+ /**
+ * Create new container
+ *
+ * @param array $values The parameters or objects.
+ */
+ public function __construct(array $values = [])
+ {
+ parent::__construct($values);
+
+ $userSettings = isset($values['settings']) ? $values['settings'] : [];
+ $this->registerDefaultServices($userSettings);
+ }
+
+ /**
+ * This function registers the default services that Slim needs to work.
+ *
+ * All services are shared - that is, they are registered such that the
+ * same instance is returned on subsequent calls.
+ *
+ * @param array $userSettings Associative array of application settings
+ *
+ * @return void
+ */
+ private function registerDefaultServices($userSettings)
+ {
+ $defaultSettings = $this->defaultSettings;
+
+ /**
+ * This service MUST return an array or an
+ * instance of \ArrayAccess.
+ *
+ * @return array|\ArrayAccess
+ */
+ $this['settings'] = function () use ($userSettings, $defaultSettings) {
+ return new Collection(array_merge($defaultSettings, $userSettings));
+ };
+
+ if (!isset($this['environment'])) {
+ /**
+ * This service MUST return a shared instance
+ * of \Slim\Interfaces\Http\EnvironmentInterface.
+ *
+ * @return EnvironmentInterface
+ */
+ $this['environment'] = function () {
+ return new Environment($_SERVER);
+ };
+ }
+
+ if (!isset($this['request'])) {
+ /**
+ * PSR-7 Request object
+ *
+ * @param Container $c
+ *
+ * @return ServerRequestInterface
+ */
+ $this['request'] = function ($c) {
+ return Request::createFromEnvironment($c->get('environment'));
+ };
+ }
+
+ if (!isset($this['response'])) {
+ /**
+ * PSR-7 Response object
+ *
+ * @param Container $c
+ *
+ * @return ResponseInterface
+ */
+ $this['response'] = function ($c) {
+ $headers = new Headers(['Content-Type' => 'text/html; charset=UTF-8']);
+ $response = new Response(200, $headers);
+
+ return $response->withProtocolVersion($c->get('settings')['httpVersion']);
+ };
+ }
+
+ if (!isset($this['router'])) {
+ /**
+ * This service MUST return a SHARED instance
+ * of \Slim\Interfaces\RouterInterface.
+ *
+ * @return RouterInterface
+ */
+ $this['router'] = function () {
+ return new Router;
+ };
+ }
+
+ if (!isset($this['foundHandler'])) {
+ /**
+ * This service MUST return a SHARED instance
+ * of \Slim\Interfaces\InvocationStrategyInterface.
+ *
+ * @return InvocationStrategyInterface
+ */
+ $this['foundHandler'] = function () {
+ return new RequestResponse;
+ };
+ }
+
+ if (!isset($this['errorHandler'])) {
+ /**
+ * This service MUST return a callable
+ * that accepts three arguments:
+ *
+ * 1. Instance of \Psr\Http\Message\ServerRequestInterface
+ * 2. Instance of \Psr\Http\Message\ResponseInterface
+ * 3. Instance of \Exception
+ *
+ * The callable MUST return an instance of
+ * \Psr\Http\Message\ResponseInterface.
+ *
+ * @param Container $c
+ *
+ * @return callable
+ */
+ $this['errorHandler'] = function ($c) {
+ return new Error($c->get('settings')['displayErrorDetails']);
+ };
+ }
+
+ if (!isset($this['notFoundHandler'])) {
+ /**
+ * This service MUST return a callable
+ * that accepts two arguments:
+ *
+ * 1. Instance of \Psr\Http\Message\ServerRequestInterface
+ * 2. Instance of \Psr\Http\Message\ResponseInterface
+ *
+ * The callable MUST return an instance of
+ * \Psr\Http\Message\ResponseInterface.
+ *
+ * @return callable
+ */
+ $this['notFoundHandler'] = function () {
+ return new NotFound;
+ };
+ }
+
+ if (!isset($this['notAllowedHandler'])) {
+ /**
+ * This service MUST return a callable
+ * that accepts three arguments:
+ *
+ * 1. Instance of \Psr\Http\Message\ServerRequestInterface
+ * 2. Instance of \Psr\Http\Message\ResponseInterface
+ * 3. Array of allowed HTTP methods
+ *
+ * The callable MUST return an instance of
+ * \Psr\Http\Message\ResponseInterface.
+ *
+ * @return callable
+ */
+ $this['notAllowedHandler'] = function () {
+ return new NotAllowed;
+ };
+ }
+
+ if (!isset($this['callableResolver'])) {
+ /**
+ * Instance of \Slim\Interfaces\CallableResolverInterface
+ *
+ * @param Container $c
+ *
+ * @return CallableResolverInterface
+ */
+ $this['callableResolver'] = function ($c) {
+ return new CallableResolver($c);
+ };
+ }
+ }
+
+ /********************************************************************************
+ * Methods to satisfy Interop\Container\ContainerInterface
+ *******************************************************************************/
+
+ /**
+ * Finds an entry of the container by its identifier and returns it.
+ *
+ * @param string $id Identifier of the entry to look for.
+ *
+ * @throws ContainerValueNotFoundException No entry was found for this identifier.
+ * @throws ContainerException Error while retrieving the entry.
+ *
+ * @return mixed Entry.
+ */
+ public function get($id)
+ {
+ if (!$this->offsetExists($id)) {
+ throw new ContainerValueNotFoundException(sprintf('Identifier "%s" is not defined.', $id));
+ }
+ return $this->offsetGet($id);
+ }
+
+ /**
+ * Returns true if the container can return an entry for the given identifier.
+ * Returns false otherwise.
+ *
+ * @param string $id Identifier of the entry to look for.
+ *
+ * @return boolean
+ */
+ public function has($id)
+ {
+ return $this->offsetExists($id);
+ }
+
+
+ /********************************************************************************
+ * Magic methods for convenience
+ *******************************************************************************/
+
+ public function __get($name)
+ {
+ return $this->get($name);
+ }
+
+ public function __isset($name)
+ {
+ return $this->has($name);
+ }
+}
diff --git a/Slim/Exception/ContainerValueNotFoundException.php b/Slim/Exception/ContainerValueNotFoundException.php
new file mode 100644
index 0000000..9627164
--- /dev/null
+++ b/Slim/Exception/ContainerValueNotFoundException.php
@@ -0,0 +1,20 @@
+allowedMethods = $allowedMethods;
+ }
+
+ /**
+ * Get allowed methods
+ *
+ * @return string[]
+ */
+ public function getAllowedMethods()
+ {
+ return $this->allowedMethods;
+ }
+}
diff --git a/Slim/Exception/NotFoundException.php b/Slim/Exception/NotFoundException.php
new file mode 100644
index 0000000..3739085
--- /dev/null
+++ b/Slim/Exception/NotFoundException.php
@@ -0,0 +1,8 @@
+request = $request;
+ $this->response = $response;
+ }
+
+ /**
+ * Get request
+ *
+ * @return ServerRequestInterface
+ */
+ public function getRequest()
+ {
+ return $this->request;
+ }
+
+ /**
+ * Get response
+ *
+ * @return ResponseInterface
+ */
+ public function getResponse()
+ {
+ return $this->response;
+ }
+}
diff --git a/Slim/Handlers/Error.php b/Slim/Handlers/Error.php
new file mode 100644
index 0000000..f525391
--- /dev/null
+++ b/Slim/Handlers/Error.php
@@ -0,0 +1,239 @@
+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 = '
The application could not run because of the following error:
';
+ $html .= 'Details
';
+ $html .= $this->renderHtmlException($exception);
+
+ while ($exception = $exception->getPrevious()) {
+ $html .= 'Previous exception
';
+ $html .= $this->renderHtmlException($exception);
+ }
+ } else {
+ $html = 'A website error has occurred. Sorry for the temporary inconvenience.
';
+ }
+
+ $output = sprintf(
+ "" .
+ "%s%s
%s",
+ $title,
+ $title,
+ $html
+ );
+
+ return $output;
+ }
+
+ /**
+ * Render exception as HTML.
+ *
+ * @param Exception $exception
+ *
+ * @return string
+ */
+ protected function renderHtmlException(Exception $exception)
+ {
+ $html = sprintf('Type: %s
', get_class($exception));
+
+ if (($code = $exception->getCode())) {
+ $html .= sprintf('Code: %s
', $code);
+ }
+
+ if (($message = $exception->getMessage())) {
+ $html .= sprintf('Message: %s
', htmlentities($message));
+ }
+
+ if (($file = $exception->getFile())) {
+ $html .= sprintf('File: %s
', $file);
+ }
+
+ if (($line = $exception->getLine())) {
+ $html .= sprintf('Line: %s
', $line);
+ }
+
+ if (($trace = $exception->getTraceAsString())) {
+ $html .= 'Trace
';
+ $html .= sprintf('%s
', 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 = "\n Slim Application Error\n";
+ if ($this->displayErrorDetails) {
+ do {
+ $xml .= " \n";
+ $xml .= " " . get_class($exception) . "\n";
+ $xml .= " " . $exception->getCode() . "\n";
+ $xml .= " " . $this->createCdataSection($exception->getMessage()) . "\n";
+ $xml .= " " . $exception->getFile() . "\n";
+ $xml .= " " . $exception->getLine() . "\n";
+ $xml .= " " . $this->createCdataSection($exception->getTraceAsString()) . "\n";
+ $xml .= " \n";
+ } while ($exception = $exception->getPrevious());
+ }
+ $xml .= "";
+
+ return $xml;
+ }
+
+ /**
+ * Returns a CDATA section with the given content.
+ *
+ * @param string $content
+ * @return string
+ */
+ private function createCdataSection($content)
+ {
+ return sprintf('', str_replace(']]>', ']]]]>', $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';
+ }
+}
diff --git a/Slim/Handlers/NotAllowed.php b/Slim/Handlers/NotAllowed.php
new file mode 100644
index 0000000..5fa9ab3
--- /dev/null
+++ b/Slim/Handlers/NotAllowed.php
@@ -0,0 +1,173 @@
+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 "Method not allowed. Must be one of: $allow";
+ }
+
+ /**
+ * Render HTML not allowed message
+ *
+ * @param array $methods
+ * @return string
+ */
+ protected function renderHtmlNotAllowedMessage($methods)
+ {
+ $allow = implode(', ', $methods);
+ $output = <<
+
+ Method not allowed
+
+
+
+ Method not allowed
+ Method not allowed. Must be one of: $allow
+
+