Skip to content

Commit ae196d1

Browse files
committed
Run controller with dynamics parameters route | The basic for run
1 parent 59b7439 commit ae196d1

14 files changed

+292
-23
lines changed

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
1-
/vendor
1+
/vendor
2+
.htaccess
3+
index.php

ControllerTeste.php

Lines changed: 0 additions & 12 deletions
This file was deleted.

index.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
<?php
22
require_once("vendor/autoload.php");
3+
use MareaTurbo\Route;
34

4-
(new MareaTurbo\Router)->controllers([
5+
class ControllerTeste
6+
{
7+
public function __construct(){}
8+
9+
#[Route("/teste", "POST")]
10+
public function teste()
11+
{
12+
echo "EITA";
13+
}
514

15+
#[Route("/teste/{id}/teste", "GET")]
16+
public function teste2($parameters)
17+
{
18+
echo "EITA 2" . $parameters->id;
19+
}
20+
}
21+
22+
(new MareaTurbo\Router)->controllers([
23+
ControllerTeste::class,
624
]);

phpunit.xml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
4+
bootstrap="vendor/autoload.php"
5+
colors="true"
6+
>
7+
<testsuites>
8+
<testsuite name="Test Suite">
9+
<directory suffix="Test.php">./tests</directory>
10+
</testsuite>
11+
</testsuites>
12+
<source>
13+
<include>
14+
<directory suffix=".php">./app</directory>
15+
<directory suffix=".php">./src</directory>
16+
</include>
17+
</source>
18+
</phpunit>

src/Controller.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MareaTurbo;
5+
use MareaTurbo\MareaTurboException;
6+
use ReflectionClass;
7+
use MareaTurbo\RouteParameters;
8+
9+
class Controller
10+
{
11+
private String $classController;
12+
private Mixed $controller;
13+
14+
public function __construct(String $classController)
15+
{
16+
$this->classController = $classController;
17+
}
18+
19+
private function build() : void
20+
{
21+
$reflectionControllerInstance = new ReflectionClass($this->classController);
22+
$this->controller = $this->recursiveDependenciesBuild($reflectionControllerInstance);
23+
}
24+
25+
public function runMethod(String $method, RouteParameters $routeParams) : mixed
26+
{
27+
if($this->isValidMethod($method) == false) {
28+
throw new MareaTurboException("Method not found");
29+
}
30+
$this->build();
31+
return $this->controller->$method($routeParams);
32+
}
33+
34+
private function isValidMethod(String $method, ) : bool
35+
{
36+
return method_exists($this->classController, $method);
37+
}
38+
39+
private function recursiveDependenciesBuild(ReflectionClass $reflectionControllerInstance) : mixed
40+
{
41+
$dependencies = $reflectionControllerInstance->getConstructor()->getParameters();
42+
if($dependencies == null) {
43+
return $reflectionControllerInstance->newInstance();
44+
}
45+
46+
$arguments = array();
47+
foreach($dependencies as $dependency){
48+
$depencyClassName = $dependency->getType()->getName();
49+
$dependencyReflectionClass = new ReflectionClass($depencyClassName);
50+
$arguments[] = $this->recursiveDependenciesBuild($dependencyReflectionClass);
51+
}
52+
return $reflectionControllerInstance->newInstanceArgs($arguments);
53+
}
54+
}

src/HttpMelhod.php renamed to src/HttpMethod.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
<?php
2+
declare(strict_types=1);
23

34
namespace MareaTurbo;
45

@@ -9,13 +10,13 @@ class HttpMethod
910

1011
public function __construct(String $name)
1112
{
12-
$this->name = $this->validateName($name);
13+
$this->name = $this->validateName(strtoupper($name));
1314
}
1415

15-
private function validateName(String $name) : String
16+
protected function validateName(String $name) : String
1617
{
1718
if (!in_array($name, ["GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"])) {
18-
throw new \Exception("Invalid http method");
19+
throw new \MareaTurbo\MareaTurboException("Invalid http method");
1920
}
2021
return $name;
2122
}

src/MareaTurboException.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
<?php
2+
declare(strict_types=1);
3+
24
namespace MareaTurbo;
35
use Exception;
46

src/Request.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<?php

src/Route.php

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,59 @@
11
<?php
2+
declare(strict_types=1);
23

34
namespace MareaTurbo;
45

6+
use MareaTurbo\RouteParameters;
57
use Attribute;
68

79
#[Attribute]
8-
class Router
10+
class Route
911
{
1012
public String $path;
11-
public String $method;
13+
public HttpMethod $method;
1214

13-
public function __construct(String $path = '/', String $method = "GET")
14-
{
15+
public function __construct(String $path, String $method) {
1516
$this->path = $path;
16-
$this->method = $method;
17+
$this->method = new HttpMethod($method);
18+
}
19+
20+
public function isMatch(Route $route) : bool
21+
{
22+
$currentRoute = explode('/', $this->path);
23+
$accessedRoute = explode('/', $route->path);
24+
25+
if($route->method->name != $this->method->name) {
26+
return false;
27+
}
28+
29+
if(count($accessedRoute) != count($currentRoute)) {
30+
return false;
31+
}
32+
33+
for($i = 0; $i < count($accessedRoute); $i++) {
34+
if($accessedRoute[$i] != $currentRoute[$i]) {
35+
if(strpos($currentRoute[$i], '{') !== false) {
36+
continue;
37+
}
38+
return false;
39+
}
40+
}
41+
return true;
42+
}
43+
44+
public function getDynamicParameters(Route $acessedRoute) : RouteParameters
45+
{
46+
$currentRoute = explode('/', $this->path);
47+
$accessedRoute = explode('/', $acessedRoute->path);
48+
$parameters = new RouteParameters();
49+
50+
for($i=0; $i < count($accessedRoute); $i++) {
51+
if($accessedRoute[$i] != $currentRoute[$i]) {
52+
if(strpos($currentRoute[$i], '{') !== false) {
53+
$parameters->{str_replace(['{', '}'], '', $currentRoute[$i])} = $accessedRoute[$i];
54+
}
55+
}
56+
}
57+
return $parameters;
1758
}
18-
}
59+
}

src/RouteParameters.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace MareaTurbo;
5+
6+
use AllowDynamicProperties;
7+
8+
#[AllowDynamicProperties]
9+
class RouteParameters
10+
{}

src/Router.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace MareaTurbo;
55

6+
use MareaTurbo\Controller;
67
use ReflectionClass;
78

89
class Router
@@ -12,6 +13,41 @@ class Router
1213
public function controllers(array $controllers = [])
1314
{
1415
$this->controllers = $controllers;
16+
$this->run();
17+
}
18+
19+
public function run()
20+
{
21+
$acessedRoute = $this->getAccessedRoute();
22+
23+
foreach($this->controllers as $controller) {
24+
$reflectionController = new ReflectionClass($controller);
25+
foreach($reflectionController->getMethods() as $method) {
26+
foreach($method->getAttributes() as $route) {
27+
$routeInstance = $route->newInstance();
28+
if($routeInstance->isMatch($acessedRoute)) {
29+
return (new Controller($controller))->runMethod(
30+
$method->getName(),
31+
$routeInstance->getDynamicParameters($acessedRoute)
32+
);
33+
}
34+
}
35+
}
36+
}
37+
}
38+
39+
public function isCli()
40+
{
41+
return php_sapi_name() === 'cli';
42+
}
43+
44+
public function getAccessedRoute()
45+
{
46+
global $argv;
47+
$route = $this->isCli() ? $argv[1] : $_SERVER['REQUEST_URI'];
48+
$method = $this->isCli() ? "GET" : $_SERVER['REQUEST_METHOD'];
49+
50+
return new Route($route, $method);
1551
}
1652
}
1753

tests/Pest.php

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php
2+
3+
/*
4+
|--------------------------------------------------------------------------
5+
| Test Case
6+
|--------------------------------------------------------------------------
7+
|
8+
| The closure you provide to your test functions is always bound to a specific PHPUnit test
9+
| case class. By default, that class is "PHPUnit\Framework\TestCase". Of course, you may
10+
| need to change it using the "uses()" function to bind a different classes or traits.
11+
|
12+
*/
13+
14+
// uses(Tests\TestCase::class)->in('Feature');
15+
16+
/*
17+
|--------------------------------------------------------------------------
18+
| Expectations
19+
|--------------------------------------------------------------------------
20+
|
21+
| When you're writing tests, you often need to check that values meet certain conditions. The
22+
| "expect()" function gives you access to a set of "expectations" methods that you can use
23+
| to assert different things. Of course, you may extend the Expectation API at any time.
24+
|
25+
*/
26+
27+
expect()->extend('toBeOne', function () {
28+
return $this->toBe(1);
29+
});
30+
31+
/*
32+
|--------------------------------------------------------------------------
33+
| Functions
34+
|--------------------------------------------------------------------------
35+
|
36+
| While Pest is very powerful out-of-the-box, you may have some testing code specific to your
37+
| project that you don't want to repeat in every file. Here you can also expose helpers as
38+
| global functions to help you to reduce the number of lines of code in your test files.
39+
|
40+
*/
41+
42+
function something()
43+
{
44+
// ..
45+
}

tests/Unit/HttpMethodTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
test('the name must be valid in upper case - GET, POST, etc', function () {
4+
$httpMethod = new \MareaTurbo\HttpMethod("GET");
5+
expect($httpMethod->name)->toBe("GET");
6+
});
7+
8+
test('the name must be valid - get, post, etc', function () {
9+
$httpMethod = new \MareaTurbo\HttpMethod("post");
10+
expect($httpMethod->name)->toBe("POST");
11+
});
12+
13+
test('an exception should occur if the name is invalid', function () {
14+
$httpMethod = new \MareaTurbo\HttpMethod("INVALID");
15+
})->throws(\MareaTurbo\MareaTurboException::class, "Invalid http method");
16+

tests/Unit/RouteTest.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
test("must return true when the http routes and methods are the same as the request", function () {
4+
$route = new \MareaTurbo\Route("/post/1", "GET");
5+
$currentRoute = new \MareaTurbo\Route("/post/1", "GET");
6+
7+
$match = $route->isMatch($currentRoute);
8+
9+
expect($match)->toBeTrue();
10+
});
11+
12+
test("must return true when it is equal and contains dynamic parameters", function () {
13+
$route = new \MareaTurbo\Route("category/{id_category}/post/{id}", "GET");
14+
$currentRoute = new \MareaTurbo\Route("category/10/post/1", "GET");
15+
16+
$match = $route->isMatch($currentRoute);
17+
18+
expect($match)->toBeTrue();
19+
});
20+
21+
test("should return false when different", function () {
22+
$route = new \MareaTurbo\Route("/post/{id}/limit", "GET");
23+
$currentRoute = new \MareaTurbo\Route("/post/1", "GET");
24+
25+
$match = $route->isMatch($currentRoute);
26+
27+
expect($match)->toBeFalse();
28+
});
29+
30+
test("must return false when the method is different", function () {
31+
$route = new \MareaTurbo\Route("/post/{id}/limit", "GET");
32+
$currentRoute = new \MareaTurbo\Route("/post/1", "POST");
33+
34+
$match = $route->isMatch($currentRoute);
35+
36+
expect($match)->toBeFalse();
37+
});

0 commit comments

Comments
 (0)