Skip to content

Commit 7ca5e6c

Browse files
authored
Merge pull request #1 from Micro-PHP/v1.0-release
v1.0-rc
2 parents af9ece6 + e74a421 commit 7ca5e6c

File tree

96 files changed

+4486
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

96 files changed

+4486
-0
lines changed

.gitattributes

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
/.github export-ignore
2+
/tests export-ignore
3+
/phpunit.xml.dist export-ignore
4+
/.gitattributes export-ignore
5+
/.gitignore export-ignore
6+
/.php-cs-fixer.dist.php export-ignore
7+
/psalm.xml export-ignore
8+
9+
*.php diff=php

.github/workflows/.editorconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[{*.yaml,*.yml}]
2+
indent_size = 2

.github/workflows/ci.yaml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Plugin CI
2+
on:
3+
push:
4+
branches: [ 'master' ]
5+
pull_request:
6+
7+
env:
8+
PHP_CS_FIXER_IGNORE_ENV: 1
9+
XDEBUG_MODE: coverage
10+
11+
jobs:
12+
tests:
13+
name: "Tests ${{ matrix.php-version }} deps ${{ matrix.dependency-versions }}"
14+
runs-on: ubuntu-22.04
15+
16+
strategy:
17+
fail-fast: false
18+
matrix:
19+
# normal, highest, non-dev installs
20+
php-version: [ '8.2' ]
21+
dependency-versions: [ 'highest' ]
22+
include:
23+
# testing lowest PHP version with the lowest dependencies
24+
# - php-version: '8.2'
25+
# dependency-versions: 'lowest'
26+
27+
# testing dev versions with the highest PHP
28+
- php-version: '8.2'
29+
dependency-versions: 'highest'
30+
31+
steps:
32+
- name: "Checkout code"
33+
uses: "actions/checkout@v2"
34+
35+
- name: "Install PHP"
36+
uses: "shivammathur/setup-php@v2"
37+
with:
38+
coverage: "none"
39+
php-version: "${{ matrix.php-version }}"
40+
41+
- name: "Composer install"
42+
uses: "ramsey/composer-install@v2"
43+
with:
44+
dependency-versions: "${{ matrix.dependency-versions }}"
45+
composer-options: "--prefer-dist --no-progress"
46+
47+
- name: Run tests
48+
run: composer run test

.php-cs-fixer.dist.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
if (!file_exists(__DIR__.'/src')) {
4+
exit(0);
5+
}
6+
7+
$finder = (new PhpCsFixer\Finder())
8+
->in(__DIR__.'/src')
9+
->in(__DIR__.'/tests')
10+
;
11+
12+
return (new PhpCsFixer\Config())
13+
->setRules(array(
14+
'@Symfony' => true,
15+
'@Symfony:risky' => true,
16+
'protected_to_private' => false,
17+
'semicolon_after_instruction' => false,
18+
'header_comment' => [
19+
'header' => <<<EOF
20+
This file is part of the Micro framework package.
21+
22+
(c) Stanislau Komar <[email protected]>
23+
24+
For the full copyright and license information, please view the LICENSE
25+
file that was distributed with this source code.
26+
EOF
27+
]
28+
))
29+
->setRiskyAllowed(true)
30+
->setFinder($finder);

