merge
This commit is contained in:
commit
2c199f1ce1
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
|||||||
.idea
|
.idea
|
||||||
|
vendor
|
@ -3,17 +3,19 @@
|
|||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
|
|
||||||
|
use app\helpers\Debug;
|
||||||
use app\models\Post;
|
use app\models\Post;
|
||||||
|
|
||||||
class Posts
|
class PostController
|
||||||
{
|
{
|
||||||
public function actionCreatePost($post, $user_id)
|
public function actionCreatePost($post, $user_id)
|
||||||
{
|
{
|
||||||
return Post::create(['post'=>$post, 'user_id'=>$user_id]);
|
return Post::create(['post'=>$post, 'user_id'=>$user_id]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionViewAllPosts()
|
public function actionIndex(): void
|
||||||
{
|
{
|
||||||
|
Debug::dd("Post list");
|
||||||
foreach (Post::all() as $post)
|
foreach (Post::all() as $post)
|
||||||
{
|
{
|
||||||
echo $post->post . "<br>";
|
echo $post->post . "<br>";
|
@ -2,15 +2,18 @@
|
|||||||
namespace app\controllers;
|
namespace app\controllers;
|
||||||
|
|
||||||
|
|
||||||
|
use app\helpers\Debug;
|
||||||
use app\models\Question;
|
use app\models\Question;
|
||||||
use app\models\User;
|
use app\models\User;
|
||||||
|
use http\Encoding\Stream\Debrotli;
|
||||||
use Illuminate\Contracts\View\View;
|
use Illuminate\Contracts\View\View;
|
||||||
use Illuminate\Support\Facades\DB;
|
use Illuminate\Support\Facades\DB;
|
||||||
|
|
||||||
class Users {
|
class UserController {
|
||||||
public function actionCreateUser($username, $email, $password)
|
public function actionCreate(): void
|
||||||
{
|
{
|
||||||
return User::create(['username'=>$username,'email'=>$email,'password'=>$password]);
|
Debug::dd("create");
|
||||||
|
//return User::create(['username'=>$username,'email'=>$email,'password'=>$password]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionQuestionCount($user_id)
|
public function actionQuestionCount($user_id)
|
||||||
@ -18,17 +21,19 @@ class Users {
|
|||||||
return Question::where('user_id', $user_id)->count();
|
return Question::where('user_id', $user_id)->count();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionViewAllUsers(): void
|
public function actionIndex(): void
|
||||||
{
|
{
|
||||||
|
Debug::dd("list");
|
||||||
foreach (User::all() as $user)
|
foreach (User::all() as $user)
|
||||||
{
|
{
|
||||||
echo $user->username . "<br>";
|
echo $user->username . "<br>";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function actionViewUser(): void
|
public function actionView($id): void
|
||||||
{
|
{
|
||||||
echo User::where('id', '=', 13)->get();
|
Debug::dd($id);
|
||||||
|
echo User::where('id', '=', $id)->get();
|
||||||
// $user = User::where('id', '=', 13)->get();
|
// $user = User::where('id', '=', 13)->get();
|
||||||
|
|
||||||
// echo $user->username . "<br>";
|
// echo $user->username . "<br>";
|
20
app/helpers/Debug.php
Normal file
20
app/helpers/Debug.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\helpers;
|
||||||
|
|
||||||
|
class Debug
|
||||||
|
{
|
||||||
|
public static function prn($content)
|
||||||
|
{
|
||||||
|
echo '<pre style="background: lightgray; border: 1px solid black; padding: 2px">';
|
||||||
|
print_r($content);
|
||||||
|
echo '</pre>';
|
||||||
|
}
|
||||||
|
public static function dd($content)
|
||||||
|
{
|
||||||
|
echo '<pre style="background: lightgray; border: 1px solid black; padding: 2px">';
|
||||||
|
print_r($content);
|
||||||
|
echo '</pre>';
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@
|
|||||||
"description": "Implementation of Database Queries with illuminate and Eloquent",
|
"description": "Implementation of Database Queries with illuminate and Eloquent",
|
||||||
"type": "project",
|
"type": "project",
|
||||||
"require": {
|
"require": {
|
||||||
"illuminate/database": "^7.30",
|
"illuminate/database": "^11.14",
|
||||||
"craft-group/phroute": "^2.1"
|
"craft-group/phroute": "^2.1"
|
||||||
},
|
},
|
||||||
"autoload": {
|
"autoload": {
|
||||||
|
1119
composer.lock
generated
1119
composer.lock
generated
File diff suppressed because it is too large
Load Diff
22
index.php
22
index.php
@ -1,4 +1,8 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
error_reporting(-1);
|
||||||
|
ini_set("display_errors", true);
|
||||||
|
|
||||||
require_once "vendor/autoload.php";
|
require_once "vendor/autoload.php";
|
||||||
require 'bootstrap.php';
|
require 'bootstrap.php';
|
||||||
|
|
||||||
@ -14,11 +18,21 @@ $router = new RouteCollector();
|
|||||||
|
|
||||||
$router->get('/', [MainController::class, 'actionIndex']);
|
$router->get('/', [MainController::class, 'actionIndex']);
|
||||||
$router->get('/example', [MainController::class, 'actionExample']);
|
$router->get('/example', [MainController::class, 'actionExample']);
|
||||||
//$router->get('/createUser', [Users::class, 'actionCreateUser']);
|
$router->group(["prefix" => "admin"], function (RouteCollector $router){
|
||||||
$router->get('/allUsers', [Users::class, 'actionViewAllUsers']);
|
$router->group(["prefix" => "user"], function (RouteCollector $router){
|
||||||
$router->get('/User', [Users::class, 'actionViewUser']);
|
$router->get('/create', [\app\controllers\UserController::class, 'actionCreate']);
|
||||||
|
$router->get('/update', [\app\controllers\UserController::class, 'actionCreate']);
|
||||||
|
$router->get('/', [\app\controllers\UserController::class, 'actionIndex']);
|
||||||
|
$router->get('/{id}', [\app\controllers\UserController::class, 'actionView']);
|
||||||
|
$router->post("/", []);
|
||||||
|
});
|
||||||
|
$router->group(["prefix" => "post"], function (RouteCollector $router){
|
||||||
|
$router->get('/', [\app\controllers\PostController::class, 'actionIndex']);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
$router->get('/allQuestions', [Questions::class, 'actionViewAllQuestions']);
|
$router->get('/allQuestions', [Questions::class, 'actionViewAllQuestions']);
|
||||||
$router->get('/allPosts', [Posts::class, 'actionViewAllPosts']);
|
|
||||||
$router->get('/allAnswers', [Answers::class, 'actionViewAllAnswers']);
|
$router->get('/allAnswers', [Answers::class, 'actionViewAllAnswers']);
|
||||||
|
|
||||||
|
|
||||||
|
25
vendor/autoload.php
vendored
25
vendor/autoload.php
vendored
@ -1,25 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload.php @generated by Composer
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 50600) {
|
|
||||||
if (!headers_sent()) {
|
|
||||||
header('HTTP/1.1 500 Internal Server Error');
|
|
||||||
}
|
|
||||||
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
|
|
||||||
if (!ini_get('display_errors')) {
|
|
||||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
|
||||||
fwrite(STDERR, $err);
|
|
||||||
} elseif (!headers_sent()) {
|
|
||||||
echo $err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trigger_error(
|
|
||||||
$err,
|
|
||||||
E_USER_ERROR
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
|
||||||
|
|
||||||
return ComposerAutoloaderInitfe2a84e2cd498dd89c8e792659f7a55c::getLoader();
|
|
119
vendor/bin/carbon
vendored
119
vendor/bin/carbon
vendored
@ -1,119 +0,0 @@
|
|||||||
#!/usr/bin/env php
|
|
||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy PHP file generated by Composer
|
|
||||||
*
|
|
||||||
* This file includes the referenced bin path (../nesbot/carbon/bin/carbon)
|
|
||||||
* using a stream wrapper to prevent the shebang from being output on PHP<8
|
|
||||||
*
|
|
||||||
* @generated
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
$GLOBALS['_composer_bin_dir'] = __DIR__;
|
|
||||||
$GLOBALS['_composer_autoload_path'] = __DIR__ . '/..'.'/autoload.php';
|
|
||||||
|
|
||||||
if (PHP_VERSION_ID < 80000) {
|
|
||||||
if (!class_exists('Composer\BinProxyWrapper')) {
|
|
||||||
/**
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
final class BinProxyWrapper
|
|
||||||
{
|
|
||||||
private $handle;
|
|
||||||
private $position;
|
|
||||||
private $realpath;
|
|
||||||
|
|
||||||
public function stream_open($path, $mode, $options, &$opened_path)
|
|
||||||
{
|
|
||||||
// get rid of phpvfscomposer:// prefix for __FILE__ & __DIR__ resolution
|
|
||||||
$opened_path = substr($path, 17);
|
|
||||||
$this->realpath = realpath($opened_path) ?: $opened_path;
|
|
||||||
$opened_path = $this->realpath;
|
|
||||||
$this->handle = fopen($this->realpath, $mode);
|
|
||||||
$this->position = 0;
|
|
||||||
|
|
||||||
return (bool) $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_read($count)
|
|
||||||
{
|
|
||||||
$data = fread($this->handle, $count);
|
|
||||||
|
|
||||||
if ($this->position === 0) {
|
|
||||||
$data = preg_replace('{^#!.*\r?\n}', '', $data);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->position += strlen($data);
|
|
||||||
|
|
||||||
return $data;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_cast($castAs)
|
|
||||||
{
|
|
||||||
return $this->handle;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_close()
|
|
||||||
{
|
|
||||||
fclose($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_lock($operation)
|
|
||||||
{
|
|
||||||
return $operation ? flock($this->handle, $operation) : true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_seek($offset, $whence)
|
|
||||||
{
|
|
||||||
if (0 === fseek($this->handle, $offset, $whence)) {
|
|
||||||
$this->position = ftell($this->handle);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_tell()
|
|
||||||
{
|
|
||||||
return $this->position;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_eof()
|
|
||||||
{
|
|
||||||
return feof($this->handle);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_stat()
|
|
||||||
{
|
|
||||||
return array();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function stream_set_option($option, $arg1, $arg2)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function url_stat($path, $flags)
|
|
||||||
{
|
|
||||||
$path = substr($path, 17);
|
|
||||||
if (file_exists($path)) {
|
|
||||||
return stat($path);
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), true))
|
|
||||||
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
|
|
||||||
) {
|
|
||||||
return include("phpvfscomposer://" . __DIR__ . '/..'.'/nesbot/carbon/bin/carbon');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return include __DIR__ . '/..'.'/nesbot/carbon/bin/carbon';
|
|
21
vendor/carbonphp/carbon-doctrine-types/LICENSE
vendored
21
vendor/carbonphp/carbon-doctrine-types/LICENSE
vendored
@ -1,21 +0,0 @@
|
|||||||
MIT License
|
|
||||||
|
|
||||||
Copyright (c) 2023 Carbon
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
14
vendor/carbonphp/carbon-doctrine-types/README.md
vendored
14
vendor/carbonphp/carbon-doctrine-types/README.md
vendored
@ -1,14 +0,0 @@
|
|||||||
# carbonphp/carbon-doctrine-types
|
|
||||||
|
|
||||||
Types to use Carbon in Doctrine
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
[Check how to use in the official Carbon documentation](https://carbon.nesbot.com/symfony/)
|
|
||||||
|
|
||||||
This package is an externalization of [src/Carbon/Doctrine](https://github.com/briannesbitt/Carbon/tree/2.71.0/src/Carbon/Doctrine)
|
|
||||||
from `nestbot/carbon` package.
|
|
||||||
|
|
||||||
Externalization allows to better deal with different versions of dbal. With
|
|
||||||
version 4.0 of dbal, it no longer sustainable to be compatible with all version
|
|
||||||
using a single code.
|
|
@ -1,36 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "carbonphp/carbon-doctrine-types",
|
|
||||||
"description": "Types to use Carbon in Doctrine",
|
|
||||||
"type": "library",
|
|
||||||
"keywords": [
|
|
||||||
"date",
|
|
||||||
"time",
|
|
||||||
"DateTime",
|
|
||||||
"Carbon",
|
|
||||||
"Doctrine"
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": "^8.1"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/dbal": "^4.0.0",
|
|
||||||
"nesbot/carbon": "^2.71.0 || ^3.0.0",
|
|
||||||
"phpunit/phpunit": "^10.3"
|
|
||||||
},
|
|
||||||
"conflict": {
|
|
||||||
"doctrine/dbal": "<4.0.0 || >=5.0.0"
|
|
||||||
},
|
|
||||||
"license": "MIT",
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Carbon\\Doctrine\\": "src/Carbon/Doctrine/"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "KyleKatarn",
|
|
||||||
"email": "kylekatarnls@gmail.com"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"minimum-stability": "dev"
|
|
||||||
}
|
|
@ -1,16 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
||||||
|
|
||||||
interface CarbonDoctrineType
|
|
||||||
{
|
|
||||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform);
|
|
||||||
|
|
||||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform);
|
|
||||||
|
|
||||||
public function convertToDatabaseValue($value, AbstractPlatform $platform);
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
class CarbonImmutableType extends DateTimeImmutableType implements CarbonDoctrineType
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
class CarbonType extends DateTimeType implements CarbonDoctrineType
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,131 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use Carbon\CarbonInterface;
|
|
||||||
use DateTimeInterface;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
||||||
use Doctrine\DBAL\Platforms\DB2Platform;
|
|
||||||
use Doctrine\DBAL\Platforms\OraclePlatform;
|
|
||||||
use Doctrine\DBAL\Platforms\SQLitePlatform;
|
|
||||||
use Doctrine\DBAL\Platforms\SQLServerPlatform;
|
|
||||||
use Doctrine\DBAL\Types\Exception\InvalidType;
|
|
||||||
use Doctrine\DBAL\Types\Exception\ValueNotConvertible;
|
|
||||||
use Exception;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @template T of CarbonInterface
|
|
||||||
*/
|
|
||||||
trait CarbonTypeConverter
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* This property differentiates types installed by carbonphp/carbon-doctrine-types
|
|
||||||
* from the ones embedded previously in nesbot/carbon source directly.
|
|
||||||
*
|
|
||||||
* @readonly
|
|
||||||
*/
|
|
||||||
public bool $external = true;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return class-string<T>
|
|
||||||
*/
|
|
||||||
protected function getCarbonClassName(): string
|
|
||||||
{
|
|
||||||
return Carbon::class;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string
|
|
||||||
{
|
|
||||||
$precision = min(
|
|
||||||
$fieldDeclaration['precision'] ?? DateTimeDefaultPrecision::get(),
|
|
||||||
$this->getMaximumPrecision($platform),
|
|
||||||
);
|
|
||||||
|
|
||||||
$type = parent::getSQLDeclaration($fieldDeclaration, $platform);
|
|
||||||
|
|
||||||
if (!$precision) {
|
|
||||||
return $type;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (str_contains($type, '(')) {
|
|
||||||
return preg_replace('/\(\d+\)/', "($precision)", $type);
|
|
||||||
}
|
|
||||||
|
|
||||||
[$before, $after] = explode(' ', "$type ");
|
|
||||||
|
|
||||||
return trim("$before($precision) $after");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
|
||||||
*/
|
|
||||||
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
|
|
||||||
{
|
|
||||||
if ($value === null) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($value instanceof DateTimeInterface) {
|
|
||||||
return $value->format('Y-m-d H:i:s.u');
|
|
||||||
}
|
|
||||||
|
|
||||||
throw InvalidType::new(
|
|
||||||
$value,
|
|
||||||
static::class,
|
|
||||||
['null', 'DateTime', 'Carbon']
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
private function doConvertToPHPValue(mixed $value)
|
|
||||||
{
|
|
||||||
$class = $this->getCarbonClassName();
|
|
||||||
|
|
||||||
if ($value === null || is_a($value, $class)) {
|
|
||||||
return $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($value instanceof DateTimeInterface) {
|
|
||||||
return $class::instance($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
$date = null;
|
|
||||||
$error = null;
|
|
||||||
|
|
||||||
try {
|
|
||||||
$date = $class::parse($value);
|
|
||||||
} catch (Exception $exception) {
|
|
||||||
$error = $exception;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$date) {
|
|
||||||
throw ValueNotConvertible::new(
|
|
||||||
$value,
|
|
||||||
static::class,
|
|
||||||
'Y-m-d H:i:s.u or any format supported by '.$class.'::parse()',
|
|
||||||
$error
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $date;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function getMaximumPrecision(AbstractPlatform $platform): int
|
|
||||||
{
|
|
||||||
if ($platform instanceof DB2Platform) {
|
|
||||||
return 12;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($platform instanceof OraclePlatform) {
|
|
||||||
return 9;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($platform instanceof SQLServerPlatform || $platform instanceof SQLitePlatform) {
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
class DateTimeDefaultPrecision
|
|
||||||
{
|
|
||||||
private static $precision = 6;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the default Doctrine datetime and datetime_immutable precision.
|
|
||||||
*
|
|
||||||
* @param int $precision
|
|
||||||
*/
|
|
||||||
public static function set(int $precision): void
|
|
||||||
{
|
|
||||||
self::$precision = $precision;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the default Doctrine datetime and datetime_immutable precision.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public static function get(): int
|
|
||||||
{
|
|
||||||
return self::$precision;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
use Carbon\CarbonImmutable;
|
|
||||||
use DateTimeImmutable;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
||||||
use Doctrine\DBAL\Types\VarDateTimeImmutableType;
|
|
||||||
|
|
||||||
class DateTimeImmutableType extends VarDateTimeImmutableType implements CarbonDoctrineType
|
|
||||||
{
|
|
||||||
/** @use CarbonTypeConverter<CarbonImmutable> */
|
|
||||||
use CarbonTypeConverter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
|
||||||
*/
|
|
||||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?CarbonImmutable
|
|
||||||
{
|
|
||||||
return $this->doConvertToPHPValue($value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return class-string<CarbonImmutable>
|
|
||||||
*/
|
|
||||||
protected function getCarbonClassName(): string
|
|
||||||
{
|
|
||||||
return CarbonImmutable::class;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Carbon\Doctrine;
|
|
||||||
|
|
||||||
use Carbon\Carbon;
|
|
||||||
use DateTime;
|
|
||||||
use Doctrine\DBAL\Platforms\AbstractPlatform;
|
|
||||||
use Doctrine\DBAL\Types\VarDateTimeType;
|
|
||||||
|
|
||||||
class DateTimeType extends VarDateTimeType implements CarbonDoctrineType
|
|
||||||
{
|
|
||||||
/** @use CarbonTypeConverter<Carbon> */
|
|
||||||
use CarbonTypeConverter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
|
|
||||||
*/
|
|
||||||
public function convertToPHPValue(mixed $value, AbstractPlatform $platform): ?Carbon
|
|
||||||
{
|
|
||||||
return $this->doConvertToPHPValue($value);
|
|
||||||
}
|
|
||||||
}
|
|
359
vendor/composer/InstalledVersions.php
vendored
359
vendor/composer/InstalledVersions.php
vendored
@ -1,359 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This file is part of Composer.
|
|
||||||
*
|
|
||||||
* (c) Nils Adermann <naderman@naderman.de>
|
|
||||||
* Jordi Boggiano <j.boggiano@seld.be>
|
|
||||||
*
|
|
||||||
* For the full copyright and license information, please view the LICENSE
|
|
||||||
* file that was distributed with this source code.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Composer;
|
|
||||||
|
|
||||||
use Composer\Autoload\ClassLoader;
|
|
||||||
use Composer\Semver\VersionParser;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This class is copied in every Composer installed project and available to all
|
|
||||||
*
|
|
||||||
* See also https://getcomposer.org/doc/07-runtime.md#installed-versions
|
|
||||||
*
|
|
||||||
* To require its presence, you can require `composer-runtime-api ^2.0`
|
|
||||||
*
|
|
||||||
* @final
|
|
||||||
*/
|
|
||||||
class InstalledVersions
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* @var mixed[]|null
|
|
||||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
|
||||||
*/
|
|
||||||
private static $installed;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var bool|null
|
|
||||||
*/
|
|
||||||
private static $canGetVendors;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array[]
|
|
||||||
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
|
||||||
*/
|
|
||||||
private static $installedByVendor = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of all package names which are present, either by being installed, replaced or provided
|
|
||||||
*
|
|
||||||
* @return string[]
|
|
||||||
* @psalm-return list<string>
|
|
||||||
*/
|
|
||||||
public static function getInstalledPackages()
|
|
||||||
{
|
|
||||||
$packages = array();
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
$packages[] = array_keys($installed['versions']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (1 === \count($packages)) {
|
|
||||||
return $packages[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_keys(array_flip(\call_user_func_array('array_merge', $packages)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a list of all package names with a specific type e.g. 'library'
|
|
||||||
*
|
|
||||||
* @param string $type
|
|
||||||
* @return string[]
|
|
||||||
* @psalm-return list<string>
|
|
||||||
*/
|
|
||||||
public static function getInstalledPackagesByType($type)
|
|
||||||
{
|
|
||||||
$packagesByType = array();
|
|
||||||
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
foreach ($installed['versions'] as $name => $package) {
|
|
||||||
if (isset($package['type']) && $package['type'] === $type) {
|
|
||||||
$packagesByType[] = $name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $packagesByType;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given package is installed
|
|
||||||
*
|
|
||||||
* This also returns true if the package name is provided or replaced by another package
|
|
||||||
*
|
|
||||||
* @param string $packageName
|
|
||||||
* @param bool $includeDevRequirements
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function isInstalled($packageName, $includeDevRequirements = true)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (isset($installed['versions'][$packageName])) {
|
|
||||||
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the given package satisfies a version constraint
|
|
||||||
*
|
|
||||||
* e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call:
|
|
||||||
*
|
|
||||||
* Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3')
|
|
||||||
*
|
|
||||||
* @param VersionParser $parser Install composer/semver to have access to this class and functionality
|
|
||||||
* @param string $packageName
|
|
||||||
* @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public static function satisfies(VersionParser $parser, $packageName, $constraint)
|
|
||||||
{
|
|
||||||
$constraint = $parser->parseConstraints((string) $constraint);
|
|
||||||
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
|
|
||||||
|
|
||||||
return $provided->matches($constraint);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a version constraint representing all the range(s) which are installed for a given package
|
|
||||||
*
|
|
||||||
* It is easier to use this via isInstalled() with the $constraint argument if you need to check
|
|
||||||
* whether a given version of a package is installed, and not just whether it exists
|
|
||||||
*
|
|
||||||
* @param string $packageName
|
|
||||||
* @return string Version constraint usable with composer/semver
|
|
||||||
*/
|
|
||||||
public static function getVersionRanges($packageName)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (!isset($installed['versions'][$packageName])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$ranges = array();
|
|
||||||
if (isset($installed['versions'][$packageName]['pretty_version'])) {
|
|
||||||
$ranges[] = $installed['versions'][$packageName]['pretty_version'];
|
|
||||||
}
|
|
||||||
if (array_key_exists('aliases', $installed['versions'][$packageName])) {
|
|
||||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']);
|
|
||||||
}
|
|
||||||
if (array_key_exists('replaced', $installed['versions'][$packageName])) {
|
|
||||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']);
|
|
||||||
}
|
|
||||||
if (array_key_exists('provided', $installed['versions'][$packageName])) {
|
|
||||||
$ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']);
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode(' || ', $ranges);
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $packageName
|
|
||||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
|
||||||
*/
|
|
||||||
public static function getVersion($packageName)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (!isset($installed['versions'][$packageName])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($installed['versions'][$packageName]['version'])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $installed['versions'][$packageName]['version'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $packageName
|
|
||||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present
|
|
||||||
*/
|
|
||||||
public static function getPrettyVersion($packageName)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (!isset($installed['versions'][$packageName])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($installed['versions'][$packageName]['pretty_version'])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $installed['versions'][$packageName]['pretty_version'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $packageName
|
|
||||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference
|
|
||||||
*/
|
|
||||||
public static function getReference($packageName)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (!isset($installed['versions'][$packageName])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($installed['versions'][$packageName]['reference'])) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $installed['versions'][$packageName]['reference'];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $packageName
|
|
||||||
* @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path.
|
|
||||||
*/
|
|
||||||
public static function getInstallPath($packageName)
|
|
||||||
{
|
|
||||||
foreach (self::getInstalled() as $installed) {
|
|
||||||
if (!isset($installed['versions'][$packageName])) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null;
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
|
|
||||||
*/
|
|
||||||
public static function getRootPackage()
|
|
||||||
{
|
|
||||||
$installed = self::getInstalled();
|
|
||||||
|
|
||||||
return $installed[0]['root'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the raw installed.php data for custom implementations
|
|
||||||
*
|
|
||||||
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
|
|
||||||
* @return array[]
|
|
||||||
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
|
|
||||||
*/
|
|
||||||
public static function getRawData()
|
|
||||||
{
|
|
||||||
@trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED);
|
|
||||||
|
|
||||||
if (null === self::$installed) {
|
|
||||||
// only require the installed.php file if this file is loaded from its dumped location,
|
|
||||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
|
||||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
|
||||||
self::$installed = include __DIR__ . '/installed.php';
|
|
||||||
} else {
|
|
||||||
self::$installed = array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$installed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the raw data of all installed.php which are currently loaded for custom implementations
|
|
||||||
*
|
|
||||||
* @return array[]
|
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
|
||||||
*/
|
|
||||||
public static function getAllRawData()
|
|
||||||
{
|
|
||||||
return self::getInstalled();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Lets you reload the static array from another file
|
|
||||||
*
|
|
||||||
* This is only useful for complex integrations in which a project needs to use
|
|
||||||
* this class but then also needs to execute another project's autoloader in process,
|
|
||||||
* and wants to ensure both projects have access to their version of installed.php.
|
|
||||||
*
|
|
||||||
* A typical case would be PHPUnit, where it would need to make sure it reads all
|
|
||||||
* the data it needs from this class, then call reload() with
|
|
||||||
* `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure
|
|
||||||
* the project in which it runs can then also use this class safely, without
|
|
||||||
* interference between PHPUnit's dependencies and the project's dependencies.
|
|
||||||
*
|
|
||||||
* @param array[] $data A vendor/composer/installed.php data set
|
|
||||||
* @return void
|
|
||||||
*
|
|
||||||
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
|
|
||||||
*/
|
|
||||||
public static function reload($data)
|
|
||||||
{
|
|
||||||
self::$installed = $data;
|
|
||||||
self::$installedByVendor = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array[]
|
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
|
||||||
*/
|
|
||||||
private static function getInstalled()
|
|
||||||
{
|
|
||||||
if (null === self::$canGetVendors) {
|
|
||||||
self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders');
|
|
||||||
}
|
|
||||||
|
|
||||||
$installed = array();
|
|
||||||
|
|
||||||
if (self::$canGetVendors) {
|
|
||||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
|
||||||
if (isset(self::$installedByVendor[$vendorDir])) {
|
|
||||||
$installed[] = self::$installedByVendor[$vendorDir];
|
|
||||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
|
||||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
|
||||||
$required = require $vendorDir.'/composer/installed.php';
|
|
||||||
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
|
||||||
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
|
||||||
self::$installed = $installed[count($installed) - 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (null === self::$installed) {
|
|
||||||
// only require the installed.php file if this file is loaded from its dumped location,
|
|
||||||
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
|
|
||||||
if (substr(__DIR__, -8, 1) !== 'C') {
|
|
||||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
|
||||||
$required = require __DIR__ . '/installed.php';
|
|
||||||
self::$installed = $required;
|
|
||||||
} else {
|
|
||||||
self::$installed = array();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (self::$installed !== array()) {
|
|
||||||
$installed[] = self::$installed;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $installed;
|
|
||||||
}
|
|
||||||
}
|
|
21
vendor/composer/LICENSE
vendored
21
vendor/composer/LICENSE
vendored
@ -1,21 +0,0 @@
|
|||||||
|
|
||||||
Copyright (c) Nils Adermann, Jordi Boggiano
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is furnished
|
|
||||||
to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
19
vendor/composer/autoload_files.php
vendored
19
vendor/composer/autoload_files.php
vendored
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_files.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
|
||||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
|
||||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
|
||||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
|
||||||
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
|
||||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
|
||||||
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
|
|
||||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
|
|
||||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
|
||||||
'72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
|
|
||||||
);
|
|
9
vendor/composer/autoload_namespaces.php
vendored
9
vendor/composer/autoload_namespaces.php
vendored
@ -1,9 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_namespaces.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
);
|
|
33
vendor/composer/autoload_psr4.php
vendored
33
vendor/composer/autoload_psr4.php
vendored
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_psr4.php @generated by Composer
|
|
||||||
|
|
||||||
$vendorDir = dirname(__DIR__);
|
|
||||||
$baseDir = dirname($vendorDir);
|
|
||||||
|
|
||||||
return array(
|
|
||||||
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
|
|
||||||
'app\\' => array($baseDir . '/app'),
|
|
||||||
'Symfony\\Polyfill\\Php80\\' => array($vendorDir . '/symfony/polyfill-php80'),
|
|
||||||
'Symfony\\Polyfill\\Php73\\' => array($vendorDir . '/symfony/polyfill-php73'),
|
|
||||||
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
|
|
||||||
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
|
|
||||||
'Symfony\\Polyfill\\Intl\\Grapheme\\' => array($vendorDir . '/symfony/polyfill-intl-grapheme'),
|
|
||||||
'Symfony\\Polyfill\\Ctype\\' => array($vendorDir . '/symfony/polyfill-ctype'),
|
|
||||||
'Symfony\\Contracts\\Translation\\' => array($vendorDir . '/symfony/translation-contracts'),
|
|
||||||
'Symfony\\Contracts\\Service\\' => array($vendorDir . '/symfony/service-contracts'),
|
|
||||||
'Symfony\\Component\\Translation\\' => array($vendorDir . '/symfony/translation'),
|
|
||||||
'Symfony\\Component\\String\\' => array($vendorDir . '/symfony/string'),
|
|
||||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
|
||||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
|
||||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
|
||||||
'Psr\\Clock\\' => array($vendorDir . '/psr/clock/src'),
|
|
||||||
'Phroute\\Phroute\\' => array($vendorDir . '/craft-group/phroute/src/Phroute'),
|
|
||||||
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/support'),
|
|
||||||
'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'),
|
|
||||||
'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
|
|
||||||
'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
|
|
||||||
'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
|
|
||||||
'Carbon\\Doctrine\\' => array($vendorDir . '/carbonphp/carbon-doctrine-types/src/Carbon/Doctrine'),
|
|
||||||
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
|
|
||||||
);
|
|
50
vendor/composer/autoload_real.php
vendored
50
vendor/composer/autoload_real.php
vendored
@ -1,50 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// autoload_real.php @generated by Composer
|
|
||||||
|
|
||||||
class ComposerAutoloaderInitfe2a84e2cd498dd89c8e792659f7a55c
|
|
||||||
{
|
|
||||||
private static $loader;
|
|
||||||
|
|
||||||
public static function loadClassLoader($class)
|
|
||||||
{
|
|
||||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
|
||||||
require __DIR__ . '/ClassLoader.php';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return \Composer\Autoload\ClassLoader
|
|
||||||
*/
|
|
||||||
public static function getLoader()
|
|
||||||
{
|
|
||||||
if (null !== self::$loader) {
|
|
||||||
return self::$loader;
|
|
||||||
}
|
|
||||||
|
|
||||||
require __DIR__ . '/platform_check.php';
|
|
||||||
|
|
||||||
spl_autoload_register(array('ComposerAutoloaderInitfe2a84e2cd498dd89c8e792659f7a55c', 'loadClassLoader'), true, true);
|
|
||||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader(\dirname(__DIR__));
|
|
||||||
spl_autoload_unregister(array('ComposerAutoloaderInitfe2a84e2cd498dd89c8e792659f7a55c', 'loadClassLoader'));
|
|
||||||
|
|
||||||
require __DIR__ . '/autoload_static.php';
|
|
||||||
call_user_func(\Composer\Autoload\ComposerStaticInitfe2a84e2cd498dd89c8e792659f7a55c::getInitializer($loader));
|
|
||||||
|
|
||||||
$loader->register(true);
|
|
||||||
|
|
||||||
$filesToLoad = \Composer\Autoload\ComposerStaticInitfe2a84e2cd498dd89c8e792659f7a55c::$files;
|
|
||||||
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
|
|
||||||
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
|
|
||||||
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
|
|
||||||
|
|
||||||
require $file;
|
|
||||||
}
|
|
||||||
}, null, null);
|
|
||||||
foreach ($filesToLoad as $fileIdentifier => $file) {
|
|
||||||
$requireFile($fileIdentifier, $file);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $loader;
|
|
||||||
}
|
|
||||||
}
|
|
1826
vendor/composer/installed.json
vendored
1826
vendor/composer/installed.json
vendored
File diff suppressed because it is too large
Load Diff
26
vendor/composer/platform_check.php
vendored
26
vendor/composer/platform_check.php
vendored
@ -1,26 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
// platform_check.php @generated by Composer
|
|
||||||
|
|
||||||
$issues = array();
|
|
||||||
|
|
||||||
if (!(PHP_VERSION_ID >= 80100)) {
|
|
||||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.';
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($issues) {
|
|
||||||
if (!headers_sent()) {
|
|
||||||
header('HTTP/1.1 500 Internal Server Error');
|
|
||||||
}
|
|
||||||
if (!ini_get('display_errors')) {
|
|
||||||
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
|
|
||||||
fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL);
|
|
||||||
} elseif (!headers_sent()) {
|
|
||||||
echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
trigger_error(
|
|
||||||
'Composer detected issues in your platform: ' . implode(' ', $issues),
|
|
||||||
E_USER_ERROR
|
|
||||||
);
|
|
||||||
}
|
|
3
vendor/craft-group/phroute/.gitignore
vendored
3
vendor/craft-group/phroute/.gitignore
vendored
@ -1,3 +0,0 @@
|
|||||||
vendor
|
|
||||||
composer.lock
|
|
||||||
.idea
|
|
17
vendor/craft-group/phroute/.travis.yml
vendored
17
vendor/craft-group/phroute/.travis.yml
vendored
@ -1,17 +0,0 @@
|
|||||||
language: php
|
|
||||||
sudo: false
|
|
||||||
|
|
||||||
php:
|
|
||||||
- 5.6
|
|
||||||
- 7.0
|
|
||||||
- 7.1
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- composer install --dev
|
|
||||||
|
|
||||||
script:
|
|
||||||
- mkdir -p build/logs
|
|
||||||
- php vendor/bin/phpunit --coverage-clover build/logs/clover.xml
|
|
||||||
|
|
||||||
after_script:
|
|
||||||
- php vendor/bin/coveralls -v
|
|
31
vendor/craft-group/phroute/LICENSE
vendored
31
vendor/craft-group/phroute/LICENSE
vendored
@ -1,31 +0,0 @@
|
|||||||
Copyright (c) 2013 by Nikita Popov.
|
|
||||||
|
|
||||||
Some rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions are
|
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
|
|
||||||
* Redistributions in binary form must reproduce the above
|
|
||||||
copyright notice, this list of conditions and the following
|
|
||||||
disclaimer in the documentation and/or other materials provided
|
|
||||||
with the distribution.
|
|
||||||
|
|
||||||
* The names of the contributors may not be used to endorse or
|
|
||||||
promote products derived from this software without specific
|
|
||||||
prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
592
vendor/craft-group/phroute/README.md
vendored
592
vendor/craft-group/phroute/README.md
vendored
@ -1,592 +0,0 @@
|
|||||||
PHRoute - Fast request router for PHP
|
|
||||||
=======================================
|
|
||||||
|
|
||||||
[![Build Status](https://travis-ci.org/mrjgreen/phroute.svg)](https://travis-ci.org/mrjgreen/phroute)
|
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/mrjgreen/phroute/badge.svg)](https://coveralls.io/github/mrjgreen/phroute)
|
|
||||||
[![Latest Stable Version](https://poser.pugx.org/phroute/phroute/v/stable)](https://packagist.org/packages/phroute/phroute)
|
|
||||||
[![License](https://poser.pugx.org/phroute/phroute/license)](https://packagist.org/packages/phroute/phroute)
|
|
||||||
[![Total Downloads](https://poser.pugx.org/phroute/phroute/downloads)](https://packagist.org/packages/phroute/phroute)
|
|
||||||
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/92fb42d3-5254-4b3e-8a84-69d535941465/mini.png)](https://insight.sensiolabs.com/projects/92fb42d3-5254-4b3e-8a84-69d535941465)
|
|
||||||
|
|
||||||
## This library provides a fast implementation of a regular expression based router.
|
|
||||||
|
|
||||||
* [Super fast](#performance)
|
|
||||||
* [Route parameters and optional route parameters](#defining-routes)
|
|
||||||
* [Dependency Injection Resolving (Integrates easily with 3rd parties eg. Orno/Di)](#dependency-injection)
|
|
||||||
* [Named routes and reverse routing](#named-routes-for-reverse-routing)
|
|
||||||
* [Restful controller routing](#controllers)
|
|
||||||
* [Route filters and filter groups](#filters)
|
|
||||||
* [Route prefix groups](#prefix-groups)
|
|
||||||
|
|
||||||
### Credit to nikic/FastRoute.
|
|
||||||
|
|
||||||
While the bulk of the library and extensive unit tests are my own, credit for the regex matching core implementation and benchmarking goes to [nikic](https://github.com/nikic/FastRoute). Please go and read nikic's
|
|
||||||
[blog post explaining how the implementation works and why it's fast.](http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html)
|
|
||||||
|
|
||||||
Many modifications to the core have been made to suit the new library wrapper, and additional features added such as optional route parameters and reverse routing etc, but please head over and checkout nikic's library to see the origins of the core and how it works.
|
|
||||||
|
|
||||||
|
|
||||||
Installation
|
|
||||||
------------
|
|
||||||
Install via composer
|
|
||||||
|
|
||||||
```
|
|
||||||
composer require phroute/phroute
|
|
||||||
```
|
|
||||||
|
|
||||||
Usage
|
|
||||||
-----
|
|
||||||
### Example
|
|
||||||
|
|
||||||
~~~PHP
|
|
||||||
|
|
||||||
$router->get('/example', function(){
|
|
||||||
return 'This route responds to requests with the GET method at the path /example';
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->post('/example/{id}', function($id){
|
|
||||||
return 'This route responds to requests with the POST method at the path /example/1234. It passes in the parameter as a function argument.';
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->any('/example', function(){
|
|
||||||
return 'This route responds to any method (POST, GET, DELETE, OPTIONS, HEAD etc...) at the path /example';
|
|
||||||
});
|
|
||||||
~~~
|
|
||||||
|
|
||||||
|
|
||||||
### Defining routes
|
|
||||||
|
|
||||||
~~~PHP
|
|
||||||
use Phroute\Phroute\RouteCollector;
|
|
||||||
|
|
||||||
$router = new RouteCollector();
|
|
||||||
|
|
||||||
$router->get($route, $handler); # match only get requests
|
|
||||||
$router->post($route, $handler); # match only post requests
|
|
||||||
$router->delete($route, $handler); # match only delete requests
|
|
||||||
$router->any($route, $handler); # match any request method
|
|
||||||
|
|
||||||
etc...
|
|
||||||
~~~
|
|
||||||
|
|
||||||
> These helper methods are wrappers around `addRoute($method, $route, $handler)`
|
|
||||||
|
|
||||||
This method accepts the HTTP method the route must match, the route pattern and a callable handler, which can be a closure, function name or `['ClassName', 'method']` pair.
|
|
||||||
|
|
||||||
The methods also accept an additional parameter which is an array of middlewares: currently filters `before` and `after`, and route prefixing with `prefix` are supported. See the sections on Filters and Prefixes for more info and examples.
|
|
||||||
|
|
||||||
By default a route pattern syntax is used where `{foo}` specifies a placeholder with name `foo`
|
|
||||||
and matching the string `[^/]+`. To adjust the pattern the placeholder matches, you can specify
|
|
||||||
a custom pattern by writing `{bar:[0-9]+}`. However, it is also possible to adjust the pattern
|
|
||||||
syntax by passing a custom route parser to the router at construction.
|
|
||||||
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router->any('/example', function(){
|
|
||||||
return 'This route responds to any method (POST, GET, DELETE etc...) at the URI /example';
|
|
||||||
});
|
|
||||||
|
|
||||||
// or '/page/{id:i}' (see shortcuts)
|
|
||||||
|
|
||||||
$router->post('/page/{id:\d+}', function($id){
|
|
||||||
|
|
||||||
// $id contains the url paramter
|
|
||||||
|
|
||||||
return 'This route responds to the post method at the URI /page/{param} where param is at least one number';
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->any('/', function(){
|
|
||||||
|
|
||||||
return 'This responds to the default route';
|
|
||||||
});
|
|
||||||
|
|
||||||
// Lazy load autoloaded route handling classes using strings for classnames
|
|
||||||
// Calls the Controllers\User::displayUser($id) method with {id} parameter as an argument
|
|
||||||
$router->any('/users/{id}', ['Controllers\User','displayUser']);
|
|
||||||
|
|
||||||
// Optional Parameters
|
|
||||||
// simply add a '?' after the route name to make the parameter optional
|
|
||||||
// NB. be sure to add a default value for the function argument
|
|
||||||
$router->get('/user/{id}?', function($id = null) {
|
|
||||||
return 'second';
|
|
||||||
});
|
|
||||||
|
|
||||||
# NB. You can cache the return value from $router->getData() so you don't have to create the routes each request - massive speed gains
|
|
||||||
$dispatcher = new Phroute\Phroute\Dispatcher($router->getData());
|
|
||||||
|
|
||||||
$response = $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
|
|
||||||
|
|
||||||
// Print out the value returned from the dispatched function
|
|
||||||
echo $response;
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
### Regex Shortcuts
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
:i => :/d+ # numbers only
|
|
||||||
:a => :[a-zA-Z0-9]+ # alphanumeric
|
|
||||||
:c => :[a-zA-Z0-9+_\-\.]+ # alnumnumeric and + _ - . characters
|
|
||||||
:h => :[a-fA-F0-9]+ # hex
|
|
||||||
|
|
||||||
use in routes:
|
|
||||||
|
|
||||||
'/user/{name:i}'
|
|
||||||
'/user/{name:a}'
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
###Named Routes for Reverse Routing
|
|
||||||
|
|
||||||
Pass in an array as the first argument, where the first item is your route and the second item is a name with which to reference it later.
|
|
||||||
|
|
||||||
```php
|
|
||||||
$router->get(['/user/{name}', 'username'], function($name){
|
|
||||||
return 'Hello ' . $name;
|
|
||||||
})
|
|
||||||
->get(['/page/{slug}/{id:\d+}', 'page'], function($id){
|
|
||||||
return 'You must be authenticated to see this page: ' . $id;
|
|
||||||
});
|
|
||||||
|
|
||||||
// Use the routename and pass in any route parameters to reverse engineer an existing route path
|
|
||||||
// If you change your route path above, you won't need to go through your code updating any links/references to that route
|
|
||||||
$router->route('username', 'joe');
|
|
||||||
// string(9) '/user/joe'
|
|
||||||
|
|
||||||
$router->route('page', ['intro', 456]);
|
|
||||||
// string(15) '/page/intro/456'
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
###Filters
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
$router->filter('statsStart', function(){
|
|
||||||
setPageStartTime(microtime(true));
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->filter('statsComplete', function(){
|
|
||||||
var_dump('Page load time: ' . (microtime(true) - getPageStartTime()));
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->get('/user/{name}', function($name){
|
|
||||||
return 'Hello ' . $name;
|
|
||||||
}, ['before' => 'statsStart', 'after' => 'statsComplete']);
|
|
||||||
```
|
|
||||||
|
|
||||||
###Filter Groups
|
|
||||||
|
|
||||||
Wrap multiple routes in a route group to apply that filter to every route defined within. You can nest route groups if required.
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
// Any thing other than null returned from a filter will prevent the route handler from being dispatched
|
|
||||||
$router->filter('auth', function(){
|
|
||||||
if(!isset($_SESSION['user']))
|
|
||||||
{
|
|
||||||
header('Location: /login');
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->group(['before' => 'auth'], function($router){
|
|
||||||
|
|
||||||
$router->get('/user/{name}', function($name){
|
|
||||||
return 'Hello ' . $name;
|
|
||||||
})
|
|
||||||
->get('/page/{id:\d+}', function($id){
|
|
||||||
return 'You must be authenticated to see this page: ' . $id;
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
```
|
|
||||||
###Prefix Groups
|
|
||||||
|
|
||||||
```php
|
|
||||||
|
|
||||||
// You can combine a prefix with a filter, eg. `['prefix' => 'admin', 'before' => 'auth']`
|
|
||||||
|
|
||||||
$router->group(['prefix' => 'admin'], function($router){
|
|
||||||
|
|
||||||
$router->get('pages', function(){
|
|
||||||
return 'page management';
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->get('products', function(){
|
|
||||||
return 'product management';
|
|
||||||
});
|
|
||||||
|
|
||||||
$router->get('orders', function(){
|
|
||||||
return 'order management';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
```
|
|
||||||
|
|
||||||
###Controllers
|
|
||||||
|
|
||||||
```php
|
|
||||||
namespace MyApp;
|
|
||||||
|
|
||||||
class Test {
|
|
||||||
|
|
||||||
public function anyIndex()
|
|
||||||
{
|
|
||||||
return 'This is the default page and will respond to /controller and /controller/index';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* One required paramter and one optional parameter
|
|
||||||
*/
|
|
||||||
public function anyTest($param, $param2 = 'default')
|
|
||||||
{
|
|
||||||
return 'This will respond to /controller/test/{param}/{param2}? with any method';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTest()
|
|
||||||
{
|
|
||||||
return 'This will respond to /controller/test with only a GET method';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function postTest()
|
|
||||||
{
|
|
||||||
return 'This will respond to /controller/test with only a POST method';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function putTest()
|
|
||||||
{
|
|
||||||
return 'This will respond to /controller/test with only a PUT method';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function deleteTest()
|
|
||||||
{
|
|
||||||
return 'This will respond to /controller/test with only a DELETE method';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$router->controller('/controller', 'MyApp\\Test');
|
|
||||||
|
|
||||||
// Controller with associated filter
|
|
||||||
$router->controller('/controller', 'MyApp\\Test', ['before' => 'auth']);
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
### Dispatching a URI
|
|
||||||
|
|
||||||
A URI is dispatched by calling the `dispatch()` method of the created dispatcher. This method
|
|
||||||
accepts the HTTP method and a URI. Getting those two bits of information (and normalizing them
|
|
||||||
appropriately) is your job - this library is not bound to the PHP web SAPIs.
|
|
||||||
|
|
||||||
$response = (new Phroute\Phroute\Dispatcher($router))
|
|
||||||
->dispatch($_SERVER['REQUEST_METHOD'], $_SERVER['REQUEST_URI']);
|
|
||||||
|
|
||||||
The `dispatch()` method will call the matched route, or if no matches, throw one of the exceptions below:
|
|
||||||
|
|
||||||
# Route not found
|
|
||||||
Phroute\Phroute\Exception\HttpRouteNotFoundException;
|
|
||||||
|
|
||||||
# Route found, but method not allowed
|
|
||||||
Phroute\Phroute\Exception\HttpMethodNotAllowedException;
|
|
||||||
|
|
||||||
> **NOTE:** The HTTP specification requires that a `405 Method Not Allowed` response include the
|
|
||||||
`Allow:` header to detail available methods for the requested resource.
|
|
||||||
This information can be obtained from the thrown exception's message content:
|
|
||||||
which will look like: `"Allow: HEAD, GET, POST"` etc... depending on the methods you have set
|
|
||||||
You should catch the exception and use this to send a header to the client: `header($e->getMessage());`
|
|
||||||
|
|
||||||
|
|
||||||
###Dependency Injection
|
|
||||||
|
|
||||||
Defining your own dependency resolver is simple and easy. The router will attempt to resolve filters,
|
|
||||||
and route handlers via the dependency resolver.
|
|
||||||
|
|
||||||
The example below shows how you can define your own resolver to integrate with orno/di,
|
|
||||||
but pimple/pimple or others will work just as well.
|
|
||||||
|
|
||||||
~~~PHP
|
|
||||||
|
|
||||||
use Orno\Di\Container;
|
|
||||||
use Phroute\Phroute\HandlerResolverInterface;
|
|
||||||
|
|
||||||
class RouterResolver implements HandlerResolverInterface
|
|
||||||
{
|
|
||||||
private $container;
|
|
||||||
|
|
||||||
public function __construct(Container $container)
|
|
||||||
{
|
|
||||||
$this->container = $container;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function resolve($handler)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Only attempt resolve uninstantiated objects which will be in the form:
|
|
||||||
*
|
|
||||||
* $handler = ['App\Controllers\Home', 'method'];
|
|
||||||
*/
|
|
||||||
if(is_array($handler) and is_string($handler[0]))
|
|
||||||
{
|
|
||||||
$handler[0] = $this->container[$handler[0]];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $handler;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
~~~
|
|
||||||
|
|
||||||
|
|
||||||
When you create your dispatcher:
|
|
||||||
|
|
||||||
~~~PHP
|
|
||||||
|
|
||||||
$appContainer = new Orno\Di;
|
|
||||||
|
|
||||||
// Attach your controllers as normal
|
|
||||||
// $appContainer->add('App\Controllers\Home')
|
|
||||||
|
|
||||||
|
|
||||||
$resolver = new RouterResolver($appContainer);
|
|
||||||
$response = (new Phroute\Phroute\Dispatcher($router, $resolver))->dispatch($requestMethod, $requestUri);
|
|
||||||
|
|
||||||
~~~
|
|
||||||
|
|
||||||
### A Note on HEAD Requests
|
|
||||||
|
|
||||||
The HTTP spec requires servers to [support both GET and HEAD methods][2616-511]:
|
|
||||||
|
|
||||||
> The methods GET and HEAD MUST be supported by all general-purpose servers
|
|
||||||
|
|
||||||
To avoid forcing users to manually register HEAD routes for each resource we fallback to matching an
|
|
||||||
available GET route for a given resource. The PHP web SAPI transparently removes the entity body
|
|
||||||
from HEAD responses so this behavior has no effect on the vast majority of users.
|
|
||||||
|
|
||||||
However, implementors using Phroute outside the web SAPI environment (e.g. a custom server) MUST
|
|
||||||
NOT send entity bodies generated in response to HEAD requests. If you are a non-SAPI user this is
|
|
||||||
*your responsibility*; Phroute has no purview to prevent you from breaking HTTP in such cases.
|
|
||||||
|
|
||||||
Finally, note that applications MAY always specify their own HEAD method route for a given
|
|
||||||
resource to bypass this behavior entirely.
|
|
||||||
|
|
||||||
|
|
||||||
### Performance
|
|
||||||
|
|
||||||
Performed on a machine with :
|
|
||||||
|
|
||||||
* Processor 2.3 GHz Intel Core i7
|
|
||||||
* Memory 8 GB 1600 MHz DDR3
|
|
||||||
|
|
||||||
####Phroute
|
|
||||||
|
|
||||||
This test is to illustrate, in part, the efficiency of the lightweight routing-core, but mostly the lack of degradation of matching speed as the number of routes grows, as compared to conventional libraries.
|
|
||||||
|
|
||||||
##### With 10 routes, matching 1st route (best case)
|
|
||||||
~~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:9943/
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 3.062 seconds
|
|
||||||
Requests per second: 326.60 [#/sec] (mean)
|
|
||||||
Time per request: 306.181 [ms] (mean)
|
|
||||||
Time per request: 3.062 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 37.32 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 306
|
|
||||||
66% 307
|
|
||||||
75% 307
|
|
||||||
80% 308
|
|
||||||
90% 309
|
|
||||||
95% 309
|
|
||||||
98% 310
|
|
||||||
99% 310
|
|
||||||
100% 310 (longest request)
|
|
||||||
~~~~
|
|
||||||
|
|
||||||
##### With 10 routes, matching last route (worst case)
|
|
||||||
|
|
||||||
Note that the match is just as quick as against the first route
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:9943/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 3.079 seconds
|
|
||||||
Requests per second: 324.80 [#/sec] (mean)
|
|
||||||
Time per request: 307.880 [ms] (mean)
|
|
||||||
Time per request: 3.079 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 37.11 [Kbytes/sec] received
|
|
||||||
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 307
|
|
||||||
66% 308
|
|
||||||
75% 309
|
|
||||||
80% 309
|
|
||||||
90% 310
|
|
||||||
95% 311
|
|
||||||
98% 312
|
|
||||||
99% 312
|
|
||||||
100% 313 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
##### With 100 routes, matching last route (worst case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:9943/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 3.195 seconds
|
|
||||||
Requests per second: 312.97 [#/sec] (mean)
|
|
||||||
Time per request: 319.515 [ms] (mean)
|
|
||||||
Time per request: 3.195 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 35.76 [Kbytes/sec] received
|
|
||||||
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 318
|
|
||||||
66% 319
|
|
||||||
75% 320
|
|
||||||
80% 320
|
|
||||||
90% 322
|
|
||||||
95% 323
|
|
||||||
98% 323
|
|
||||||
99% 324
|
|
||||||
100% 324 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
##### With 1000 routes, matching the last route (worst case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:9943/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 4.497 seconds
|
|
||||||
Complete requests: 1000
|
|
||||||
Requests per second: 222.39 [#/sec] (mean)
|
|
||||||
Time per request: 449.668 [ms] (mean)
|
|
||||||
Time per request: 4.497 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 25.41 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 445
|
|
||||||
66% 447
|
|
||||||
75% 448
|
|
||||||
80% 449
|
|
||||||
90% 454
|
|
||||||
95% 456
|
|
||||||
98% 457
|
|
||||||
99% 458
|
|
||||||
100% 478 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
###For comparison, Laravel 4.0 routing core
|
|
||||||
|
|
||||||
Please note, this is no slight against laravel - it is based on a routing loop, which is why the performance worsens as the number of routes grows
|
|
||||||
|
|
||||||
##### With 10 routes, matching first route (best case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:4968/
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 13.366 seconds
|
|
||||||
Requests per second: 74.82 [#/sec] (mean)
|
|
||||||
Time per request: 1336.628 [ms] (mean)
|
|
||||||
Time per request: 13.366 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 8.55 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 1336
|
|
||||||
66% 1339
|
|
||||||
75% 1340
|
|
||||||
80% 1341
|
|
||||||
90% 1346
|
|
||||||
95% 1348
|
|
||||||
98% 1349
|
|
||||||
99% 1351
|
|
||||||
100% 1353 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
|
|
||||||
##### With 10 routes, matching last route (worst case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:4968/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 14.621 seconds
|
|
||||||
Requests per second: 68.39 [#/sec] (mean)
|
|
||||||
Time per request: 1462.117 [ms] (mean)
|
|
||||||
Time per request: 14.621 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 7.81 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 1461
|
|
||||||
66% 1465
|
|
||||||
75% 1469
|
|
||||||
80% 1472
|
|
||||||
90% 1476
|
|
||||||
95% 1479
|
|
||||||
98% 1480
|
|
||||||
99% 1482
|
|
||||||
100% 1484 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
##### With 100 routes, matching last route (worst case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:4968/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 31.254 seconds
|
|
||||||
Requests per second: 32.00 [#/sec] (mean)
|
|
||||||
Time per request: 3125.402 [ms] (mean)
|
|
||||||
Time per request: 31.254 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 3.66 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 3124
|
|
||||||
66% 3145
|
|
||||||
75% 3154
|
|
||||||
80% 3163
|
|
||||||
90% 3188
|
|
||||||
95% 3219
|
|
||||||
98% 3232
|
|
||||||
99% 3236
|
|
||||||
100% 3241 (longest request)
|
|
||||||
~~~
|
|
||||||
|
|
||||||
##### With 1000 routes, matching last route (worst case)
|
|
||||||
|
|
||||||
~~~
|
|
||||||
$ /usr/local/bin/ab -n 1000 -c 100 http://127.0.0.1:5740/thelastroute
|
|
||||||
|
|
||||||
Finished 1000 requests
|
|
||||||
|
|
||||||
Time taken for tests: 197.366 seconds
|
|
||||||
Requests per second: 5.07 [#/sec] (mean)
|
|
||||||
Time per request: 19736.598 [ms] (mean)
|
|
||||||
Time per request: 197.366 [ms] (mean, across all concurrent requests)
|
|
||||||
Transfer rate: 0.58 [Kbytes/sec] received
|
|
||||||
|
|
||||||
Percentage of the requests served within a certain time (ms)
|
|
||||||
50% 19736
|
|
||||||
66% 19802
|
|
||||||
75% 19827
|
|
||||||
80% 19855
|
|
||||||
90% 19898
|
|
||||||
95% 19918
|
|
||||||
98% 19945
|
|
||||||
99% 19960
|
|
||||||
100% 19975 (longest request)
|
|
||||||
~~~
|
|
54
vendor/craft-group/phroute/benchmark/simple.php
vendored
54
vendor/craft-group/phroute/benchmark/simple.php
vendored
@ -1,54 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
$collector = new Phroute\Phroute\RouteCollector();
|
|
||||||
|
|
||||||
$collector->get('/test', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('/test2', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('/test3', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('/test1/{name}', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('/test2/{name2}', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('/test3/{name3}', function(){
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
$dispatcher = new Phroute\Phroute\Dispatcher($collector->getData());
|
|
||||||
|
|
||||||
$runTime = 10;
|
|
||||||
|
|
||||||
$time = microtime(true);
|
|
||||||
|
|
||||||
$count = 0;
|
|
||||||
$seconds = 0;
|
|
||||||
while($seconds < $runTime)
|
|
||||||
{
|
|
||||||
$count++;
|
|
||||||
$dispatcher->dispatch('GET', '/test2/joe');
|
|
||||||
|
|
||||||
if($time + 1 < microtime(true))
|
|
||||||
{
|
|
||||||
$time = microtime(true);
|
|
||||||
$seconds++;
|
|
||||||
echo $count . ' routes dispatched per second' . "\r";
|
|
||||||
$count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
echo PHP_EOL;
|
|
||||||
|
|
24
vendor/craft-group/phroute/composer.json
vendored
24
vendor/craft-group/phroute/composer.json
vendored
@ -1,24 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "craft-group/phroute",
|
|
||||||
"description": "Fast, fully featured restful request router for PHP",
|
|
||||||
"keywords": ["routing", "router"],
|
|
||||||
"license": "BSD-3-Clause",
|
|
||||||
"authors": [
|
|
||||||
{
|
|
||||||
"name": "Kavalar",
|
|
||||||
"email": "apuc06@mail.ru"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Phroute\\Phroute\\": "src/Phroute"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"require": {
|
|
||||||
"php": ">=5.4.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"satooshi/php-coveralls": "^1.0",
|
|
||||||
"phpunit/phpunit": "^5.0"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
use Phroute\Phroute\RouteCollector;
|
|
||||||
use Phroute\Phroute\Dispatcher;
|
|
||||||
|
|
||||||
$collector = new RouteCollector();
|
|
||||||
|
|
||||||
$USER_SESSION = false;
|
|
||||||
|
|
||||||
$collector->filter('auth', function() use(&$USER_SESSION){
|
|
||||||
if(!$USER_SESSION)
|
|
||||||
{
|
|
||||||
return "Nope! Must be authenticated";
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->group(array('before' => 'auth'), function(RouteCollector $collector){
|
|
||||||
|
|
||||||
$collector->get('/', function(){
|
|
||||||
return 'Hurrah! Home Page';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$dispatcher = new Dispatcher($collector->getData());
|
|
||||||
|
|
||||||
echo $dispatcher->dispatch('GET', '/'), "\n"; // Nope! Must be authenticated
|
|
||||||
|
|
||||||
$USER_SESSION = true;
|
|
||||||
|
|
||||||
echo $dispatcher->dispatch('GET', '/'), "\n"; // Hurrah! Home Page
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
use Phroute\Phroute\RouteCollector;
|
|
||||||
use Phroute\Phroute\Dispatcher;
|
|
||||||
|
|
||||||
$collector = new RouteCollector();
|
|
||||||
|
|
||||||
$collector->group(array('prefix' => 'admin'), function(RouteCollector $collector){
|
|
||||||
|
|
||||||
$collector->get('pages', function(){
|
|
||||||
return 'page management';
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('products', function(){
|
|
||||||
return 'product management';
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('orders', function(){
|
|
||||||
return 'order management';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$dispatcher = new Dispatcher($collector->getData());
|
|
||||||
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/pages'), "\n"; // page management
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/products'), "\n"; // product management
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/orders'), "\n"; // order management
|
|
@ -1,36 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
use Phroute\Phroute\RouteCollector;
|
|
||||||
use Phroute\Phroute\Dispatcher;
|
|
||||||
|
|
||||||
$collector = new RouteCollector();
|
|
||||||
|
|
||||||
$collector->filter('auth', function(){
|
|
||||||
return "Nope!";
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->group(array('prefix' => 'admin'), function(RouteCollector $collector){
|
|
||||||
|
|
||||||
$collector->group(['before' => 'auth'], function(RouteCollector $collector){
|
|
||||||
$collector->get('pages', function(){
|
|
||||||
return 'page management';
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->get('products', function(){
|
|
||||||
return 'product management';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
// Not inside auth group
|
|
||||||
$collector->get('orders', function(){
|
|
||||||
return 'Order management';
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$dispatcher = new Dispatcher($collector->getData());
|
|
||||||
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/pages'), "\n"; // Nope!
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/products'), "\n"; // Nope!
|
|
||||||
echo $dispatcher->dispatch('GET', '/admin/orders'), "\n"; // order management
|
|
27
vendor/craft-group/phroute/examples/simple.php
vendored
27
vendor/craft-group/phroute/examples/simple.php
vendored
@ -1,27 +0,0 @@
|
|||||||
<?php
|
|
||||||
error_reporting(-1);
|
|
||||||
ini_set('display_errors', 1);
|
|
||||||
include __DIR__ . '/../vendor/autoload.php';
|
|
||||||
|
|
||||||
use Phroute\Phroute\RouteCollector;
|
|
||||||
use Phroute\Phroute\Dispatcher;
|
|
||||||
|
|
||||||
$collector = new RouteCollector();
|
|
||||||
|
|
||||||
$collector->get('/', function(){
|
|
||||||
return 'Home Page';
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->post('products', function(){
|
|
||||||
return 'Create Product';
|
|
||||||
});
|
|
||||||
|
|
||||||
$collector->put('items/{id}', function($id){
|
|
||||||
return 'Amend Item ' . $id;
|
|
||||||
});
|
|
||||||
|
|
||||||
$dispatcher = new Dispatcher($collector->getData());
|
|
||||||
|
|
||||||
echo $dispatcher->dispatch($_SERVER['REQUEST_METHOD'], parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)); // Home Page
|
|
||||||
//echo $dispatcher->dispatch('POST', '/products'), "\n"; // Create Product
|
|
||||||
//echo $dispatcher->dispatch('PUT', '/items/123'), "\n"; // Amend Item 123
|
|
25
vendor/craft-group/phroute/phpunit.xml
vendored
25
vendor/craft-group/phroute/phpunit.xml
vendored
@ -1,25 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
|
|
||||||
<phpunit backupGlobals="false"
|
|
||||||
backupStaticAttributes="false"
|
|
||||||
colors="true"
|
|
||||||
convertErrorsToExceptions="true"
|
|
||||||
convertNoticesToExceptions="true"
|
|
||||||
convertWarningsToExceptions="true"
|
|
||||||
processIsolation="false"
|
|
||||||
stopOnFailure="true"
|
|
||||||
syntaxCheck="false"
|
|
||||||
bootstrap="vendor/autoload.php"
|
|
||||||
>
|
|
||||||
<testsuites>
|
|
||||||
<testsuite name="Phroute Tests">
|
|
||||||
<directory>./test/</directory>
|
|
||||||
</testsuite>
|
|
||||||
</testsuites>
|
|
||||||
|
|
||||||
<filter>
|
|
||||||
<whitelist>
|
|
||||||
<directory>./src/</directory>
|
|
||||||
</whitelist>
|
|
||||||
</filter>
|
|
||||||
</phpunit>
|
|
@ -1,232 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
use Phroute\Phroute\Exception\HttpMethodNotAllowedException;
|
|
||||||
use Phroute\Phroute\Exception\HttpRouteNotFoundException;
|
|
||||||
|
|
||||||
class Dispatcher {
|
|
||||||
|
|
||||||
private $staticRouteMap;
|
|
||||||
private $variableRouteData;
|
|
||||||
private $filters;
|
|
||||||
private $handlerResolver;
|
|
||||||
public $matchedRoute;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new route dispatcher.
|
|
||||||
*
|
|
||||||
* @param RouteDataInterface $data
|
|
||||||
* @param HandlerResolverInterface $resolver
|
|
||||||
*/
|
|
||||||
public function __construct(RouteDataInterface $data, HandlerResolverInterface $resolver = null)
|
|
||||||
{
|
|
||||||
$this->staticRouteMap = $data->getStaticRoutes();
|
|
||||||
|
|
||||||
$this->variableRouteData = $data->getVariableRoutes();
|
|
||||||
|
|
||||||
$this->filters = $data->getFilters();
|
|
||||||
|
|
||||||
if ($resolver === null)
|
|
||||||
{
|
|
||||||
$this->handlerResolver = new HandlerResolver();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$this->handlerResolver = $resolver;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch a route for the given HTTP Method / URI.
|
|
||||||
*
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $uri
|
|
||||||
* @return mixed|null
|
|
||||||
*/
|
|
||||||
public function dispatch($httpMethod, $uri)
|
|
||||||
{
|
|
||||||
list($handler, $filters, $vars) = $this->dispatchRoute($httpMethod, trim($uri, '/'));
|
|
||||||
|
|
||||||
list($beforeFilter, $afterFilter) = $this->parseFilters($filters);
|
|
||||||
|
|
||||||
if(($response = $this->dispatchFilters($beforeFilter)) !== null)
|
|
||||||
{
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
$resolvedHandler = $this->handlerResolver->resolve($handler);
|
|
||||||
|
|
||||||
$response = call_user_func_array($resolvedHandler, $vars);
|
|
||||||
|
|
||||||
return $this->dispatchFilters($afterFilter, $response);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Dispatch a route filter.
|
|
||||||
*
|
|
||||||
* @param $filters
|
|
||||||
* @param null $response
|
|
||||||
* @return mixed|null
|
|
||||||
*/
|
|
||||||
private function dispatchFilters($filters, $response = null)
|
|
||||||
{
|
|
||||||
while($filter = array_shift($filters))
|
|
||||||
{
|
|
||||||
$handler = $this->handlerResolver->resolve($filter['closure']);
|
|
||||||
|
|
||||||
$params = array_merge([$response], $filter['params']);
|
|
||||||
|
|
||||||
if(($filteredResponse = call_user_func_array($handler, $params)) !== null)
|
|
||||||
{
|
|
||||||
return $filteredResponse;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $response;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalise the array filters attached to the route and merge with any global filters.
|
|
||||||
*
|
|
||||||
* @param $filters
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function parseFilters($filters)
|
|
||||||
{
|
|
||||||
$beforeFilter = array();
|
|
||||||
$afterFilter = array();
|
|
||||||
|
|
||||||
if(isset($filters[Route::BEFORE]))
|
|
||||||
{
|
|
||||||
foreach ($filters[Route::BEFORE] as $filter){
|
|
||||||
if(array_key_exists($filter['name'], $this->filters)){
|
|
||||||
$beforeFilter[] = array_merge($filter, ['closure' => $this->filters[$filter['name']]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//$beforeFilter = array_intersect_key($this->filters, array_flip((array) $filters[Route::BEFORE]));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(isset($filters[Route::AFTER]))
|
|
||||||
{
|
|
||||||
foreach ($filters[Route::AFTER] as $filter){
|
|
||||||
if(array_key_exists($filter['name'], $this->filters)){
|
|
||||||
$afterFilter[] = array_merge($filter, ['closure' => $this->filters[$filter['name']]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//$afterFilter = array_intersect_key($this->filters, array_flip((array) $filters[Route::AFTER]));
|
|
||||||
}
|
|
||||||
|
|
||||||
return array($beforeFilter, $afterFilter);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Perform the route dispatching. Check static routes first followed by variable routes.
|
|
||||||
*
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $uri
|
|
||||||
* @throws Exception\HttpRouteNotFoundException
|
|
||||||
*/
|
|
||||||
private function dispatchRoute($httpMethod, $uri)
|
|
||||||
{
|
|
||||||
if (isset($this->staticRouteMap[$uri]))
|
|
||||||
{
|
|
||||||
return $this->dispatchStaticRoute($httpMethod, $uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->dispatchVariableRoute($httpMethod, $uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the dispatching of static routes.
|
|
||||||
*
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $uri
|
|
||||||
* @return mixed
|
|
||||||
* @throws Exception\HttpMethodNotAllowedException
|
|
||||||
*/
|
|
||||||
private function dispatchStaticRoute($httpMethod, $uri)
|
|
||||||
{
|
|
||||||
$routes = $this->staticRouteMap[$uri];
|
|
||||||
|
|
||||||
if (!isset($routes[$httpMethod]))
|
|
||||||
{
|
|
||||||
$httpMethod = $this->checkFallbacks($routes, $httpMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $routes[$httpMethod];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check fallback routes: HEAD for GET requests followed by the ANY attachment.
|
|
||||||
*
|
|
||||||
* @param $routes
|
|
||||||
* @param $httpMethod
|
|
||||||
* @throws Exception\HttpMethodNotAllowedException
|
|
||||||
*/
|
|
||||||
private function checkFallbacks($routes, $httpMethod)
|
|
||||||
{
|
|
||||||
$additional = array(Route::ANY);
|
|
||||||
|
|
||||||
if($httpMethod === Route::HEAD)
|
|
||||||
{
|
|
||||||
$additional[] = Route::GET;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach($additional as $method)
|
|
||||||
{
|
|
||||||
if(isset($routes[$method]))
|
|
||||||
{
|
|
||||||
return $method;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->matchedRoute = $routes;
|
|
||||||
|
|
||||||
throw new HttpMethodNotAllowedException('Allow: ' . implode(', ', array_keys($routes)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the dispatching of variable routes.
|
|
||||||
*
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $uri
|
|
||||||
* @throws Exception\HttpMethodNotAllowedException
|
|
||||||
* @throws Exception\HttpRouteNotFoundException
|
|
||||||
*/
|
|
||||||
private function dispatchVariableRoute($httpMethod, $uri)
|
|
||||||
{
|
|
||||||
foreach ($this->variableRouteData as $data)
|
|
||||||
{
|
|
||||||
if (!preg_match($data['regex'], $uri, $matches))
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$count = count($matches);
|
|
||||||
|
|
||||||
while(!isset($data['routeMap'][$count++]));
|
|
||||||
|
|
||||||
$routes = $data['routeMap'][$count - 1];
|
|
||||||
|
|
||||||
if (!isset($routes[$httpMethod]))
|
|
||||||
{
|
|
||||||
$httpMethod = $this->checkFallbacks($routes, $httpMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (array_values($routes[$httpMethod][2]) as $i => $varName)
|
|
||||||
{
|
|
||||||
if(!isset($matches[$i + 1]) || $matches[$i + 1] === '')
|
|
||||||
{
|
|
||||||
unset($routes[$httpMethod][2][$varName]);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$routes[$httpMethod][2][$varName] = $matches[$i + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $routes[$httpMethod];
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new HttpRouteNotFoundException('Route ' . $uri . ' does not exist');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,4 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute\Exception;
|
|
||||||
|
|
||||||
class BadRouteException extends \LogicException {
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute\Exception;
|
|
||||||
|
|
||||||
class HttpException extends \Exception {}
|
|
@ -1,3 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute\Exception;
|
|
||||||
|
|
||||||
class HttpMethodNotAllowedException extends HttpException {}
|
|
@ -1,4 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute\Exception;
|
|
||||||
|
|
||||||
class HttpRouteNotFoundException extends HttpException {}
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
class HandlerResolver implements HandlerResolverInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an instance of the given handler.
|
|
||||||
*
|
|
||||||
* @param $handler
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
|
|
||||||
public function resolve ($handler)
|
|
||||||
{
|
|
||||||
if(is_array($handler) && is_string($handler[0]))
|
|
||||||
{
|
|
||||||
$handler[0] = new $handler[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $handler;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
interface HandlerResolverInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create an instance of the given handler.
|
|
||||||
*
|
|
||||||
* @param $handler
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
|
|
||||||
public function resolve($handler);
|
|
||||||
}
|
|
33
vendor/craft-group/phroute/src/Phroute/Route.php
vendored
33
vendor/craft-group/phroute/src/Phroute/Route.php
vendored
@ -1,33 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
class Route {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants for before and after filters
|
|
||||||
*/
|
|
||||||
const BEFORE = 'before';
|
|
||||||
|
|
||||||
const AFTER = 'after';
|
|
||||||
|
|
||||||
const PREFIX = 'prefix';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constants for common HTTP methods
|
|
||||||
*/
|
|
||||||
const ANY = 'ANY';
|
|
||||||
|
|
||||||
const GET = 'GET';
|
|
||||||
|
|
||||||
const HEAD = 'HEAD';
|
|
||||||
|
|
||||||
const POST = 'POST';
|
|
||||||
|
|
||||||
const PUT = 'PUT';
|
|
||||||
|
|
||||||
const PATCH = 'PATCH';
|
|
||||||
|
|
||||||
const DELETE = 'DELETE';
|
|
||||||
|
|
||||||
const OPTIONS = 'OPTIONS';
|
|
||||||
}
|
|
||||||
|
|
@ -1,472 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
use ReflectionClass;
|
|
||||||
use ReflectionMethod;
|
|
||||||
|
|
||||||
use Phroute\Phroute\Exception\BadRouteException;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class RouteCollector
|
|
||||||
* @package Phroute\Phroute
|
|
||||||
*/
|
|
||||||
class RouteCollector implements RouteDataProviderInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const DEFAULT_CONTROLLER_ROUTE = 'index';
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
const APPROX_CHUNK_SIZE = 10;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var RouteParser
|
|
||||||
*/
|
|
||||||
private $routeParser;
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $filters = [];
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $staticRoutes = [];
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $regexToRoutesMap = [];
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $reverse = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $globalFilters = [];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var
|
|
||||||
*/
|
|
||||||
private $globalRoutePrefix;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param RouteParser $routeParser
|
|
||||||
*/
|
|
||||||
public function __construct(RouteParser $routeParser = null) {
|
|
||||||
$this->routeParser = $routeParser ?: new RouteParser();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function hasRoute($name) {
|
|
||||||
return isset($this->reverse[$name]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @param array $args
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function route($name, array $args = null)
|
|
||||||
{
|
|
||||||
$url = [];
|
|
||||||
|
|
||||||
$replacements = is_null($args) ? [] : array_values($args);
|
|
||||||
|
|
||||||
$variable = 0;
|
|
||||||
|
|
||||||
foreach($this->reverse[$name] as $part)
|
|
||||||
{
|
|
||||||
if(!$part['variable'])
|
|
||||||
{
|
|
||||||
$url[] = $part['value'];
|
|
||||||
}
|
|
||||||
elseif(isset($replacements[$variable]))
|
|
||||||
{
|
|
||||||
if($part['optional'])
|
|
||||||
{
|
|
||||||
$url[] = '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
$url[] = $replacements[$variable++];
|
|
||||||
}
|
|
||||||
elseif(!$part['optional'])
|
|
||||||
{
|
|
||||||
throw new BadRouteException("Expecting route variable '{$part['name']}'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return implode('', $url);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function addRoute($httpMethod, $route, $handler, array $filters = []) {
|
|
||||||
|
|
||||||
if(is_array($route))
|
|
||||||
{
|
|
||||||
list($route, $name) = $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
$route = $this->addPrefix($this->trim($route));
|
|
||||||
|
|
||||||
list($routeData, $reverseData) = $this->routeParser->parse($route);
|
|
||||||
|
|
||||||
if(isset($name))
|
|
||||||
{
|
|
||||||
$this->reverse[$name] = $reverseData;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(array_key_exists(Route::BEFORE, $filters)){
|
|
||||||
$filters = [Route::BEFORE => [['name' => $filters[Route::BEFORE], 'params' => $filters['params']]]];
|
|
||||||
}
|
|
||||||
if(array_key_exists(Route::AFTER, $filters)){
|
|
||||||
$filters = [Route::AFTER => [['name' => $filters[Route::AFTER], 'params' => $filters['params']]]];
|
|
||||||
}
|
|
||||||
|
|
||||||
$filters = array_merge_recursive($this->globalFilters, $filters);
|
|
||||||
|
|
||||||
isset($routeData[1]) ?
|
|
||||||
$this->addVariableRoute($httpMethod, $routeData, $handler, $filters) :
|
|
||||||
$this->addStaticRoute($httpMethod, $routeData, $handler, $filters);
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $routeData
|
|
||||||
* @param $handler
|
|
||||||
* @param $filters
|
|
||||||
*/
|
|
||||||
private function addStaticRoute($httpMethod, $routeData, $handler, $filters)
|
|
||||||
{
|
|
||||||
$routeStr = $routeData[0];
|
|
||||||
|
|
||||||
if (isset($this->staticRoutes[$routeStr][$httpMethod]))
|
|
||||||
{
|
|
||||||
throw new BadRouteException("Cannot register two routes matching '$routeStr' for method '$httpMethod'");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->regexToRoutesMap as $regex => $routes) {
|
|
||||||
if (isset($routes[$httpMethod]) && preg_match('~^' . $regex . '$~', $routeStr))
|
|
||||||
{
|
|
||||||
throw new BadRouteException("Static route '$routeStr' is shadowed by previously defined variable route '$regex' for method '$httpMethod'");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->staticRoutes[$routeStr][$httpMethod] = array($handler, $filters, []);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $httpMethod
|
|
||||||
* @param $routeData
|
|
||||||
* @param $handler
|
|
||||||
* @param $filters
|
|
||||||
*/
|
|
||||||
private function addVariableRoute($httpMethod, $routeData, $handler, $filters)
|
|
||||||
{
|
|
||||||
list($regex, $variables) = $routeData;
|
|
||||||
|
|
||||||
if (isset($this->regexToRoutesMap[$regex][$httpMethod]))
|
|
||||||
{
|
|
||||||
throw new BadRouteException("Cannot register two routes matching '$regex' for method '$httpMethod'");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->regexToRoutesMap[$regex][$httpMethod] = [$handler, $filters, $variables];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $filters
|
|
||||||
* @param \Closure $callback
|
|
||||||
*/
|
|
||||||
public function group(array $filters, \Closure $callback)
|
|
||||||
{
|
|
||||||
if(array_key_exists(Route::BEFORE, $filters)){
|
|
||||||
$filters = [Route::BEFORE => [['name' => $filters[Route::BEFORE], 'params' => isset($filters['params']) ? $filters['params'] : []]]];
|
|
||||||
}
|
|
||||||
if(array_key_exists(Route::AFTER, $filters)){
|
|
||||||
$filters = [Route::AFTER => [['name' => $filters[Route::AFTER], 'params' => isset($filters['params']) ? $filters['params'] : []]]];
|
|
||||||
}
|
|
||||||
$oldGlobalFilters = $this->globalFilters;
|
|
||||||
|
|
||||||
$oldGlobalPrefix = $this->globalRoutePrefix;
|
|
||||||
|
|
||||||
$this->globalFilters = array_merge_recursive($this->globalFilters, array_intersect_key($filters, [Route::AFTER => 1, Route::BEFORE => 1]));
|
|
||||||
|
|
||||||
$newPrefix = isset($filters[Route::PREFIX]) ? $this->trim($filters[Route::PREFIX]) : null;
|
|
||||||
|
|
||||||
$this->globalRoutePrefix = $this->addPrefix($newPrefix);
|
|
||||||
|
|
||||||
$callback($this);
|
|
||||||
|
|
||||||
$this->globalFilters = $oldGlobalFilters;
|
|
||||||
|
|
||||||
$this->globalRoutePrefix = $oldGlobalPrefix;
|
|
||||||
}
|
|
||||||
|
|
||||||
private function addPrefix($route)
|
|
||||||
{
|
|
||||||
return $this->trim($this->trim($this->globalRoutePrefix) . '/' . $route);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $name
|
|
||||||
* @param $handler
|
|
||||||
*/
|
|
||||||
public function filter($name, $handler)
|
|
||||||
{
|
|
||||||
$this->filters[$name] = $handler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function get($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::GET, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function head($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::HEAD, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function post($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::POST, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function put($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::PUT, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function patch($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::PATCH, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function delete($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::DELETE, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function options($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::OPTIONS, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $handler
|
|
||||||
* @param array $filters
|
|
||||||
* @return RouteCollector
|
|
||||||
*/
|
|
||||||
public function any($route, $handler, array $filters = [])
|
|
||||||
{
|
|
||||||
return $this->addRoute(Route::ANY, $route, $handler, $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $classname
|
|
||||||
* @param array $filters
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function controller($route, $classname, array $filters = [])
|
|
||||||
{
|
|
||||||
$reflection = new ReflectionClass($classname);
|
|
||||||
|
|
||||||
$validMethods = $this->getValidMethods();
|
|
||||||
|
|
||||||
$sep = $route === '/' ? '' : '/';
|
|
||||||
|
|
||||||
foreach($reflection->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
|
|
||||||
{
|
|
||||||
foreach($validMethods as $valid)
|
|
||||||
{
|
|
||||||
if(stripos($method->name, $valid) === 0)
|
|
||||||
{
|
|
||||||
$methodName = $this->camelCaseToDashed(substr($method->name, strlen($valid)));
|
|
||||||
|
|
||||||
$params = $this->buildControllerParameters($method);
|
|
||||||
|
|
||||||
if($methodName === self::DEFAULT_CONTROLLER_ROUTE)
|
|
||||||
{
|
|
||||||
$this->addRoute($valid, $route . $params, [$classname, $method->name], $filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->addRoute($valid, $route . $sep . $methodName . $params, [$classname, $method->name], $filters);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param ReflectionMethod $method
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function buildControllerParameters(ReflectionMethod $method)
|
|
||||||
{
|
|
||||||
$params = '';
|
|
||||||
|
|
||||||
foreach($method->getParameters() as $param)
|
|
||||||
{
|
|
||||||
$params .= "/{" . $param->getName() . "}" . ($param->isOptional() ? '?' : '');
|
|
||||||
}
|
|
||||||
|
|
||||||
return $params;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $string
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function camelCaseToDashed($string)
|
|
||||||
{
|
|
||||||
return strtolower(preg_replace('/([A-Z])/', '-$1', lcfirst($string)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getValidMethods()
|
|
||||||
{
|
|
||||||
return [
|
|
||||||
Route::ANY,
|
|
||||||
Route::GET,
|
|
||||||
Route::POST,
|
|
||||||
Route::PUT,
|
|
||||||
Route::PATCH,
|
|
||||||
Route::DELETE,
|
|
||||||
Route::HEAD,
|
|
||||||
Route::OPTIONS,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return RouteDataArray
|
|
||||||
*/
|
|
||||||
public function getData()
|
|
||||||
{
|
|
||||||
if (empty($this->regexToRoutesMap))
|
|
||||||
{
|
|
||||||
return new RouteDataArray($this->staticRoutes, [], $this->filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RouteDataArray($this->staticRoutes, $this->generateVariableRouteData(), $this->filters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function trim($route)
|
|
||||||
{
|
|
||||||
if(is_null($route)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return trim($route, '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function generateVariableRouteData()
|
|
||||||
{
|
|
||||||
$chunkSize = $this->computeChunkSize(count($this->regexToRoutesMap));
|
|
||||||
$chunks = array_chunk($this->regexToRoutesMap, $chunkSize, true);
|
|
||||||
return array_map([$this, 'processChunk'], $chunks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $count
|
|
||||||
* @return float
|
|
||||||
*/
|
|
||||||
private function computeChunkSize($count)
|
|
||||||
{
|
|
||||||
$numParts = max(1, round($count / self::APPROX_CHUNK_SIZE));
|
|
||||||
return ceil($count / $numParts);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $regexToRoutesMap
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
private function processChunk($regexToRoutesMap)
|
|
||||||
{
|
|
||||||
$routeMap = [];
|
|
||||||
$regexes = [];
|
|
||||||
$numGroups = 0;
|
|
||||||
foreach ($regexToRoutesMap as $regex => $routes) {
|
|
||||||
$firstRoute = reset($routes);
|
|
||||||
$numVariables = count($firstRoute[2]);
|
|
||||||
$numGroups = max($numGroups, $numVariables);
|
|
||||||
|
|
||||||
$regexes[] = $regex . str_repeat('()', $numGroups - $numVariables);
|
|
||||||
|
|
||||||
foreach ($routes as $httpMethod => $route) {
|
|
||||||
$routeMap[$numGroups + 1][$httpMethod] = $route;
|
|
||||||
}
|
|
||||||
|
|
||||||
$numGroups++;
|
|
||||||
}
|
|
||||||
|
|
||||||
$regex = '~^(?|' . implode('|', $regexes) . ')$~';
|
|
||||||
return ['regex' => $regex, 'routeMap' => $routeMap];
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
class RouteDataArray implements RouteDataInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $variableRoutes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $staticRoutes;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $filters;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param array $staticRoutes
|
|
||||||
* @param array $variableRoutes
|
|
||||||
* @param array $filters
|
|
||||||
*/
|
|
||||||
public function __construct(array $staticRoutes, array $variableRoutes, array $filters)
|
|
||||||
{
|
|
||||||
$this->staticRoutes = $staticRoutes;
|
|
||||||
|
|
||||||
$this->variableRoutes = $variableRoutes;
|
|
||||||
|
|
||||||
$this->filters = $filters;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getStaticRoutes()
|
|
||||||
{
|
|
||||||
return $this->staticRoutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getVariableRoutes()
|
|
||||||
{
|
|
||||||
return $this->variableRoutes;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getFilters()
|
|
||||||
{
|
|
||||||
return $this->filters;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface RouteDataInterface
|
|
||||||
* @package Phroute\Phroute
|
|
||||||
*/
|
|
||||||
interface RouteDataInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getStaticRoutes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getVariableRoutes();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getFilters();
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface RouteDataProviderInterface
|
|
||||||
* @package Phroute\Phroute
|
|
||||||
*/
|
|
||||||
interface RouteDataProviderInterface {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
public function getData();
|
|
||||||
}
|
|
@ -1,207 +0,0 @@
|
|||||||
<?php namespace Phroute\Phroute;
|
|
||||||
|
|
||||||
use Phroute\Phroute\Exception\BadRouteException;
|
|
||||||
/**
|
|
||||||
* Parses routes of the following form:
|
|
||||||
*
|
|
||||||
* "/user/{name}/{id:[0-9]+}?"
|
|
||||||
*/
|
|
||||||
class RouteParser {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Search through the given route looking for dynamic portions.
|
|
||||||
*
|
|
||||||
* Using ~ as the regex delimiter.
|
|
||||||
*
|
|
||||||
* We start by looking for a literal '{' character followed by any amount of whitespace.
|
|
||||||
* The next portion inside the parentheses looks for a parameter name containing alphanumeric characters or underscore.
|
|
||||||
*
|
|
||||||
* After this we look for the ':\d+' and ':[0-9]+' style portion ending with a closing '}' character.
|
|
||||||
*
|
|
||||||
* Finally we look for an optional '?' which is used to signify an optional route.
|
|
||||||
*/
|
|
||||||
const VARIABLE_REGEX =
|
|
||||||
"~\{
|
|
||||||
\s* ([a-zA-Z0-9_]*) \s*
|
|
||||||
(?:
|
|
||||||
: \s* ([^{]+(?:\{.*?\})?)
|
|
||||||
)?
|
|
||||||
\}\??~x";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The default parameter character restriction (One or more characters that is not a '/').
|
|
||||||
*/
|
|
||||||
const DEFAULT_DISPATCH_REGEX = '[^/]+';
|
|
||||||
|
|
||||||
private $parts;
|
|
||||||
|
|
||||||
private $reverseParts;
|
|
||||||
|
|
||||||
private $partsCounter;
|
|
||||||
|
|
||||||
private $variables;
|
|
||||||
|
|
||||||
private $regexOffset;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handy parameter type restrictions.
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
private $regexShortcuts = array(
|
|
||||||
':i}' => ':[0-9]+}',
|
|
||||||
':a}' => ':[0-9A-Za-z]+}',
|
|
||||||
':h}' => ':[0-9A-Fa-f]+}',
|
|
||||||
':c}' => ':[a-zA-Z0-9+_\-\.]+}'
|
|
||||||
);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Parse a route returning the correct data format to pass to the dispatch engine.
|
|
||||||
*
|
|
||||||
* @param $route
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function parse($route)
|
|
||||||
{
|
|
||||||
$this->reset();
|
|
||||||
|
|
||||||
$route = strtr($route, $this->regexShortcuts);
|
|
||||||
|
|
||||||
if (!$matches = $this->extractVariableRouteParts($route))
|
|
||||||
{
|
|
||||||
$reverse = array(
|
|
||||||
'variable' => false,
|
|
||||||
'value' => $route
|
|
||||||
);
|
|
||||||
|
|
||||||
return [[$route], array($reverse)];
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($matches as $set) {
|
|
||||||
|
|
||||||
$this->staticParts($route, $set[0][1]);
|
|
||||||
|
|
||||||
$this->validateVariable($set[1][0]);
|
|
||||||
|
|
||||||
$regexPart = (isset($set[2]) ? trim($set[2][0]) : self::DEFAULT_DISPATCH_REGEX);
|
|
||||||
|
|
||||||
$this->regexOffset = $set[0][1] + strlen($set[0][0]);
|
|
||||||
|
|
||||||
$match = '(' . $regexPart . ')';
|
|
||||||
|
|
||||||
$isOptional = substr($set[0][0], -1) === '?';
|
|
||||||
|
|
||||||
if($isOptional)
|
|
||||||
{
|
|
||||||
$match = $this->makeOptional($match);
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->reverseParts[$this->partsCounter] = array(
|
|
||||||
'variable' => true,
|
|
||||||
'optional' => $isOptional,
|
|
||||||
'name' => $set[1][0]
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->parts[$this->partsCounter++] = $match;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->staticParts($route, strlen($route));
|
|
||||||
|
|
||||||
return [[implode('', $this->parts), $this->variables], array_values($this->reverseParts)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the parser ready for the next route.
|
|
||||||
*/
|
|
||||||
private function reset()
|
|
||||||
{
|
|
||||||
$this->parts = array();
|
|
||||||
|
|
||||||
$this->reverseParts = array();
|
|
||||||
|
|
||||||
$this->partsCounter = 0;
|
|
||||||
|
|
||||||
$this->variables = array();
|
|
||||||
|
|
||||||
$this->regexOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return any variable route portions from the given route.
|
|
||||||
*
|
|
||||||
* @param $route
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
private function extractVariableRouteParts($route)
|
|
||||||
{
|
|
||||||
if(preg_match_all(self::VARIABLE_REGEX, $route, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER))
|
|
||||||
{
|
|
||||||
return $matches;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $route
|
|
||||||
* @param $nextOffset
|
|
||||||
*/
|
|
||||||
private function staticParts($route, $nextOffset)
|
|
||||||
{
|
|
||||||
$static = preg_split('~(/)~u', substr($route, $this->regexOffset, $nextOffset - $this->regexOffset), 0, PREG_SPLIT_DELIM_CAPTURE);
|
|
||||||
|
|
||||||
foreach($static as $staticPart)
|
|
||||||
{
|
|
||||||
if($staticPart)
|
|
||||||
{
|
|
||||||
$quotedPart = $this->quote($staticPart);
|
|
||||||
|
|
||||||
$this->parts[$this->partsCounter] = $quotedPart;
|
|
||||||
|
|
||||||
$this->reverseParts[$this->partsCounter] = array(
|
|
||||||
'variable' => false,
|
|
||||||
'value' => $staticPart
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->partsCounter++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $varName
|
|
||||||
*/
|
|
||||||
private function validateVariable($varName)
|
|
||||||
{
|
|
||||||
if (isset($this->variables[$varName]))
|
|
||||||
{
|
|
||||||
throw new BadRouteException("Cannot use the same placeholder '$varName' twice");
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->variables[$varName] = $varName;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $match
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function makeOptional($match)
|
|
||||||
{
|
|
||||||
$previous = $this->partsCounter - 1;
|
|
||||||
|
|
||||||
if(isset($this->parts[$previous]) && $this->parts[$previous] === '/')
|
|
||||||
{
|
|
||||||
$this->partsCounter--;
|
|
||||||
$match = '(?:/' . $match . ')';
|
|
||||||
}
|
|
||||||
|
|
||||||
return $match . '?';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param $part
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function quote($part)
|
|
||||||
{
|
|
||||||
return preg_quote($part, '~');
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
19
vendor/doctrine/inflector/LICENSE
vendored
19
vendor/doctrine/inflector/LICENSE
vendored
@ -1,19 +0,0 @@
|
|||||||
Copyright (c) 2006-2015 Doctrine Project
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
7
vendor/doctrine/inflector/README.md
vendored
7
vendor/doctrine/inflector/README.md
vendored
@ -1,7 +0,0 @@
|
|||||||
# Doctrine Inflector
|
|
||||||
|
|
||||||
Doctrine Inflector is a small library that can perform string manipulations
|
|
||||||
with regard to uppercase/lowercase and singular/plural forms of words.
|
|
||||||
|
|
||||||
[![Build Status](https://github.com/doctrine/inflector/workflows/Continuous%20Integration/badge.svg)](https://github.com/doctrine/inflector/actions?query=workflow%3A%22Continuous+Integration%22+branch%3A4.0.x)
|
|
||||||
[![Code Coverage](https://codecov.io/gh/doctrine/inflector/branch/2.0.x/graph/badge.svg)](https://codecov.io/gh/doctrine/inflector/branch/2.0.x)
|
|
41
vendor/doctrine/inflector/composer.json
vendored
41
vendor/doctrine/inflector/composer.json
vendored
@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "doctrine/inflector",
|
|
||||||
"type": "library",
|
|
||||||
"description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
|
|
||||||
"keywords": ["php", "strings", "words", "manipulation", "inflector", "inflection", "uppercase", "lowercase", "singular", "plural"],
|
|
||||||
"homepage": "https://www.doctrine-project.org/projects/inflector.html",
|
|
||||||
"license": "MIT",
|
|
||||||
"authors": [
|
|
||||||
{"name": "Guilherme Blanco", "email": "guilhermeblanco@gmail.com"},
|
|
||||||
{"name": "Roman Borschel", "email": "roman@code-factory.org"},
|
|
||||||
{"name": "Benjamin Eberlei", "email": "kontakt@beberlei.de"},
|
|
||||||
{"name": "Jonathan Wage", "email": "jonwage@gmail.com"},
|
|
||||||
{"name": "Johannes Schmitt", "email": "schmittjoh@gmail.com"}
|
|
||||||
],
|
|
||||||
"require": {
|
|
||||||
"php": "^7.2 || ^8.0"
|
|
||||||
},
|
|
||||||
"require-dev": {
|
|
||||||
"doctrine/coding-standard": "^11.0",
|
|
||||||
"phpstan/phpstan": "^1.8",
|
|
||||||
"phpstan/phpstan-phpunit": "^1.1",
|
|
||||||
"phpstan/phpstan-strict-rules": "^1.3",
|
|
||||||
"phpunit/phpunit": "^8.5 || ^9.5",
|
|
||||||
"vimeo/psalm": "^4.25 || ^5.4"
|
|
||||||
},
|
|
||||||
"autoload": {
|
|
||||||
"psr-4": {
|
|
||||||
"Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"autoload-dev": {
|
|
||||||
"psr-4": {
|
|
||||||
"Doctrine\\Tests\\Inflector\\": "tests/Doctrine/Tests/Inflector"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
"allow-plugins": {
|
|
||||||
"dealerdirect/phpcodesniffer-composer-installer": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
226
vendor/doctrine/inflector/docs/en/index.rst
vendored
226
vendor/doctrine/inflector/docs/en/index.rst
vendored
@ -1,226 +0,0 @@
|
|||||||
Introduction
|
|
||||||
============
|
|
||||||
|
|
||||||
The Doctrine Inflector has methods for inflecting text. The features include pluralization,
|
|
||||||
singularization, converting between camelCase and under_score and capitalizing
|
|
||||||
words.
|
|
||||||
|
|
||||||
Installation
|
|
||||||
============
|
|
||||||
|
|
||||||
You can install the Inflector with composer:
|
|
||||||
|
|
||||||
.. code-block:: console
|
|
||||||
|
|
||||||
$ composer require doctrine/inflector
|
|
||||||
|
|
||||||
Usage
|
|
||||||
=====
|
|
||||||
|
|
||||||
Using the inflector is easy, you can create a new ``Doctrine\Inflector\Inflector`` instance by using
|
|
||||||
the ``Doctrine\Inflector\InflectorFactory`` class:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Inflector\InflectorFactory;
|
|
||||||
|
|
||||||
$inflector = InflectorFactory::create()->build();
|
|
||||||
|
|
||||||
By default it will create an English inflector. If you want to use another language, just pass the language
|
|
||||||
you want to create an inflector for to the ``createForLanguage()`` method:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Inflector\InflectorFactory;
|
|
||||||
use Doctrine\Inflector\Language;
|
|
||||||
|
|
||||||
$inflector = InflectorFactory::createForLanguage(Language::SPANISH)->build();
|
|
||||||
|
|
||||||
The supported languages are as follows:
|
|
||||||
|
|
||||||
- ``Language::ENGLISH``
|
|
||||||
- ``Language::FRENCH``
|
|
||||||
- ``Language::NORWEGIAN_BOKMAL``
|
|
||||||
- ``Language::PORTUGUESE``
|
|
||||||
- ``Language::SPANISH``
|
|
||||||
- ``Language::TURKISH``
|
|
||||||
|
|
||||||
If you want to manually construct the inflector instead of using a factory, you can do so like this:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Inflector\CachedWordInflector;
|
|
||||||
use Doctrine\Inflector\RulesetInflector;
|
|
||||||
use Doctrine\Inflector\Rules\English;
|
|
||||||
|
|
||||||
$inflector = new Inflector(
|
|
||||||
new CachedWordInflector(new RulesetInflector(
|
|
||||||
English\Rules::getSingularRuleset()
|
|
||||||
)),
|
|
||||||
new CachedWordInflector(new RulesetInflector(
|
|
||||||
English\Rules::getPluralRuleset()
|
|
||||||
))
|
|
||||||
);
|
|
||||||
|
|
||||||
Adding Languages
|
|
||||||
----------------
|
|
||||||
|
|
||||||
If you are interested in adding support for your language, take a look at the other languages defined in the
|
|
||||||
``Doctrine\Inflector\Rules`` namespace and the tests located in ``Doctrine\Tests\Inflector\Rules``. You can copy
|
|
||||||
one of the languages and update the rules for your language.
|
|
||||||
|
|
||||||
Once you have done this, send a pull request to the ``doctrine/inflector`` repository with the additions.
|
|
||||||
|
|
||||||
Custom Setup
|
|
||||||
============
|
|
||||||
|
|
||||||
If you want to setup custom singular and plural rules, you can configure these in the factory:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Inflector\InflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
$inflector = InflectorFactory::create()
|
|
||||||
->withSingularRules(
|
|
||||||
new Ruleset(
|
|
||||||
new Transformations(
|
|
||||||
new Transformation(new Pattern('/^(bil)er$/i'), '\1'),
|
|
||||||
new Transformation(new Pattern('/^(inflec|contribu)tors$/i'), '\1ta')
|
|
||||||
),
|
|
||||||
new Patterns(new Pattern('singulars')),
|
|
||||||
new Substitutions(new Substitution(new Word('spins'), new Word('spinor')))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
->withPluralRules(
|
|
||||||
new Ruleset(
|
|
||||||
new Transformations(
|
|
||||||
new Transformation(new Pattern('^(bil)er$'), '\1'),
|
|
||||||
new Transformation(new Pattern('^(inflec|contribu)tors$'), '\1ta')
|
|
||||||
),
|
|
||||||
new Patterns(new Pattern('noflect'), new Pattern('abtuse')),
|
|
||||||
new Substitutions(
|
|
||||||
new Substitution(new Word('amaze'), new Word('amazable')),
|
|
||||||
new Substitution(new Word('phone'), new Word('phonezes'))
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
->build();
|
|
||||||
|
|
||||||
No operation inflector
|
|
||||||
----------------------
|
|
||||||
|
|
||||||
The ``Doctrine\Inflector\NoopWordInflector`` may be used to configure an inflector that doesn't perform any operation for
|
|
||||||
pluralization and/or singularization. If will simply return the input as output.
|
|
||||||
|
|
||||||
This is an implementation of the `Null Object design pattern <https://sourcemaking.com/design_patterns/null_object>`_.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Inflector;
|
|
||||||
use Doctrine\Inflector\NoopWordInflector;
|
|
||||||
|
|
||||||
$inflector = new Inflector(new NoopWordInflector(), new NoopWordInflector());
|
|
||||||
|
|
||||||
Tableize
|
|
||||||
========
|
|
||||||
|
|
||||||
Converts ``ModelName`` to ``model_name``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->tableize('ModelName'); // model_name
|
|
||||||
|
|
||||||
Classify
|
|
||||||
========
|
|
||||||
|
|
||||||
Converts ``model_name`` to ``ModelName``:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->classify('model_name'); // ModelName
|
|
||||||
|
|
||||||
Camelize
|
|
||||||
========
|
|
||||||
|
|
||||||
This method uses `Classify`_ and then converts the first character to lowercase:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->camelize('model_name'); // modelName
|
|
||||||
|
|
||||||
Capitalize
|
|
||||||
==========
|
|
||||||
|
|
||||||
Takes a string and capitalizes all of the words, like PHP's built-in
|
|
||||||
``ucwords`` function. This extends that behavior, however, by allowing the
|
|
||||||
word delimiters to be configured, rather than only separating on
|
|
||||||
whitespace.
|
|
||||||
|
|
||||||
Here is an example:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
$string = 'top-o-the-morning to all_of_you!';
|
|
||||||
|
|
||||||
echo $inflector->capitalize($string); // Top-O-The-Morning To All_of_you!
|
|
||||||
|
|
||||||
echo $inflector->capitalize($string, '-_ '); // Top-O-The-Morning To All_Of_You!
|
|
||||||
|
|
||||||
Pluralize
|
|
||||||
=========
|
|
||||||
|
|
||||||
Returns a word in plural form.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->pluralize('browser'); // browsers
|
|
||||||
|
|
||||||
Singularize
|
|
||||||
===========
|
|
||||||
|
|
||||||
Returns a word in singular form.
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->singularize('browsers'); // browser
|
|
||||||
|
|
||||||
Urlize
|
|
||||||
======
|
|
||||||
|
|
||||||
Generate a URL friendly string from a string of text:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->urlize('My first blog post'); // my-first-blog-post
|
|
||||||
|
|
||||||
Unaccent
|
|
||||||
========
|
|
||||||
|
|
||||||
You can unaccent a string of text using the ``unaccent()`` method:
|
|
||||||
|
|
||||||
.. code-block:: php
|
|
||||||
|
|
||||||
echo $inflector->unaccent('año'); // ano
|
|
||||||
|
|
||||||
Legacy API
|
|
||||||
==========
|
|
||||||
|
|
||||||
The API present in Inflector 1.x is still available, but will be deprecated in a future release and dropped for 3.0.
|
|
||||||
Support for languages other than English is available in the 2.0 API only.
|
|
||||||
|
|
||||||
Acknowledgements
|
|
||||||
================
|
|
||||||
|
|
||||||
The language rules in this library have been adapted from several different sources, including but not limited to:
|
|
||||||
|
|
||||||
- `Ruby On Rails Inflector <http://api.rubyonrails.org/classes/ActiveSupport/Inflector.html>`_
|
|
||||||
- `ICanBoogie Inflector <https://github.com/ICanBoogie/Inflector>`_
|
|
||||||
- `CakePHP Inflector <https://book.cakephp.org/3.0/en/core-libraries/inflector.html>`_
|
|
@ -1,24 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
class CachedWordInflector implements WordInflector
|
|
||||||
{
|
|
||||||
/** @var WordInflector */
|
|
||||||
private $wordInflector;
|
|
||||||
|
|
||||||
/** @var string[] */
|
|
||||||
private $cache = [];
|
|
||||||
|
|
||||||
public function __construct(WordInflector $wordInflector)
|
|
||||||
{
|
|
||||||
$this->wordInflector = $wordInflector;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
return $this->cache[$word] ?? $this->cache[$word] = $this->wordInflector->inflect($word);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
use function array_unshift;
|
|
||||||
|
|
||||||
abstract class GenericLanguageInflectorFactory implements LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
/** @var Ruleset[] */
|
|
||||||
private $singularRulesets = [];
|
|
||||||
|
|
||||||
/** @var Ruleset[] */
|
|
||||||
private $pluralRulesets = [];
|
|
||||||
|
|
||||||
final public function __construct()
|
|
||||||
{
|
|
||||||
$this->singularRulesets[] = $this->getSingularRuleset();
|
|
||||||
$this->pluralRulesets[] = $this->getPluralRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function build(): Inflector
|
|
||||||
{
|
|
||||||
return new Inflector(
|
|
||||||
new CachedWordInflector(new RulesetInflector(
|
|
||||||
...$this->singularRulesets
|
|
||||||
)),
|
|
||||||
new CachedWordInflector(new RulesetInflector(
|
|
||||||
...$this->pluralRulesets
|
|
||||||
))
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function withSingularRules(?Ruleset $singularRules, bool $reset = false): LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
if ($reset) {
|
|
||||||
$this->singularRulesets = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($singularRules instanceof Ruleset) {
|
|
||||||
array_unshift($this->singularRulesets, $singularRules);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
final public function withPluralRules(?Ruleset $pluralRules, bool $reset = false): LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
if ($reset) {
|
|
||||||
$this->pluralRulesets = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($pluralRules instanceof Ruleset) {
|
|
||||||
array_unshift($this->pluralRulesets, $pluralRules);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract protected function getSingularRuleset(): Ruleset;
|
|
||||||
|
|
||||||
abstract protected function getPluralRuleset(): Ruleset;
|
|
||||||
}
|
|
@ -1,507 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
use RuntimeException;
|
|
||||||
|
|
||||||
use function chr;
|
|
||||||
use function function_exists;
|
|
||||||
use function lcfirst;
|
|
||||||
use function mb_strtolower;
|
|
||||||
use function ord;
|
|
||||||
use function preg_match;
|
|
||||||
use function preg_replace;
|
|
||||||
use function sprintf;
|
|
||||||
use function str_replace;
|
|
||||||
use function strlen;
|
|
||||||
use function strtolower;
|
|
||||||
use function strtr;
|
|
||||||
use function trim;
|
|
||||||
use function ucwords;
|
|
||||||
|
|
||||||
class Inflector
|
|
||||||
{
|
|
||||||
private const ACCENTED_CHARACTERS = [
|
|
||||||
'À' => 'A',
|
|
||||||
'Á' => 'A',
|
|
||||||
'Â' => 'A',
|
|
||||||
'Ã' => 'A',
|
|
||||||
'Ä' => 'Ae',
|
|
||||||
'Æ' => 'Ae',
|
|
||||||
'Å' => 'Aa',
|
|
||||||
'æ' => 'a',
|
|
||||||
'Ç' => 'C',
|
|
||||||
'È' => 'E',
|
|
||||||
'É' => 'E',
|
|
||||||
'Ê' => 'E',
|
|
||||||
'Ë' => 'E',
|
|
||||||
'Ì' => 'I',
|
|
||||||
'Í' => 'I',
|
|
||||||
'Î' => 'I',
|
|
||||||
'Ï' => 'I',
|
|
||||||
'Ñ' => 'N',
|
|
||||||
'Ò' => 'O',
|
|
||||||
'Ó' => 'O',
|
|
||||||
'Ô' => 'O',
|
|
||||||
'Õ' => 'O',
|
|
||||||
'Ö' => 'Oe',
|
|
||||||
'Ù' => 'U',
|
|
||||||
'Ú' => 'U',
|
|
||||||
'Û' => 'U',
|
|
||||||
'Ü' => 'Ue',
|
|
||||||
'Ý' => 'Y',
|
|
||||||
'ß' => 'ss',
|
|
||||||
'à' => 'a',
|
|
||||||
'á' => 'a',
|
|
||||||
'â' => 'a',
|
|
||||||
'ã' => 'a',
|
|
||||||
'ä' => 'ae',
|
|
||||||
'å' => 'aa',
|
|
||||||
'ç' => 'c',
|
|
||||||
'è' => 'e',
|
|
||||||
'é' => 'e',
|
|
||||||
'ê' => 'e',
|
|
||||||
'ë' => 'e',
|
|
||||||
'ì' => 'i',
|
|
||||||
'í' => 'i',
|
|
||||||
'î' => 'i',
|
|
||||||
'ï' => 'i',
|
|
||||||
'ñ' => 'n',
|
|
||||||
'ò' => 'o',
|
|
||||||
'ó' => 'o',
|
|
||||||
'ô' => 'o',
|
|
||||||
'õ' => 'o',
|
|
||||||
'ö' => 'oe',
|
|
||||||
'ù' => 'u',
|
|
||||||
'ú' => 'u',
|
|
||||||
'û' => 'u',
|
|
||||||
'ü' => 'ue',
|
|
||||||
'ý' => 'y',
|
|
||||||
'ÿ' => 'y',
|
|
||||||
'Ā' => 'A',
|
|
||||||
'ā' => 'a',
|
|
||||||
'Ă' => 'A',
|
|
||||||
'ă' => 'a',
|
|
||||||
'Ą' => 'A',
|
|
||||||
'ą' => 'a',
|
|
||||||
'Ć' => 'C',
|
|
||||||
'ć' => 'c',
|
|
||||||
'Ĉ' => 'C',
|
|
||||||
'ĉ' => 'c',
|
|
||||||
'Ċ' => 'C',
|
|
||||||
'ċ' => 'c',
|
|
||||||
'Č' => 'C',
|
|
||||||
'č' => 'c',
|
|
||||||
'Ď' => 'D',
|
|
||||||
'ď' => 'd',
|
|
||||||
'Đ' => 'D',
|
|
||||||
'đ' => 'd',
|
|
||||||
'Ē' => 'E',
|
|
||||||
'ē' => 'e',
|
|
||||||
'Ĕ' => 'E',
|
|
||||||
'ĕ' => 'e',
|
|
||||||
'Ė' => 'E',
|
|
||||||
'ė' => 'e',
|
|
||||||
'Ę' => 'E',
|
|
||||||
'ę' => 'e',
|
|
||||||
'Ě' => 'E',
|
|
||||||
'ě' => 'e',
|
|
||||||
'Ĝ' => 'G',
|
|
||||||
'ĝ' => 'g',
|
|
||||||
'Ğ' => 'G',
|
|
||||||
'ğ' => 'g',
|
|
||||||
'Ġ' => 'G',
|
|
||||||
'ġ' => 'g',
|
|
||||||
'Ģ' => 'G',
|
|
||||||
'ģ' => 'g',
|
|
||||||
'Ĥ' => 'H',
|
|
||||||
'ĥ' => 'h',
|
|
||||||
'Ħ' => 'H',
|
|
||||||
'ħ' => 'h',
|
|
||||||
'Ĩ' => 'I',
|
|
||||||
'ĩ' => 'i',
|
|
||||||
'Ī' => 'I',
|
|
||||||
'ī' => 'i',
|
|
||||||
'Ĭ' => 'I',
|
|
||||||
'ĭ' => 'i',
|
|
||||||
'Į' => 'I',
|
|
||||||
'į' => 'i',
|
|
||||||
'İ' => 'I',
|
|
||||||
'ı' => 'i',
|
|
||||||
'IJ' => 'IJ',
|
|
||||||
'ij' => 'ij',
|
|
||||||
'Ĵ' => 'J',
|
|
||||||
'ĵ' => 'j',
|
|
||||||
'Ķ' => 'K',
|
|
||||||
'ķ' => 'k',
|
|
||||||
'ĸ' => 'k',
|
|
||||||
'Ĺ' => 'L',
|
|
||||||
'ĺ' => 'l',
|
|
||||||
'Ļ' => 'L',
|
|
||||||
'ļ' => 'l',
|
|
||||||
'Ľ' => 'L',
|
|
||||||
'ľ' => 'l',
|
|
||||||
'Ŀ' => 'L',
|
|
||||||
'ŀ' => 'l',
|
|
||||||
'Ł' => 'L',
|
|
||||||
'ł' => 'l',
|
|
||||||
'Ń' => 'N',
|
|
||||||
'ń' => 'n',
|
|
||||||
'Ņ' => 'N',
|
|
||||||
'ņ' => 'n',
|
|
||||||
'Ň' => 'N',
|
|
||||||
'ň' => 'n',
|
|
||||||
'ʼn' => 'N',
|
|
||||||
'Ŋ' => 'n',
|
|
||||||
'ŋ' => 'N',
|
|
||||||
'Ō' => 'O',
|
|
||||||
'ō' => 'o',
|
|
||||||
'Ŏ' => 'O',
|
|
||||||
'ŏ' => 'o',
|
|
||||||
'Ő' => 'O',
|
|
||||||
'ő' => 'o',
|
|
||||||
'Œ' => 'OE',
|
|
||||||
'œ' => 'oe',
|
|
||||||
'Ø' => 'O',
|
|
||||||
'ø' => 'o',
|
|
||||||
'Ŕ' => 'R',
|
|
||||||
'ŕ' => 'r',
|
|
||||||
'Ŗ' => 'R',
|
|
||||||
'ŗ' => 'r',
|
|
||||||
'Ř' => 'R',
|
|
||||||
'ř' => 'r',
|
|
||||||
'Ś' => 'S',
|
|
||||||
'ś' => 's',
|
|
||||||
'Ŝ' => 'S',
|
|
||||||
'ŝ' => 's',
|
|
||||||
'Ş' => 'S',
|
|
||||||
'ş' => 's',
|
|
||||||
'Š' => 'S',
|
|
||||||
'š' => 's',
|
|
||||||
'Ţ' => 'T',
|
|
||||||
'ţ' => 't',
|
|
||||||
'Ť' => 'T',
|
|
||||||
'ť' => 't',
|
|
||||||
'Ŧ' => 'T',
|
|
||||||
'ŧ' => 't',
|
|
||||||
'Ũ' => 'U',
|
|
||||||
'ũ' => 'u',
|
|
||||||
'Ū' => 'U',
|
|
||||||
'ū' => 'u',
|
|
||||||
'Ŭ' => 'U',
|
|
||||||
'ŭ' => 'u',
|
|
||||||
'Ů' => 'U',
|
|
||||||
'ů' => 'u',
|
|
||||||
'Ű' => 'U',
|
|
||||||
'ű' => 'u',
|
|
||||||
'Ų' => 'U',
|
|
||||||
'ų' => 'u',
|
|
||||||
'Ŵ' => 'W',
|
|
||||||
'ŵ' => 'w',
|
|
||||||
'Ŷ' => 'Y',
|
|
||||||
'ŷ' => 'y',
|
|
||||||
'Ÿ' => 'Y',
|
|
||||||
'Ź' => 'Z',
|
|
||||||
'ź' => 'z',
|
|
||||||
'Ż' => 'Z',
|
|
||||||
'ż' => 'z',
|
|
||||||
'Ž' => 'Z',
|
|
||||||
'ž' => 'z',
|
|
||||||
'ſ' => 's',
|
|
||||||
'€' => 'E',
|
|
||||||
'£' => '',
|
|
||||||
];
|
|
||||||
|
|
||||||
/** @var WordInflector */
|
|
||||||
private $singularizer;
|
|
||||||
|
|
||||||
/** @var WordInflector */
|
|
||||||
private $pluralizer;
|
|
||||||
|
|
||||||
public function __construct(WordInflector $singularizer, WordInflector $pluralizer)
|
|
||||||
{
|
|
||||||
$this->singularizer = $singularizer;
|
|
||||||
$this->pluralizer = $pluralizer;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a word into the format for a Doctrine table name. Converts 'ModelName' to 'model_name'.
|
|
||||||
*/
|
|
||||||
public function tableize(string $word): string
|
|
||||||
{
|
|
||||||
$tableized = preg_replace('~(?<=\\w)([A-Z])~u', '_$1', $word);
|
|
||||||
|
|
||||||
if ($tableized === null) {
|
|
||||||
throw new RuntimeException(sprintf(
|
|
||||||
'preg_replace returned null for value "%s"',
|
|
||||||
$word
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return mb_strtolower($tableized);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Converts a word into the format for a Doctrine class name. Converts 'table_name' to 'TableName'.
|
|
||||||
*/
|
|
||||||
public function classify(string $word): string
|
|
||||||
{
|
|
||||||
return str_replace([' ', '_', '-'], '', ucwords($word, ' _-'));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Camelizes a word. This uses the classify() method and turns the first character to lowercase.
|
|
||||||
*/
|
|
||||||
public function camelize(string $word): string
|
|
||||||
{
|
|
||||||
return lcfirst($this->classify($word));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Uppercases words with configurable delimiters between words.
|
|
||||||
*
|
|
||||||
* Takes a string and capitalizes all of the words, like PHP's built-in
|
|
||||||
* ucwords function. This extends that behavior, however, by allowing the
|
|
||||||
* word delimiters to be configured, rather than only separating on
|
|
||||||
* whitespace.
|
|
||||||
*
|
|
||||||
* Here is an example:
|
|
||||||
* <code>
|
|
||||||
* <?php
|
|
||||||
* $string = 'top-o-the-morning to all_of_you!';
|
|
||||||
* echo $inflector->capitalize($string);
|
|
||||||
* // Top-O-The-Morning To All_of_you!
|
|
||||||
*
|
|
||||||
* echo $inflector->capitalize($string, '-_ ');
|
|
||||||
* // Top-O-The-Morning To All_Of_You!
|
|
||||||
* ?>
|
|
||||||
* </code>
|
|
||||||
*
|
|
||||||
* @param string $string The string to operate on.
|
|
||||||
* @param string $delimiters A list of word separators.
|
|
||||||
*
|
|
||||||
* @return string The string with all delimiter-separated words capitalized.
|
|
||||||
*/
|
|
||||||
public function capitalize(string $string, string $delimiters = " \n\t\r\0\x0B-"): string
|
|
||||||
{
|
|
||||||
return ucwords($string, $delimiters);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the given string seems like it has utf8 characters in it.
|
|
||||||
*
|
|
||||||
* @param string $string The string to check for utf8 characters in.
|
|
||||||
*/
|
|
||||||
public function seemsUtf8(string $string): bool
|
|
||||||
{
|
|
||||||
for ($i = 0; $i < strlen($string); $i++) {
|
|
||||||
if (ord($string[$i]) < 0x80) {
|
|
||||||
continue; // 0bbbbbbb
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ord($string[$i]) & 0xE0) === 0xC0) {
|
|
||||||
$n = 1; // 110bbbbb
|
|
||||||
} elseif ((ord($string[$i]) & 0xF0) === 0xE0) {
|
|
||||||
$n = 2; // 1110bbbb
|
|
||||||
} elseif ((ord($string[$i]) & 0xF8) === 0xF0) {
|
|
||||||
$n = 3; // 11110bbb
|
|
||||||
} elseif ((ord($string[$i]) & 0xFC) === 0xF8) {
|
|
||||||
$n = 4; // 111110bb
|
|
||||||
} elseif ((ord($string[$i]) & 0xFE) === 0xFC) {
|
|
||||||
$n = 5; // 1111110b
|
|
||||||
} else {
|
|
||||||
return false; // Does not match any model
|
|
||||||
}
|
|
||||||
|
|
||||||
for ($j = 0; $j < $n; $j++) { // n bytes matching 10bbbbbb follow ?
|
|
||||||
if (++$i === strlen($string) || ((ord($string[$i]) & 0xC0) !== 0x80)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Remove any illegal characters, accents, etc.
|
|
||||||
*
|
|
||||||
* @param string $string String to unaccent
|
|
||||||
*
|
|
||||||
* @return string Unaccented string
|
|
||||||
*/
|
|
||||||
public function unaccent(string $string): string
|
|
||||||
{
|
|
||||||
if (preg_match('/[\x80-\xff]/', $string) === false) {
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($this->seemsUtf8($string)) {
|
|
||||||
$string = strtr($string, self::ACCENTED_CHARACTERS);
|
|
||||||
} else {
|
|
||||||
$characters = [];
|
|
||||||
|
|
||||||
// Assume ISO-8859-1 if not UTF-8
|
|
||||||
$characters['in'] =
|
|
||||||
chr(128)
|
|
||||||
. chr(131)
|
|
||||||
. chr(138)
|
|
||||||
. chr(142)
|
|
||||||
. chr(154)
|
|
||||||
. chr(158)
|
|
||||||
. chr(159)
|
|
||||||
. chr(162)
|
|
||||||
. chr(165)
|
|
||||||
. chr(181)
|
|
||||||
. chr(192)
|
|
||||||
. chr(193)
|
|
||||||
. chr(194)
|
|
||||||
. chr(195)
|
|
||||||
. chr(196)
|
|
||||||
. chr(197)
|
|
||||||
. chr(199)
|
|
||||||
. chr(200)
|
|
||||||
. chr(201)
|
|
||||||
. chr(202)
|
|
||||||
. chr(203)
|
|
||||||
. chr(204)
|
|
||||||
. chr(205)
|
|
||||||
. chr(206)
|
|
||||||
. chr(207)
|
|
||||||
. chr(209)
|
|
||||||
. chr(210)
|
|
||||||
. chr(211)
|
|
||||||
. chr(212)
|
|
||||||
. chr(213)
|
|
||||||
. chr(214)
|
|
||||||
. chr(216)
|
|
||||||
. chr(217)
|
|
||||||
. chr(218)
|
|
||||||
. chr(219)
|
|
||||||
. chr(220)
|
|
||||||
. chr(221)
|
|
||||||
. chr(224)
|
|
||||||
. chr(225)
|
|
||||||
. chr(226)
|
|
||||||
. chr(227)
|
|
||||||
. chr(228)
|
|
||||||
. chr(229)
|
|
||||||
. chr(231)
|
|
||||||
. chr(232)
|
|
||||||
. chr(233)
|
|
||||||
. chr(234)
|
|
||||||
. chr(235)
|
|
||||||
. chr(236)
|
|
||||||
. chr(237)
|
|
||||||
. chr(238)
|
|
||||||
. chr(239)
|
|
||||||
. chr(241)
|
|
||||||
. chr(242)
|
|
||||||
. chr(243)
|
|
||||||
. chr(244)
|
|
||||||
. chr(245)
|
|
||||||
. chr(246)
|
|
||||||
. chr(248)
|
|
||||||
. chr(249)
|
|
||||||
. chr(250)
|
|
||||||
. chr(251)
|
|
||||||
. chr(252)
|
|
||||||
. chr(253)
|
|
||||||
. chr(255);
|
|
||||||
|
|
||||||
$characters['out'] = 'EfSZszYcYuAAAAAACEEEEIIIINOOOOOOUUUUYaaaaaaceeeeiiiinoooooouuuuyy';
|
|
||||||
|
|
||||||
$string = strtr($string, $characters['in'], $characters['out']);
|
|
||||||
|
|
||||||
$doubleChars = [];
|
|
||||||
|
|
||||||
$doubleChars['in'] = [
|
|
||||||
chr(140),
|
|
||||||
chr(156),
|
|
||||||
chr(198),
|
|
||||||
chr(208),
|
|
||||||
chr(222),
|
|
||||||
chr(223),
|
|
||||||
chr(230),
|
|
||||||
chr(240),
|
|
||||||
chr(254),
|
|
||||||
];
|
|
||||||
|
|
||||||
$doubleChars['out'] = ['OE', 'oe', 'AE', 'DH', 'TH', 'ss', 'ae', 'dh', 'th'];
|
|
||||||
|
|
||||||
$string = str_replace($doubleChars['in'], $doubleChars['out'], $string);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $string;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Convert any passed string to a url friendly string.
|
|
||||||
* Converts 'My first blog post' to 'my-first-blog-post'
|
|
||||||
*
|
|
||||||
* @param string $string String to urlize.
|
|
||||||
*
|
|
||||||
* @return string Urlized string.
|
|
||||||
*/
|
|
||||||
public function urlize(string $string): string
|
|
||||||
{
|
|
||||||
// Remove all non url friendly characters with the unaccent function
|
|
||||||
$unaccented = $this->unaccent($string);
|
|
||||||
|
|
||||||
if (function_exists('mb_strtolower')) {
|
|
||||||
$lowered = mb_strtolower($unaccented);
|
|
||||||
} else {
|
|
||||||
$lowered = strtolower($unaccented);
|
|
||||||
}
|
|
||||||
|
|
||||||
$replacements = [
|
|
||||||
'/\W/' => ' ',
|
|
||||||
'/([A-Z]+)([A-Z][a-z])/' => '\1_\2',
|
|
||||||
'/([a-z\d])([A-Z])/' => '\1_\2',
|
|
||||||
'/[^A-Z^a-z^0-9^\/]+/' => '-',
|
|
||||||
];
|
|
||||||
|
|
||||||
$urlized = $lowered;
|
|
||||||
|
|
||||||
foreach ($replacements as $pattern => $replacement) {
|
|
||||||
$replaced = preg_replace($pattern, $replacement, $urlized);
|
|
||||||
|
|
||||||
if ($replaced === null) {
|
|
||||||
throw new RuntimeException(sprintf(
|
|
||||||
'preg_replace returned null for value "%s"',
|
|
||||||
$urlized
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
$urlized = $replaced;
|
|
||||||
}
|
|
||||||
|
|
||||||
return trim($urlized, '-');
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a word in singular form.
|
|
||||||
*
|
|
||||||
* @param string $word The word in plural form.
|
|
||||||
*
|
|
||||||
* @return string The word in singular form.
|
|
||||||
*/
|
|
||||||
public function singularize(string $word): string
|
|
||||||
{
|
|
||||||
return $this->singularizer->inflect($word);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a word in plural form.
|
|
||||||
*
|
|
||||||
* @param string $word The word in singular form.
|
|
||||||
*
|
|
||||||
* @return string The word in plural form.
|
|
||||||
*/
|
|
||||||
public function pluralize(string $word): string
|
|
||||||
{
|
|
||||||
return $this->pluralizer->inflect($word);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\English;
|
|
||||||
use Doctrine\Inflector\Rules\French;
|
|
||||||
use Doctrine\Inflector\Rules\NorwegianBokmal;
|
|
||||||
use Doctrine\Inflector\Rules\Portuguese;
|
|
||||||
use Doctrine\Inflector\Rules\Spanish;
|
|
||||||
use Doctrine\Inflector\Rules\Turkish;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
|
|
||||||
use function sprintf;
|
|
||||||
|
|
||||||
final class InflectorFactory
|
|
||||||
{
|
|
||||||
public static function create(): LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
return self::createForLanguage(Language::ENGLISH);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function createForLanguage(string $language): LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
switch ($language) {
|
|
||||||
case Language::ENGLISH:
|
|
||||||
return new English\InflectorFactory();
|
|
||||||
|
|
||||||
case Language::FRENCH:
|
|
||||||
return new French\InflectorFactory();
|
|
||||||
|
|
||||||
case Language::NORWEGIAN_BOKMAL:
|
|
||||||
return new NorwegianBokmal\InflectorFactory();
|
|
||||||
|
|
||||||
case Language::PORTUGUESE:
|
|
||||||
return new Portuguese\InflectorFactory();
|
|
||||||
|
|
||||||
case Language::SPANISH:
|
|
||||||
return new Spanish\InflectorFactory();
|
|
||||||
|
|
||||||
case Language::TURKISH:
|
|
||||||
return new Turkish\InflectorFactory();
|
|
||||||
|
|
||||||
default:
|
|
||||||
throw new InvalidArgumentException(sprintf(
|
|
||||||
'Language "%s" is not supported.',
|
|
||||||
$language
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
final class Language
|
|
||||||
{
|
|
||||||
public const ENGLISH = 'english';
|
|
||||||
public const FRENCH = 'french';
|
|
||||||
public const NORWEGIAN_BOKMAL = 'norwegian-bokmal';
|
|
||||||
public const PORTUGUESE = 'portuguese';
|
|
||||||
public const SPANISH = 'spanish';
|
|
||||||
public const TURKISH = 'turkish';
|
|
||||||
|
|
||||||
private function __construct()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
interface LanguageInflectorFactory
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Applies custom rules for singularisation
|
|
||||||
*
|
|
||||||
* @param bool $reset If true, will unset default inflections for all new rules
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function withSingularRules(?Ruleset $singularRules, bool $reset = false): self;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Applies custom rules for pluralisation
|
|
||||||
*
|
|
||||||
* @param bool $reset If true, will unset default inflections for all new rules
|
|
||||||
*
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function withPluralRules(?Ruleset $pluralRules, bool $reset = false): self;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Builds the inflector instance with all applicable rules
|
|
||||||
*/
|
|
||||||
public function build(): Inflector;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
class NoopWordInflector implements WordInflector
|
|
||||||
{
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,184 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\English;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('(s)tatuses$'), '\1\2tatus');
|
|
||||||
yield new Transformation(new Pattern('(s)tatus$'), '\1\2tatus');
|
|
||||||
yield new Transformation(new Pattern('(c)ampus$'), '\1\2ampus');
|
|
||||||
yield new Transformation(new Pattern('^(.*)(menu)s$'), '\1\2');
|
|
||||||
yield new Transformation(new Pattern('(quiz)zes$'), '\\1');
|
|
||||||
yield new Transformation(new Pattern('(matr)ices$'), '\1ix');
|
|
||||||
yield new Transformation(new Pattern('(vert|ind)ices$'), '\1ex');
|
|
||||||
yield new Transformation(new Pattern('^(ox)en'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(alias)(es)*$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)oes$'), '\1o');
|
|
||||||
yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|viri?)i$'), '\1us');
|
|
||||||
yield new Transformation(new Pattern('([ftw]ax)es'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(analys|ax|cris|test|thes)es$'), '\1is');
|
|
||||||
yield new Transformation(new Pattern('(shoe|slave)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(o)es$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('ouses$'), 'ouse');
|
|
||||||
yield new Transformation(new Pattern('([^a])uses$'), '\1us');
|
|
||||||
yield new Transformation(new Pattern('([m|l])ice$'), '\1ouse');
|
|
||||||
yield new Transformation(new Pattern('(x|ch|ss|sh)es$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(m)ovies$'), '\1\2ovie');
|
|
||||||
yield new Transformation(new Pattern('(s)eries$'), '\1\2eries');
|
|
||||||
yield new Transformation(new Pattern('([^aeiouy]|qu)ies$'), '\1y');
|
|
||||||
yield new Transformation(new Pattern('([lr])ves$'), '\1f');
|
|
||||||
yield new Transformation(new Pattern('(tive)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(hive)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(drive)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(dive)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('(olive)s$'), '\1');
|
|
||||||
yield new Transformation(new Pattern('([^fo])ves$'), '\1fe');
|
|
||||||
yield new Transformation(new Pattern('(^analy)ses$'), '\1sis');
|
|
||||||
yield new Transformation(new Pattern('(analy|diagno|^ba|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$'), '\1\2sis');
|
|
||||||
yield new Transformation(new Pattern('(tax)a$'), '\1on');
|
|
||||||
yield new Transformation(new Pattern('(c)riteria$'), '\1riterion');
|
|
||||||
yield new Transformation(new Pattern('([ti])a(?<!regatta)$'), '\1um');
|
|
||||||
yield new Transformation(new Pattern('(p)eople$'), '\1\2erson');
|
|
||||||
yield new Transformation(new Pattern('(m)en$'), '\1an');
|
|
||||||
yield new Transformation(new Pattern('(c)hildren$'), '\1\2hild');
|
|
||||||
yield new Transformation(new Pattern('(f)eet$'), '\1oot');
|
|
||||||
yield new Transformation(new Pattern('(n)ews$'), '\1\2ews');
|
|
||||||
yield new Transformation(new Pattern('eaus$'), 'eau');
|
|
||||||
yield new Transformation(new Pattern('^tights$'), 'tights');
|
|
||||||
yield new Transformation(new Pattern('^shorts$'), 'shorts');
|
|
||||||
yield new Transformation(new Pattern('s$'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('(s)tatus$'), '\1\2tatuses');
|
|
||||||
yield new Transformation(new Pattern('(quiz)$'), '\1zes');
|
|
||||||
yield new Transformation(new Pattern('^(ox)$'), '\1\2en');
|
|
||||||
yield new Transformation(new Pattern('([m|l])ouse$'), '\1ice');
|
|
||||||
yield new Transformation(new Pattern('(matr|vert|ind)(ix|ex)$'), '\1ices');
|
|
||||||
yield new Transformation(new Pattern('(x|ch|ss|sh)$'), '\1es');
|
|
||||||
yield new Transformation(new Pattern('([^aeiouy]|qu)y$'), '\1ies');
|
|
||||||
yield new Transformation(new Pattern('(hive|gulf)$'), '\1s');
|
|
||||||
yield new Transformation(new Pattern('(?:([^f])fe|([lr])f)$'), '\1\2ves');
|
|
||||||
yield new Transformation(new Pattern('sis$'), 'ses');
|
|
||||||
yield new Transformation(new Pattern('([ti])um$'), '\1a');
|
|
||||||
yield new Transformation(new Pattern('(tax)on$'), '\1a');
|
|
||||||
yield new Transformation(new Pattern('(c)riterion$'), '\1riteria');
|
|
||||||
yield new Transformation(new Pattern('(p)erson$'), '\1eople');
|
|
||||||
yield new Transformation(new Pattern('(m)an$'), '\1en');
|
|
||||||
yield new Transformation(new Pattern('(c)hild$'), '\1hildren');
|
|
||||||
yield new Transformation(new Pattern('(f)oot$'), '\1eet');
|
|
||||||
yield new Transformation(new Pattern('(buffal|her|potat|tomat|volcan)o$'), '\1\2oes');
|
|
||||||
yield new Transformation(new Pattern('(alumn|bacill|cact|foc|fung|nucle|radi|stimul|syllab|termin|vir)us$'), '\1i');
|
|
||||||
yield new Transformation(new Pattern('us$'), 'uses');
|
|
||||||
yield new Transformation(new Pattern('(alias)$'), '\1es');
|
|
||||||
yield new Transformation(new Pattern('(analys|ax|cris|test|thes)is$'), '\1es');
|
|
||||||
yield new Transformation(new Pattern('s$'), 's');
|
|
||||||
yield new Transformation(new Pattern('^$'), '');
|
|
||||||
yield new Transformation(new Pattern('$'), 's');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('atlas'), new Word('atlases'));
|
|
||||||
yield new Substitution(new Word('axis'), new Word('axes'));
|
|
||||||
yield new Substitution(new Word('axe'), new Word('axes'));
|
|
||||||
yield new Substitution(new Word('beef'), new Word('beefs'));
|
|
||||||
yield new Substitution(new Word('blouse'), new Word('blouses'));
|
|
||||||
yield new Substitution(new Word('brother'), new Word('brothers'));
|
|
||||||
yield new Substitution(new Word('cafe'), new Word('cafes'));
|
|
||||||
yield new Substitution(new Word('cave'), new Word('caves'));
|
|
||||||
yield new Substitution(new Word('chateau'), new Word('chateaux'));
|
|
||||||
yield new Substitution(new Word('niveau'), new Word('niveaux'));
|
|
||||||
yield new Substitution(new Word('child'), new Word('children'));
|
|
||||||
yield new Substitution(new Word('canvas'), new Word('canvases'));
|
|
||||||
yield new Substitution(new Word('cookie'), new Word('cookies'));
|
|
||||||
yield new Substitution(new Word('brownie'), new Word('brownies'));
|
|
||||||
yield new Substitution(new Word('corpus'), new Word('corpuses'));
|
|
||||||
yield new Substitution(new Word('cow'), new Word('cows'));
|
|
||||||
yield new Substitution(new Word('criterion'), new Word('criteria'));
|
|
||||||
yield new Substitution(new Word('curriculum'), new Word('curricula'));
|
|
||||||
yield new Substitution(new Word('demo'), new Word('demos'));
|
|
||||||
yield new Substitution(new Word('domino'), new Word('dominoes'));
|
|
||||||
yield new Substitution(new Word('echo'), new Word('echoes'));
|
|
||||||
yield new Substitution(new Word('epoch'), new Word('epochs'));
|
|
||||||
yield new Substitution(new Word('foot'), new Word('feet'));
|
|
||||||
yield new Substitution(new Word('fungus'), new Word('fungi'));
|
|
||||||
yield new Substitution(new Word('ganglion'), new Word('ganglions'));
|
|
||||||
yield new Substitution(new Word('gas'), new Word('gases'));
|
|
||||||
yield new Substitution(new Word('genie'), new Word('genies'));
|
|
||||||
yield new Substitution(new Word('genus'), new Word('genera'));
|
|
||||||
yield new Substitution(new Word('goose'), new Word('geese'));
|
|
||||||
yield new Substitution(new Word('graffito'), new Word('graffiti'));
|
|
||||||
yield new Substitution(new Word('hippopotamus'), new Word('hippopotami'));
|
|
||||||
yield new Substitution(new Word('hoof'), new Word('hoofs'));
|
|
||||||
yield new Substitution(new Word('human'), new Word('humans'));
|
|
||||||
yield new Substitution(new Word('iris'), new Word('irises'));
|
|
||||||
yield new Substitution(new Word('larva'), new Word('larvae'));
|
|
||||||
yield new Substitution(new Word('leaf'), new Word('leaves'));
|
|
||||||
yield new Substitution(new Word('lens'), new Word('lenses'));
|
|
||||||
yield new Substitution(new Word('loaf'), new Word('loaves'));
|
|
||||||
yield new Substitution(new Word('man'), new Word('men'));
|
|
||||||
yield new Substitution(new Word('medium'), new Word('media'));
|
|
||||||
yield new Substitution(new Word('memorandum'), new Word('memoranda'));
|
|
||||||
yield new Substitution(new Word('money'), new Word('monies'));
|
|
||||||
yield new Substitution(new Word('mongoose'), new Word('mongooses'));
|
|
||||||
yield new Substitution(new Word('motto'), new Word('mottoes'));
|
|
||||||
yield new Substitution(new Word('move'), new Word('moves'));
|
|
||||||
yield new Substitution(new Word('mythos'), new Word('mythoi'));
|
|
||||||
yield new Substitution(new Word('niche'), new Word('niches'));
|
|
||||||
yield new Substitution(new Word('nucleus'), new Word('nuclei'));
|
|
||||||
yield new Substitution(new Word('numen'), new Word('numina'));
|
|
||||||
yield new Substitution(new Word('occiput'), new Word('occiputs'));
|
|
||||||
yield new Substitution(new Word('octopus'), new Word('octopuses'));
|
|
||||||
yield new Substitution(new Word('opus'), new Word('opuses'));
|
|
||||||
yield new Substitution(new Word('ox'), new Word('oxen'));
|
|
||||||
yield new Substitution(new Word('passerby'), new Word('passersby'));
|
|
||||||
yield new Substitution(new Word('penis'), new Word('penises'));
|
|
||||||
yield new Substitution(new Word('person'), new Word('people'));
|
|
||||||
yield new Substitution(new Word('plateau'), new Word('plateaux'));
|
|
||||||
yield new Substitution(new Word('runner-up'), new Word('runners-up'));
|
|
||||||
yield new Substitution(new Word('safe'), new Word('safes'));
|
|
||||||
yield new Substitution(new Word('sex'), new Word('sexes'));
|
|
||||||
yield new Substitution(new Word('sieve'), new Word('sieves'));
|
|
||||||
yield new Substitution(new Word('soliloquy'), new Word('soliloquies'));
|
|
||||||
yield new Substitution(new Word('son-in-law'), new Word('sons-in-law'));
|
|
||||||
yield new Substitution(new Word('syllabus'), new Word('syllabi'));
|
|
||||||
yield new Substitution(new Word('testis'), new Word('testes'));
|
|
||||||
yield new Substitution(new Word('thief'), new Word('thieves'));
|
|
||||||
yield new Substitution(new Word('tooth'), new Word('teeth'));
|
|
||||||
yield new Substitution(new Word('tornado'), new Word('tornadoes'));
|
|
||||||
yield new Substitution(new Word('trilby'), new Word('trilbys'));
|
|
||||||
yield new Substitution(new Word('turf'), new Word('turfs'));
|
|
||||||
yield new Substitution(new Word('valve'), new Word('valves'));
|
|
||||||
yield new Substitution(new Word('volcano'), new Word('volcanoes'));
|
|
||||||
yield new Substitution(new Word('abuse'), new Word('abuses'));
|
|
||||||
yield new Substitution(new Word('avalanche'), new Word('avalanches'));
|
|
||||||
yield new Substitution(new Word('cache'), new Word('caches'));
|
|
||||||
yield new Substitution(new Word('criterion'), new Word('criteria'));
|
|
||||||
yield new Substitution(new Word('curve'), new Word('curves'));
|
|
||||||
yield new Substitution(new Word('emphasis'), new Word('emphases'));
|
|
||||||
yield new Substitution(new Word('foe'), new Word('foes'));
|
|
||||||
yield new Substitution(new Word('grave'), new Word('graves'));
|
|
||||||
yield new Substitution(new Word('hoax'), new Word('hoaxes'));
|
|
||||||
yield new Substitution(new Word('medium'), new Word('media'));
|
|
||||||
yield new Substitution(new Word('neurosis'), new Word('neuroses'));
|
|
||||||
yield new Substitution(new Word('save'), new Word('saves'));
|
|
||||||
yield new Substitution(new Word('wave'), new Word('waves'));
|
|
||||||
yield new Substitution(new Word('oasis'), new Word('oases'));
|
|
||||||
yield new Substitution(new Word('valve'), new Word('valves'));
|
|
||||||
yield new Substitution(new Word('zombie'), new Word('zombies'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\English;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\English;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,189 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\English;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
|
|
||||||
yield new Pattern('.*ss');
|
|
||||||
yield new Pattern('clothes');
|
|
||||||
yield new Pattern('data');
|
|
||||||
yield new Pattern('fascia');
|
|
||||||
yield new Pattern('fuchsia');
|
|
||||||
yield new Pattern('galleria');
|
|
||||||
yield new Pattern('mafia');
|
|
||||||
yield new Pattern('militia');
|
|
||||||
yield new Pattern('pants');
|
|
||||||
yield new Pattern('petunia');
|
|
||||||
yield new Pattern('sepia');
|
|
||||||
yield new Pattern('trivia');
|
|
||||||
yield new Pattern('utopia');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
|
|
||||||
yield new Pattern('people');
|
|
||||||
yield new Pattern('trivia');
|
|
||||||
yield new Pattern('\w+ware$');
|
|
||||||
yield new Pattern('media');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('\w+media');
|
|
||||||
yield new Pattern('advice');
|
|
||||||
yield new Pattern('aircraft');
|
|
||||||
yield new Pattern('amoyese');
|
|
||||||
yield new Pattern('art');
|
|
||||||
yield new Pattern('audio');
|
|
||||||
yield new Pattern('baggage');
|
|
||||||
yield new Pattern('bison');
|
|
||||||
yield new Pattern('borghese');
|
|
||||||
yield new Pattern('bream');
|
|
||||||
yield new Pattern('breeches');
|
|
||||||
yield new Pattern('britches');
|
|
||||||
yield new Pattern('buffalo');
|
|
||||||
yield new Pattern('butter');
|
|
||||||
yield new Pattern('cantus');
|
|
||||||
yield new Pattern('carp');
|
|
||||||
yield new Pattern('cattle');
|
|
||||||
yield new Pattern('chassis');
|
|
||||||
yield new Pattern('clippers');
|
|
||||||
yield new Pattern('clothing');
|
|
||||||
yield new Pattern('coal');
|
|
||||||
yield new Pattern('cod');
|
|
||||||
yield new Pattern('coitus');
|
|
||||||
yield new Pattern('compensation');
|
|
||||||
yield new Pattern('congoese');
|
|
||||||
yield new Pattern('contretemps');
|
|
||||||
yield new Pattern('coreopsis');
|
|
||||||
yield new Pattern('corps');
|
|
||||||
yield new Pattern('cotton');
|
|
||||||
yield new Pattern('data');
|
|
||||||
yield new Pattern('debris');
|
|
||||||
yield new Pattern('deer');
|
|
||||||
yield new Pattern('diabetes');
|
|
||||||
yield new Pattern('djinn');
|
|
||||||
yield new Pattern('education');
|
|
||||||
yield new Pattern('eland');
|
|
||||||
yield new Pattern('elk');
|
|
||||||
yield new Pattern('emoji');
|
|
||||||
yield new Pattern('equipment');
|
|
||||||
yield new Pattern('evidence');
|
|
||||||
yield new Pattern('faroese');
|
|
||||||
yield new Pattern('feedback');
|
|
||||||
yield new Pattern('fish');
|
|
||||||
yield new Pattern('flounder');
|
|
||||||
yield new Pattern('flour');
|
|
||||||
yield new Pattern('foochowese');
|
|
||||||
yield new Pattern('food');
|
|
||||||
yield new Pattern('furniture');
|
|
||||||
yield new Pattern('gallows');
|
|
||||||
yield new Pattern('genevese');
|
|
||||||
yield new Pattern('genoese');
|
|
||||||
yield new Pattern('gilbertese');
|
|
||||||
yield new Pattern('gold');
|
|
||||||
yield new Pattern('headquarters');
|
|
||||||
yield new Pattern('herpes');
|
|
||||||
yield new Pattern('hijinks');
|
|
||||||
yield new Pattern('homework');
|
|
||||||
yield new Pattern('hottentotese');
|
|
||||||
yield new Pattern('impatience');
|
|
||||||
yield new Pattern('information');
|
|
||||||
yield new Pattern('innings');
|
|
||||||
yield new Pattern('jackanapes');
|
|
||||||
yield new Pattern('jeans');
|
|
||||||
yield new Pattern('jedi');
|
|
||||||
yield new Pattern('kin');
|
|
||||||
yield new Pattern('kiplingese');
|
|
||||||
yield new Pattern('knowledge');
|
|
||||||
yield new Pattern('kongoese');
|
|
||||||
yield new Pattern('leather');
|
|
||||||
yield new Pattern('love');
|
|
||||||
yield new Pattern('lucchese');
|
|
||||||
yield new Pattern('luggage');
|
|
||||||
yield new Pattern('mackerel');
|
|
||||||
yield new Pattern('Maltese');
|
|
||||||
yield new Pattern('management');
|
|
||||||
yield new Pattern('metadata');
|
|
||||||
yield new Pattern('mews');
|
|
||||||
yield new Pattern('money');
|
|
||||||
yield new Pattern('moose');
|
|
||||||
yield new Pattern('mumps');
|
|
||||||
yield new Pattern('music');
|
|
||||||
yield new Pattern('nankingese');
|
|
||||||
yield new Pattern('news');
|
|
||||||
yield new Pattern('nexus');
|
|
||||||
yield new Pattern('niasese');
|
|
||||||
yield new Pattern('nutrition');
|
|
||||||
yield new Pattern('offspring');
|
|
||||||
yield new Pattern('oil');
|
|
||||||
yield new Pattern('patience');
|
|
||||||
yield new Pattern('pekingese');
|
|
||||||
yield new Pattern('piedmontese');
|
|
||||||
yield new Pattern('pincers');
|
|
||||||
yield new Pattern('pistoiese');
|
|
||||||
yield new Pattern('plankton');
|
|
||||||
yield new Pattern('pliers');
|
|
||||||
yield new Pattern('pokemon');
|
|
||||||
yield new Pattern('police');
|
|
||||||
yield new Pattern('polish');
|
|
||||||
yield new Pattern('portuguese');
|
|
||||||
yield new Pattern('proceedings');
|
|
||||||
yield new Pattern('progress');
|
|
||||||
yield new Pattern('rabies');
|
|
||||||
yield new Pattern('rain');
|
|
||||||
yield new Pattern('research');
|
|
||||||
yield new Pattern('rhinoceros');
|
|
||||||
yield new Pattern('rice');
|
|
||||||
yield new Pattern('salmon');
|
|
||||||
yield new Pattern('sand');
|
|
||||||
yield new Pattern('sarawakese');
|
|
||||||
yield new Pattern('scissors');
|
|
||||||
yield new Pattern('sea[- ]bass');
|
|
||||||
yield new Pattern('series');
|
|
||||||
yield new Pattern('shavese');
|
|
||||||
yield new Pattern('shears');
|
|
||||||
yield new Pattern('sheep');
|
|
||||||
yield new Pattern('siemens');
|
|
||||||
yield new Pattern('silk');
|
|
||||||
yield new Pattern('sms');
|
|
||||||
yield new Pattern('soap');
|
|
||||||
yield new Pattern('social media');
|
|
||||||
yield new Pattern('spam');
|
|
||||||
yield new Pattern('species');
|
|
||||||
yield new Pattern('staff');
|
|
||||||
yield new Pattern('sugar');
|
|
||||||
yield new Pattern('swine');
|
|
||||||
yield new Pattern('talent');
|
|
||||||
yield new Pattern('toothpaste');
|
|
||||||
yield new Pattern('traffic');
|
|
||||||
yield new Pattern('travel');
|
|
||||||
yield new Pattern('trousers');
|
|
||||||
yield new Pattern('trout');
|
|
||||||
yield new Pattern('tuna');
|
|
||||||
yield new Pattern('us');
|
|
||||||
yield new Pattern('vermontese');
|
|
||||||
yield new Pattern('vinegar');
|
|
||||||
yield new Pattern('weather');
|
|
||||||
yield new Pattern('wenchowese');
|
|
||||||
yield new Pattern('wheat');
|
|
||||||
yield new Pattern('whiting');
|
|
||||||
yield new Pattern('wildebeest');
|
|
||||||
yield new Pattern('wood');
|
|
||||||
yield new Pattern('wool');
|
|
||||||
yield new Pattern('yengeese');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\French;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)aux$/'), '\1ail');
|
|
||||||
yield new Transformation(new Pattern('/ails$/'), 'ail');
|
|
||||||
yield new Transformation(new Pattern('/(journ|chev)aux$/'), '\1al');
|
|
||||||
yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|pou|au|eu|eau)x$/'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/s$/'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/(s|x|z)$/'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/(b|cor|ém|gemm|soupir|trav|vant|vitr)ail$/'), '\1aux');
|
|
||||||
yield new Transformation(new Pattern('/ail$/'), 'ails');
|
|
||||||
yield new Transformation(new Pattern('/(chacal|carnaval|festival|récital)$/'), '\1s');
|
|
||||||
yield new Transformation(new Pattern('/al$/'), 'aux');
|
|
||||||
yield new Transformation(new Pattern('/(bleu|émeu|landau|pneu|sarrau)$/'), '\1s');
|
|
||||||
yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|lieu|pou|au|eu|eau)$/'), '\1x');
|
|
||||||
yield new Transformation(new Pattern('/$/'), 's');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('monsieur'), new Word('messieurs'));
|
|
||||||
yield new Substitution(new Word('madame'), new Word('mesdames'));
|
|
||||||
yield new Substitution(new Word('mademoiselle'), new Word('mesdemoiselles'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\French;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\French;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\French;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\NorwegianBokmal;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/re$/i'), 'r');
|
|
||||||
yield new Transformation(new Pattern('/er$/i'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/e$/i'), 'er');
|
|
||||||
yield new Transformation(new Pattern('/r$/i'), 're');
|
|
||||||
yield new Transformation(new Pattern('/$/'), 'er');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('konto'), new Word('konti'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\NorwegianBokmal;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\NorwegianBokmal;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\NorwegianBokmal;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('barn');
|
|
||||||
yield new Pattern('fjell');
|
|
||||||
yield new Pattern('hus');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,42 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
use function preg_match;
|
|
||||||
|
|
||||||
final class Pattern
|
|
||||||
{
|
|
||||||
/** @var string */
|
|
||||||
private $pattern;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $regex;
|
|
||||||
|
|
||||||
public function __construct(string $pattern)
|
|
||||||
{
|
|
||||||
$this->pattern = $pattern;
|
|
||||||
|
|
||||||
if (isset($this->pattern[0]) && $this->pattern[0] === '/') {
|
|
||||||
$this->regex = $this->pattern;
|
|
||||||
} else {
|
|
||||||
$this->regex = '/' . $this->pattern . '/i';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPattern(): string
|
|
||||||
{
|
|
||||||
return $this->pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRegex(): string
|
|
||||||
{
|
|
||||||
return $this->regex;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function matches(string $word): bool
|
|
||||||
{
|
|
||||||
return preg_match($this->getRegex(), $word) === 1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
use function array_map;
|
|
||||||
use function implode;
|
|
||||||
use function preg_match;
|
|
||||||
|
|
||||||
class Patterns
|
|
||||||
{
|
|
||||||
/** @var Pattern[] */
|
|
||||||
private $patterns;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $regex;
|
|
||||||
|
|
||||||
public function __construct(Pattern ...$patterns)
|
|
||||||
{
|
|
||||||
$this->patterns = $patterns;
|
|
||||||
|
|
||||||
$patterns = array_map(static function (Pattern $pattern): string {
|
|
||||||
return $pattern->getPattern();
|
|
||||||
}, $this->patterns);
|
|
||||||
|
|
||||||
$this->regex = '/^(?:' . implode('|', $patterns) . ')$/i';
|
|
||||||
}
|
|
||||||
|
|
||||||
public function matches(string $word): bool
|
|
||||||
{
|
|
||||||
return preg_match($this->regex, $word, $regs) === 1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Portuguese;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/^(g|)ases$/i'), '\1ás');
|
|
||||||
yield new Transformation(new Pattern('/(japon|escoc|ingl|dinamarqu|fregu|portugu)eses$/i'), '\1ês');
|
|
||||||
yield new Transformation(new Pattern('/(ae|ao|oe)s$/'), 'ao');
|
|
||||||
yield new Transformation(new Pattern('/(ãe|ão|õe)s$/'), 'ão');
|
|
||||||
yield new Transformation(new Pattern('/^(.*[^s]s)es$/i'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/sses$/i'), 'sse');
|
|
||||||
yield new Transformation(new Pattern('/ns$/i'), 'm');
|
|
||||||
yield new Transformation(new Pattern('/(r|t|f|v)is$/i'), '\1il');
|
|
||||||
yield new Transformation(new Pattern('/uis$/i'), 'ul');
|
|
||||||
yield new Transformation(new Pattern('/ois$/i'), 'ol');
|
|
||||||
yield new Transformation(new Pattern('/eis$/i'), 'ei');
|
|
||||||
yield new Transformation(new Pattern('/éis$/i'), 'el');
|
|
||||||
yield new Transformation(new Pattern('/([^p])ais$/i'), '\1al');
|
|
||||||
yield new Transformation(new Pattern('/(r|z)es$/i'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/^(á|gá)s$/i'), '\1s');
|
|
||||||
yield new Transformation(new Pattern('/([^ê])s$/i'), '\1');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/^(alem|c|p)ao$/i'), '\1aes');
|
|
||||||
yield new Transformation(new Pattern('/^(irm|m)ao$/i'), '\1aos');
|
|
||||||
yield new Transformation(new Pattern('/ao$/i'), 'oes');
|
|
||||||
yield new Transformation(new Pattern('/^(alem|c|p)ão$/i'), '\1ães');
|
|
||||||
yield new Transformation(new Pattern('/^(irm|m)ão$/i'), '\1ãos');
|
|
||||||
yield new Transformation(new Pattern('/ão$/i'), 'ões');
|
|
||||||
yield new Transformation(new Pattern('/^(|g)ás$/i'), '\1ases');
|
|
||||||
yield new Transformation(new Pattern('/^(japon|escoc|ingl|dinamarqu|fregu|portugu)ês$/i'), '\1eses');
|
|
||||||
yield new Transformation(new Pattern('/m$/i'), 'ns');
|
|
||||||
yield new Transformation(new Pattern('/([^aeou])il$/i'), '\1is');
|
|
||||||
yield new Transformation(new Pattern('/ul$/i'), 'uis');
|
|
||||||
yield new Transformation(new Pattern('/ol$/i'), 'ois');
|
|
||||||
yield new Transformation(new Pattern('/el$/i'), 'eis');
|
|
||||||
yield new Transformation(new Pattern('/al$/i'), 'ais');
|
|
||||||
yield new Transformation(new Pattern('/(z|r)$/i'), '\1es');
|
|
||||||
yield new Transformation(new Pattern('/(s)$/i'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/$/'), 's');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('abdomen'), new Word('abdomens'));
|
|
||||||
yield new Substitution(new Word('alemão'), new Word('alemães'));
|
|
||||||
yield new Substitution(new Word('artesã'), new Word('artesãos'));
|
|
||||||
yield new Substitution(new Word('álcool'), new Word('álcoois'));
|
|
||||||
yield new Substitution(new Word('árvore'), new Word('árvores'));
|
|
||||||
yield new Substitution(new Word('bencão'), new Word('bencãos'));
|
|
||||||
yield new Substitution(new Word('cão'), new Word('cães'));
|
|
||||||
yield new Substitution(new Word('campus'), new Word('campi'));
|
|
||||||
yield new Substitution(new Word('cadáver'), new Word('cadáveres'));
|
|
||||||
yield new Substitution(new Word('capelão'), new Word('capelães'));
|
|
||||||
yield new Substitution(new Word('capitão'), new Word('capitães'));
|
|
||||||
yield new Substitution(new Word('chão'), new Word('chãos'));
|
|
||||||
yield new Substitution(new Word('charlatão'), new Word('charlatães'));
|
|
||||||
yield new Substitution(new Word('cidadão'), new Word('cidadãos'));
|
|
||||||
yield new Substitution(new Word('consul'), new Word('consules'));
|
|
||||||
yield new Substitution(new Word('cristão'), new Word('cristãos'));
|
|
||||||
yield new Substitution(new Word('difícil'), new Word('difíceis'));
|
|
||||||
yield new Substitution(new Word('email'), new Word('emails'));
|
|
||||||
yield new Substitution(new Word('escrivão'), new Word('escrivães'));
|
|
||||||
yield new Substitution(new Word('fóssil'), new Word('fósseis'));
|
|
||||||
yield new Substitution(new Word('gás'), new Word('gases'));
|
|
||||||
yield new Substitution(new Word('germens'), new Word('germen'));
|
|
||||||
yield new Substitution(new Word('grão'), new Word('grãos'));
|
|
||||||
yield new Substitution(new Word('hífen'), new Word('hífens'));
|
|
||||||
yield new Substitution(new Word('irmão'), new Word('irmãos'));
|
|
||||||
yield new Substitution(new Word('liquens'), new Word('liquen'));
|
|
||||||
yield new Substitution(new Word('mal'), new Word('males'));
|
|
||||||
yield new Substitution(new Word('mão'), new Word('mãos'));
|
|
||||||
yield new Substitution(new Word('orfão'), new Word('orfãos'));
|
|
||||||
yield new Substitution(new Word('país'), new Word('países'));
|
|
||||||
yield new Substitution(new Word('pai'), new Word('pais'));
|
|
||||||
yield new Substitution(new Word('pão'), new Word('pães'));
|
|
||||||
yield new Substitution(new Word('projétil'), new Word('projéteis'));
|
|
||||||
yield new Substitution(new Word('réptil'), new Word('répteis'));
|
|
||||||
yield new Substitution(new Word('sacristão'), new Word('sacristães'));
|
|
||||||
yield new Substitution(new Word('sotão'), new Word('sotãos'));
|
|
||||||
yield new Substitution(new Word('tabelião'), new Word('tabeliães'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Portuguese;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Portuguese;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Portuguese;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('tórax');
|
|
||||||
yield new Pattern('tênis');
|
|
||||||
yield new Pattern('ônibus');
|
|
||||||
yield new Pattern('lápis');
|
|
||||||
yield new Pattern('fênix');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
class Ruleset
|
|
||||||
{
|
|
||||||
/** @var Transformations */
|
|
||||||
private $regular;
|
|
||||||
|
|
||||||
/** @var Patterns */
|
|
||||||
private $uninflected;
|
|
||||||
|
|
||||||
/** @var Substitutions */
|
|
||||||
private $irregular;
|
|
||||||
|
|
||||||
public function __construct(Transformations $regular, Patterns $uninflected, Substitutions $irregular)
|
|
||||||
{
|
|
||||||
$this->regular = $regular;
|
|
||||||
$this->uninflected = $uninflected;
|
|
||||||
$this->irregular = $irregular;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getRegular(): Transformations
|
|
||||||
{
|
|
||||||
return $this->regular;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getUninflected(): Patterns
|
|
||||||
{
|
|
||||||
return $this->uninflected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getIrregular(): Substitutions
|
|
||||||
{
|
|
||||||
return $this->irregular;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Spanish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/ereses$/'), 'erés');
|
|
||||||
yield new Transformation(new Pattern('/iones$/'), 'ión');
|
|
||||||
yield new Transformation(new Pattern('/ces$/'), 'z');
|
|
||||||
yield new Transformation(new Pattern('/es$/'), '');
|
|
||||||
yield new Transformation(new Pattern('/s$/'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/ú([sn])$/i'), 'u\1es');
|
|
||||||
yield new Transformation(new Pattern('/ó([sn])$/i'), 'o\1es');
|
|
||||||
yield new Transformation(new Pattern('/í([sn])$/i'), 'i\1es');
|
|
||||||
yield new Transformation(new Pattern('/é([sn])$/i'), 'e\1es');
|
|
||||||
yield new Transformation(new Pattern('/á([sn])$/i'), 'a\1es');
|
|
||||||
yield new Transformation(new Pattern('/z$/i'), 'ces');
|
|
||||||
yield new Transformation(new Pattern('/([aeiou]s)$/i'), '\1');
|
|
||||||
yield new Transformation(new Pattern('/([^aeéiou])$/i'), '\1es');
|
|
||||||
yield new Transformation(new Pattern('/$/'), 's');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('el'), new Word('los'));
|
|
||||||
yield new Substitution(new Word('papá'), new Word('papás'));
|
|
||||||
yield new Substitution(new Word('mamá'), new Word('mamás'));
|
|
||||||
yield new Substitution(new Word('sofá'), new Word('sofás'));
|
|
||||||
yield new Substitution(new Word('mes'), new Word('meses'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Spanish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Spanish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Spanish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('lunes');
|
|
||||||
yield new Pattern('rompecabezas');
|
|
||||||
yield new Pattern('crisis');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
final class Substitution
|
|
||||||
{
|
|
||||||
/** @var Word */
|
|
||||||
private $from;
|
|
||||||
|
|
||||||
/** @var Word */
|
|
||||||
private $to;
|
|
||||||
|
|
||||||
public function __construct(Word $from, Word $to)
|
|
||||||
{
|
|
||||||
$this->from = $from;
|
|
||||||
$this->to = $to;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFrom(): Word
|
|
||||||
{
|
|
||||||
return $this->from;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getTo(): Word
|
|
||||||
{
|
|
||||||
return $this->to;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,57 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\WordInflector;
|
|
||||||
|
|
||||||
use function strtolower;
|
|
||||||
use function strtoupper;
|
|
||||||
use function substr;
|
|
||||||
|
|
||||||
class Substitutions implements WordInflector
|
|
||||||
{
|
|
||||||
/** @var Substitution[] */
|
|
||||||
private $substitutions;
|
|
||||||
|
|
||||||
public function __construct(Substitution ...$substitutions)
|
|
||||||
{
|
|
||||||
foreach ($substitutions as $substitution) {
|
|
||||||
$this->substitutions[$substitution->getFrom()->getWord()] = $substitution;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getFlippedSubstitutions(): Substitutions
|
|
||||||
{
|
|
||||||
$substitutions = [];
|
|
||||||
|
|
||||||
foreach ($this->substitutions as $substitution) {
|
|
||||||
$substitutions[] = new Substitution(
|
|
||||||
$substitution->getTo(),
|
|
||||||
$substitution->getFrom()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new Substitutions(...$substitutions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
$lowerWord = strtolower($word);
|
|
||||||
|
|
||||||
if (isset($this->substitutions[$lowerWord])) {
|
|
||||||
$firstLetterUppercase = $lowerWord[0] !== $word[0];
|
|
||||||
|
|
||||||
$toWord = $this->substitutions[$lowerWord]->getTo()->getWord();
|
|
||||||
|
|
||||||
if ($firstLetterUppercase) {
|
|
||||||
return strtoupper($toWord[0]) . substr($toWord, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $toWord;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,39 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\WordInflector;
|
|
||||||
|
|
||||||
use function preg_replace;
|
|
||||||
|
|
||||||
final class Transformation implements WordInflector
|
|
||||||
{
|
|
||||||
/** @var Pattern */
|
|
||||||
private $pattern;
|
|
||||||
|
|
||||||
/** @var string */
|
|
||||||
private $replacement;
|
|
||||||
|
|
||||||
public function __construct(Pattern $pattern, string $replacement)
|
|
||||||
{
|
|
||||||
$this->pattern = $pattern;
|
|
||||||
$this->replacement = $replacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getPattern(): Pattern
|
|
||||||
{
|
|
||||||
return $this->pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getReplacement(): string
|
|
||||||
{
|
|
||||||
return $this->replacement;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
return (string) preg_replace($this->pattern->getRegex(), $this->replacement, $word);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\WordInflector;
|
|
||||||
|
|
||||||
class Transformations implements WordInflector
|
|
||||||
{
|
|
||||||
/** @var Transformation[] */
|
|
||||||
private $transformations;
|
|
||||||
|
|
||||||
public function __construct(Transformation ...$transformations)
|
|
||||||
{
|
|
||||||
$this->transformations = $transformations;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
foreach ($this->transformations as $transformation) {
|
|
||||||
if ($transformation->getPattern()->matches($word)) {
|
|
||||||
return $transformation->inflect($word);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,34 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Turkish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
use Doctrine\Inflector\Rules\Substitution;
|
|
||||||
use Doctrine\Inflector\Rules\Transformation;
|
|
||||||
use Doctrine\Inflector\Rules\Word;
|
|
||||||
|
|
||||||
class Inflectible
|
|
||||||
{
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/l[ae]r$/i'), '');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Transformation[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield new Transformation(new Pattern('/([eöiü][^aoıueöiü]{0,6})$/u'), '\1ler');
|
|
||||||
yield new Transformation(new Pattern('/([aoıu][^aoıueöiü]{0,6})$/u'), '\1lar');
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Substitution[] */
|
|
||||||
public static function getIrregular(): iterable
|
|
||||||
{
|
|
||||||
yield new Substitution(new Word('ben'), new Word('biz'));
|
|
||||||
yield new Substitution(new Word('sen'), new Word('siz'));
|
|
||||||
yield new Substitution(new Word('o'), new Word('onlar'));
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Turkish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\GenericLanguageInflectorFactory;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
final class InflectorFactory extends GenericLanguageInflectorFactory
|
|
||||||
{
|
|
||||||
protected function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getSingularRuleset();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return Rules::getPluralRuleset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Turkish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Patterns;
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
use Doctrine\Inflector\Rules\Substitutions;
|
|
||||||
use Doctrine\Inflector\Rules\Transformations;
|
|
||||||
|
|
||||||
final class Rules
|
|
||||||
{
|
|
||||||
public static function getSingularRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getSingular()),
|
|
||||||
new Patterns(...Uninflected::getSingular()),
|
|
||||||
(new Substitutions(...Inflectible::getIrregular()))->getFlippedSubstitutions()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static function getPluralRuleset(): Ruleset
|
|
||||||
{
|
|
||||||
return new Ruleset(
|
|
||||||
new Transformations(...Inflectible::getPlural()),
|
|
||||||
new Patterns(...Uninflected::getPlural()),
|
|
||||||
new Substitutions(...Inflectible::getIrregular())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,30 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules\Turkish;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Pattern;
|
|
||||||
|
|
||||||
final class Uninflected
|
|
||||||
{
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getSingular(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
public static function getPlural(): iterable
|
|
||||||
{
|
|
||||||
yield from self::getDefault();
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @return Pattern[] */
|
|
||||||
private static function getDefault(): iterable
|
|
||||||
{
|
|
||||||
yield new Pattern('lunes');
|
|
||||||
yield new Pattern('rompecabezas');
|
|
||||||
yield new Pattern('crisis');
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector\Rules;
|
|
||||||
|
|
||||||
class Word
|
|
||||||
{
|
|
||||||
/** @var string */
|
|
||||||
private $word;
|
|
||||||
|
|
||||||
public function __construct(string $word)
|
|
||||||
{
|
|
||||||
$this->word = $word;
|
|
||||||
}
|
|
||||||
|
|
||||||
public function getWord(): string
|
|
||||||
{
|
|
||||||
return $this->word;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,56 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
use Doctrine\Inflector\Rules\Ruleset;
|
|
||||||
|
|
||||||
use function array_merge;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Inflects based on multiple rulesets.
|
|
||||||
*
|
|
||||||
* Rules:
|
|
||||||
* - If the word matches any uninflected word pattern, it is not inflected
|
|
||||||
* - The first ruleset that returns a different value for an irregular word wins
|
|
||||||
* - The first ruleset that returns a different value for a regular word wins
|
|
||||||
* - If none of the above match, the word is left as-is
|
|
||||||
*/
|
|
||||||
class RulesetInflector implements WordInflector
|
|
||||||
{
|
|
||||||
/** @var Ruleset[] */
|
|
||||||
private $rulesets;
|
|
||||||
|
|
||||||
public function __construct(Ruleset $ruleset, Ruleset ...$rulesets)
|
|
||||||
{
|
|
||||||
$this->rulesets = array_merge([$ruleset], $rulesets);
|
|
||||||
}
|
|
||||||
|
|
||||||
public function inflect(string $word): string
|
|
||||||
{
|
|
||||||
if ($word === '') {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($this->rulesets as $ruleset) {
|
|
||||||
if ($ruleset->getUninflected()->matches($word)) {
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
|
|
||||||
$inflected = $ruleset->getIrregular()->inflect($word);
|
|
||||||
|
|
||||||
if ($inflected !== $word) {
|
|
||||||
return $inflected;
|
|
||||||
}
|
|
||||||
|
|
||||||
$inflected = $ruleset->getRegular()->inflect($word);
|
|
||||||
|
|
||||||
if ($inflected !== $word) {
|
|
||||||
return $inflected;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $word;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,10 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
declare(strict_types=1);
|
|
||||||
|
|
||||||
namespace Doctrine\Inflector;
|
|
||||||
|
|
||||||
interface WordInflector
|
|
||||||
{
|
|
||||||
public function inflect(string $word): string;
|
|
||||||
}
|
|
194
vendor/illuminate/container/BoundMethod.php
vendored
194
vendor/illuminate/container/BoundMethod.php
vendored
@ -1,194 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Illuminate\Container;
|
|
||||||
|
|
||||||
use Closure;
|
|
||||||
use Illuminate\Contracts\Container\BindingResolutionException;
|
|
||||||
use InvalidArgumentException;
|
|
||||||
use ReflectionFunction;
|
|
||||||
use ReflectionMethod;
|
|
||||||
|
|
||||||
class BoundMethod
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Call the given Closure / class@method and inject its dependencies.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Container\Container $container
|
|
||||||
* @param callable|string $callback
|
|
||||||
* @param array $parameters
|
|
||||||
* @param string|null $defaultMethod
|
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \ReflectionException
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
public static function call($container, $callback, array $parameters = [], $defaultMethod = null)
|
|
||||||
{
|
|
||||||
if (is_string($callback) && ! $defaultMethod && method_exists($callback, '__invoke')) {
|
|
||||||
$defaultMethod = '__invoke';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (static::isCallableWithAtSign($callback) || $defaultMethod) {
|
|
||||||
return static::callClass($container, $callback, $parameters, $defaultMethod);
|
|
||||||
}
|
|
||||||
|
|
||||||
return static::callBoundMethod($container, $callback, function () use ($container, $callback, $parameters) {
|
|
||||||
return $callback(...array_values(static::getMethodDependencies($container, $callback, $parameters)));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a string reference to a class using Class@method syntax.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Container\Container $container
|
|
||||||
* @param string $target
|
|
||||||
* @param array $parameters
|
|
||||||
* @param string|null $defaultMethod
|
|
||||||
* @return mixed
|
|
||||||
*
|
|
||||||
* @throws \InvalidArgumentException
|
|
||||||
*/
|
|
||||||
protected static function callClass($container, $target, array $parameters = [], $defaultMethod = null)
|
|
||||||
{
|
|
||||||
$segments = explode('@', $target);
|
|
||||||
|
|
||||||
// We will assume an @ sign is used to delimit the class name from the method
|
|
||||||
// name. We will split on this @ sign and then build a callable array that
|
|
||||||
// we can pass right back into the "call" method for dependency binding.
|
|
||||||
$method = count($segments) === 2
|
|
||||||
? $segments[1] : $defaultMethod;
|
|
||||||
|
|
||||||
if (is_null($method)) {
|
|
||||||
throw new InvalidArgumentException('Method not provided.');
|
|
||||||
}
|
|
||||||
|
|
||||||
return static::call(
|
|
||||||
$container, [$container->make($segments[0]), $method], $parameters
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call a method that has been bound to the container.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Container\Container $container
|
|
||||||
* @param callable $callback
|
|
||||||
* @param mixed $default
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
protected static function callBoundMethod($container, $callback, $default)
|
|
||||||
{
|
|
||||||
if (! is_array($callback)) {
|
|
||||||
return Util::unwrapIfClosure($default);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Here we need to turn the array callable into a Class@method string we can use to
|
|
||||||
// examine the container and see if there are any method bindings for this given
|
|
||||||
// method. If there are, we can call this method binding callback immediately.
|
|
||||||
$method = static::normalizeMethod($callback);
|
|
||||||
|
|
||||||
if ($container->hasMethodBinding($method)) {
|
|
||||||
return $container->callMethodBinding($method, $callback[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Util::unwrapIfClosure($default);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Normalize the given callback into a Class@method string.
|
|
||||||
*
|
|
||||||
* @param callable $callback
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected static function normalizeMethod($callback)
|
|
||||||
{
|
|
||||||
$class = is_string($callback[0]) ? $callback[0] : get_class($callback[0]);
|
|
||||||
|
|
||||||
return "{$class}@{$callback[1]}";
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all dependencies for a given method.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Container\Container $container
|
|
||||||
* @param callable|string $callback
|
|
||||||
* @param array $parameters
|
|
||||||
* @return array
|
|
||||||
*
|
|
||||||
* @throws \ReflectionException
|
|
||||||
*/
|
|
||||||
protected static function getMethodDependencies($container, $callback, array $parameters = [])
|
|
||||||
{
|
|
||||||
$dependencies = [];
|
|
||||||
|
|
||||||
foreach (static::getCallReflector($callback)->getParameters() as $parameter) {
|
|
||||||
static::addDependencyForCallParameter($container, $parameter, $parameters, $dependencies);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_merge($dependencies, array_values($parameters));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the proper reflection instance for the given callback.
|
|
||||||
*
|
|
||||||
* @param callable|string $callback
|
|
||||||
* @return \ReflectionFunctionAbstract
|
|
||||||
*
|
|
||||||
* @throws \ReflectionException
|
|
||||||
*/
|
|
||||||
protected static function getCallReflector($callback)
|
|
||||||
{
|
|
||||||
if (is_string($callback) && strpos($callback, '::') !== false) {
|
|
||||||
$callback = explode('::', $callback);
|
|
||||||
} elseif (is_object($callback) && ! $callback instanceof Closure) {
|
|
||||||
$callback = [$callback, '__invoke'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return is_array($callback)
|
|
||||||
? new ReflectionMethod($callback[0], $callback[1])
|
|
||||||
: new ReflectionFunction($callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the dependency for the given call parameter.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Container\Container $container
|
|
||||||
* @param \ReflectionParameter $parameter
|
|
||||||
* @param array $parameters
|
|
||||||
* @param array $dependencies
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
protected static function addDependencyForCallParameter($container, $parameter,
|
|
||||||
array &$parameters, &$dependencies)
|
|
||||||
{
|
|
||||||
if (array_key_exists($paramName = $parameter->getName(), $parameters)) {
|
|
||||||
$dependencies[] = $parameters[$paramName];
|
|
||||||
|
|
||||||
unset($parameters[$paramName]);
|
|
||||||
} elseif (! is_null($className = Util::getParameterClassName($parameter))) {
|
|
||||||
if (array_key_exists($className, $parameters)) {
|
|
||||||
$dependencies[] = $parameters[$className];
|
|
||||||
|
|
||||||
unset($parameters[$className]);
|
|
||||||
} else {
|
|
||||||
$dependencies[] = $container->make($className);
|
|
||||||
}
|
|
||||||
} elseif ($parameter->isDefaultValueAvailable()) {
|
|
||||||
$dependencies[] = $parameter->getDefaultValue();
|
|
||||||
} elseif (! $parameter->isOptional() && ! array_key_exists($paramName, $parameters)) {
|
|
||||||
$message = "Unable to resolve dependency [{$parameter}] in class {$parameter->getDeclaringClass()->getName()}";
|
|
||||||
|
|
||||||
throw new BindingResolutionException($message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determine if the given string is in Class@method syntax.
|
|
||||||
*
|
|
||||||
* @param mixed $callback
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
protected static function isCallableWithAtSign($callback)
|
|
||||||
{
|
|
||||||
return is_string($callback) && strpos($callback, '@') !== false;
|
|
||||||
}
|
|
||||||
}
|
|
1333
vendor/illuminate/container/Container.php
vendored
1333
vendor/illuminate/container/Container.php
vendored
File diff suppressed because it is too large
Load Diff
@ -1,84 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
namespace Illuminate\Container;
|
|
||||||
|
|
||||||
use Illuminate\Contracts\Container\Container;
|
|
||||||
use Illuminate\Contracts\Container\ContextualBindingBuilder as ContextualBindingBuilderContract;
|
|
||||||
|
|
||||||
class ContextualBindingBuilder implements ContextualBindingBuilderContract
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The underlying container instance.
|
|
||||||
*
|
|
||||||
* @var \Illuminate\Contracts\Container\Container
|
|
||||||
*/
|
|
||||||
protected $container;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The concrete instance.
|
|
||||||
*
|
|
||||||
* @var string|array
|
|
||||||
*/
|
|
||||||
protected $concrete;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The abstract target.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $needs;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a new contextual binding builder.
|
|
||||||
*
|
|
||||||
* @param \Illuminate\Contracts\Container\Container $container
|
|
||||||
* @param string|array $concrete
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function __construct(Container $container, $concrete)
|
|
||||||
{
|
|
||||||
$this->concrete = $concrete;
|
|
||||||
$this->container = $container;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the abstract target that depends on the context.
|
|
||||||
*
|
|
||||||
* @param string $abstract
|
|
||||||
* @return $this
|
|
||||||
*/
|
|
||||||
public function needs($abstract)
|
|
||||||
{
|
|
||||||
$this->needs = $abstract;
|
|
||||||
|
|
||||||
return $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define the implementation for the contextual binding.
|
|
||||||
*
|
|
||||||
* @param \Closure|string|array $implementation
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function give($implementation)
|
|
||||||
{
|
|
||||||
foreach (Util::arrayWrap($this->concrete) as $concrete) {
|
|
||||||
$this->container->addContextualBinding($concrete, $this->needs, $implementation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define tagged services to be used as the implementation for the contextual binding.
|
|
||||||
*
|
|
||||||
* @param string $tag
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
public function giveTagged($tag)
|
|
||||||
{
|
|
||||||
$this->give(function ($container) use ($tag) {
|
|
||||||
$taggedServices = $container->tagged($tag);
|
|
||||||
|
|
||||||
return is_array($taggedServices) ? $taggedServices : iterator_to_array($taggedServices);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user