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

feat: modernize library #33

Merged
merged 5 commits into from
Sep 9, 2024
Merged
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
42 changes: 29 additions & 13 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,28 @@ on:
workflow_dispatch:

jobs:
tests:
runs-on: ubuntu-20.04
cs-fix:
name: CS Fixer
runs-on: ubuntu-22.04

strategy:
fail-fast: true
matrix:
php-versions: ['7.3', '7.4']
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'

- name: Install dependencies
run: composer install

- name: Run CS Fixer
run: composer run-script cs

phpstan:
name: PHPStan
runs-on: ubuntu-22.04

steps:
- name: Checkout
Expand All @@ -25,16 +40,17 @@ jobs:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-versions }}
php-version: '8.1'

- name: Install dependencies
run: composer install --optimize-autoloader --prefer-dist
run: composer install

- name: Run tests
run: composer run-script test
- name: Run CS Fixer
run: composer run-script phpstan

tests-php8:
runs-on: ubuntu-20.04
tests:
name: PHPUnit on PHP ${{ matrix.php-versions }}
runs-on: ubuntu-22.04

strategy:
fail-fast: true
Expand All @@ -51,7 +67,7 @@ jobs:
php-version: ${{ matrix.php-versions }}

- name: Install dependencies
run: composer require -W phpunit/phpunit
run: composer install

- name: Run tests
run: composer run-script test
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea
vendor
composer.lock
.DS_Store
19 changes: 19 additions & 0 deletions .php-cs-fixer.dist.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

use PhpCsFixer\Config;
use PhpCsFixer\Finder;
use PhpCsFixer\Runner\Parallel\ParallelConfigFactory;

return (new Config())
->setParallelConfig(ParallelConfigFactory::detect())
->setRiskyAllowed(true)
->setUsingCache(false)
->setRules([
'@PER-CS2.0' => true,
])
->setFinder(
(new Finder())
->in([__DIR__ . '/src', __DIR__ . '/tests'])
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing newline at the end.

11 changes: 8 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,22 @@
}
],
"require": {
"php": ">=5.3.0"
"php": ">=8.1"
},
"require-dev": {
"phpunit/phpunit": "~4.8.36"
"phpunit/phpunit": "~10.0",
"phpstan/phpstan": "^1.12",
"friendsofphp/php-cs-fixer": "^3.63"
},
"autoload": {
"psr-4": {
"Rize\\": "src/Rize"
}
},
"scripts": {
"test": "vendor/bin/phpunit test/"
"test": "vendor/bin/phpunit",
"cs": "vendor/bin/php-cs-fixer fix --dry-run",
"cs-fix": "vendor/bin/php-cs-fixer fix",
"phpstan": "vendor/bin/phpstan"
}
}
5 changes: 5 additions & 0 deletions phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
parameters:
level: 5
paths:
- src
- tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here.

22 changes: 22 additions & 0 deletions phpunit.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.5/phpunit.xsd"
bootstrap="vendor/autoload.php"
executionOrder="depends,defects"
requireCoverageMetadata="false"
beStrictAboutCoverageMetadata="false"
beStrictAboutOutputDuringTests="true"
failOnRisky="true"
failOnWarning="true">
<testsuites>
<testsuite name="default">
<directory>tests</directory>
</testsuite>
</testsuites>

<source restrictDeprecations="true" restrictNotices="true" restrictWarnings="true">
<include>
<directory>src</directory>
</include>
</source>
</phpunit>
69 changes: 30 additions & 39 deletions src/Rize/UriTemplate.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,103 +5,94 @@
use Rize\UriTemplate\Parser;

