Refactored structure

This commit is contained in:
Dmitry Khomutov 2016-04-17 12:34:12 +06:00
commit e5164ae1dd
329 changed files with 277 additions and 457 deletions

149
src/B8Framework/Http/Request.php Executable file
View file

@ -0,0 +1,149 @@
<?php
namespace b8\Http;
class Request
{
/**
* @var array
*/
protected $params = array();
/**
* Request data.
*/
protected $data = array();
/**
* Set up the request.
*/
public function __construct()
{
$this->parseInput();
$this->data['path'] = $this->getRequestPath();
$this->data['parts'] = array_values(array_filter(explode('/', $this->data['path'])));
}
protected function getRequestPath()
{
$path = '';
// Start out with the REQUEST_URI:
if (!empty($_SERVER['REQUEST_URI'])) {
$path = $_SERVER['REQUEST_URI'];
}
if ($_SERVER['SCRIPT_NAME'] != $_SERVER['REQUEST_URI']) {
$scriptPath = str_replace('/index.php', '', $_SERVER['SCRIPT_NAME']);
$path = str_replace($scriptPath, '', $path);
}
// Remove index.php from the URL if it is present:
$path = str_replace(array('/index.php', 'index.php'), '', $path);
// Also cut out the query string:
$path = explode('?', $path);
$path = array_shift($path);
return $path;
}
/**
* Parse incoming variables, incl. $_GET, $_POST and also reads php://input for PUT/DELETE.
*/
protected function parseInput()
{
$params = $_REQUEST;
if(!isset($_SERVER['REQUEST_METHOD']) || in_array($_SERVER['REQUEST_METHOD'], array('PUT', 'DELETE')))
{
$vars = file_get_contents('php://input');
if(!is_string($vars) || strlen(trim($vars)) === 0)
{
$vars = '';
}
$inputData = array();
parse_str($vars, $inputData);
$params = array_merge($params, $inputData);
}
$this->setParams($params);
}
/**
* Returns all request parameters.
* @return array
*/
public function getParams()
{
return $this->params;
}
/**
* Return a specific request parameter, or a default value if not set.
*/
public function getParam($key, $default = null)
{
if (isset($this->params[$key])) {
return $this->params[$key];
} else {
return $default;
}
}
/**
* Set or override a request parameter.
*/
public function setParam($key, $value = null)
{
$this->params[$key] = $value;
}
/**
* Set an array of request parameters.
*/
public function setParams(array $params)
{
$this->params = array_merge($this->params, $params);
}
/**
* Un-set a specific parameter.
*/
public function unsetParam($key)
{
unset($this->params[$key]);
}
public function getMethod()
{
return strtoupper($_SERVER['REQUEST_METHOD']);
}
public function getPath()
{
return $this->data['path'];
}
public function getPathParts()
{
return $this->data['parts'];
}
public function isAjax()
{
if (!isset($_SERVER['HTTP_X_REQUESTED_WITH'])) {
return false;
}
if (strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
return true;
}
return false;
}
}

132
src/B8Framework/Http/Response.php Executable file
View file

@ -0,0 +1,132 @@
<?php
namespace b8\Http;
class Response
{
protected $data = array();
public function __construct(Response $createFrom = null)
{
if (!is_null($createFrom)) {
$this->data = $createFrom->getData();
}
}
public function hasLayout()
{
return !isset($this->data['layout']) ? true : $this->data['layout'];
}
public function disableLayout()
{
$this->data['layout'] = false;
}
public function enableLayout()
{
$this->data['layout'] = true;
}
public function getData()
{
return $this->data;
}
public function setResponseCode($code)
{
$this->data['code'] = (int)$code;
}
public function setHeader($key, $val)
{
$this->data['headers'][$key] = $val;
}
public function clearHeaders()
{
$this->data['headers'] = array();
}
public function setContent($content)
{
$this->data['body'] = $content;
}
public function getContent()
{
return $this->data['body'];
}
public function flush()
{
$this->sendResponseCode();
if (isset($this->data['headers'])) {
foreach ($this->data['headers'] as $header => $val) {
header($header . ': ' . $val, true);
}
}
return $this->flushBody();
}
protected function sendResponseCode()
{
if (!isset($this->data['code'])) {
$this->data['code'] = 200;
}
switch ($this->data['code'])
{
// 300 class
case 301:
$text = 'Moved Permanently';
break;
case 302:
$text = 'Moved Temporarily';
break;
// 400 class errors
case 400:
$text = 'Bad Request';
break;
case 401:
$text = 'Not Authorized';
break;
case 403:
$text = 'Forbidden';
break;
case 404:
$text = 'Not Found';
break;
// 500 class errors
case 500:
$text = 'Internal Server Error';
break;
// OK
case 200:
default:
$text = 'OK';
break;
}
header('HTTP/1.1 ' . $this->data['code'] . ' ' . $text, true, $this->data['code']);
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return $this->data['body'];
}
return '';
}
public function __toString()
{
return $this->flush();
}
}