composer.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"name": "micro/http-core",
3+
"description": "Micro Framework: Lightweight HTTP router",
4+
"license": "MIT",
5+
"type": "micro-plugin",
6+
"authors": [
7+
{
8+
"name": "Stanislau Komar",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {
13+
"micro/autowire": "^1",
14+
"micro/kernel": "^1",
15+
"micro/kernel-app": "^1",
16+
"micro/kernel-boot-configuration": "^1",
17+
"micro/kernel-boot-dependency": "^1",
18+
"micro/kernel-boot-plugin-depended": "^1",
19+
"micro/plugin-locator": "^1",
20+
"symfony/http-foundation": "^6.2"
21+
},
22+
"require-dev": {
23+
"ergebnis/composer-normalize": "^2.29",
24+
"friendsofphp/php-cs-fixer": "^3.13",
25+
"phpstan/phpstan": "^1.9",
26+
"phpunit/php-code-coverage": "^9.2",
27+
"phpunit/phpunit": "^9.5",
28+
"vimeo/psalm": "^5.2"
29+
},
30+
"autoload": {
31+
"psr-4": {
32+
"Micro\\Plugin\\Http\\": "src/"
33+
}
34+
},
35+
"autoload-dev": {
36+
"psr-4": {
37+
"Micro\\Plugin\\Http\\Test\\": "tests/"
38+
}
39+
},
40+
"config": {
41+
"allow-plugins": {
42+
"ergebnis/composer-normalize": true
43+
},
44+
"sort-packages": true
45+
},
46+
"scripts": {
47+
"coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-text",
48+
"php-cs-fix": "./vendor/bin/php-cs-fixer fix --verbose --using-cache=no",
49+
"php-cs-try": "./vendor/bin/php-cs-fixer fix --verbose --dry-run --using-cache=no",
50+
"phpstan": "./vendor/bin/phpstan analyze --no-progress",
51+
"phpunit": "./vendor/bin/phpunit",
52+
"psalm": "./vendor/bin/psalm --no-progress --show-info=true",
53+
"statics": [
54+
"@phpstan",
55+
"@psalm",
56+
"@php-cs-try"
57+
],
58+
"test": [
59+
"@statics",
60+
"composer validate --strict",
61+
"composer normalize",
62+
"@coverage"
63+
]
64+
}
65+
}

phpstan.neon.dist

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
parameters:
2+
level: 7
3+
paths:
4+
- src

phpunit.xml.dist

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!-- https://phpunit.readthedocs.io/en/9.5/configuration.html#the-phpunit-element -->
3+
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.5/phpunit.xsd"
5+
backupGlobals="false"
6+
bootstrap="vendor/autoload.php"
7+
colors="true"
8+
failOnRisky="true"
9+
failOnWarning="true"
10+
>
11+
<php>
12+
<ini name="error_reporting" value="-1" force="true"/>
13+
</php>
14+
<testsuites>
15+
<testsuite name="Unit tests">
16+
<directory>tests/Unit</directory>
17+
</testsuite>
18+
</testsuites>
19+
<filter>
20+
<whitelist>
21+
<directory suffix=".php">src/</directory>
22+
<exclude>
23+
<directory>src/Exception</directory>
24+
<file>src/HttpCorePlugin.php</file>
25+
</exclude>
26+
</whitelist>
27+
</filter>
28+
<coverage>
29+
<include>
30+
<directory suffix=".php">src</directory>
31+
</include>
32+
<report>
33+
<html outputDirectory="test-coverage-report/" />
34+
</report>
35+
</coverage>
36+
</phpunit>

psalm.xml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?xml version="1.0"?>
2+
<psalm
3+
errorLevel="2"
4+
resolveFromConfigFile="true"
5+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
6+
xmlns="https://getpsalm.org/schema/config"
7+
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
8+
>
9+
<projectFiles>
10+
<directory name="src" />
11+
<ignoreFiles>
12+
<directory name="vendor" />
13+
</ignoreFiles>
14+
15+
</projectFiles>
16+
17+
<issueHandlers>
18+
19+
<UnnecessaryVarAnnotation>
20+
<errorLevel type="suppress">
21+
<file name="src/HttpCorePlugin.php"/>
22+
</errorLevel>
23+
</UnnecessaryVarAnnotation>
24+
25+
<MissingConstructor>
26+
<errorLevel type="suppress">
27+
<file name="src/HttpCorePlugin.php"/>
28+
</errorLevel>
29+
</MissingConstructor>
30+
31+
<ImplementedReturnTypeMismatch>
32+
<errorLevel type="suppress">
33+
<file name="src/HttpCorePlugin.php"/>
34+
</errorLevel>
35+
</ImplementedReturnTypeMismatch>
36+
</issueHandlers>
37+
38+
</psalm>
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Micro framework package.
7+
*
8+
* (c) Stanislau Komar <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Micro\Plugin\Http\Business\Executor;
15+
16+
use Micro\Component\DependencyInjection\ContainerRegistryInterface;
17+
use Micro\Plugin\Http\Business\Matcher\UrlMatcherInterface;
18+
use Micro\Plugin\Http\Business\Response\Callback\ResponseCallbackFactoryInterface;
19+
use Micro\Plugin\Http\Business\Response\Transformer\ResponseTransformerFactoryInterface;
20+
use Micro\Plugin\Http\Exception\HttpException;
21+
use Micro\Plugin\Http\Exception\HttpInternalServerException;
22+
use Symfony\Component\HttpFoundation\Request;
23+
use Symfony\Component\HttpFoundation\Response;
24+
25+
/**
26+
* @author Stanislau Komar <[email protected]>
27+
*/
28+
readonly class RouteExecutor implements RouteExecutorInterface
29+
{
30+
public function __construct(
31+
private UrlMatcherInterface $urlMatcher,
32+
private ContainerRegistryInterface $containerRegistry,
33+
private ResponseCallbackFactoryInterface $responseCallbackFactory,
34+
private ResponseTransformerFactoryInterface $responseTransformerFactory
35+
) {
36+
}
37+
38+
/**
39+
* {@inheritDoc}
40+
*/
41+
public function execute(Request $request, bool $flush = true): Response
42+
{
43+
$route = $this->urlMatcher->match($request);
44+
$this->containerRegistry->register(Request::class, fn (): Request => $request);
45+
$callback = $this->responseCallbackFactory->create($route);
46+
47+
try {
48+
$response = $callback();
49+
$response = $this->generateResponse($request, $response);
50+
} catch (HttpException $exception) {
51+
throw $exception;
52+
} catch (\Throwable $exception) {
53+
$response = $this->generateResponse($request, $exception, false);
54+
}
55+
56+
if ($flush) {
57+
$response->send();
58+
}
59+
60+
return $response;
61+
}
62+
63+
protected function generateResponse(Request $request, mixed $responseData, bool $tryIfThrowNoHttpException = true): Response
64+
{
65+
if ($responseData instanceof Response) {
66+
return $responseData;
67+
}
68+
69+
$response = new Response();
70+
try {
71+
$transformed = $this->responseTransformerFactory
72+
->create()
73+
->transform(
74+
$request,
75+
$response,
76+
$responseData
77+
);
78+
} catch (HttpException $exception) {
79+
throw $exception;
80+
} catch (\Throwable $exception) {
81+
if ($tryIfThrowNoHttpException) {
82+
return $this->generateResponse($request, $exception, false);
83+
}
84+
85+
throw new HttpInternalServerException('Internal Server Error.', $exception);
86+
}
87+
88+
if (!$transformed) {
89+
throw new HttpInternalServerException();
90+
}
91+
92+
return $response;
93+
}
94+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
/*
6+
* This file is part of the Micro framework package.
7+
*
8+
* (c) Stanislau Komar <[email protected]>
9+
*
10+
* For the full copyright and license information, please view the LICENSE
11+
* file that was distributed with this source code.
12+
*/
13+
14+
namespace Micro\Plugin\Http\Business\Executor;
15+
16+
use Micro\Component\DependencyInjection\ContainerRegistryInterface;
17+
use Micro\Plugin\Http\Business\Matcher\UrlMatcherFactoryInterface;
18+
use Micro\Plugin\Http\Business\Response\Callback\ResponseCallbackFactoryInterface;
19+
use Micro\Plugin\Http\Business\Response\Transformer\ResponseTransformerFactoryInterface;
20+
21+
/**
22+
* @author Stanislau Komar <[email protected]>
23+
*/
24+
readonly class RouteExecutorFactory implements RouteExecutorFactoryInterface
25+
{
26+
public function __construct(
27+
private UrlMatcherFactoryInterface $urlMatcherFactory,
28+
private ContainerRegistryInterface $containerRegistry,
29+
private ResponseCallbackFactoryInterface $responseCallbackFactory,
30+
private ResponseTransformerFactoryInterface $responseTransformerFactory
31+
) {
32+
}
33+
34+
/**
35+
* {@inheritDoc}
36+
*/
37+
public function create(): RouteExecutorInterface
38+
{
39+
return new RouteExecutor(
40+
$this->urlMatcherFactory->create(),
41+
$this->containerRegistry,
42+
$this->responseCallbackFactory,
43+
$this->responseTransformerFactory
44+
);
45+
}
46+
}

0 commit comments

Comments
 (0)