Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

REST feature divided into two, REST and Resource #6

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
136 changes: 136 additions & 0 deletions src/Experimental/Routing/Resource.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
<?php
/*
* Inphinit
*
* Copyright (c) 2019 Guilherme Nascimento (brcontainer@yahoo.com.br)
*
* Released under the MIT license
*/

namespace Inphinit\Experimental\Routing;

use Inphinit\App;
use Inphinit\Routing\Route;
use Inphinit\Routing\Router;
use Inphinit\Experimental\Exception;
use Inphinit\Experimental\Dom\Document;

class Resource extends Router
{
private static $debuglvl = 2;
private $path = '';
private $fullController;
private $ready = false;
private static $valids = array(
'index' => array( 'GET', '/' ),
'create' => array( 'GET', '/create' ),
'store' => array( 'POST', '/' ),
'show' => array( 'GET', '/{:[^/]+:}' ),
'edit' => array( 'GET', '/{:[^/]+:}/edit' ),
'update' => array( 'POST', '/{:[^/]+:}/update' ),
'destroy' => array( 'POST', '/{:[^/]+:}/destroy' ),
);

/**
* Create REST routes based in a \Controller
*
* @param string $controller
* @return void
*/
public static function create($controller)
{
self::$debuglvl = 3;

$rest = new static($controller);
$rest->prepare();
$rest = null;
}

/**
* Create REST routes based in a \Controller
*
* @param string $controller
* @throws \Inphinit\Experimental\Exception
* @return \Inphinit\Experimental\Rest
*/
public function __construct($controller)
{
$fullController = '\\Controller\\' . parent::$prefixNS . strtr($controller, '.', '\\');

if (class_exists($fullController) === false) {
$level = self::$debuglvl;

self::$debuglvl = 2;

throw new Exception('Invalid class ' . $fullController, $level);
}

$this->fullController = $fullController;

$path = strtolower(preg_replace('#([a-z])([A-Z])#', '$1-$2', strtr($controller, '.', '/')));

$this->path = '/' . trim($path, '/');
}

/**
* Define the Content-Type charset
*
* @param string $prefix
* @return \Inphinit\Experimental\Rest
*/
public function path($path)
{
if ($path === '') {
$this->path = '';
} else {
$this->path = '/' . trim(str_replace('//', '/', $path), '/');
}

return $this;
}

/**
* Define routes
*
* @throws \Inphinit\Experimental\Exception
* @return void
*/
public function prepare()
{
if ($this->ready) {
return null;
}

$this->ready = true;

$controller = $this->fullController;

$methods = get_class_methods($controller);
$allowedMethods = array_keys(self::$valids);

$classMethods = array_intersect($methods, $allowedMethods);

if (empty($classMethods)) {
$level = self::$debuglvl;

self::$debuglvl = 2;

throw new Exception($controller . ' controller exists, but is not valid', $level);
}

$contentType = $this->contentType . '; charset=' . $this->charset;
$path = $this->path;

foreach ($classMethods as $method) {
if (false === empty(self::$valids[$method])) {
$route = self::$valids[$method];

Route::set($route[0], $path . $route[1], function () use ($method, $contentType, $controller) {
header('Content-Type: text/html; charset=UTF-8');

return call_user_func_array(array(new $controller, $method), func_get_args());
});
}
}
}
}
94 changes: 76 additions & 18 deletions src/Experimental/Routing/Rest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,20 @@
use Inphinit\Routing\Route;
use Inphinit\Routing\Router;
use Inphinit\Experimental\Exception;
use Inphinit\Experimental\Dom\Document;

class Rest extends Router
{
private static $debuglvl = 2;
private $contentType = 'application/json';
private $charset = 'UTF-8';
private $controller;
private $path = '';
private $fullController;
private $ready = false;
private static $valids = array(
'index' => array( 'GET', '/' ),
'create' => array( 'GET', '/create' ),
'store' => array( 'POST', '/' ),
'show' => array( 'GET', '/{:[^/]+:}' ),
'edit' => array( 'GET', '/{:[^/]+:}/edit' ),
'update' => array( array('PUT', 'PATCH'), '/{:[^/]+:}' ),
'destroy' => array( 'DELETE', '/{:[^/]+:}' ),
);
Expand All @@ -39,6 +39,8 @@ class Rest extends Router
*/
public static function create($controller)
{
self::$debuglvl = 3;

$rest = new static($controller);
$rest->prepare();
$rest = null;
Expand All @@ -49,32 +51,68 @@ public static function create($controller)
*
* @param string $controller
* @throws \Inphinit\Experimental\Exception
* @return void
* @return \Inphinit\Experimental\Rest
*/
public function __construct($controller)
{
$fullController = parent::$prefixNS . strtr($controller, '.', '\\');
$fullController = '\\Controller\\' . $fullController;
$fullController = '\\Controller\\' . parent::$prefixNS . strtr($controller, '.', '\\');

if (class_exists($fullController) === false) {
throw new Exception('Invalid class ' . $fullController, 2);
$level = self::$debuglvl;

self::$debuglvl = 2;

throw new Exception('Invalid class ' . $fullController, $level);
}

$this->controller = $controller;
$this->fullController = $fullController;

$path = strtolower(preg_replace('#([a-z])([A-Z])#', '$1-$2', strtr($controller, '.', '/')));

$this->path = '/' . trim($path, '/');
}

/**
* Define routes
* Define the Content-Type header
*
* @param string $contentType
* @param string $charset
* @return void
* @return \Inphinit\Experimental\Rest
*/
public function type($contentType, $charset = 'UTF-8')
public function type($contentType)
{
$this->contentType = $contentType;

return $this;
}

/**
* Define the Content-Type charset
*
* @param string $charset
* @return \Inphinit\Experimental\Rest
*/
public function charset($charset)
{
$this->charset = $charset;

return $this;
}

/**
* Define the Content-Type charset
*
* @param string $prefix
* @return \Inphinit\Experimental\Rest
*/
public function path($path)
{
if ($path === '') {
$this->path = '';
} else {
$this->path = '/' . trim(str_replace('//', '/', $path), '/');
}

return $this;
}

/**
Expand All @@ -99,20 +137,40 @@ public function prepare()
$classMethods = array_intersect($methods, $allowedMethods);

if (empty($classMethods)) {
throw new Exception($controller . ' controller exists, but is not a valid', 2);
$level = self::$debuglvl;

self::$debuglvl = 2;

throw new Exception($controller . ' controller exists, but is not valid', $level);
}

$contentType = $this->contentType . '; charset=' . $this->charset;
$path = $this->path;

foreach ($classMethods as $method) {
$route = empty(self::$valids[$method]) ? false : self::$valids[$method];
if (false === empty(self::$valids[$method])) {
$route = self::$valids[$method];

if ($route) {
Route::set($route[0], $route[1], function ()
use ($method, $contentType, $controller) {
Route::set($route[0], $path . $route[1], function () use ($method, $contentType, $controller) {
header('Content-Type: ' . $contentType);

return call_user_func_array(array(new $controller, $method), func_get_args());
$response = call_user_func_array(array(new $controller, $method), func_get_args());

if (is_array($response) || is_object($response)) {
$doc = new Document;

$doc->fromArray(array(
'root' => $response
));

if (strcasecmp($contentType, 'application/json')) {
$response = $doc->toJson();
} elseif (strcasecmp($contentType, 'text/xml') || strcasecmp($contentType, 'application/xml')) {
$response = $doc->toString();
}
}

return $response;
});
}
}
Expand Down