View file

@ -0,0 +1,30 @@
<?php
namespace b8\Http\Response;
use b8\Http\Response;
class JsonResponse extends Response
{
public function __construct(Response $createFrom = null)
{
parent::__construct($createFrom);
$this->setContent(array());
$this->setHeader('Content-Type', 'application/json');
}
public function hasLayout()
{
return false;
}
protected function flushBody()
{
if (isset($this->data['body'])) {
return json_encode($this->data['body']);
}
return json_encode(null);
}
}

View file

@ -0,0 +1,27 @@
<?php
namespace b8\Http\Response;
use b8\Http\Response;
class RedirectResponse extends Response
{
public function __construct(Response $createFrom = null)
{
parent::__construct($createFrom);
$this->setContent(null);
$this->setResponseCode(302);
}
public function hasLayout()
{
return false;
}
public function flush()
{
parent::flush();
die;
}
}

123
src/B8Framework/Http/Router.php Executable file
View file

@ -0,0 +1,123 @@
<?php
namespace b8\Http;
use b8\Application;
use b8\Config;
use b8\Http\Request;
class Router
{
/**
* @var \b8\Http\Request;
*/
protected $request;
/**
* @var \b8\Http\Config;
*/
protected $config;
/**
* @var \b8\Application
*/
protected $application;
/**
* @var array
*/
protected $routes = array(array('route' => '/:controller/:action', 'callback' => null, 'defaults' => array()));
public function __construct(Application $application, Request $request, Config $config)
{
$this->application = $application;
$this->request = $request;
$this->config = $config;
}
public function clearRoutes()
{
$this->routes = array();
}
/**
* @param string $route Route definition
* @param array $options
* @param callable $callback
* @throws \InvalidArgumentException
*/
public function register($route, $options = array(), $callback = null)
{
if (!is_callable($callback)) {
throw new \InvalidArgumentException('$callback must be callable.');
}
array_unshift($this->routes, array('route' => $route, 'callback' => $callback, 'defaults' => $options));
}
public function dispatch()
{
foreach ($this->routes as $route) {
$pathParts = $this->request->getPathParts();
//-------
// Set up default values for everything:
//-------
$thisNamespace = 'Controller';
$thisController = null;
$thisAction = null;
if (array_key_exists('namespace', $route['defaults'])) {
$thisNamespace = $route['defaults']['namespace'];
}
if (array_key_exists('controller', $route['defaults'])) {
$thisController = $route['defaults']['controller'];
}
if (array_key_exists('action', $route['defaults'])) {
$thisAction = $route['defaults']['action'];
}
$routeParts = array_filter(explode('/', $route['route']));
$routeMatches = true;
while (count($routeParts)) {
$routePart = array_shift($routeParts);
$pathPart = array_shift($pathParts);
switch ($routePart) {
case ':namespace':
$thisNamespace = !is_null($pathPart) ? $pathPart : $thisNamespace;
break;
case ':controller':
$thisController = !is_null($pathPart) ? $pathPart : $thisController;
break;
case ':action':
$thisAction = !is_null($pathPart) ? $pathPart : $thisAction;
break;
default:
if ($routePart != $pathPart) {
$routeMatches = false;
}
}
if (!$routeMatches || !count($pathParts)) {
break;
}
}
$thisArgs = $pathParts;
if ($routeMatches) {
$route = array('namespace' => $thisNamespace, 'controller' => $thisController, 'action' => $thisAction, 'args' => $thisArgs, 'callback' => $route['callback']);
if ($this->application->isValidRoute($route)) {
return $route;
}
}
}
return null;
}
}