/**
* URI Template
* URI Template.
*/
class UriTemplate
{
/**
* @var Parser
*/
protected $parser,
$parsed = array(),
$base_uri,
$params = array();

public function __construct($base_uri = '', $params = array(), Parser $parser = null)
protected Parser $parser;
protected array $parsed = [];

public function __construct(protected string $base_uri = '', protected array $params = [], ?Parser $parser = null)
{
$this->base_uri = $base_uri;
$this->params = $params;
$this->parser = $parser ?: $this->createNodeParser();
$this->parser = $parser ?: $this->createNodeParser();
}

/**
* Expands URI Template
* Expands URI Template.
*
* @param string $uri URI Template
* @param array $params URI Template's parameters
* @return string
* @param mixed $params
*/
public function expand($uri, $params = array())
public function expand(string $uri, $params = []): string
{
$params += $this->params;
$uri = $this->base_uri.$uri;
$result = array();
$uri = $this->base_uri . $uri;
$result = [];

// quick check
if (($start = strpos($uri, '{')) === false) {
if (!str_contains($uri, '{')) {
return $uri;
}

$parser = $this->parser;
$nodes = $parser->parse($uri);

foreach($nodes as $node) {
foreach ($nodes as $node) {
$result[] = $node->expand($parser, $params);
}

return implode('', $result);
}

/**
* Extracts variables from URI
* Extracts variables from URI.
*
* @param string $template
* @param string $uri
* @param bool $strict This will perform a full match
* @return null|array params or null if not match and $strict is true
*/
public function extract($template, $uri, $strict = false)
public function extract(string $template, string $uri, bool $strict = false): ?array
{
$params = array();
$params = [];
$nodes = $this->parser->parse($template);

# PHP 8.1.0RC4-dev still throws deprecation warning for `strlen`.
# $uri = (string) $uri;

foreach($nodes as $node) {
// PHP 8.1.0RC4-dev still throws deprecation warning for `strlen`.
// $uri = (string) $uri;

foreach ($nodes as $node) {
// if strict is given, and there's no remaining uri just return null
if ($strict && !strlen((string) $uri)) {
if ($strict && (string) $uri === '') {
return null;
}

// uri'll be truncated from the start when a match is found
// URI will be truncated from the start when a match is found
$match = $node->match($this->parser, $uri, $params, $strict);

list($uri, $params) = $match;
if ($match === null) {
return null;
}

[$uri, $params] = $match;
}

// if there's remaining $uri, matching is failed
if ($strict && strlen((string) $uri)) {
if ($strict && (string) $uri !== '') {
return null;
}

return $params;
}

public function getParser()
public function getParser(): Parser
{
return $this->parser;
}

protected function createNodeParser()
protected function createNodeParser(): Parser
{
static $parser;

if ($parser) {
return $parser;
}

return $parser = new Parser;
return $parser = new Parser();
}
}
44 changes: 14 additions & 30 deletions src/Rize/UriTemplate/Node/Abstraction.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,61 +5,45 @@
use Rize\UriTemplate\Parser;

/**
* Base class for all Nodes
* Base class for all Nodes.
*/
abstract class Abstraction
{
/**
* @var string
*/
private $token;

public function __construct($token)
{
$this->token = $token;
}
public function __construct(private readonly string $token) {}

/**
* Expands URI template
*
* @param Parser $parser
* @param array $params
* @return null|string
* @param array<string, mixed> $params
*/
public function expand(Parser $parser, array $params = array())
public function expand(Parser $parser, array $params = []): ?string
{
return $this->token;
}

/**
* Matches given URI against current node
* Matches given URI against current node.
*
* @param array<string, mixed> $params
*
* @param Parser $parser
* @param string $uri
* @param array $params
* @param bool $strict
* @return null|array `uri and params` or `null` if not match and $strict is true
* @return null|array{0: string, 1: array<string, mixed>} `uri and params` or `null` if not match and $strict is true
*/
public function match(Parser $parser, $uri, $params = array(), $strict = false)
public function match(Parser $parser, string $uri, array $params = [], bool $strict = false): ?array
{
// match literal string from start to end
$length = strlen($this->token);
if (substr($uri, 0, $length) === $this->token) {
$uri = substr($uri, $length);
if (str_starts_with($uri, $this->token)) {
$uri = substr($uri, strlen($this->token));
}

// when there's no match, just return null if strict mode is given
else if ($strict) {
elseif ($strict) {
return null;
}

return array($uri, $params);
return [$uri, $params];
}

/**
* @return string
*/
public function getToken()
public function getToken(): string
{
return $this->token;
}
Expand Down
Loading