Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
673b7054aa | ||
|
|
1472cbf257 | ||
|
|
d806935c58 | ||
|
|
6b56eb79e1 | ||
|
|
d2aea16744 | ||
|
|
bb800f032e | ||
|
|
64b9f9443e | ||
|
|
fd2d3a0e06 | ||
|
|
08d678bdb8 | ||
|
|
418007e572 | ||
|
|
4a1bccdf75 | ||
|
|
00c0b59e9d | ||
|
|
ac82c8ff0b | ||
|
|
f4bef8a090 | ||
|
|
d8a1055bff | ||
|
|
d672ce4d80 | ||
|
|
43ec361d03 | ||
|
|
c3c99c5f76 | ||
|
|
eb1e1421ab | ||
|
|
e8a1d87919 | ||
|
|
921ba6811d | ||
|
|
906dd241b4 | ||
|
|
3f0cd2ad64 | ||
|
|
41420d1954 | ||
|
|
6e5a72b170 | ||
|
|
4b19e6aec8 | ||
|
|
58572cbc36 | ||
|
|
096d5766bf |
+36
-30
@@ -15,20 +15,34 @@ return [
|
||||
// Note that the **only** effect of choosing `'5.6'` is to infer
|
||||
// that functions removed in php 7.0 exist.
|
||||
// (See `backward_compatibility_checks` for additional options)
|
||||
"target_php_version" => '7.4',
|
||||
"target_php_version" => '8.0',
|
||||
'backward_compatibility_checks ' => true,
|
||||
'minimum_severity'=>\Phan\Issue::SEVERITY_CRITICAL,
|
||||
'minimum_severity' => \Phan\Issue::SEVERITY_NORMAL,
|
||||
|
||||
'file_list' => [
|
||||
'f_config/config.php',
|
||||
'hwe/_119_b.php',
|
||||
'hwe/_119.php',
|
||||
'hwe/a_bestGeneral.php',
|
||||
'hwe/a_emperior.php',
|
||||
'hwe/_admin1.php',
|
||||
'hwe/_admin1_submit.php',
|
||||
'hwe/_admin2.php',
|
||||
'hwe/_admin2_submit.php',
|
||||
'hwe/_admin4.php',
|
||||
'hwe/_admin4_submit.php',
|
||||
'hwe/_admin5.php',
|
||||
'hwe/_admin5_submit.php',
|
||||
'hwe/_admin7.php',
|
||||
'hwe/_admin8.php',
|
||||
'hwe/_admin_force_rehall.php',
|
||||
'hwe/a_emperior_detail.php',
|
||||
'hwe/a_emperior.php',
|
||||
'hwe/a_genList.php',
|
||||
'hwe/a_hallOfFame.php',
|
||||
'hwe/a_history.php',
|
||||
'hwe/a_kingdomList.php',
|
||||
'hwe/a_npcList.php',
|
||||
'hwe/api.php',
|
||||
'hwe/a_status.php',
|
||||
'hwe/a_traffic.php',
|
||||
'hwe/a_vote.php',
|
||||
@@ -41,13 +55,11 @@ return [
|
||||
'hwe/b_dipcenter.php',
|
||||
'hwe/b_diplomacy.php',
|
||||
'hwe/b_genList.php',
|
||||
'hwe/v_inheritPoint.php',
|
||||
'hwe/b_myBossInfo.php',
|
||||
'hwe/b_myCityInfo.php',
|
||||
'hwe/b_myGenInfo.php',
|
||||
'hwe/b_myKingdomInfo.php',
|
||||
'hwe/b_myPage.php',
|
||||
'hwe/b_npc_control.php',
|
||||
'hwe/b_processing.php',
|
||||
'hwe/b_tournament.php',
|
||||
'hwe/b_troop.php',
|
||||
@@ -55,7 +67,6 @@ return [
|
||||
'hwe/c_dipcenter.php',
|
||||
'hwe/c_tournament.php',
|
||||
'hwe/c_vote.php',
|
||||
'hwe/func.php',
|
||||
'hwe/func_auction.php',
|
||||
'hwe/func_command.php',
|
||||
'hwe/func_converter.php',
|
||||
@@ -64,16 +75,15 @@ return [
|
||||
'hwe/func_legacy.php',
|
||||
'hwe/func_map.php',
|
||||
'hwe/func_message.php',
|
||||
'hwe/func.php',
|
||||
'hwe/func_process.php',
|
||||
'hwe/func_string.php',
|
||||
'hwe/func_template.php',
|
||||
'hwe/func_time_event.php',
|
||||
'hwe/func_tournament.php',
|
||||
'hwe/index.php',
|
||||
'hwe/install.php',
|
||||
'hwe/install_db.php',
|
||||
'hwe/join.php',
|
||||
'hwe/join_post.php',
|
||||
'hwe/install.php',
|
||||
'hwe/j_adjust_icon.php',
|
||||
'hwe/j_autoreset.php',
|
||||
'hwe/j_basic_info.php',
|
||||
@@ -92,8 +102,8 @@ return [
|
||||
'hwe/j_general_log_old.php',
|
||||
'hwe/j_general_set_permission.php',
|
||||
'hwe/j_general_turn.php',
|
||||
'hwe/j_getChiefTurn.php',
|
||||
'hwe/j_get_basic_general_list.php',
|
||||
'hwe/j_getChiefTurn.php',
|
||||
'hwe/j_get_city_list.php',
|
||||
'hwe/j_get_general_list.php',
|
||||
'hwe/j_get_nation_general_list.php',
|
||||
@@ -101,11 +111,12 @@ return [
|
||||
'hwe/j_get_select_npc_token.php',
|
||||
'hwe/j_get_select_pool.php',
|
||||
'hwe/j_image_upload.php',
|
||||
'hwe/j_install.php',
|
||||
'hwe/j_install_db.php',
|
||||
'hwe/j_install.php',
|
||||
'hwe/j_load_scenarios.php',
|
||||
'hwe/j_map.php',
|
||||
'hwe/j_map_history.php',
|
||||
'hwe/j_map.php',
|
||||
'hwe/j_map_recent.php',
|
||||
'hwe/j_msg_contact_list.php',
|
||||
'hwe/j_msg_decide_opt.php',
|
||||
'hwe/j_msg_delete.php',
|
||||
@@ -123,26 +134,20 @@ return [
|
||||
'hwe/j_set_npc_control.php',
|
||||
'hwe/j_simulate_battle.php',
|
||||
'hwe/j_troop.php',
|
||||
'hwe/j_update_picked_general.php',
|
||||
'hwe/j_vacation.php',
|
||||
'hwe/lib.php',
|
||||
'hwe/process_war.php',
|
||||
'hwe/proc.php',
|
||||
'hwe/readme.php',
|
||||
'hwe/recent_map.php',
|
||||
'hwe/select_general_from_pool.php',
|
||||
'hwe/select_npc.php',
|
||||
'hwe/t_board.php',
|
||||
'hwe/t_diplomacy.php',
|
||||
'hwe/_119.php',
|
||||
'hwe/_119_b.php',
|
||||
'hwe/_admin1.php',
|
||||
'hwe/_admin1_submit.php',
|
||||
'hwe/_admin2.php',
|
||||
'hwe/_admin2_submit.php',
|
||||
'hwe/_admin4.php',
|
||||
'hwe/_admin4_submit.php',
|
||||
'hwe/_admin5.php',
|
||||
'hwe/_admin5_submit.php',
|
||||
'hwe/_admin7.php',
|
||||
'hwe/_admin8.php',
|
||||
'hwe/_admin_force_rehall.php',
|
||||
'hwe/v_board.php',
|
||||
'hwe/v_inheritPoint.php',
|
||||
'hwe/v_join.php',
|
||||
'hwe/v_NPCControl.php',
|
||||
],
|
||||
|
||||
// A list of directories that should be parsed for class and
|
||||
@@ -153,9 +158,9 @@ return [
|
||||
// Thus, both first-party and third-party code being used by
|
||||
// your application should be included in this list.
|
||||
'directory_list' => [
|
||||
'hwe/d_setting',
|
||||
'hwe/sammo',
|
||||
'd_setting',
|
||||
'hwe/d_setting',
|
||||
'hwe/sammo',
|
||||
'd_setting',
|
||||
'src/sammo',
|
||||
'src/kakao',
|
||||
'vendor'
|
||||
@@ -179,6 +184,7 @@ return [
|
||||
|
||||
'suppress_issue_types' => [
|
||||
'PhanUnreferencedUseNormal',
|
||||
'PhanTypeArraySuspiciousNullable',
|
||||
],
|
||||
|
||||
// A list of plugin files to execute.
|
||||
@@ -195,4 +201,4 @@ return [
|
||||
'PregRegexCheckerPlugin',
|
||||
'PrintfCheckerPlugin',
|
||||
],
|
||||
];
|
||||
];
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
<title>닫혀 있습니다.</title>
|
||||
<script>
|
||||
setTimeout(function(){
|
||||
window.location = window.location+'/../';
|
||||
window.location.href = '../';
|
||||
}, 5000);
|
||||
</script>
|
||||
<style>
|
||||
@@ -13,7 +13,7 @@
|
||||
background-color:black;
|
||||
color:yellow;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
include "func.php";
|
||||
require(__DIR__ . '/vendor/autoload.php');
|
||||
|
||||
|
||||
if (!class_exists('\\sammo\\RootDB')) {
|
||||
Json::dieWithReason('No DB');
|
||||
}
|
||||
|
||||
APIHelper::launch(dirname(__FILE__));
|
||||
+3
-1
@@ -28,7 +28,9 @@
|
||||
"catfan/medoo": "^1.5",
|
||||
"phan/phan": "*",
|
||||
"erusev/parsedown-extra": "^0.8.1",
|
||||
"nette/caching": "^3.0"
|
||||
"nette/caching": "^3.0",
|
||||
"illuminate/database": "^8.61",
|
||||
"illuminate/events": "^8.61"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
|
||||
Generated
+987
-9
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "2aeb036fc53a6fdc343bd2707d4697ee",
|
||||
"content-hash": "317938cff7b30806f4e385a70f4943fc",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brandonwamboldt/utilphp",
|
||||
@@ -265,6 +265,101 @@
|
||||
],
|
||||
"time": "2021-07-31T17:03:58+00:00"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "2.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/inflector.git",
|
||||
"reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/inflector/zipball/9cf661f4eb38f7c881cac67c75ea9b00bf97b210",
|
||||
"reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^7.0",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpstan/phpstan-phpunit": "^0.11",
|
||||
"phpstan/phpstan-strict-rules": "^0.11",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/inflector.html",
|
||||
"keywords": [
|
||||
"inflection",
|
||||
"inflector",
|
||||
"lowercase",
|
||||
"manipulation",
|
||||
"php",
|
||||
"plural",
|
||||
"singular",
|
||||
"strings",
|
||||
"uppercase",
|
||||
"words"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/inflector/issues",
|
||||
"source": "https://github.com/doctrine/inflector/tree/2.0.x"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-05-29T15:13:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
"version": "1.7.4",
|
||||
@@ -707,6 +802,497 @@
|
||||
},
|
||||
"time": "2021-04-26T09:17:50+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/bus",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/bus.git",
|
||||
"reference": "808097c0dfd893309bd77b00139586c516b965c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/bus/zipball/808097c0dfd893309bd77b00139586c516b965c9",
|
||||
"reference": "808097c0dfd893309bd77b00139586c516b965c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/pipeline": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/queue": "Required to use closures when chaining jobs (^7.0)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Bus\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Bus package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-08-10T16:49:48+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/collections.git",
|
||||
"reference": "18fa841df912ec56849351dd6ca8928e8a98b69d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/collections/zipball/18fa841df912ec56849351dd6ca8928e8a98b69d",
|
||||
"reference": "18fa841df912ec56849351dd6ca8928e8a98b69d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-dumper": "Required to use the dump method (^5.1.4)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Collections package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-09-08T12:48:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/container",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/container.git",
|
||||
"reference": "862b64ea4ab56e307a1676104a1b93295d347ad0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/container/zipball/862b64ea4ab56e307a1676104a1b93295d347ad0",
|
||||
"reference": "862b64ea4ab56e307a1676104a1b93295d347ad0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"php": "^7.3|^8.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Container\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Container package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-09-09T13:55:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
"reference": "ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/contracts/zipball/ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913",
|
||||
"reference": "ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Contracts\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Contracts package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-09-08T12:09:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/database",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/database.git",
|
||||
"reference": "acc11d6839ddb3b694bc6585177fa5141b70c693"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/database/zipball/acc11d6839ddb3b694bc6585177fa5141b70c693",
|
||||
"reference": "acc11d6839ddb3b694bc6585177fa5141b70c693",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/container": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/console": "^5.1.4"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).",
|
||||
"fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).",
|
||||
"illuminate/console": "Required to use the database commands (^8.0).",
|
||||
"illuminate/events": "Required to use the observers with Eloquent (^8.0).",
|
||||
"illuminate/filesystem": "Required to use the migrations (^8.0).",
|
||||
"illuminate/pagination": "Required to paginate the result set (^8.0).",
|
||||
"symfony/finder": "Required to use Eloquent model factories (^5.1.4)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Database\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Database package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"keywords": [
|
||||
"database",
|
||||
"laravel",
|
||||
"orm",
|
||||
"sql"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-09-13T18:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/events",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/events.git",
|
||||
"reference": "7def78033f29cd0c0383513b27c291d233a7f90e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/events/zipball/7def78033f29cd0c0383513b27c291d233a7f90e",
|
||||
"reference": "7def78033f29cd0c0383513b27c291d233a7f90e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/bus": "^8.0",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/container": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Events\\": ""
|
||||
},
|
||||
"files": [
|
||||
"functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Events package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-08-16T21:45:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/macroable",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/macroable.git",
|
||||
"reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/macroable/zipball/300aa13c086f25116b5f3cde3ca54ff5c822fb05",
|
||||
"reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Macroable package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2020-10-27T15:20:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/pipeline",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/pipeline.git",
|
||||
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
|
||||
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Pipeline\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Pipeline package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-03-26T18:39:16+00:00"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v8.61.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "b0a21c41163381dd9a5abbd68fe85ed7b4247d30"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/b0a21c41163381dd9a5abbd68fe85ed7b4247d30",
|
||||
"reference": "b0a21c41163381dd9a5abbd68fe85ed7b4247d30",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "^1.4|^2.0",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"nesbot/carbon": "^2.31",
|
||||
"php": "^7.3|^8.0",
|
||||
"voku/portable-ascii": "^1.4.8"
|
||||
},
|
||||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/filesystem": "Required to use the composer class (^8.0).",
|
||||
"league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0).",
|
||||
"ramsey/uuid": "Required to use Str::uuid() (^4.0).",
|
||||
"symfony/process": "Required to use the composer class (^5.1.4).",
|
||||
"symfony/var-dumper": "Required to use the dd function (^5.1.4).",
|
||||
"vlucas/phpdotenv": "Required to use the Env class and env helper (^5.2)."
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Support package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"time": "2021-09-13T18:43:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/plates",
|
||||
"version": "v3.4.0",
|
||||
@@ -902,6 +1488,100 @@
|
||||
],
|
||||
"time": "2021-05-28T08:32:12+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.53.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "f4655858a784988f880c1b8c7feabbf02dfdf045"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f4655858a784988f880c1b8c7feabbf02dfdf045",
|
||||
"reference": "f4655858a784988f880c1b8c7feabbf02dfdf045",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.1.8 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation": "^3.4 || ^4.0 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/orm": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"kylekatarnls/multi-tester": "^2.0",
|
||||
"phpmd/phpmd": "^2.9",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^0.12.54",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.14",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"bin": [
|
||||
"bin/carbon"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-3.x": "3.x-dev",
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "https://markido.com"
|
||||
},
|
||||
{
|
||||
"name": "kylekatarnls",
|
||||
"homepage": "https://github.com/kylekatarnls"
|
||||
}
|
||||
],
|
||||
"description": "An API extension for DateTime that supports 281 different languages.",
|
||||
"homepage": "https://carbon.nesbot.com",
|
||||
"keywords": [
|
||||
"date",
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/briannesbitt/Carbon/issues",
|
||||
"source": "https://github.com/briannesbitt/Carbon"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/Carbon",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-09-06T09:29:23+00:00"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v4.0.0",
|
||||
@@ -1206,16 +1886,16 @@
|
||||
},
|
||||
{
|
||||
"name": "phan/phan",
|
||||
"version": "5.0.0",
|
||||
"version": "5.2.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phan/phan.git",
|
||||
"reference": "f36b6b9a2f4143a25f35ce94d712ceb0527e9d90"
|
||||
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phan/phan/zipball/f36b6b9a2f4143a25f35ce94d712ceb0527e9d90",
|
||||
"reference": "f36b6b9a2f4143a25f35ce94d712ceb0527e9d90",
|
||||
"url": "https://api.github.com/repos/phan/phan/zipball/d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
|
||||
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1232,7 +1912,7 @@
|
||||
"symfony/console": "^3.2|^4.0|^5.0",
|
||||
"symfony/polyfill-mbstring": "^1.11.0",
|
||||
"symfony/polyfill-php80": "^1.20.0",
|
||||
"tysonandre/var_representation_polyfill": "^0.0.2"
|
||||
"tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.0"
|
||||
@@ -1279,9 +1959,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phan/phan/issues",
|
||||
"source": "https://github.com/phan/phan/tree/5.0.0"
|
||||
"source": "https://github.com/phan/phan/tree/5.2.1"
|
||||
},
|
||||
"time": "2021-08-01T18:17:28+00:00"
|
||||
"time": "2021-09-15T00:08:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "php-extended/php-system",
|
||||
@@ -1684,6 +2364,57 @@
|
||||
},
|
||||
"time": "2021-05-03T11:20:27+00:00"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/simple-cache/tree/master"
|
||||
},
|
||||
"time": "2017-10-23T01:57:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
@@ -2970,6 +3701,179 @@
|
||||
],
|
||||
"time": "2021-06-27T11:44:38+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v5.3.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6",
|
||||
"reference": "4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation-contracts": "^2.3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/config": "<4.4",
|
||||
"symfony/dependency-injection": "<5.0",
|
||||
"symfony/http-kernel": "<5.0",
|
||||
"symfony/twig-bundle": "<5.0",
|
||||
"symfony/yaml": "<4.4"
|
||||
},
|
||||
"provide": {
|
||||
"symfony/translation-implementation": "2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/config": "^4.4|^5.0",
|
||||
"symfony/console": "^4.4|^5.0",
|
||||
"symfony/dependency-injection": "^5.0",
|
||||
"symfony/finder": "^4.4|^5.0",
|
||||
"symfony/http-kernel": "^5.0",
|
||||
"symfony/intl": "^4.4|^5.0",
|
||||
"symfony/polyfill-intl-icu": "^1.21",
|
||||
"symfony/service-contracts": "^1.1.2|^2",
|
||||
"symfony/yaml": "^4.4|^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log-implementation": "To use logging capability in translator",
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Translation\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v5.3.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-08-26T08:22:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
"version": "v2.4.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation-contracts.git",
|
||||
"reference": "95c812666f3e91db75385749fe219c5e494c7f95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95",
|
||||
"reference": "95c812666f3e91db75385749fe219c5e494c7f95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/translation-implementation": ""
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Translation\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to translation",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation-contracts/tree/v2.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2021-03-23T23:28:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "tysonandre/var_representation_polyfill",
|
||||
"version": "0.0.2",
|
||||
@@ -3080,6 +3984,80 @@
|
||||
],
|
||||
"time": "2021-07-08T16:18:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
"version": "1.5.6",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/voku/portable-ascii.git",
|
||||
"reference": "80953678b19901e5165c56752d087fc11526017c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/voku/portable-ascii/zipball/80953678b19901e5165c56752d087fc11526017c",
|
||||
"reference": "80953678b19901e5165c56752d087fc11526017c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "Use Intl for transliterator_transliterate() support"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"voku\\": "src/voku/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Lars Moelleken",
|
||||
"homepage": "http://www.moelleken.org/"
|
||||
}
|
||||
],
|
||||
"description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
|
||||
"homepage": "https://github.com/voku/portable-ascii",
|
||||
"keywords": [
|
||||
"ascii",
|
||||
"clean",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/voku/portable-ascii/issues",
|
||||
"source": "https://github.com/voku/portable-ascii/tree/1.5.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.me/moelleken",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/voku",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://opencollective.com/portable-ascii",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/voku",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-11-12T00:07:28+00:00"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.10.0",
|
||||
@@ -3203,7 +4181,7 @@
|
||||
"platform": [],
|
||||
"platform-dev": [],
|
||||
"platform-overrides": {
|
||||
"php": "7.3"
|
||||
"php": "7.4"
|
||||
},
|
||||
"plugin-api-version": "2.0.0"
|
||||
}
|
||||
|
||||
+41
-16
@@ -15,35 +15,35 @@ ini_set("session.gc_maxlifetime", '604800'); // seconds
|
||||
function getFriendlyErrorType($type)
|
||||
{
|
||||
switch ($type) {
|
||||
case E_ERROR: // 1 //
|
||||
case E_ERROR: // 1 //
|
||||
return 'E_ERROR';
|
||||
case E_WARNING: // 2 //
|
||||
case E_WARNING: // 2 //
|
||||
return 'E_WARNING';
|
||||
case E_PARSE: // 4 //
|
||||
case E_PARSE: // 4 //
|
||||
return 'E_PARSE';
|
||||
case E_NOTICE: // 8 //
|
||||
case E_NOTICE: // 8 //
|
||||
return 'E_NOTICE';
|
||||
case E_CORE_ERROR: // 16 //
|
||||
case E_CORE_ERROR: // 16 //
|
||||
return 'E_CORE_ERROR';
|
||||
case E_CORE_WARNING: // 32 //
|
||||
case E_CORE_WARNING: // 32 //
|
||||
return 'E_CORE_WARNING';
|
||||
case E_COMPILE_ERROR: // 64 //
|
||||
case E_COMPILE_ERROR: // 64 //
|
||||
return 'E_COMPILE_ERROR';
|
||||
case E_COMPILE_WARNING: // 128 //
|
||||
case E_COMPILE_WARNING: // 128 //
|
||||
return 'E_COMPILE_WARNING';
|
||||
case E_USER_ERROR: // 256 //
|
||||
case E_USER_ERROR: // 256 //
|
||||
return 'E_USER_ERROR';
|
||||
case E_USER_WARNING: // 512 //
|
||||
case E_USER_WARNING: // 512 //
|
||||
return 'E_USER_WARNING';
|
||||
case E_USER_NOTICE: // 1024 //
|
||||
case E_USER_NOTICE: // 1024 //
|
||||
return 'E_USER_NOTICE';
|
||||
case E_STRICT: // 2048 //
|
||||
case E_STRICT: // 2048 //
|
||||
return 'E_STRICT';
|
||||
case E_RECOVERABLE_ERROR: // 4096 //
|
||||
case E_RECOVERABLE_ERROR: // 4096 //
|
||||
return 'E_RECOVERABLE_ERROR';
|
||||
case E_DEPRECATED: // 8192 //
|
||||
case E_DEPRECATED: // 8192 //
|
||||
return 'E_DEPRECATED';
|
||||
case E_USER_DEPRECATED: // 16384 //
|
||||
case E_USER_DEPRECATED: // 16384 //
|
||||
return 'E_USER_DEPRECATED';
|
||||
}
|
||||
return "{$type}";
|
||||
@@ -134,7 +134,7 @@ function logErrorByCustomHandler(int $errno, string $errstr, string $errfile, in
|
||||
getExceptionTraceAsString($e)
|
||||
);
|
||||
}
|
||||
set_error_handler("\sammo\logErrorByCustomHandler");
|
||||
set_error_handler("\\sammo\\logErrorByCustomHandler");
|
||||
|
||||
|
||||
function logExceptionByCustomHandler(\Throwable $e)
|
||||
@@ -151,3 +151,28 @@ function logExceptionByCustomHandler(\Throwable $e)
|
||||
throw $e;
|
||||
}
|
||||
set_exception_handler('\\sammo\\logExceptionByCustomHandler');
|
||||
|
||||
function getAPIExecutorClass($path){
|
||||
|
||||
static $basePath = __NAMESPACE__.'\\API\\';
|
||||
if(is_string($path)){
|
||||
}
|
||||
else if(is_array($path)){
|
||||
$path = join('\\', $path);
|
||||
}
|
||||
else{
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
|
||||
}
|
||||
|
||||
$classPath = str_replace('/', '\\', $basePath.$path);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
|
||||
}
|
||||
|
||||
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{
|
||||
$class = getAPIExecutorClass($type);
|
||||
return new $class($rootPath, $args);
|
||||
}
|
||||
@@ -58,7 +58,7 @@ CREATE TABLE `member_log` (
|
||||
INDEX `action` (`member_no`, `action_type`, `date`),
|
||||
INDEX `member` (`member_no`, `date`)
|
||||
)
|
||||
ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;
|
||||
ENGINE=Aria DEFAULT CHARSET=utf8mb4;
|
||||
|
||||
###################
|
||||
# KV storage
|
||||
@@ -72,4 +72,19 @@ CREATE TABLE if not exists `storage` (
|
||||
UNIQUE INDEX `key` (`namespace`, `key`)
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE=MyISAM
|
||||
ENGINE=Aria;
|
||||
|
||||
CREATE TABLE `login_token` (
|
||||
`id` INT(11) NOT NULL AUTO_INCREMENT,
|
||||
`user_id` INT(11) NOT NULL,
|
||||
`base_token` VARCHAR(20) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`reg_ip` VARCHAR(40) NOT NULL COLLATE 'utf8mb4_general_ci',
|
||||
`reg_date` DATETIME NOT NULL,
|
||||
`expire_date` DATETIME NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE INDEX `by_token` (`base_token`),
|
||||
INDEX `by_date` (`user_id`, `expire_date`)
|
||||
)
|
||||
COLLATE='utf8mb4_general_ci'
|
||||
ENGINE=Aria
|
||||
;
|
||||
@@ -2,9 +2,15 @@
|
||||
|
||||
namespace sammo;
|
||||
|
||||
//https://hub.packtpub.com/eloquent-without-laravel/
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
class RootDB
|
||||
{
|
||||
private static $uDB = null;
|
||||
private static ?Capsule $uIlluminate = null;
|
||||
|
||||
private static $host = '_tK_host_';
|
||||
private static $user = '_tK_user_';
|
||||
@@ -12,6 +18,8 @@ class RootDB
|
||||
private static $dbName = '_tK_dbName_';
|
||||
private static $port = _tK_port_;
|
||||
private static $encoding = 'utf8mb4';
|
||||
private static $collation = 'utf8mb4_general_ci';
|
||||
|
||||
|
||||
private static $globalSalt = '_tK_globalSalt_';
|
||||
|
||||
@@ -19,6 +27,29 @@ class RootDB
|
||||
{
|
||||
}
|
||||
|
||||
public static function illuminate(): Capsule
|
||||
{
|
||||
if(self::$uIlluminate !== null){
|
||||
return self::$uIlluminate;
|
||||
}
|
||||
$capsule = new Capsule;
|
||||
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'host' => self::$host,
|
||||
'database' => self::$dbName,
|
||||
'username' => self::$user,
|
||||
'password' => self::$password,
|
||||
'charset' => self::$encoding,
|
||||
'collation' => self::$collation,
|
||||
], 'root');
|
||||
|
||||
$capsule->setEventDispatcher(new Dispatcher(new Container));
|
||||
$capsule->bootEloquent();
|
||||
self::$uIlluminate = $capsule;
|
||||
return $capsule;
|
||||
}
|
||||
|
||||
/**
|
||||
* DB 객체 생성
|
||||
*
|
||||
|
||||
@@ -342,6 +342,7 @@ switch ($btn) {
|
||||
}
|
||||
break;
|
||||
case "랜덤턴":
|
||||
$turnterm = $gameStor->turnterm;
|
||||
foreach ($genlist as $generalID) {
|
||||
$turntime = getRandTurn($turnterm);
|
||||
$db->update('general', [
|
||||
|
||||
@@ -28,7 +28,7 @@ $scenarioList = (function(){
|
||||
|
||||
|
||||
|
||||
if($scenarioIdx !== null && key_exists($scenarioIdx, $scenarioList)){
|
||||
if($scenarioIdx && key_exists($scenarioIdx, $scenarioList[$seasonIdx]??[])){
|
||||
$searchScenarioName = $scenarioList[$seasonIdx][$scenarioIdx]['name'];
|
||||
$searchFilter = $db->sqleval('season = %i AND scenario = %i', $seasonIdx, $scenarioIdx);
|
||||
}
|
||||
|
||||
@@ -1,8 +1,16 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
class DB{
|
||||
//https://hub.packtpub.com/eloquent-without-laravel/
|
||||
use Illuminate\Database\Capsule\Manager as Capsule;
|
||||
use Illuminate\Events\Dispatcher;
|
||||
use Illuminate\Container\Container;
|
||||
|
||||
class DB
|
||||
{
|
||||
private static $uDB = null;
|
||||
private static ?Capsule $uIlluminate = null;
|
||||
|
||||
private static $host = '_tK_host_';
|
||||
private static $user = '_tK_user_';
|
||||
@@ -10,11 +18,36 @@ class DB{
|
||||
private static $dbName = '_tK_dbName_';
|
||||
private static $port = _tK_port_;
|
||||
private static $encoding = 'utf8mb4';
|
||||
private static $collation = 'utf8mb4_general_ci';
|
||||
|
||||
private static $prefix = '_tK_prefix_';
|
||||
|
||||
private function __construct(){
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
public static function illuminate(): Capsule
|
||||
{
|
||||
if(self::$uIlluminate !== null){
|
||||
return self::$uIlluminate;
|
||||
}
|
||||
$capsule = new Capsule;
|
||||
|
||||
$capsule->addConnection([
|
||||
'driver' => 'mysql',
|
||||
'host' => self::$host,
|
||||
'database' => self::$dbName,
|
||||
'username' => self::$user,
|
||||
'password' => self::$password,
|
||||
'charset' => self::$encoding,
|
||||
'collation' => self::$collation,
|
||||
]);
|
||||
|
||||
$capsule->setEventDispatcher(new Dispatcher(new Container));
|
||||
$capsule->setAsGlobal();
|
||||
$capsule->bootEloquent();
|
||||
self::$uIlluminate = $capsule;
|
||||
return $capsule;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -23,12 +56,14 @@ class DB{
|
||||
* @return \MeekroDB
|
||||
* @suppress PhanTypeMismatchProperty
|
||||
*/
|
||||
public static function db(){
|
||||
if(self::$uDB === null){
|
||||
self::$uDB = new \MeekroDB(self::$host,self::$user,self::$password,self::$dbName,self::$port,self::$encoding);
|
||||
public static function db()
|
||||
{
|
||||
if (self::$uDB === null) {
|
||||
self::$uDB = new \MeekroDB(self::$host, self::$user, self::$password, self::$dbName, self::$port, self::$encoding);
|
||||
self::$uDB->connect_options[MYSQLI_OPT_INT_AND_FLOAT_NATIVE] = true;
|
||||
|
||||
self::$uDB->error_handler= function(){};
|
||||
self::$uDB->error_handler = function () {
|
||||
};
|
||||
self::$uDB->throw_exception_on_error = true;
|
||||
self::$uDB->throw_exception_on_nonsql_error = true;
|
||||
}
|
||||
@@ -39,4 +74,4 @@ class DB{
|
||||
{
|
||||
return self::$prefix;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
<div class="buttonPlate bg1">
|
||||
<div>
|
||||
<a href="a_status.php" target="_blank"><button class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank"><button class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank"><button class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank"><button class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank"><button class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank"><button class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank"><button class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank"><button class="toolbarButton">접속량정보</button></a>
|
||||
<a href="a_status.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">접속량정보</button></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/bbs/board" target="_blank"><button class="toolbarButton2">삼모게시판</button></a>
|
||||
<a href="/bbs/tip" target="_blank"><button class="toolbarButton">팁/강좌</button></a>
|
||||
<a href="/bbs/news" target="_blank"><button class="toolbarButton">삼국 일보</button></a>
|
||||
<a href="/bbs/history2" target="_blank"><button class="toolbarButton">개인 열전</button></a>
|
||||
<a href="/bbs/history3" target="_blank"><button class="toolbarButton">국가 열전</button></a>
|
||||
<a href="/bbs/patch" target="_blank"><button class="toolbarButton">패치 내역</button></a>
|
||||
<a href="../i_other/help.php" target="_blank"><button class="toolbarButton">튜토리얼</button></a>
|
||||
<a href="<?=$site?>" target="_blank"><button class="toolbarButton"><?=$call?></button></a>
|
||||
<a href="/bbs/board" target="_blank"><button type="button" class="toolbarButton2">삼모게시판</button></a>
|
||||
<a href="/bbs/tip" target="_blank"><button type="button" class="toolbarButton">팁/강좌</button></a>
|
||||
<a href="/bbs/news" target="_blank"><button type="button" class="toolbarButton">삼국 일보</button></a>
|
||||
<a href="/bbs/history2" target="_blank"><button type="button" class="toolbarButton">개인 열전</button></a>
|
||||
<a href="/bbs/history3" target="_blank"><button type="button" class="toolbarButton">국가 열전</button></a>
|
||||
<a href="/bbs/patch" target="_blank"><button type="button" class="toolbarButton">패치 내역</button></a>
|
||||
<a href="battle_simulator.php" target="_blank"><button type="button" class="toolbarButton">전투 시뮬레이터</button></a>
|
||||
<a href="<?=$site?>" target="_blank" class="open-window"><button type="button" class="toolbarButton"><?=$call?></button></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -357,31 +357,6 @@ function buildNationCommandClass(?string $type, General $generalObj, array $env,
|
||||
return new $class($generalObj, $env, $lastTurn, $arg);
|
||||
}
|
||||
|
||||
function getAPIExecutorClass($path){
|
||||
|
||||
static $basePath = __NAMESPACE__.'\\API\\';
|
||||
if(is_string($path)){
|
||||
}
|
||||
else if(is_array($path)){
|
||||
$path = join('\\', $path);
|
||||
}
|
||||
else{
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 지시자가 아님");
|
||||
}
|
||||
|
||||
$classPath = str_replace('/', '\\', $basePath.$path);
|
||||
|
||||
if(class_exists($classPath)){
|
||||
return $classPath;
|
||||
}
|
||||
throw new \InvalidArgumentException("{$path}는 올바른 API 경로가 아님");
|
||||
}
|
||||
|
||||
function buildAPIExecutorClass($type, string $rootPath, array $args):\sammo\BaseAPI{
|
||||
$class = getAPIExecutorClass($type);
|
||||
return new $class($rootPath, $args);
|
||||
}
|
||||
|
||||
function getWarUnitTriggerClass(string $type){
|
||||
static $basePath = __NAMESPACE__.'\\WarUnitTrigger\\';
|
||||
$classPath = ($basePath.$type);
|
||||
|
||||
@@ -624,12 +624,12 @@ function updateNationState()
|
||||
$targetKillTurn
|
||||
);
|
||||
$nationGenList = General::createGeneralObjListFromDB($nationGenIDList, ['belong', 'npc', 'aux'], 2);
|
||||
$chiefObj = null;
|
||||
$chiefID = null;
|
||||
|
||||
$uniqueLotteryWeightList = [];
|
||||
foreach ($nationGenList as $nationGen) {
|
||||
if ($nationGen->getVar('officer_level') == 12) {
|
||||
$chiefObj = $nationGen;
|
||||
$chiefID = $nationGen->getID();
|
||||
}
|
||||
$trialCnt = count(GameConst::$allItems);
|
||||
|
||||
@@ -670,8 +670,10 @@ function updateNationState()
|
||||
$winnerObj->applyDB($db);
|
||||
}
|
||||
|
||||
if($chiefObj){
|
||||
if($chiefID){
|
||||
$chiefObj = General::createGeneralObjFromDB($chiefID, ['belong', 'npc', 'aux'], 2);
|
||||
$chiefObj->increaseInheritancePoint('unifier', 250 * $levelDiff);
|
||||
$chiefObj->applyDB($db);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1132,7 +1132,7 @@ function fight($tnmt_type, $tnmt, $phs, $group, $g1, $g2, $type) {
|
||||
$gen1resKey = 'd';
|
||||
$gen2resKey = 'd';
|
||||
break;
|
||||
default: new MustNotBeReachedException();
|
||||
default: throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
$db->update('rank_data', [
|
||||
|
||||
@@ -39,7 +39,7 @@ $db = DB::db();
|
||||
$me = General::createGeneralObjFromDB($generalID);
|
||||
|
||||
|
||||
if($defence_train != $me->getVar('defence_train')){
|
||||
if($defence_train !== $me->getVar('defence_train')){
|
||||
if($defence_train == 999){
|
||||
$me->increaseVar('myset', -1);
|
||||
$me->setVar('defence_train', $defence_train);
|
||||
@@ -53,14 +53,8 @@ if($defence_train != $me->getVar('defence_train')){
|
||||
}
|
||||
|
||||
$me->setAuxVar('use_treatment', Util::valueFit($use_treatment, 10, 100));
|
||||
|
||||
if($use_auto_nation_turn != $me->getAuxVar('use_auto_nation_turn')){
|
||||
$me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
|
||||
}
|
||||
|
||||
if($me->getVar('tnmt') != $tnmt){
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
}
|
||||
$me->setAuxVar('use_auto_nation_turn', $use_auto_nation_turn);
|
||||
$me->setVar('tnmt', $tnmt);
|
||||
|
||||
if($me->getNPCType() == 1 && $detachNPC){
|
||||
$turnterm = $gameStor->turnterm;
|
||||
|
||||
+69
-57
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
include "lib.php";
|
||||
@@ -21,18 +22,18 @@ $availableTypes = [
|
||||
'nationPolicy',
|
||||
];
|
||||
|
||||
if(!in_array($type, $availableTypes)){
|
||||
if (!in_array($type, $availableTypes)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 타입이 아닙니다.',
|
||||
'result' => false,
|
||||
'reason' => '올바른 타입이 아닙니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
$data = Json::decode($data);
|
||||
if(!$data || !is_array($data)){
|
||||
if (!$data || !is_array($data)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'올바른 입력이 아닙니다.',
|
||||
'result' => false,
|
||||
'reason' => '올바른 입력이 아닙니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -44,94 +45,95 @@ $me = $db->queryFirstRow('SELECT no, name, npc, nation, city, officer_level, con
|
||||
$nationID = $me['nation'];
|
||||
if (!$nationID) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'국가에 소속되어있지 않습니다.',
|
||||
'result' => false,
|
||||
'reason' => '국가에 소속되어있지 않습니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
$permission = checkSecretPermission($me);
|
||||
if ($permission < 3) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>'권한이 부족합니다. 군주, 외교권자, 조언자가 아닙니다.'
|
||||
'result' => false,
|
||||
'reason' => '권한이 부족합니다. 군주, 외교권자, 조언자가 아닙니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function applyNationPolicy($policy, $nationID, $generalName):?string{
|
||||
function applyNationPolicy($policy, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
|
||||
$defaultPolicy = AutorunNationPolicy::$defaultPolicy;
|
||||
$troopCache = null;
|
||||
foreach($db->queryFirstColumn('SELECT troop_leader FROM troop WHERE nation=%i',$nationID) as $troopID){
|
||||
foreach ($db->queryFirstColumn('SELECT troop_leader FROM troop WHERE nation=%i', $nationID) as $troopID) {
|
||||
$troopCache[$troopID] = 'Neutral';
|
||||
}
|
||||
$cityList = CityConst::all();
|
||||
$nationPolicyRoot = $nationStor->npc_nation_policy;
|
||||
$nationPolicy = $nationPolicyRoot['values']??[];
|
||||
foreach($policy as $key=>$val){
|
||||
$nationPolicy = $nationPolicyRoot['values'] ?? [];
|
||||
foreach ($policy as $key => $val) {
|
||||
|
||||
if($key === 'CombatForce'){
|
||||
if(!is_array($val)){
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
if ($key === 'CombatForce') {
|
||||
if (!is_array($val)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
foreach($val as $troopID=>$troopTarget){
|
||||
if(!key_exists($troopID, $troopCache)){
|
||||
foreach ($val as $troopID => $troopTarget) {
|
||||
if (!key_exists($troopID, $troopCache)) {
|
||||
return "{$troopID}는 국가의 부대가 아닙니다.";
|
||||
}
|
||||
if($troopCache[$troopID] != 'Neutral'){
|
||||
if ($troopCache[$troopID] != 'Neutral') {
|
||||
return "부대({$troopID}는 하나의 역할만 지정할 수 있습니다.";
|
||||
}
|
||||
if(!is_array($troopTarget) || count($troopTarget)!=2){
|
||||
if (!is_array($troopTarget) || count($troopTarget) != 2) {
|
||||
return "{$troopID}의 입력양식이 올바르지 않습니다.";
|
||||
}
|
||||
[$fromCity, $toCity] = $troopCache;
|
||||
if(!key_exists($fromCity, $cityList) || !key_exists($toCity, $cityList)){
|
||||
if (!key_exists($fromCity, $cityList) || !key_exists($toCity, $cityList)) {
|
||||
return "{$troopID}의 도시 {$fromCity}, {$toCity}가 올바른 도시 번호가 아닙니다.";
|
||||
}
|
||||
$troopCache[$troopID]=$key;
|
||||
$troopCache[$troopID] = $key;
|
||||
}
|
||||
$nationPolicy[$key]=$val;
|
||||
$nationPolicy[$key] = $val;
|
||||
continue;
|
||||
}
|
||||
if(in_array($key, ['SupportForce', 'DevelopForce'])){
|
||||
if(!is_array($val)){
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
if (in_array($key, ['SupportForce', 'DevelopForce'])) {
|
||||
if (!is_array($val)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
foreach($val as $troopID){
|
||||
if(!key_exists($troopID, $troopCache)){
|
||||
foreach ($val as $troopID) {
|
||||
if (!key_exists($troopID, $troopCache)) {
|
||||
return "{$troopID}는 국가의 부대가 아닙니다.";
|
||||
}
|
||||
if($troopCache[$troopID] != 'Neutral'){
|
||||
if ($troopCache[$troopID] != 'Neutral') {
|
||||
return "부대({$troopID}는 하나의 역할만 지정할 수 있습니다.";
|
||||
}
|
||||
$troopCache[$troopID]=$key;
|
||||
$troopCache[$troopID] = $key;
|
||||
}
|
||||
|
||||
$nationPolicy[$key]=array_values($val);
|
||||
$nationPolicy[$key] = array_values($val);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if(!key_exists($key, $defaultPolicy)){
|
||||
if (!key_exists($key, $defaultPolicy)) {
|
||||
return "{$key}는 올바른 정책값이 아닙니다.";
|
||||
}
|
||||
$defaultValue = $defaultPolicy[$key];
|
||||
if(is_numeric($defaultValue) != is_numeric($val)){
|
||||
if (is_numeric($defaultValue) != is_numeric($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_integer($defaultValue) != is_integer($val)){
|
||||
if (is_integer($defaultValue) != is_integer($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_array($defaultValue) != is_array($val)){
|
||||
if (is_array($defaultValue) != is_array($val)) {
|
||||
return "{$key}는 올바른 값이 아닙니다.";
|
||||
}
|
||||
if(is_integer($val) && $val < 0){
|
||||
if (is_integer($val) && $val < 0) {
|
||||
$val = 0;
|
||||
}
|
||||
$nationPolicy[$key] = $val;
|
||||
}
|
||||
|
||||
|
||||
$nationPolicyRoot['values'] = $nationPolicy;
|
||||
$nationPolicyRoot['valueSetter'] = $generalName;
|
||||
$nationPolicyRoot['valueSetTime'] = TimeUtil::now();
|
||||
@@ -139,14 +141,15 @@ function applyNationPolicy($policy, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
function applyNationPriority($priority, $nationID, $generalName):?string{
|
||||
function applyNationPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$nationPolicyRoot = $nationStor->npc_nation_policy;
|
||||
|
||||
$defaultPriority = AutorunNationPolicy::$defaultPriority;
|
||||
foreach($priority as $item){
|
||||
if(!in_array($item, $defaultPriority)){
|
||||
foreach ($priority as $item) {
|
||||
if (!in_array($item, $defaultPriority)) {
|
||||
return "{$item}은 올바른 명령이 아닙니다.";
|
||||
}
|
||||
}
|
||||
@@ -157,17 +160,29 @@ function applyNationPriority($priority, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
function applyGeneralPriority($priority, $nationID, $generalName):?string{
|
||||
function applyGeneralPriority($priority, $nationID, $generalName): ?string
|
||||
{
|
||||
$db = DB::db();
|
||||
$nationStor = KVStorage::getStorage($db, $nationID, 'nation_env');
|
||||
$generalPolicyRoot = $nationStor->npc_general_policy;
|
||||
|
||||
$defaultPriority = AutorunGeneralPolicy::$default_priority;
|
||||
foreach($priority as $item){
|
||||
if(!in_array($item, $defaultPriority)){
|
||||
$mustHaveActions = ['출병' => 1];
|
||||
foreach ($priority as $item) {
|
||||
if (key_exists($item, $mustHaveActions)) {
|
||||
$mustHaveActions[$item] = 0;
|
||||
}
|
||||
if (!in_array($item, $defaultPriority)) {
|
||||
return "{$item}은 올바른 명령이 아닙니다.";
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($mustHaveActions as $actionKey => $unset) {
|
||||
if ($unset) {
|
||||
return "{$actionKey}은 항상 사용해야 합니다.";
|
||||
}
|
||||
}
|
||||
|
||||
$generalPolicyRoot['priority'] = $priority;
|
||||
$generalPolicyRoot['prioritySetter'] = $generalName;
|
||||
$generalPolicyRoot['prioritySetTime'] = TimeUtil::now();
|
||||
@@ -175,26 +190,23 @@ function applyGeneralPriority($priority, $nationID, $generalName):?string{
|
||||
return null;
|
||||
}
|
||||
|
||||
if($type == 'nationPolicy'){
|
||||
if ($type == 'nationPolicy') {
|
||||
$result = applyNationPolicy($data, $nationID, $me['name']);
|
||||
}
|
||||
else if($type == 'generalPriority'){
|
||||
} else if ($type == 'generalPriority') {
|
||||
$result = applyGeneralPriority($data, $nationID, $me['name']);
|
||||
}
|
||||
else if($type == 'nationPriority'){
|
||||
} else if ($type == 'nationPriority') {
|
||||
$result = applyNationPriority($data, $nationID, $me['name']);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
throw new MustNotBeReachedException();
|
||||
}
|
||||
|
||||
if($result!==null){
|
||||
if ($result !== null) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reason'=>$result,
|
||||
'result' => false,
|
||||
'reason' => $result,
|
||||
]);
|
||||
}
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reason'=>'success',
|
||||
]);
|
||||
'result' => true,
|
||||
'reason' => 'success',
|
||||
]);
|
||||
|
||||
@@ -17,6 +17,7 @@ class BuySpecificUnique extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$availableItems = [];
|
||||
foreach (GameConst::$allItems as $items) {
|
||||
foreach ($items as $itemKey => $amount) {
|
||||
if ($amount == 0) {
|
||||
|
||||
@@ -62,10 +62,10 @@ class ResetTurnTime extends \sammo\BaseAPI
|
||||
|
||||
$userLogger = new UserLogger($userID);
|
||||
if($afterTurn >= 0){
|
||||
$userLogger->push(sprintf("{$reqPoint} 포인트로 턴 시간을 바꾼 결과 %02d:%02d 뒤로 밀림", intdiv($afterTurn, 60), $afterTurn%60), "inheritPoint");
|
||||
$userLogger->push(sprintf("{$reqPoint} 포인트로 턴 시간을 바꾼 결과 %02d:%02d 뒤로 밀림", intdiv(Util::toInt($afterTurn), 60), $afterTurn%60), "inheritPoint");
|
||||
}
|
||||
else{
|
||||
$userLogger->push(sprintf("{$reqPoint} 포인트로 턴 시간을 바꾼 결과 %02d:%02d 앞으로 당김", intdiv(-$afterTurn, 60), (-$afterTurn)%60), "inheritPoint");
|
||||
$userLogger->push(sprintf("{$reqPoint} 포인트로 턴 시간을 바꾼 결과 %02d:%02d 앞으로 당김", intdiv(Util::toInt(-$afterTurn), 60), (-$afterTurn)%60), "inheritPoint");
|
||||
}
|
||||
$userLogger->flush();
|
||||
|
||||
|
||||
@@ -11,25 +11,29 @@ class event_전투특기_무쌍 extends \sammo\BaseItem{
|
||||
protected $id = 61;
|
||||
protected $rawName = '비급';
|
||||
protected $name = '비급(무쌍)';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
protected $info = '[전투] 대미지 +5%, 피해 -2%, 공격 시 필살 확률 +10%p, <br>승리 수의 로그 비례로 대미지 상승(10회 ⇒ +5%, 40회 ⇒ +15%)<br>승리 수의 로그 비례로 피해 감소(10회 ⇒ -2%, 40회 ⇒ -6%)';
|
||||
protected $cost = 100;
|
||||
protected $buyable = true;
|
||||
protected $consumable = false;
|
||||
protected $reqSecu = 3000;
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warCriticalRatio' && $aux['isAttacker']??false){
|
||||
if($statName === 'warCriticalRatio' && ($aux['isAttacker']??false)){
|
||||
return $value += 0.1;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$attackMultiplier = 1.1;
|
||||
$defenceMultiplier = 0.95;
|
||||
$generalWarSpecial = $unit->getGeneral()->getSpecialWar();
|
||||
if($generalWarSpecial !== null && $generalWarSpecial->getName() == '무쌍'){
|
||||
return [1, 1];
|
||||
}
|
||||
$attackMultiplier = 1.05;
|
||||
$defenceMultiplier = 0.98;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
|
||||
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class che_event_무쌍 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 61;
|
||||
protected $name = '무쌍';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
protected $info = '[전투] 대미지 +5%, 피해 -2%, 공격 시 필살 확률 +10%p, <br>승리 수의 로그 비례로 대미지 상승(10회 ⇒ +5%, 40회 ⇒ +15%)<br>승리 수의 로그 비례로 피해 감소(10회 ⇒ -2%, 40회 ⇒ -6%)';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -19,18 +19,22 @@ class che_event_무쌍 extends \sammo\BaseSpecial{
|
||||
];
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warCriticalRatio' && $aux['isAttacker']??false){
|
||||
if($statName === 'warCriticalRatio' && ($aux['isAttacker']??false)){
|
||||
return $value += 0.1;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$attackMultiplier = 1.1;
|
||||
$defenceMultiplier = 1;
|
||||
$generalWarSpecial = $unit->getGeneral()->getSpecialWar();
|
||||
if($generalWarSpecial !== null && $generalWarSpecial->getName() == '무쌍'){
|
||||
return [1, 1];
|
||||
}
|
||||
$attackMultiplier = 1.05;
|
||||
$defenceMultiplier = 0.98;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
|
||||
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ class che_무쌍 extends \sammo\BaseSpecial{
|
||||
|
||||
protected $id = 61;
|
||||
protected $name = '무쌍';
|
||||
protected $info = '[전투] 대미지 +10%, 피해 -5%, 공격 시 필살 확률 +10%p, <br>승리 수만큼 대미지 0.20%씩 추가 상승(최대40%)<br>승리 수만큼 피해 0.05%씩 감소(최대30%)';
|
||||
protected $info = '[전투] 대미지 +5%, 피해 -2%, 공격 시 필살 확률 +10%p, <br>승리 수의 로그 비례로 대미지 상승(10회 ⇒ +5%, 40회 ⇒ +15%)<br>승리 수의 로그 비례로 피해 감소(10회 ⇒ -2%, 40회 ⇒ -6%)';
|
||||
|
||||
static $selectWeightType = SpecialityHelper::WEIGHT_NORM;
|
||||
static $selectWeight = 1;
|
||||
@@ -19,18 +19,18 @@ class che_무쌍 extends \sammo\BaseSpecial{
|
||||
];
|
||||
|
||||
public function onCalcStat(General $general, string $statName, $value, $aux=null){
|
||||
if($statName === 'warCriticalRatio' && $aux['isAttacker']??false){
|
||||
if($statName === 'warCriticalRatio' && ($aux['isAttacker']??false)){
|
||||
return $value += 0.1;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getWarPowerMultiplier(WarUnit $unit):array{
|
||||
$attackMultiplier = 1.1;
|
||||
$defenceMultiplier = 0.95;
|
||||
$attackMultiplier = 1.05;
|
||||
$defenceMultiplier = 0.98;
|
||||
$killnum = $unit->getGeneral()->getRankVar('killnum');
|
||||
$attackMultiplier += Util::valueFit($killnum * 0.01 * 0.2, null, 0.4);
|
||||
$defenceMultiplier -= Util::valueFit($killnum * 0.01 * 0.05, null, 0.3);
|
||||
$attackMultiplier += log(max(1, $killnum / 5), 2) / 20;
|
||||
$defenceMultiplier -= log(max(1, $killnum / 5), 2) / 50;
|
||||
return [$attackMultiplier, $defenceMultiplier];
|
||||
}
|
||||
}
|
||||
@@ -3,9 +3,9 @@ namespace sammo;
|
||||
|
||||
class CityHelper{
|
||||
//Just Helper
|
||||
private static $list = null;
|
||||
private static $listInv = null;
|
||||
private static $listByNation = null;
|
||||
private static ?array $list = null;
|
||||
private static ?array $listInv = null;
|
||||
private static ?array $listByNation = null;
|
||||
|
||||
private function __construct(){
|
||||
|
||||
@@ -25,7 +25,7 @@ class CityHelper{
|
||||
'@phan-var array<int,mixed>|null $list';
|
||||
'@phan-var array<string,mixed>|null $listInv';
|
||||
'@phan-var array<int,mixed>|null $listByNation';
|
||||
|
||||
|
||||
foreach (DB::db()->query('SELECT `city` as `id`, `name`, `level`, `nation` from city') as $city) {
|
||||
$id = $city['id'];
|
||||
$name = $city['name'];
|
||||
@@ -83,5 +83,5 @@ class CityHelper{
|
||||
return $city;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -182,13 +182,13 @@ class che_랜덤임관 extends Command\GeneralCommand
|
||||
$generalsCnt = [];
|
||||
if ($notIn) {
|
||||
$rawGeneralsCnt = $db->query(
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc != 9 AND nation.gennum < %i AND nation.scout=0 AND nation.nation NOT IN %li GROUP BY general.nation, general.npc',
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE (npc < 4 OR npc = 6) AND nation.gennum < %i AND nation.scout=0 AND nation.nation NOT IN %li GROUP BY general.nation, general.npc',
|
||||
$genLimit,
|
||||
$notIn
|
||||
);
|
||||
} else {
|
||||
$rawGeneralsCnt = $db->query(
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE npc != 9 AND nation.gennum < %i AND nation.scout=0 GROUP BY general.nation, general.npc',
|
||||
'SELECT general.nation as nation, nation.gennum, nation.name, npc, count(*) as cnt FROM general JOIN nation ON general.nation = nation.nation WHERE (npc < 4 OR npc = 6) AND nation.gennum < %i AND nation.scout=0 GROUP BY general.nation, general.npc',
|
||||
$genLimit
|
||||
);
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ class che_장비매매 extends Command\GeneralCommand{
|
||||
else if($itemCode == $general->getVar($itemType)){
|
||||
$this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail('이미 가지고 있습니다.');
|
||||
}
|
||||
else if($itemType != 'item' && !buildItemClass($general->getVar($itemType))->isBuyable()){
|
||||
else if(!buildItemClass($general->getVar($itemType))->isBuyable()){
|
||||
$this->fullConditionConstraints[] = ConstraintHelper::AlwaysFail('이미 진귀한 것을 가지고 있습니다.');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ namespace sammo\Command\General;
|
||||
|
||||
use \sammo\{
|
||||
DB, Util, JosaUtil,
|
||||
General,
|
||||
General,
|
||||
ActionLogger,
|
||||
GameConst, GameUnitConst,
|
||||
Command
|
||||
@@ -31,18 +31,20 @@ class che_탈취 extends che_화계{
|
||||
$commandName = $this->getName();
|
||||
$db = DB::db();
|
||||
|
||||
// 탈취 최대 800 * 8 * sqrt(1 + (year - startyear) / 5) / 2
|
||||
$yearCoef = sqrt(1 + ($this->env['year'] - $this->env['startyear']) / 5) / 2;
|
||||
$gold = Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax) * $destCity['level'] * $yearCoef;
|
||||
$rice = Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax) * $destCity['level'] * $yearCoef;
|
||||
// 탈취 최대 800 * 8 * sqrt(1 + (year - startyear) / 4) / 2
|
||||
$yearCoef = sqrt(1 + ($this->env['year'] - $this->env['startyear']) / 4) / 2;
|
||||
$commRatio = $destCity['comm'] / $destCity['comm_max'];
|
||||
$agriRatio = $destCity['agri'] / $destCity['agri_max'];
|
||||
$gold = Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax) * $destCity['level'] * $yearCoef * (0.25 + $commRatio / 4);
|
||||
$rice = Util::randRangeInt(GameConst::$sabotageDamageMin, GameConst::$sabotageDamageMax) * $destCity['level'] * $yearCoef * (0.25 + $agriRatio / 4);
|
||||
|
||||
if($destCity['supply']){
|
||||
[$destNationGold, $destNationRice] = $db->queryFirstList('SELECT gold,rice FROM nation WHERE nation=%i', $destNationID);
|
||||
|
||||
|
||||
$destNationGold -= $gold;
|
||||
$destNationRice -= $rice;
|
||||
|
||||
if($destNationGold < GameConst::$minNationalGold) {
|
||||
|
||||
if($destNationGold < GameConst::$minNationalGold) {
|
||||
$gold += $destNationGold - GameConst::$minNationalGold;
|
||||
$destNationGold = GameConst::$minNationalGold;
|
||||
}
|
||||
@@ -50,7 +52,7 @@ class che_탈취 extends che_화계{
|
||||
$rice += $destNationRice - GameConst::$minNationalRice;
|
||||
$destNationRice = GameConst::$minNationalRice;
|
||||
}
|
||||
|
||||
|
||||
$db->update('nation', [
|
||||
'gold'=>$destNationGold,
|
||||
'rice'=>$destNationRice
|
||||
@@ -96,5 +98,5 @@ class che_탈취 extends che_화계{
|
||||
|
||||
$logger->pushGeneralActionLog("금<C>{$goldText}</> 쌀<C>{$riceText}</>을 획득했습니다.", ActionLogger::PLAIN);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -218,7 +218,7 @@ class che_물자원조 extends Command\NationCommand{
|
||||
}
|
||||
|
||||
$josaRoSrc = JosaUtil::pick($nationName, '로');
|
||||
$destNationLogger = new ActionLogger(0, $destChiefID, $year, $month);
|
||||
$destNationLogger = new ActionLogger(0, $destNationID, $year, $month);
|
||||
$destNationLogger->pushNationalHistoryLog("<D><b>{$nationName}</b></>{$josaRoSrc}부터 금<C>{$goldAmountText}</> 쌀<C>{$riceAmountText}</>을 지원 받음");
|
||||
|
||||
$destNationStor = KVStorage::getStorage(DB::db(), $destNationID, 'nation_env');
|
||||
|
||||
@@ -33,6 +33,9 @@ class che_피장파장 extends Command\NationCommand{
|
||||
if(!key_exists('destNationID', $this->arg)){
|
||||
return false;
|
||||
}
|
||||
if(!key_exists('commandType', $this->arg)){
|
||||
return false;
|
||||
}
|
||||
$destNationID = $this->arg['destNationID'];
|
||||
$commandType = $this->arg['commandType'];
|
||||
|
||||
|
||||
@@ -42,6 +42,22 @@ class DummyGeneral extends General{
|
||||
return $value;
|
||||
}
|
||||
|
||||
public function getInheritancePoint(string $key, &$aux = null, bool $forceCalc = false){
|
||||
return 0;
|
||||
}
|
||||
|
||||
public function setInheritancePoint(string $key, $value, $aux = null){
|
||||
return;
|
||||
}
|
||||
|
||||
public function increaseInheritancePoint(string $key, $value, $aux = null){
|
||||
return;
|
||||
}
|
||||
|
||||
public function mergeTotalInheritancePoint(){
|
||||
return;
|
||||
}
|
||||
|
||||
function applyDB($db):bool{
|
||||
if($this->logger){
|
||||
$this->initLogger(1, 1);
|
||||
|
||||
@@ -9,9 +9,11 @@ use function sammo\pickGeneralFromPool;
|
||||
//기존 event_3.php
|
||||
class CreateManyNPC extends \sammo\Event\Action{
|
||||
protected $npcCount;
|
||||
protected $fillCnt;
|
||||
protected $avgGen;
|
||||
public function __construct($npcCount = 10){
|
||||
public function __construct($npcCount = 10, $fillCnt = 0){
|
||||
$this->npcCount = $npcCount;
|
||||
$this->fillCnt = $fillCnt;
|
||||
}
|
||||
|
||||
protected function generateNPC($env, int $cnt){
|
||||
@@ -41,13 +43,23 @@ class CreateManyNPC extends \sammo\Event\Action{
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public function run(array $env){
|
||||
if($this->npcCount <= 0){
|
||||
return [__CLASS__, []];
|
||||
if($this->npcCount <= 0 && $this->fillCnt <= 0){
|
||||
return [__CLASS__, []];
|
||||
}
|
||||
$result = $this->generateNPC($env, $this->npcCount);
|
||||
|
||||
|
||||
$moreGenCnt = 0;
|
||||
if($this->fillCnt){
|
||||
$db = DB::db();
|
||||
$nations = $db->queryFirstColumn('SELECT nation FROM general WHERE npc < 2 AND officer_level = 12');
|
||||
$regGens = $db->queryFirstField('SELECT count(*) FROM general WHERE nation IN %li AND npc < 4', $nations);
|
||||
$moreGenCnt = count($nations) * $this->fillCnt - $regGens;
|
||||
}
|
||||
|
||||
$result = $this->generateNPC($env, $this->npcCount + $moreGenCnt);
|
||||
|
||||
$logger = new \sammo\ActionLogger(0, 0, $env['year'], $env['month']);
|
||||
$genCnt = count($result);
|
||||
@@ -62,6 +74,6 @@ class CreateManyNPC extends \sammo\Event\Action{
|
||||
$logger->pushGlobalHistoryLog("장수 <C>{$genCnt}</>명이 <S>등장</>했습니다.", \sammo\ActionLogger::NOTICE_YEAR_MONTH);
|
||||
$logger->flush();
|
||||
|
||||
return [__CLASS__, $result];
|
||||
return [__CLASS__, $result];
|
||||
}
|
||||
}
|
||||
+771
-789
File diff suppressed because it is too large
Load Diff
@@ -15,7 +15,7 @@ class che_도시치료 extends BaseGeneralTrigger{
|
||||
/** @var \sammo\General $general */
|
||||
$general = $this->object;
|
||||
$logger = $general->getLogger();
|
||||
|
||||
|
||||
if($general->getVar('injury') > 0){
|
||||
$general->updateVar('injury', 0);
|
||||
$general->activateSkill('pre.부상경감', 'pre.치료');
|
||||
@@ -25,8 +25,8 @@ class che_도시치료 extends BaseGeneralTrigger{
|
||||
$db = DB::db();
|
||||
|
||||
$patients = $db->queryAllLists(
|
||||
'SELECT no,name,nation FROM general WHERE city=%i AND injury > 10 AND no != %i',
|
||||
$general->getCityID(),
|
||||
'SELECT no,name,nation FROM general WHERE city=%i AND injury > 10 AND no != %i',
|
||||
$general->getCityID(),
|
||||
$general->getID()
|
||||
);
|
||||
|
||||
@@ -56,7 +56,7 @@ class che_도시치료 extends BaseGeneralTrigger{
|
||||
return $env;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(count($cureList) == 1){
|
||||
$josaUl = JosaUtil::pick($curedPatientName, "을");
|
||||
$logger->pushGeneralActionLog("<C>의술</>을 펼쳐 도시의 장수 <Y>{$curedPatientName}</>{$josaUl} 치료합니다!", ActionLogger::PLAIN);
|
||||
|
||||
@@ -459,7 +459,7 @@ class GeneralBuilder{
|
||||
}
|
||||
}
|
||||
|
||||
if(!$this->dex1 && in_array('dex_t', $avgGen)){
|
||||
if(!$this->dex1 && key_exists('dex_t', $avgGen)){
|
||||
$dexTotal = $avgGen['dex_t'];
|
||||
if ($pickType == '무') {
|
||||
$dexVal = Util::choiceRandom([
|
||||
|
||||
@@ -86,7 +86,7 @@ class SpecialityHelper{
|
||||
if($leadership > GameConst::$chiefStatMin){
|
||||
$myCond |= self::STAT_LEADERSHIP;
|
||||
}
|
||||
|
||||
|
||||
if($strength >= $intel * 0.95 && $strength > GameConst::$chiefStatMin){
|
||||
$myCond |= self::STAT_STRENGTH;
|
||||
}
|
||||
@@ -101,7 +101,7 @@ class SpecialityHelper{
|
||||
}
|
||||
if($strength < GameConst::$chiefStatMin){
|
||||
$myCond |= self::STAT_NOT_STRENGTH;
|
||||
}
|
||||
}
|
||||
if($intel < GameConst::$chiefStatMin){
|
||||
$myCond |= self::STAT_NOT_INTEL;
|
||||
}
|
||||
@@ -118,7 +118,7 @@ class SpecialityHelper{
|
||||
$myCond |= self::STAT_INTEL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $myCond;
|
||||
}
|
||||
|
||||
@@ -179,7 +179,7 @@ class SpecialityHelper{
|
||||
$specialObj = buildGeneralSpecialWarClass(GameConst::$defaultSpecialWar);
|
||||
$result[GameConst::$defaultSpecialWar] = $specialObj;
|
||||
}
|
||||
|
||||
|
||||
foreach(GameConst::$availableSpecialWar as $specialID){
|
||||
$specialObj = buildGeneralSpecialWarClass($specialID);
|
||||
$result[$specialID] = $specialObj;
|
||||
@@ -220,7 +220,7 @@ class SpecialityHelper{
|
||||
if(in_array($specialID, $prevSpecials)){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($weightType === static::WEIGHT_PERCENT){
|
||||
$pAbs[$specialID] = $weight;
|
||||
@@ -229,7 +229,7 @@ class SpecialityHelper{
|
||||
$pRel[$specialID] = $weight;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if($pAbs){
|
||||
if($pRel){
|
||||
$pAbs[0] = max(0, 100 - array_sum($pAbs));
|
||||
@@ -280,7 +280,7 @@ class SpecialityHelper{
|
||||
if(in_array($specialID, $prevSpecials)){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if($cond & self::REQ_DEXTERITY){
|
||||
$reqDex[$specialID] = $weight;
|
||||
@@ -296,7 +296,7 @@ class SpecialityHelper{
|
||||
if($reqDex){
|
||||
return Util::choiceRandomUsingWeight($reqDex);
|
||||
}
|
||||
|
||||
|
||||
if($pAbs){
|
||||
if($pRel){
|
||||
$pAbs[0] = max(0, 100 - array_sum($pAbs));
|
||||
|
||||
@@ -56,6 +56,9 @@ class WarUnitGeneral extends WarUnit
|
||||
$semiTurn = $general->getTurnTime();
|
||||
} else if ($oppose !== null) {
|
||||
$semiTurn = $oppose->getGeneral()->getTurnTime();
|
||||
} else {
|
||||
LogText("WarUnitGeneral::setOppose", "defender인데 oppose가 null {$general->getID()}, {$general->getTurnTime()}");
|
||||
$semiTurn = $general->getTurnTime();
|
||||
}
|
||||
$phase = $this->getRealPhase();
|
||||
$semiTurn = substr($semiTurn, 0, strlen($semiTurn) - 2);
|
||||
@@ -205,7 +208,7 @@ class WarUnitGeneral extends WarUnit
|
||||
if ($this->isAttacker) {
|
||||
if ($officerLevel == 12) {
|
||||
$warPower *= 1.10;
|
||||
} else if ($officerLevel == 11 | $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6) {
|
||||
} else if ($officerLevel == 11 || $officerLevel == 10 || $officerLevel == 8 || $officerLevel == 6) {
|
||||
$warPower *= 1.05;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -22,7 +22,7 @@ class che_전투치료발동 extends BaseWarUnitTrigger{
|
||||
}
|
||||
$selfEnv['치료발동'] = true;
|
||||
|
||||
$oppose->getLogger()->pushGeneralBattleDetailLog("상대가 <C>치료</>했다!", ActionLogger::PLAIN);
|
||||
$oppose->getLogger()->pushGeneralBattleDetailLog("상대가 <R>치료</>했다!", ActionLogger::PLAIN);
|
||||
$self->getLogger()->pushGeneralBattleDetailLog("<C>치료</>했다!", ActionLogger::PLAIN);
|
||||
|
||||
$oppose->multiplyWarPowerMultiply(0.5);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"events":[
|
||||
[
|
||||
["or", ["Date", "==", null, 12], ["Date", "==", null, 6]],
|
||||
["CreateManyNPC", 30],
|
||||
["CreateManyNPC", 10, 10],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"events":[
|
||||
[
|
||||
["or", ["Date", "==", null, 12], ["Date", "==", null, 6]],
|
||||
["CreateManyNPC", 30],
|
||||
["CreateManyNPC", 10, 10],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
"events":[
|
||||
[
|
||||
["or", ["Date", "==", null, 12], ["Date", "==", null, 6]],
|
||||
["CreateManyNPC", 30],
|
||||
["CreateManyNPC", 10, 10],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"title": "【가상모드19b】 진유저무쌍! (대형 지도)",
|
||||
"startYear": 180,
|
||||
"history": [
|
||||
"<C>●</>180년 1월:<L><b>【가상모드19ㅠ】</b>진유저무쌍! (대형 지도)</>",
|
||||
"<C>●</>180년 1월:<L><b>【가상모드19】</b>진유저무쌍! (대형 지도)</>",
|
||||
"<C>●</>180년 1월:<L><b>【이벤트】</b></>고대장수 다 덤벼라! 유저가 최강이다!"
|
||||
],
|
||||
"stat": {
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
{
|
||||
"title": "【가상모드23】 CookieRun : Kingdom",
|
||||
"startYear": 180,
|
||||
"history": [
|
||||
"<C>●</>180년 1월:<L><b>【가상모드23】</b>CookieRun : Kingdom</>",
|
||||
"<C>●</>180년 1월:<L><b>【이벤트】</b></>쿠키들과 함께하는 삼모전"
|
||||
],
|
||||
"stat": {
|
||||
"total": 200,
|
||||
"min": 10,
|
||||
"max": 90,
|
||||
"npcTotal":180,
|
||||
"npcMax":70,
|
||||
"npcMin":10,
|
||||
"chiefMin": 60
|
||||
},
|
||||
"iconPath": "쿠키런킹덤",
|
||||
"fiction": 1,
|
||||
"nation":[
|
||||
|
||||
],
|
||||
"map":{
|
||||
"mapName":"miniche",
|
||||
"unitSet":"che"
|
||||
},
|
||||
"diplomacy":[],
|
||||
"general":[
|
||||
[30, "커스터드3세", null, 0, null, 60, 60, 60, 0, 160, 300, null, null, "새로운 백성이로구나. 반가워!"],
|
||||
[30, "클로버", null, 0, null, 71, 49, 71, 0, 160, 300, null, null, "여러분의 모험에 행운이 깃들길..."],
|
||||
[50, "마들렌", null, 0, null, 73, 57, 73, 0, 160, 300, null, null, "빛의 신께 세상을 구하라는 명을 받은 쿠키가 바로 나다!"],
|
||||
[50, "호밀", null, 0, null, 73, 65, 65, 0, 160, 300, null, null, "애송이들! 그렇게 부드러워서야 되겠어?"],
|
||||
[50, "에스프레소", null, 0, null, 75, 55, 75, 0, 160, 300, null, null, "커피마법이라고 다를 것 없습니다?"],
|
||||
[50, "라떼", null, 0, null, 72, 58, 72, 0, 160, 300, null, null, "쓰디 쓴 실패라도 부드러운 우유 몇 방울이면 달콤해질거야"],
|
||||
[50, "아몬드", null, 0, null, 69, 30, 100, 0, 160, 300, null, null, "당신을 마법 행정 규약 위반으로 체포합니다"],
|
||||
[50, "블랙레이즌", null, 0, null, 65, 70, 60, 0, 160, 300, null, null, "깜깜한 어둠 속도 상관 없어. 난 전부 보이니까!"],
|
||||
[60, "감초", null, 0, null, 70, 10, 120, 0, 160, 300, null, null, "나도 할 땐 하는 쿠키야!"],
|
||||
[60, "독버섯", null, 0, null, 70, 60, 70, 0, 160, 300, null, null, "버서엇...?"],
|
||||
[60, "딸기크레페", null, 0, null, 70, 60, 70, 0, 160, 300, null, null],
|
||||
[70, "퓨어바닐라", null, 0, null, 90, 45, 90, 0, 160, 300, null, null, "힘들 땐 힘들다고 말해도 괜찮아요."],
|
||||
[60, "다크초코", null, 0, null, 70, 60, 70, 0, 160, 300, null, null, "그저… 영웅이 되고 싶었을 뿐…"],
|
||||
[60, "석류", null, 0, null, 75, 55, 75, 0, 160, 300, null, null, "영원히 그분만을 섬기리…"],
|
||||
[999, "설탕노움", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[10, "The브레이브", null, 0, null, 69, 51, 69, 0, 160, 300, null, null, "모험은 이제부터 시작이야!"],
|
||||
[10, "스트로베리", null, 0, null, 70, 50, 70, 0, 160, 300, null, null, "쿠키생은 혼자야…"],
|
||||
[10, "매지션", null, 0, null, 66, 54, 66, 0, 160, 300, null, null, "가슴은 뜨겁게 머리는 앗 차거!"],
|
||||
[10, "에인절", null, 0, null, 63, 57, 63, 0, 160, 300, null, null, "새처럼 날아가 볼까요…"],
|
||||
[10, "비트", null, 0, null, 64, 56, 64, 0, 160, 300, null, null, "벌써 이곳에서 1000일을 버텼지!"],
|
||||
[10, "The머슬", null, 0, null, 70, 50, 70, 0, 160, 300, null, null, "이번엔 스쿼트다! 하나! 둘!"],
|
||||
[10, "닌자", null, 0, null, 63, 57, 63, 0, 160, 300, null, null, "허공을 가르고 바람을 밟는다!"],
|
||||
[30, "용사", null, 0, null, 67, 58, 67, 0, 160, 300, null, null, "더 강해져야 해!"],
|
||||
[30, "알케미스트", null, 0, null, 61, 64, 61, 0, 160, 300, null, null, "내가 어떤 걸 만들어 내는지 잘 보라구~!"],
|
||||
[30, "체리", null, 0, null, 66, 59, 66, 0, 160, 300, null, null, "어랏? 터져버렸네~? 미안...일부러 그랬어~ 헤헷!"],
|
||||
[30, "버블껌", null, 0, null, 65, 60, 65, 0, 160, 300, null, null, "껌은 씹는 것 보다 쏘는 게 더 재밌어!"],
|
||||
[30, "블랙베리", null, 0, null, 65, 60, 65, 0, 160, 300, null, null, "맡기실 일이 있다면 뭐든 말씀하세요."],
|
||||
[30, "팬케이크", null, 0, null, 52, 73, 52, 0, 160, 300, null, null, "나 도토리젤리 안 줄 거야?"],
|
||||
[30, "The프린세스", null, 0, null, 60, 65, 60, 0, 160, 300, null, null, "나들이하기 좋은 날이네~!"],
|
||||
[30, "아보카도", null, 0, null, 67, 58, 67, 0, 160, 300, null, null, "가장 맛있는 싸움은? 보쌈! 와하하!"],
|
||||
[30, "어니언", null, 0, null, 72, 53, 72, 0, 160, 300, null, null, "으아아아아앙~"],
|
||||
[30, "익스플로러", null, 0, null, 65, 60, 65, 0, 160, 300, null, null, "가보고 싶은 곳이 너무 많아!"],
|
||||
[30, "캐롯", null, 0, null, 71, 54, 71, 0, 160, 300, null, null, "밭일하러 나갈 시간이야!"],
|
||||
[60, "뱀파이어", null, 0, null, 58, 72, 58, 0, 160, 300, null, null, "나랑 포도주스 한 잔 어때?"],
|
||||
[50, "스파클링", null, 0, null, 70, 60, 70, 0, 160, 300, null, null, "승리를 위한 한 잔이 필요하겠군요!"],
|
||||
[50, "칠리", null, 0, null, 65, 65, 65, 0, 160, 300, null, null, "어이! 주머니 조심하라구!"],
|
||||
[50, "자색고구마", null, 0, null, 65, 65, 65, 0, 160, 300, null, null, "나랑 싸울 쿠키 다 나와!"],
|
||||
[50, "눈설탕", null, 0, null, 79, 51, 79, 0, 160, 300, null, null, "안녕? 반가워~ 나랑... 눈싸움할래?"],
|
||||
[50, "정글전사", null, 0, null, 80, 50, 80, 0, 160, 300, null, null, "친구…들을… 지켜야… 해…"],
|
||||
[50, "민트초코", null, 0, null, 76, 54, 76, 0, 160, 300, null, null, "어떤 음악을 들려드릴까요?"],
|
||||
[50, "허브", null, 0, null, 71, 59, 71, 0, 160, 300, null, null, "무럭무럭 자라렴~"],
|
||||
[50, "우유", null, 0, null, 72, 58, 72, 0, 160, 300, null, null, "평화를 위해 어둠과 맞서 싸우리라!"],
|
||||
[50, "웨어울프", null, 0, null, 72, 58, 72, 0, 160, 300, null, null, "다가오지 마… 다쳐…"],
|
||||
[50, "구미호", null, 0, null, 72, 58, 72, 0, 160, 300, null, null, "나한테 반하면 어떻게 되는지 궁금해?"],
|
||||
[50, "슈크림", null, 0, null, 71, 59, 71, 0, 160, 300, null, null, "저도 이제 어엿한 마법사라구요!"],
|
||||
[150, "케이크들개", null, 0, null, 40, 80, 40, 0, 160, 300, null, null],
|
||||
[999, "곰젤리", null, 0, null, 40, 80, 40, 0, 160, 300, null, null],
|
||||
[999, "곰젤리역장", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "후르츠칸앵무", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "순례자", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "은행강도", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "무녀", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[150, "역사선생님", null, 0, null, 85, 45, 85, 0, 160, 300, null, null, "오늘 확실히 가르쳐 주겠습니다! 도서관의 규칙을!"],
|
||||
[150, "화학선생님", null, 0, null, 85, 45, 85, 0, 160, 300, null, null, "화학실에 멋대로 침입한 벌을 내리겠다!!"],
|
||||
[150, "전술선생님", null, 0, null, 85, 45, 85, 0, 160, 300, null, null, "으하하하!! 그럼 어디 한 번 시험해 볼까! 너의 전술을!"],
|
||||
[150, "꿈꾸는 바할로모트", null, 0, null, 90, 40, 90, 0, 160, 300, null, "환술", "난 이 학교의 교장이니까 말일세!"],
|
||||
[999, "치료사", null, 0, null, 65, 55, 65, 0, 160, 300, null, null],
|
||||
[999, "커스터드총리", null, 0, null, 63, 63, 63, 0, 160, 300, null, null],
|
||||
[150, "3단케이크마녀", null, 0, null, 70, 70, 70, 0, 160, 300, null, null]
|
||||
],
|
||||
"general_ex":[
|
||||
[999, "바람궁수", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "달빛술사", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "바다요정", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "불꽃정령", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[150, "어둠마녀", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "천년나무", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "다크카카오", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "세인트릴리", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "홀리베리", null, 0, null, 60, 60, 60, 0, 160, 300, null, null],
|
||||
[999, "골드치즈", null, 0, null, 60, 60, 60, 0, 160, 300, null, null]
|
||||
],
|
||||
"events":[
|
||||
[
|
||||
["or", ["Date", "==", null, 12], ["Date", "==", null, 6]],
|
||||
["CreateManyNPC", 10, 10],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
["Date", "==", 181, 1],
|
||||
["RaiseNPCNation"],
|
||||
["DeleteEvent"]
|
||||
]
|
||||
]
|
||||
|
||||
}
|
||||
@@ -9,26 +9,26 @@
|
||||
"const": {
|
||||
"joinRuinedNPCProp":0,
|
||||
"availableSpecialWar":[
|
||||
"che_귀병", "che_신산", "che_환술", "che_집중", "che_신중", "che_반계",
|
||||
"che_귀병", "che_신산", "che_환술", "che_집중", "che_신중", "che_반계",
|
||||
"che_보병", "che_궁병", "che_기병", "che_공성",
|
||||
"che_돌격", "che_무쌍", "che_위압",
|
||||
"che_돌격", "che_무쌍", "che_위압",
|
||||
"che_저격", "che_필살", "che_징병", "che_의술", "che_격노", "che_척사"
|
||||
],
|
||||
"allItems":{
|
||||
"horse":{
|
||||
"che_명마_01_노기":0, "che_명마_02_조랑":0, "che_명마_03_노새":0,
|
||||
"che_명마_04_나귀":0, "che_명마_05_갈색마":0, "che_명마_06_흑색마":0,
|
||||
|
||||
"che_명마_07_백마":2, "che_명마_07_기주마":2,
|
||||
"che_명마_04_나귀":0, "che_명마_05_갈색마":0, "che_명마_06_흑색마":0,
|
||||
|
||||
"che_명마_07_백마":2, "che_명마_07_기주마":2,
|
||||
"che_명마_08_양주마":2, "che_명마_09_과하마":2,
|
||||
"che_명마_10_대완마":2, "che_명마_11_서량마":2,
|
||||
"che_명마_10_대완마":2, "che_명마_11_서량마":2,
|
||||
"che_명마_12_사륜거":2, "che_명마_13_절영":1, "che_명마_13_적로":1,
|
||||
"che_명마_14_적란마":1, "che_명마_14_조황비전":1, "che_명마_15_한혈마":1, "che_명마_15_적토마":1
|
||||
},
|
||||
"weapon":{
|
||||
"che_무기_01_단도":0, "che_무기_02_단궁":0, "che_무기_03_단극":0,
|
||||
"che_무기_04_목검":0, "che_무기_05_죽창":0, "che_무기_06_소부":0,
|
||||
|
||||
|
||||
"che_무기_07_동추":1, "che_무기_07_철편":1, "che_무기_07_철쇄":1, "che_무기_07_맥궁":1,
|
||||
"che_무기_08_유성추":1, "che_무기_08_철질여골":1, "che_무기_09_쌍철극":1, "che_무기_09_동호비궁":1,
|
||||
"che_무기_10_삼첨도":1, "che_무기_10_대부":1, "che_무기_11_고정도":1, "che_무기_11_이광궁":1,
|
||||
@@ -37,18 +37,18 @@
|
||||
},
|
||||
"book":{
|
||||
"che_서적_01_효경전":0, "che_서적_02_회남자":0, "che_서적_03_변도론":0,
|
||||
"che_서적_04_건상역주":0, "che_서적_05_여씨춘추":0, "che_서적_06_사민월령":0,
|
||||
|
||||
"che_서적_04_건상역주":0, "che_서적_05_여씨춘추":0, "che_서적_06_사민월령":0,
|
||||
|
||||
"che_서적_07_위료자":1, "che_서적_07_사마법":1, "che_서적_07_한서":1, "che_서적_07_논어":1,
|
||||
"che_서적_08_전론":1, "che_서적_08_사기":1, "che_서적_09_장자":1, "che_서적_09_역경":1,
|
||||
"che_서적_10_시경":1, "che_서적_10_구국론":1, "che_서적_11_상군서":1, "che_서적_11_춘추전":1,
|
||||
"che_서적_12_산해경":1, "che_서적_12_맹덕신서":1, "che_서적_13_관자":1, "che_서적_13_병법24편":1,
|
||||
"che_서적_10_시경":1, "che_서적_10_구국론":1, "che_서적_11_상군서":1, "che_서적_11_춘추전":1,
|
||||
"che_서적_12_산해경":1, "che_서적_12_맹덕신서":1, "che_서적_13_관자":1, "che_서적_13_병법24편":1,
|
||||
"che_서적_14_한비자":1, "che_서적_14_오자병법":1, "che_서적_15_노자":1, "che_서적_15_손자병법":1
|
||||
},
|
||||
"item":{
|
||||
"che_치료_환약":0, "che_저격_수극":0, "che_사기_탁주":0,
|
||||
"che_훈련_청주":0, "che_계략_이추":0, "che_계략_향낭":0,
|
||||
|
||||
|
||||
"event_전투특기_격노":0, "event_전투특기_공성":0, "event_전투특기_궁병":0,
|
||||
"event_전투특기_귀병":0, "event_전투특기_기병":0, "event_전투특기_돌격":0, "event_전투특기_무쌍":0,
|
||||
"event_전투특기_반계":0, "event_전투특기_보병":0, "event_전투특기_신산":0, "event_전투특기_신중":0,
|
||||
@@ -60,7 +60,7 @@
|
||||
"events":[
|
||||
[
|
||||
["Date", "==", null, 12],
|
||||
["CreateManyNPC", 30],
|
||||
["CreateManyNPC", 10, 10],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"events": [
|
||||
[
|
||||
["Date", "==", null, 12],
|
||||
["CreateManyNPC", 100],
|
||||
["CreateManyNPC", 100, 0],
|
||||
["DeleteEvent"]
|
||||
],
|
||||
[
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<div class="buttonPlate bg1">
|
||||
<div>
|
||||
<a href="a_status.php" target="_blank"><button type="button" class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank"><button type="button" class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank"><button type="button" class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank"><button type="button" class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank"><button type="button" class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank"><button type="button" class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank"><button type="button" class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank"><button type="button" class="toolbarButton">접속량정보</button></a>
|
||||
<a href="a_status.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력도</button></a>
|
||||
<a href="a_kingdomList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">세력일람</button></a>
|
||||
<a href="a_genList.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">장수일람</button></a>
|
||||
<a href="a_bestGeneral.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명장일람</button></a>
|
||||
<a href="a_history.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">연감</button></a>
|
||||
<a href="a_hallOfFame.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">명예의전당</button></a>
|
||||
<a href="a_emperior.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">왕조일람</button></a>
|
||||
<a href="a_traffic.php" target="_blank" class="open-window"><button type="button" class="toolbarButton">접속량정보</button></a>
|
||||
</div>
|
||||
<div>
|
||||
<a href="/bbs/board" target="_blank"><button type="button" class="toolbarButton2">삼모게시판</button></a>
|
||||
@@ -17,6 +17,6 @@
|
||||
<a href="/bbs/history3" target="_blank"><button type="button" class="toolbarButton">국가 열전</button></a>
|
||||
<a href="/bbs/patch" target="_blank"><button type="button" class="toolbarButton">패치 내역</button></a>
|
||||
<a href="battle_simulator.php" target="_blank"><button type="button" class="toolbarButton">전투 시뮬레이터</button></a>
|
||||
<a href="<?=$site?>" target="_blank"><button type="button" class="toolbarButton"><?=$call?></button></a>
|
||||
<a href="<?=$site?>" target="_blank" class="open-window"><button type="button" class="toolbarButton"><?=$call?></button></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -8,18 +8,18 @@
|
||||
<a href='b_dipcenter.php'><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>내 무 부</button></a>
|
||||
<a href='b_chiefcenter.php'><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>사 령 부</button></a>
|
||||
<a href='v_NPCControl.php'><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>NPC 정책</button></a>
|
||||
<a href='b_genList.php' target='_blank'><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>암 행 부</button></a>
|
||||
<a href='b_tournament.php' target='_blank'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>토 너 먼 트</button></a>
|
||||
<a href='b_genList.php' target='_blank' class="open-window"><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>암 행 부</button></a>
|
||||
<a href='b_tournament.php' target='_blank' class="open-window"><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>토 너 먼 트</button></a>
|
||||
<a href='b_myKingdomInfo.php'><button type="button" class='commandButton' <?=$meLevel>=1?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>세력 정보</button></a>
|
||||
<a href='b_myCityInfo.php'><button type="button" class='commandButton' <?=($meLevel>=1&&$nationLevel>=1)?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>세력 도시</button></a>
|
||||
<a href='b_myGenInfo.php'><button type="button" class='commandButton' <?=$meLevel>=1?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>세력 장수</button></a>
|
||||
<a href='b_diplomacy.php'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>중원 정보</button></a>
|
||||
<a href='b_currentCity.php'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>현재 도시</button></a>
|
||||
<a href='b_battleCenter.php' target='_blank'><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>감 찰 부</button></a>
|
||||
<a href='b_battleCenter.php' target='_blank' class="open-window"><button type="button" class='commandButton' <?=$showSecret?'':'disabled'?> style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>감 찰 부</button></a>
|
||||
<a href='v_inheritPoint.php'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>유산 관리</button></a>
|
||||
<a href='b_myPage.php'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>내 정보&설정</button></a>
|
||||
<a href='b_auction.php' target='_blank'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>거 래 장</button></a>
|
||||
<a href='b_betting.php' target='_blank'><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>베 팅 장</button></a>
|
||||
<a href='b_auction.php' target='_blank' class="open-window"><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>거 래 장</button></a>
|
||||
<a href='b_betting.php' target='_blank' class="open-window"><button type="button" class='commandButton' style='background-color:<?=$bgColor?>;color:<?=$fgColor?>;'>베 팅 장</button></a>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
+127
-10
@@ -1,7 +1,7 @@
|
||||
import $ from 'jquery';
|
||||
import 'popper.js';
|
||||
import Popper from 'popper.js';
|
||||
(window as unknown as {Popper:unknown}).Popper = Popper;
|
||||
(window as unknown as { Popper: unknown }).Popper = Popper;
|
||||
import 'bootstrap';
|
||||
import { JQValidateForm, NamedRules } from '../util/jqValidateForm';
|
||||
import axios from 'axios';
|
||||
@@ -11,9 +11,12 @@ import { unwrap_any } from '../util/unwrap_any';
|
||||
import { sha512 } from 'js-sha512';
|
||||
import { unwrap } from '../util/unwrap';
|
||||
import { InvalidResponse } from '../defs';
|
||||
import internal from 'stream';
|
||||
import { delay } from '../util/delay';
|
||||
|
||||
type LoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
} | {
|
||||
result: false,
|
||||
reqOTP: boolean,
|
||||
@@ -29,6 +32,19 @@ type OTPResponse = {
|
||||
reason: string,
|
||||
}
|
||||
|
||||
type AutoLoginNonceResponse = {
|
||||
result: true,
|
||||
loginNonce: string,
|
||||
} | InvalidResponse;
|
||||
|
||||
type AutoLoginResponse = {
|
||||
result: true,
|
||||
nextToken: [number, string] | undefined,
|
||||
} | {
|
||||
result: false,
|
||||
silent: boolean,
|
||||
reason: string,
|
||||
}
|
||||
declare global {
|
||||
interface Window {
|
||||
getOAuthToken: (mode: string, scope_list: string[]) => void;
|
||||
@@ -41,6 +57,92 @@ declare const kakao_oauth_redirect_uri: string;
|
||||
|
||||
let oauthMode: string | null = null;
|
||||
|
||||
const TOKEN_VERSION = 1;
|
||||
const LOGIN_TOKEN_KEY = 'sammo_login_token';
|
||||
function regNextToken(tokenInfo: [number, string]) {
|
||||
localStorage.setItem(LOGIN_TOKEN_KEY, JSON.stringify([TOKEN_VERSION, tokenInfo, Date.now()]));
|
||||
}
|
||||
|
||||
function getToken(): [number, string] | undefined {
|
||||
const trialToken = localStorage.getItem(LOGIN_TOKEN_KEY);
|
||||
if (!trialToken) {
|
||||
return;
|
||||
}
|
||||
const tokenItems = JSON.parse(trialToken);
|
||||
if (tokenItems[0] != TOKEN_VERSION) {
|
||||
console.log(tokenItems);
|
||||
resetToken();
|
||||
return;
|
||||
}
|
||||
const [, token,] = tokenItems;
|
||||
return token;
|
||||
}
|
||||
|
||||
function resetToken(){
|
||||
localStorage.removeItem(LOGIN_TOKEN_KEY);
|
||||
}
|
||||
|
||||
async function tryAutoLogin() {
|
||||
try {
|
||||
const tokenInfo = getToken();
|
||||
if (!tokenInfo) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [tokenID, token] = tokenInfo;
|
||||
|
||||
const result = await axios.post<AutoLoginNonceResponse>('api.php', {
|
||||
path: ["Login", "ReqNonce"]
|
||||
});
|
||||
|
||||
if(!result){
|
||||
//api 에러.
|
||||
return;
|
||||
}
|
||||
|
||||
if(!result.data.result){
|
||||
resetToken();
|
||||
return;
|
||||
}
|
||||
|
||||
const nonce = result.data.loginNonce;
|
||||
|
||||
const hashedToken = sha512(token + nonce);
|
||||
const _loginResult = await axios.post<AutoLoginResponse>('api.php', {
|
||||
path: ["Login", "LoginByToken"],
|
||||
args: {
|
||||
'hashedToken':hashedToken,
|
||||
'token_id':tokenID,
|
||||
}
|
||||
});
|
||||
|
||||
if(!_loginResult){
|
||||
return;
|
||||
}
|
||||
|
||||
const loginResult = _loginResult.data;
|
||||
if(!loginResult.result){
|
||||
if(!loginResult.silent){
|
||||
alert(loginResult.reason);
|
||||
}
|
||||
console.error(loginResult.reason);
|
||||
return;
|
||||
}
|
||||
|
||||
if(loginResult.nextToken){
|
||||
regNextToken(loginResult.nextToken);
|
||||
}
|
||||
window.location.href = "./";
|
||||
|
||||
}
|
||||
catch(e){
|
||||
console.error(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function getOAuthToken(mode: string, scope_list?: string[] | string) {
|
||||
if (mode === undefined) {
|
||||
mode = 'login';
|
||||
@@ -115,6 +217,9 @@ async function doLoginUsingOAuth() {
|
||||
}
|
||||
|
||||
if (result.result) {
|
||||
if (result.nextToken) {
|
||||
regNextToken(result.nextToken);
|
||||
}
|
||||
window.location.href = "./";
|
||||
return;
|
||||
}
|
||||
@@ -156,9 +261,16 @@ function postOAuthResult(mode: string) {
|
||||
window.postOAuthResult = postOAuthResult;
|
||||
|
||||
|
||||
$(function ($) {
|
||||
$(async function ($) {
|
||||
setAxiosXMLHttpRequest();
|
||||
|
||||
//로그인 먼저 해볼 것
|
||||
if(getToken()){
|
||||
void tryAutoLogin();
|
||||
await delay(100);
|
||||
}
|
||||
|
||||
|
||||
type LoginFormType = {
|
||||
username: string,
|
||||
password: string,
|
||||
@@ -194,13 +306,16 @@ $(function ($) {
|
||||
|
||||
try {
|
||||
const response = await axios({
|
||||
url: 'j_login.php',
|
||||
url: 'api.php',
|
||||
responseType: 'json',
|
||||
method: 'post',
|
||||
data: convertFormData({
|
||||
username: values.username,
|
||||
password: hash_pw,
|
||||
})
|
||||
data: {
|
||||
path: ["Login", "LoginByID"],
|
||||
args: {
|
||||
username: values.username,
|
||||
password: hash_pw,
|
||||
}
|
||||
}
|
||||
});
|
||||
result = response.data;
|
||||
}
|
||||
@@ -212,6 +327,9 @@ $(function ($) {
|
||||
|
||||
|
||||
if (result.result) {
|
||||
if (result.nextToken) {
|
||||
regNextToken(result.nextToken);
|
||||
}
|
||||
window.location.href = "./";
|
||||
return;
|
||||
}
|
||||
@@ -268,12 +386,11 @@ $(function ($) {
|
||||
getOAuthToken('change_pw', 'talk_message');
|
||||
});
|
||||
|
||||
$('#btn_kakao_login').on('click', function(e){
|
||||
$('#btn_kakao_login').on('click', function (e) {
|
||||
e.preventDefault();
|
||||
getOAuthToken('login', ['account_email','talk_message']);
|
||||
getOAuthToken('login', ['account_email', 'talk_message']);
|
||||
})
|
||||
|
||||
|
||||
//TODO: 모바일에서 크기 비례 지도 다시 띄우기?
|
||||
/*
|
||||
if (document.body.clientWidth < 700) {
|
||||
|
||||
@@ -192,6 +192,19 @@ $(function ($) {
|
||||
return false;
|
||||
})
|
||||
|
||||
$('.open-window').on('click', function(e){
|
||||
e.preventDefault();
|
||||
let target = $(e.target as HTMLAnchorElement);
|
||||
while(target.attr('href') === undefined){
|
||||
target = target.parent('a');
|
||||
if(target.length == 0){
|
||||
return;
|
||||
}
|
||||
}
|
||||
const href = target.attr('href');
|
||||
window.open(href);
|
||||
});
|
||||
|
||||
setInterval(myclock, 500);
|
||||
reloadCommandList();
|
||||
activateFlip();
|
||||
|
||||
-181
@@ -1,181 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
require(__DIR__ . '/vendor/autoload.php');
|
||||
require(__DIR__ . '/oauth_kakao/lib.join.php');
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
use \kakao\Kakao_REST_API_Helper as Kakao_REST_API_Helper;
|
||||
|
||||
$RootDB = RootDB::db();
|
||||
$session = Session::getInstance();
|
||||
if ($session->isLoggedIn()) {
|
||||
$session->logout();
|
||||
}
|
||||
|
||||
$username = mb_strtolower(Util::getPost('username'), 'utf-8');
|
||||
$password = Util::getPost('password');
|
||||
|
||||
if (!$username || !$password) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '올바르지 않은 입력입니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
function kakaoOAuthCheck(array $userInfo): ?array
|
||||
{
|
||||
|
||||
if (!\kakao\KakaoKey::REST_KEY) {
|
||||
return [false, '카카오 API 앱이 등록되지 않았습니다. 관리자에게 문의해 주세요.'];
|
||||
}
|
||||
|
||||
$oauthID = $userInfo['oauth_id'];
|
||||
$oauthInfo = Json::decode($userInfo['oauth_info']) ?? [];
|
||||
if (!$oauthInfo) {
|
||||
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$accessToken = $oauthInfo['accessToken'] ?? null;
|
||||
$refreshToken = $oauthInfo['refreshToken'] ?? null;
|
||||
$accessTokenValidUntil = $oauthInfo['accessTokenValidUntil'] ?? null;
|
||||
$refreshTokenValidUntil = $oauthInfo['refreshTokenValidUntil'] ?? null;
|
||||
$OTPValue = $oauthInfo['OTPValue'] ?? null;
|
||||
$OTPTrialUntil = $oauthInfo['OTPTrialUntil'] ?? null;
|
||||
$tokenValidUntil = $userInfo['token_valid_until'];
|
||||
|
||||
if (!$accessToken || !$refreshToken || !$accessTokenValidUntil || !$refreshTokenValidUntil) {
|
||||
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$now = TimeUtil::now();
|
||||
|
||||
if ($now > $refreshTokenValidUntil) {
|
||||
return [false, '로그인 토큰이 만료되었습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
if ($now > $accessTokenValidUntil) {
|
||||
$apiHelper = new Kakao_REST_API_Helper($accessToken);
|
||||
$refreshResult = $apiHelper->refresh_access_token($refreshToken);
|
||||
if (!$refreshResult) {
|
||||
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$accessToken = $refreshResult['access_token'] ?? null;
|
||||
|
||||
if (!$accessToken) {
|
||||
trigger_error("refreshToken 에러 " . Json::encode($refreshResult) . "," . $refreshToken . "," . substr(\kakao\KakaoKey::REST_KEY, 0, 6), E_USER_NOTICE);
|
||||
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
$accessTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['expires_in']);
|
||||
|
||||
$oauthInfo['accessToken'] = $accessToken;
|
||||
$oauthInfo['accessTokenValidUntil'] = $accessTokenValidUntil;
|
||||
|
||||
$refreshToken = $refreshResult['refresh_token'] ?? null;
|
||||
if ($refreshToken) {
|
||||
$refreshTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['refresh_token_expires_in']);
|
||||
|
||||
$oauthInfo['refreshToken'] = $refreshToken;
|
||||
$oauthInfo['refresh_token_expires_in'] = $refreshTokenValidUntil;
|
||||
}
|
||||
|
||||
RootDB::db()->update('member', [
|
||||
'oauth_info' => Json::encode($oauthInfo)
|
||||
], 'no=%i', $userInfo['no']);
|
||||
}
|
||||
|
||||
if ($tokenValidUntil && $now <= $tokenValidUntil) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//인증 시스템 가동
|
||||
$session = Session::getInstance();
|
||||
$session->access_token = $accessToken;
|
||||
$session->expires = $accessTokenValidUntil;
|
||||
$session->refresh_token = $refreshToken;
|
||||
$session->refresh_token_expires = $refreshTokenValidUntil;
|
||||
|
||||
if (!createOTPbyUserNO($userInfo['no'])) {
|
||||
return [false, '인증 코드를 보내는데 실패했습니다.'];
|
||||
}
|
||||
|
||||
return [true, '인증 코드를 입력해주세요'];
|
||||
}
|
||||
|
||||
$userInfo = $RootDB->queryFirstRow(
|
||||
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until ' .
|
||||
'from member where id=%s_username AND ' .
|
||||
'pw=sha2(concat(salt, %s_password, salt), 512)',
|
||||
[
|
||||
'username' => $username,
|
||||
'password' => $password
|
||||
]
|
||||
);
|
||||
|
||||
if (!$userInfo) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '아이디나 비밀번호가 올바르지 않습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
|
||||
if ($canLogin != 'Y' && $userInfo['grade'] < 5) {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reason' => '현재는 로그인이 금지되어있습니다!'
|
||||
]);
|
||||
}
|
||||
|
||||
$nowDate = TimeUtil::now();
|
||||
if ($userInfo['delete_after']) {
|
||||
if ($userInfo['delete_after'] < $nowDate) {
|
||||
$RootDB->delete('member', 'no=%i', $userInfo['no']);
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "기간 만기로 삭제되었습니다. 재 가입을 시도해주세요."
|
||||
]);
|
||||
} else {
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
$RootDB->insert('member_log', [
|
||||
'member_no' => $userInfo['no'],
|
||||
'action_type' => 'login',
|
||||
'action' => Json::encode([
|
||||
'ip' => Util::get_client_ip(true),
|
||||
'type' => 'plain'
|
||||
])
|
||||
]);
|
||||
|
||||
if ($userInfo['oauth_type'] == 'KAKAO') {
|
||||
$oauthFailResult = kakaoOAuthCheck($userInfo);
|
||||
if ($oauthFailResult !== null) {
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
|
||||
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
|
||||
Json::die([
|
||||
'result' => false,
|
||||
'reqOTP' => $oauthReqOTP,
|
||||
'reason' => $oauthFailReason
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl'] ?? '{}'));
|
||||
Json::die([
|
||||
'result' => true,
|
||||
'reqOTP' => false,
|
||||
'reason' => '로그인 되었습니다.'
|
||||
]);
|
||||
+123
-82
@@ -1,25 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
require(__DIR__.'/../vendor/autoload.php');
|
||||
require(__DIR__ . '/../vendor/autoload.php');
|
||||
require('lib.join.php');
|
||||
|
||||
|
||||
//TODO: KakaoOauth를 API로 정식으로 이동
|
||||
|
||||
WebUtil::requireAJAX();
|
||||
|
||||
use \kakao\Kakao_REST_API_Helper as Kakao_REST_API_Helper;
|
||||
|
||||
$RootDB = RootDB::db();
|
||||
$session = Session::getInstance();
|
||||
if($session->isLoggedIn()){
|
||||
if ($session->isLoggedIn()) {
|
||||
$session->logout();
|
||||
}
|
||||
|
||||
$canLogin = RootDB::db()->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
|
||||
if($canLogin != 'Y'){
|
||||
if ($canLogin != 'Y') {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'현재는 로그인이 금지되어있습니다!',
|
||||
'noRetry'=>true
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '현재는 로그인이 금지되어있습니다!',
|
||||
'noRetry' => true
|
||||
]);
|
||||
}
|
||||
|
||||
@@ -32,173 +37,209 @@ $refresh_token_expires = $session->refresh_token_expires;
|
||||
$email = $session->kaccount_email;
|
||||
|
||||
|
||||
if(!$access_token || !$expires){
|
||||
if (!$access_token || !$expires) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오로그인이 이루어지지 않았습니다.'
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오로그인이 이루어지지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
//TODO: join과 login의 동작이 비슷하다. helper class로 묶자.
|
||||
$restAPI = new Kakao_REST_API_Helper($access_token);
|
||||
|
||||
if($expires < $now && (!$refresh_token || ($refresh_token_expires < $now))){
|
||||
if ($expires < $now && (!$refresh_token || ($refresh_token_expires < $now))) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'로그인 토큰 만료.'.$refresh_token_expires.' 다시 카카오로그인을 수행해주세요.'
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '로그인 토큰 만료.' . $refresh_token_expires . ' 다시 카카오로그인을 수행해주세요.'
|
||||
]);
|
||||
}
|
||||
|
||||
if($expires < $now){
|
||||
if ($expires < $now) {
|
||||
$session->kaccount_email = null;
|
||||
$email = null;
|
||||
|
||||
$result = $restAPI->refresh_access_token($refresh_token);
|
||||
if(!isset($refresh_token)){
|
||||
if (!isset($refresh_token)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오 로그인 과정 중 추가 갱신 절차를 실패했습니다'
|
||||
]);
|
||||
}
|
||||
|
||||
$access_token = $result['access_token'];
|
||||
$expires = TimeUtil::nowAddSeconds($result['expires_in']);
|
||||
if(isset($result['refresh_token'])){
|
||||
if (isset($result['refresh_token'])) {
|
||||
$refresh_token = Util::array_get($result['refresh_token']);
|
||||
$refresh_token_expires = TimeUtil::nowAddSeconds($result['refresh_token_expires_in']);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(!$email){
|
||||
if (!$email) {
|
||||
$me = $restAPI->meWithEmail();
|
||||
$me['code'] = Util::array_get($me['code'], 0);
|
||||
if ($me['code']< 0) {
|
||||
if ($me['code'] < 0) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오로그인이 정상적으로 수행되지 않았습니다.'
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오로그인이 정상적으로 수행되지 않았습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
$kakao_account = $me['kakao_account']??null;
|
||||
$kakao_account = $me['kakao_account'] ?? null;
|
||||
if (!$kakao_account) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오 로그인 정보를 제대로 받아오지 못했습니다.'
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오 로그인 정보를 제대로 받아오지 못했습니다.'
|
||||
]);
|
||||
}
|
||||
|
||||
if(!($kakao_account['has_email']??false)){
|
||||
if (!($kakao_account['has_email'] ?? false)) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'이메일 정보 공유를 허가해 주셔야 합니다.',
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '이메일 정보 공유를 허가해 주셔야 합니다.',
|
||||
]);
|
||||
}
|
||||
|
||||
$validEmail = $kakao_account['is_email_valid']??false;
|
||||
$verifiedEmail = $kakao_account['is_email_verified']??false;
|
||||
$validEmail = $kakao_account['is_email_valid'] ?? false;
|
||||
$verifiedEmail = $kakao_account['is_email_verified'] ?? false;
|
||||
|
||||
if(!$validEmail || !$verifiedEmail){
|
||||
if (!$validEmail || !$verifiedEmail) {
|
||||
$restAPI->unlink();
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오 계정 이메일이 아직 인증되지 않았습니다',
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오 계정 이메일이 아직 인증되지 않았습니다',
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$email = $kakao_account['email'];
|
||||
$session->kaccount_email = $email;
|
||||
}
|
||||
|
||||
|
||||
$userInfo = $RootDB->queryFirstRow(
|
||||
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_info, token_valid_until from member where email=%s',$email);
|
||||
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_info, token_valid_until from member where email=%s',
|
||||
$email
|
||||
);
|
||||
|
||||
if(!$userInfo){
|
||||
if (!$userInfo) {
|
||||
$restAPI->unlink();
|
||||
$session->access_token = null;
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'카카오로그인에 해당하는 계정이 없습니다. 재 가입을 시도해주세요.',
|
||||
'aux'=>$session->tmpx,
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '카카오로그인에 해당하는 계정이 없습니다. 재 가입을 시도해주세요.',
|
||||
'aux' => $session->tmpx,
|
||||
]);
|
||||
}
|
||||
|
||||
if($userInfo['delete_after']){
|
||||
if($userInfo['delete_after'] < $now){
|
||||
if ($userInfo['delete_after']) {
|
||||
if ($userInfo['delete_after'] < $now) {
|
||||
$restAPI->unlink();
|
||||
$session->access_token = null;
|
||||
$RootDB->delete('member', 'no=%i', $userInfo['no']);
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>"기간 만기로 삭제되었습니다. 재 가입을 시도해주세요.",
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "기간 만기로 삭제되었습니다. 재 가입을 시도해주세요.",
|
||||
]);
|
||||
}
|
||||
else{
|
||||
} else {
|
||||
$restAPI->unlink();
|
||||
$session->access_token = null;
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>"삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$oauthInfo = Json::decode($userInfo['oauth_info'])??[];
|
||||
$oauthInfo = Json::decode($userInfo['oauth_info']) ?? [];
|
||||
$oauthInfo['accessToken'] = $access_token;
|
||||
$oauthInfo['accessTokenValidUntil'] = $expires;
|
||||
if($refresh_token){
|
||||
if ($refresh_token) {
|
||||
$oauthInfo['refreshToken'] = $refresh_token;
|
||||
$oauthInfo['refreshTokenValidUntil'] = $refresh_token_expires;
|
||||
}
|
||||
|
||||
RootDB::db()->update('member', [
|
||||
'oauth_info'=>Json::encode($oauthInfo)
|
||||
'oauth_info' => Json::encode($oauthInfo)
|
||||
], 'no=%i', $userInfo['no']);
|
||||
|
||||
|
||||
$tokenValidUntil = $userInfo['token_valid_until'];
|
||||
|
||||
if(!$tokenValidUntil || $tokenValidUntil < $now){
|
||||
if(!createOTPbyUserNO($userInfo['no'])){
|
||||
if (!$tokenValidUntil || $tokenValidUntil < $now) {
|
||||
if (!createOTPbyUserNO($userInfo['no'])) {
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'인증 코드를 보내는데 실패했습니다.'
|
||||
]);
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => '인증 코드를 보내는데 실패했습니다.'
|
||||
]);
|
||||
}
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}'));
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
|
||||
Json::die([
|
||||
'result'=>false,
|
||||
'reqOTP'=>true,
|
||||
'reason'=>'인증 코드를 입력해주세요.'
|
||||
'result' => false,
|
||||
'reqOTP' => true,
|
||||
'reason' => '인증 코드를 입력해주세요.'
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
$RootDB->insert('member_log',[
|
||||
'member_no'=>$userInfo['no'],
|
||||
'action_type'=>'login',
|
||||
'action'=>Json::encode([
|
||||
'ip'=>Util::get_client_ip(true),
|
||||
'type'=>'kakao'
|
||||
$RootDB->insert('member_log', [
|
||||
'member_no' => $userInfo['no'],
|
||||
'action_type' => 'login',
|
||||
'action' => Json::encode([
|
||||
'ip' => Util::get_client_ip(true),
|
||||
'type' => 'kakao'
|
||||
])
|
||||
]);
|
||||
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], Json::decode($userInfo['acl']??'{}'));
|
||||
|
||||
//TODO: 이동하면서 이부분 정리
|
||||
$nowDate = TimeUtil::now();
|
||||
$RootDB->delete(
|
||||
'login_token',
|
||||
'user_id = %i AND expire_date < %s',
|
||||
$userID,
|
||||
$nowDate
|
||||
);
|
||||
$RootDB->query(
|
||||
'DELETE invalid FROM login_token AS invalid
|
||||
JOIN
|
||||
( SELECT id
|
||||
FROM login_token
|
||||
WHERE user_id = %i
|
||||
ORDER BY id DESC
|
||||
LIMIT 8,1
|
||||
) AS valid
|
||||
ON invalid.id < valid.id WHERE user_id = %i',
|
||||
$userID,
|
||||
$userID
|
||||
);
|
||||
$token = Util::randomStr(20);
|
||||
$RootDB->insert('login_token', [
|
||||
'user_id' => $userInfo['no'],
|
||||
'base_token' => $token,
|
||||
'reg_ip' => Util::get_client_ip(true),
|
||||
'reg_date' => $nowDate,
|
||||
'expire_date' => TimeUtil::nowAddDays(7)
|
||||
]);
|
||||
$tokenID = $RootDB->insertId();
|
||||
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $tokenID, Json::decode($userInfo['acl'] ?? '{}'));
|
||||
|
||||
|
||||
|
||||
Json::die([
|
||||
'result'=>true,
|
||||
'reqOTP'=>false,
|
||||
'reason'=>'로그인 되었습니다.'
|
||||
]);
|
||||
'result' => true,
|
||||
'reqOTP' => false,
|
||||
'nextToken' => [$tokenID, $token],
|
||||
'reason' => '로그인 되었습니다.'
|
||||
]);
|
||||
|
||||
@@ -0,0 +1,162 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Login;
|
||||
|
||||
use DateTime;
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\BaseAPI;
|
||||
use sammo\Json;
|
||||
use sammo\KakaoUtil;
|
||||
use sammo\RootDB;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
class LoginByID extends \sammo\BaseAPI
|
||||
{
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v
|
||||
->rule('required', [
|
||||
'username',
|
||||
'password'
|
||||
]);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return BaseAPI::NO_SESSION;
|
||||
}
|
||||
|
||||
public function scrubToken(int $userID)
|
||||
{
|
||||
$RootDB = RootDB::db();
|
||||
$nowDate = TimeUtil::now();
|
||||
$RootDB->delete(
|
||||
'login_token',
|
||||
'user_id = %i AND expire_date < %s',
|
||||
$userID,
|
||||
$nowDate
|
||||
);
|
||||
$RootDB->query(
|
||||
'DELETE invalid FROM login_token AS invalid
|
||||
JOIN
|
||||
( SELECT id
|
||||
FROM login_token
|
||||
WHERE user_id = %i
|
||||
ORDER BY id DESC
|
||||
LIMIT 8,1
|
||||
) AS valid
|
||||
ON invalid.id < valid.id WHERE user_id = %i',
|
||||
$userID,
|
||||
$userID
|
||||
);
|
||||
}
|
||||
|
||||
public function addToken(int $userID)
|
||||
{
|
||||
$RootDB = RootDB::db();
|
||||
$nowDate = TimeUtil::now();
|
||||
$token = Util::randomStr(20);
|
||||
$RootDB->insert('login_token', [
|
||||
'user_id' => $userID,
|
||||
'base_token' => $token,
|
||||
'reg_ip' => Util::get_client_ip(true),
|
||||
'reg_date' => $nowDate,
|
||||
'expire_date' => TimeUtil::nowAddDays(7)
|
||||
]);
|
||||
$tokenID = $RootDB->insertId();
|
||||
return [$tokenID, $token];
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$RootDB = RootDB::db();
|
||||
if ($session->isLoggedIn()) {
|
||||
$session->logout();
|
||||
}
|
||||
|
||||
$username = $this->args['username'];
|
||||
$password = $this->args['password'];
|
||||
|
||||
$userInfo = $RootDB->queryFirstRow(
|
||||
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until ' .
|
||||
'from member where id=%s_username AND ' .
|
||||
'pw=sha2(concat(salt, %s_password, salt), 512)',
|
||||
[
|
||||
'username' => $username,
|
||||
'password' => $password
|
||||
]
|
||||
);
|
||||
|
||||
if (!$userInfo) {
|
||||
return '아이디나 비밀번호가 올바르지 않습니다.';
|
||||
}
|
||||
|
||||
$canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
|
||||
if ($canLogin != 'Y' && $userInfo['grade'] < 5) {
|
||||
return '현재는 로그인이 금지되어있습니다!';
|
||||
}
|
||||
|
||||
|
||||
$nowDate = TimeUtil::now();
|
||||
if ($userInfo['delete_after']) {
|
||||
if ($userInfo['delete_after'] < $nowDate) {
|
||||
$RootDB->delete('member', 'no=%i', $userInfo['no']);
|
||||
return [
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "기간 만기로 삭제되었습니다. 재 가입을 시도해주세요."
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'result' => false,
|
||||
'reqOTP' => false,
|
||||
'reason' => "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$RootDB->insert('member_log', [
|
||||
'member_no' => $userInfo['no'],
|
||||
'action_type' => 'login',
|
||||
'action' => Json::encode([
|
||||
'ip' => Util::get_client_ip(true),
|
||||
'type' => 'plain'
|
||||
])
|
||||
]);
|
||||
|
||||
if ($userInfo['oauth_type'] == 'KAKAO') {
|
||||
$oauthFailResult = KakaoUtil::kakaoOAuthCheck($userInfo);
|
||||
if ($oauthFailResult !== null) {
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
|
||||
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
|
||||
return [
|
||||
'result' => false,
|
||||
'reqOTP' => $oauthReqOTP,
|
||||
'reason' => $oauthFailReason
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$this->scrubToken($userInfo['no']);
|
||||
$nextToken = $this->addToken($userInfo['no']);
|
||||
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $nextToken[0], Json::decode($userInfo['acl'] ?? '{}'));
|
||||
|
||||
|
||||
return [
|
||||
'result' => true,
|
||||
'reqOTP' => false,
|
||||
'nextToken' => $nextToken,
|
||||
'reason' => '로그인 되었습니다.'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Login;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\BaseAPI;
|
||||
use sammo\Json;
|
||||
use sammo\KakaoUtil;
|
||||
use sammo\RootDB;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
class LoginByToken extends LoginByID
|
||||
{
|
||||
|
||||
public function getRequiredSessionMode(): int
|
||||
{
|
||||
return \sammo\BaseAPI::NO_SESSION; //XXX: Token 때문에 엄밀히는 NO_SESSION이 아님
|
||||
}
|
||||
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
$v = new Validator($this->args);
|
||||
$v
|
||||
->rule('required', [
|
||||
'token_id',
|
||||
'hashedToken'
|
||||
]);
|
||||
|
||||
if (!$v->validate()) {
|
||||
return $v->errorStr();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag)
|
||||
{
|
||||
$loginNonce = $session->loginNonce ?? null;
|
||||
$loginNonceExpired = $session->loginNonceExpired ?? null;
|
||||
if (!is_string($loginNonce) || !is_string($loginNonceExpired)) {
|
||||
return '자동 로그인: 절차 오류';
|
||||
}
|
||||
|
||||
$RootDB = RootDB::db();
|
||||
if ($session->isLoggedIn()) {
|
||||
$session->logout();
|
||||
}
|
||||
|
||||
$token_id = $this->args['token_id'];
|
||||
|
||||
$token_info = $RootDB->queryFirstRow('SELECT * FROM login_token WHERE id = %i', $token_id);
|
||||
if (!$token_info) {
|
||||
return [
|
||||
'result' => false,
|
||||
'silent' => true,
|
||||
'reason' => 'failed'
|
||||
];
|
||||
}
|
||||
|
||||
$hashedToken = $this->args['hashedToken'];
|
||||
$tokenAnswer = hash('sha512', "{$token_info['base_token']}{$loginNonce}");
|
||||
if (strtolower($hashedToken) != strtolower($tokenAnswer)) {
|
||||
return [
|
||||
'result' => false,
|
||||
'silent' => true,
|
||||
'reason' => 'failed'
|
||||
];
|
||||
}
|
||||
|
||||
$userInfo = $RootDB->queryFirstRow(
|
||||
'SELECT `no`, `id`, `name`, `grade`, `delete_after`, `acl`, oauth_id, oauth_type, oauth_info, token_valid_until ' .
|
||||
'from member where NO = %i',
|
||||
$token_info['user_id']
|
||||
);
|
||||
if(!$userInfo){
|
||||
return '자동 로그인: 올바른 계정이 아닙니다.';
|
||||
}
|
||||
|
||||
$canLogin = $RootDB->queryFirstField('SELECT `LOGIN` FROM `system` WHERE `NO` = 1');
|
||||
if ($canLogin != 'Y' && $userInfo['grade'] < 5) {
|
||||
return '자동 로그인: 현재는 로그인이 금지되어있습니다!';
|
||||
}
|
||||
|
||||
$nowDate = TimeUtil::now();
|
||||
if ($userInfo['delete_after']) {
|
||||
if ($userInfo['delete_after'] < $nowDate) {
|
||||
$RootDB->delete('member', 'no=%i', $userInfo['no']);
|
||||
return [
|
||||
'result' => false,
|
||||
'silent' => true,
|
||||
'reason' => "기간 만기"
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'result' => false,
|
||||
'silent' => true,
|
||||
'reason' => "삭제 요청된 계정[{$userInfo['delete_after']}]"
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
$RootDB->insert('member_log', [
|
||||
'member_no' => $userInfo['no'],
|
||||
'action_type' => 'login',
|
||||
'action' => Json::encode([
|
||||
'ip' => Util::get_client_ip(true),
|
||||
'type' => 'auto'
|
||||
])
|
||||
]);
|
||||
|
||||
if ($userInfo['oauth_type'] == 'KAKAO') {
|
||||
$oauthFailResult = KakaoUtil::kakaoOAuthCheck($userInfo);
|
||||
if ($oauthFailResult !== null) {
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], true, $userInfo['token_valid_until'], null, Json::decode($userInfo['acl'] ?? '{}'));
|
||||
[$oauthReqOTP, $oauthFailReason] = $oauthFailResult;
|
||||
$RootDB->delete(
|
||||
'login_token',
|
||||
'id = %i', $token_id
|
||||
);
|
||||
return $oauthFailReason;
|
||||
}
|
||||
}
|
||||
|
||||
$session->login($userInfo['no'], $userInfo['id'], $userInfo['grade'], false, $userInfo['token_valid_until'], $token_id, Json::decode($userInfo['acl'] ?? '{}'));
|
||||
$this->scrubToken($userInfo['no']);
|
||||
|
||||
$nextDate = TimeUtil::nowAddDays(2);
|
||||
if($nextDate < $token_info['expire_date']){
|
||||
return [
|
||||
'result' => true,
|
||||
'silent' => true,
|
||||
'reason' => 'success'
|
||||
];
|
||||
}
|
||||
|
||||
$RootDB->delete(
|
||||
'login_token',
|
||||
'id = %i', $token_id
|
||||
);
|
||||
$nextToken = $this->addToken($token_id);
|
||||
return [
|
||||
'result' => true,
|
||||
'silent' => true,
|
||||
'nextToken' => $nextToken,
|
||||
'reason' => 'success'
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace sammo\API\Login;
|
||||
|
||||
use sammo\Session;
|
||||
use DateTimeInterface;
|
||||
use sammo\BaseAPI;
|
||||
use sammo\Json;
|
||||
use sammo\KakaoUtil;
|
||||
use sammo\RootDB;
|
||||
use sammo\TimeUtil;
|
||||
use sammo\Util;
|
||||
use sammo\Validator;
|
||||
|
||||
class ReqNonce extends BaseAPI{
|
||||
|
||||
public function getRequiredSessionMode(): int {
|
||||
return \sammo\BaseAPI::NO_SESSION;
|
||||
}
|
||||
|
||||
public function validateArgs(): ?string
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public function launch(Session $session, ?DateTimeInterface $modifiedSince, ?string $reqEtag) {
|
||||
$loginNonce = Util::randomStr(16);
|
||||
$loginNonceExpired = TimeUtil::nowAddSeconds(2);
|
||||
$session->loginNonce = $loginNonce;
|
||||
$session->loginNonceExpired = $loginNonceExpired;
|
||||
return [
|
||||
'result'=>true,
|
||||
'loginNonce'=>$loginNonce,
|
||||
];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -40,7 +40,7 @@ class APIHelper
|
||||
|
||||
$sessionMode = $obj->getRequiredSessionMode();
|
||||
if ($sessionMode === BaseAPI::NO_SESSION) {
|
||||
$session = null;
|
||||
$session = Session::getInstance();//XXX: NoSession이면 진짜 NoSession이어야..?
|
||||
} else {
|
||||
if ($sessionMode & BaseAPI::REQ_GAME_LOGIN) {
|
||||
$session = Session::requireGameLogin();
|
||||
@@ -71,7 +71,7 @@ class APIHelper
|
||||
[$lastModified, $etag] = $cacheResult;
|
||||
|
||||
if ($lastModified !== null) {
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s", TimeUtil::DateTimeToSeconds($lastModified, true)) . " GMT");
|
||||
header("Last-Modified: " . gmdate("D, d M Y H:i:s", Util::toInt(TimeUtil::DateTimeToSeconds($lastModified, true))) . " GMT");
|
||||
}
|
||||
if ($etag !== null) {
|
||||
header("Etag: $etag");
|
||||
@@ -94,10 +94,10 @@ class APIHelper
|
||||
], $cacheResult === null ? Json::NO_CACHE : 0);
|
||||
}
|
||||
Json::die($result, $cacheResult === null ? Json::NO_CACHE : 0);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
Json::dieWithReason($e->getMessage());
|
||||
} catch (mixed $e) {
|
||||
Json::dieWithReason($e);
|
||||
Json::dieWithReason(strval($e));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ class Json
|
||||
return json_decode($value);
|
||||
}
|
||||
|
||||
/** @return never */
|
||||
public static function die($value, $flag = self::NO_CACHE)
|
||||
{
|
||||
//NOTE: REST 형식에 맞게, ok(), fail()로 쪼개는게 낫지 않을까 생각해봄.
|
||||
|
||||
@@ -0,0 +1,221 @@
|
||||
<?php
|
||||
|
||||
namespace sammo;
|
||||
|
||||
use kakao\Kakao_REST_API_Helper;
|
||||
|
||||
class KakaoUtil
|
||||
{
|
||||
private function __construct()
|
||||
{
|
||||
}
|
||||
|
||||
static function checkUsernameDup($username)
|
||||
{
|
||||
if (!$username) {
|
||||
return '계정명을 입력해주세요';
|
||||
}
|
||||
|
||||
$username = mb_strtolower($username, 'utf-8');
|
||||
$length = strlen($username);
|
||||
if ($length < 4 || $length > 64) {
|
||||
return '적절하지 않은 길이입니다.';
|
||||
}
|
||||
|
||||
$cnt = RootDB::db()->queryFirstField('SELECT count(no) FROM member WHERE `id` = %s LIMIT 1', $username);
|
||||
if ($cnt != 0) {
|
||||
return '이미 사용중인 계정명입니다';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static function checkNicknameDup($nickname)
|
||||
{
|
||||
if (!$nickname) {
|
||||
return '닉네임을 입력해주세요';
|
||||
}
|
||||
|
||||
$length = mb_strwidth($nickname, 'utf-8');
|
||||
if ($length < 1 || $length > 18) {
|
||||
return '적절하지 않은 길이입니다.';
|
||||
}
|
||||
|
||||
$cnt = RootDB::db()->queryFirstField('SELECT count(no) FROM member WHERE `name` = %s LIMIT 1', $nickname);
|
||||
if ($cnt != 0) {
|
||||
return '이미 사용중인 닉네임입니다';
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static function checkEmailDup($email)
|
||||
{
|
||||
if (!$email) {
|
||||
return '이메일을 입력해주세요';
|
||||
}
|
||||
|
||||
$length = strlen($email);
|
||||
if ($length < 1 || $length > 64) {
|
||||
return '적절하지 않은 길이입니다.';
|
||||
}
|
||||
|
||||
$userInfo = RootDB::db()->queryFirstField('SELECT `no`, `delete_after` FROM member WHERE `email` = %s LIMIT 1', $email);
|
||||
if ($userInfo) {
|
||||
if (!$userInfo['delete_after']) {
|
||||
return '이미 사용중인 이메일입니다. 관리자에게 문의해주세요.';
|
||||
}
|
||||
|
||||
if ($userInfo['delete_after'] >= $userInfo) {
|
||||
return "삭제 요청된 계정입니다.[{$userInfo['delete_after']}]";
|
||||
}
|
||||
|
||||
//$userInfo['delete_after'] < $userInfo
|
||||
RootDB::db()->delete('member', 'no=%i', $userInfo['no']);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static function createOTPbyUserNO(int $userNo): bool
|
||||
{
|
||||
$userInfo = RootDB::db()->queryFirstRow('SELECT oauth_info FROM member WHERE no=%i', $userNo);
|
||||
if (!$userInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oauthInfo = Json::decode($userInfo['oauth_info']);
|
||||
if (!$oauthInfo) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$accessToken = $oauthInfo['accessToken'];
|
||||
$OTPValue = $oauthInfo['OTPValue'] ?? null;
|
||||
$OTPTrialUntil = $oauthInfo['OTPTrialUntil'] ?? null;
|
||||
|
||||
$now = TimeUtil::now();
|
||||
|
||||
|
||||
if ($OTPTrialUntil && $OTPValue && $OTPTrialUntil > $now) {
|
||||
return true;
|
||||
}
|
||||
|
||||
[$OTPValue, $OTPTrialUntil] = static::createOTP($accessToken);
|
||||
|
||||
if (!$OTPValue) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$oauthInfo['OTPValue'] = $OTPValue;
|
||||
$oauthInfo['OTPTrialUntil'] = $OTPTrialUntil;
|
||||
$oauthInfo['OTPTrialCount'] = 3;
|
||||
|
||||
RootDB::db()->update('member', [
|
||||
'oauth_info' => Json::encode($oauthInfo)
|
||||
], 'no=%i', $userNo);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static function createOTP(string $accessToken): ?array
|
||||
{
|
||||
$restAPI = new Kakao_REST_API_Helper($accessToken);
|
||||
|
||||
$OTPValue = Util::randRangeInt(1000, 9999);
|
||||
$OTPTrialUntil = TimeUtil::nowAddSeconds(180);
|
||||
|
||||
$sendResult = $restAPI->talk_to_me_default([
|
||||
"object_type" => "text",
|
||||
"text" => "인증 코드는 $OTPValue 입니다. $OTPTrialUntil 이내에 입력해주세요.",
|
||||
"link" => [
|
||||
"web_url" => ServConfig::getServerBasepath(),
|
||||
"mobile_web_url" => ServConfig::getServerBasepath()
|
||||
],
|
||||
"button_title" => "로그인 페이지 열기"
|
||||
]);
|
||||
$sendResult['code'] = Util::array_get($sendResult['code'], 0);
|
||||
if ($sendResult['code'] < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return [$OTPValue, $OTPTrialUntil];
|
||||
}
|
||||
|
||||
static function kakaoOAuthCheck(array $userInfo): ?array
|
||||
{
|
||||
|
||||
if (!\kakao\KakaoKey::REST_KEY) {
|
||||
return [false, '카카오 API 앱이 등록되지 않았습니다. 관리자에게 문의해 주세요.'];
|
||||
}
|
||||
|
||||
$oauthID = $userInfo['oauth_id'];
|
||||
$oauthInfo = Json::decode($userInfo['oauth_info']) ?? [];
|
||||
if (!$oauthInfo) {
|
||||
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$accessToken = $oauthInfo['accessToken'] ?? null;
|
||||
$refreshToken = $oauthInfo['refreshToken'] ?? null;
|
||||
$accessTokenValidUntil = $oauthInfo['accessTokenValidUntil'] ?? null;
|
||||
$refreshTokenValidUntil = $oauthInfo['refreshTokenValidUntil'] ?? null;
|
||||
$OTPValue = $oauthInfo['OTPValue'] ?? null;
|
||||
$OTPTrialUntil = $oauthInfo['OTPTrialUntil'] ?? null;
|
||||
$tokenValidUntil = $userInfo['token_valid_until'];
|
||||
|
||||
if (!$accessToken || !$refreshToken || !$accessTokenValidUntil || !$refreshTokenValidUntil) {
|
||||
return [false, 'OAuth 정보가 보관되어 있지 않습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$now = TimeUtil::now();
|
||||
|
||||
if ($now > $refreshTokenValidUntil) {
|
||||
return [false, '로그인 토큰이 만료되었습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
if ($now > $accessTokenValidUntil) {
|
||||
$apiHelper = new Kakao_REST_API_Helper($accessToken);
|
||||
$refreshResult = $apiHelper->refresh_access_token($refreshToken);
|
||||
if (!$refreshResult) {
|
||||
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
|
||||
$accessToken = $refreshResult['access_token'] ?? null;
|
||||
|
||||
if (!$accessToken) {
|
||||
trigger_error("refreshToken 에러 " . Json::encode($refreshResult) . "," . $refreshToken . "," . substr(\kakao\KakaoKey::REST_KEY, 0, 6), E_USER_NOTICE);
|
||||
return [false, '로그인 토큰 자동 갱신을 실패했습니다. 카카오 로그인을 수행해 주세요.'];
|
||||
}
|
||||
$accessTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['expires_in']);
|
||||
|
||||
$oauthInfo['accessToken'] = $accessToken;
|
||||
$oauthInfo['accessTokenValidUntil'] = $accessTokenValidUntil;
|
||||
|
||||
$refreshToken = $refreshResult['refresh_token'] ?? null;
|
||||
if ($refreshToken) {
|
||||
$refreshTokenValidUntil = TimeUtil::nowAddSeconds($refreshResult['refresh_token_expires_in']);
|
||||
|
||||
$oauthInfo['refreshToken'] = $refreshToken;
|
||||
$oauthInfo['refresh_token_expires_in'] = $refreshTokenValidUntil;
|
||||
}
|
||||
|
||||
RootDB::db()->update('member', [
|
||||
'oauth_info' => Json::encode($oauthInfo)
|
||||
], 'no=%i', $userInfo['no']);
|
||||
}
|
||||
|
||||
if ($tokenValidUntil && $now <= $tokenValidUntil) {
|
||||
return null;
|
||||
}
|
||||
|
||||
//인증 시스템 가동
|
||||
$session = Session::getInstance();
|
||||
$session->access_token = $accessToken;
|
||||
$session->expires = $accessTokenValidUntil;
|
||||
$session->refresh_token = $refreshToken;
|
||||
$session->refresh_token_expires = $refreshTokenValidUntil;
|
||||
|
||||
if (!createOTPbyUserNO($userInfo['no'])) {
|
||||
return [false, '인증 코드를 보내는데 실패했습니다.'];
|
||||
}
|
||||
|
||||
return [true, '인증 코드를 입력해주세요'];
|
||||
}
|
||||
}
|
||||
+16
-10
@@ -10,8 +10,9 @@ namespace sammo;
|
||||
* @property string $ip IP
|
||||
* @property bool $reqOTP 인증 코드 필요
|
||||
* @property array $acl 권한
|
||||
* @property int|null $tokenID 토큰ID
|
||||
* @property string $tokenValidUntil 로그인 토큰 길이
|
||||
*
|
||||
*
|
||||
* @property int $generalID 장수 번호 (게임 로그인 필요)
|
||||
* @property string $generalName 장수 이름 (게임 로그인 필요)
|
||||
*/
|
||||
@@ -35,7 +36,7 @@ class Session
|
||||
const GAME_KEY_GENERAL_ID = '_g_no';
|
||||
const GAME_KEY_GENERAL_NAME = '_g_name';
|
||||
const GAME_KEY_EXPECTED_DEADTIME = '_g_deadtime';
|
||||
|
||||
|
||||
|
||||
private $writeClosed = false;
|
||||
private $sessionID = null;
|
||||
@@ -170,7 +171,7 @@ class Session
|
||||
return Util::array_get($_SESSION[$name]);
|
||||
}
|
||||
|
||||
public function login(int $userID, string $userName, int $grade, bool $reqOTP, ?string $tokenValidUntil, array $acl): Session
|
||||
public function login(int $userID, string $userName, int $grade, bool $reqOTP, ?string $tokenValidUntil, ?int $tokenID, array $acl): Session
|
||||
{
|
||||
$this->set('userID', $userID);
|
||||
$this->set('userName', $userName);
|
||||
@@ -180,6 +181,7 @@ class Session
|
||||
$this->set('acl', $acl);
|
||||
$this->set('reqOTP', $reqOTP);
|
||||
$this->set('tokenValidUntil', $tokenValidUntil);
|
||||
$this->set('tokenID', $tokenID);
|
||||
return $this;
|
||||
}
|
||||
|
||||
@@ -197,7 +199,11 @@ class Session
|
||||
if (class_exists('\\sammo\\UniqueConst')) {
|
||||
$this->logoutGame();
|
||||
}
|
||||
|
||||
|
||||
if($this->tokenID??null){
|
||||
RootDB::db()->delete('login_token', 'id = %i', $this->tokenID);
|
||||
}
|
||||
|
||||
$this->set('userID', null);
|
||||
$this->set('userName', null);
|
||||
$this->set('userGrade', null);
|
||||
@@ -261,7 +267,7 @@ class Session
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
$turnterm = $gameStor->turnterm;
|
||||
$isUnited = $gameStor->isunited != 0;
|
||||
|
||||
@@ -319,7 +325,7 @@ class Session
|
||||
} else {
|
||||
$obj = self::getInstance();
|
||||
}
|
||||
|
||||
|
||||
return $obj->userGrade;
|
||||
}
|
||||
|
||||
@@ -335,12 +341,12 @@ class Session
|
||||
} else {
|
||||
$obj = self::getInstance();
|
||||
}
|
||||
|
||||
|
||||
return $obj->userID;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public static function getGeneralID(bool $requireLogin = false, string $exitPath = '..')
|
||||
{
|
||||
@@ -349,7 +355,7 @@ class Session
|
||||
} else {
|
||||
$obj = self::getInstance();
|
||||
}
|
||||
|
||||
|
||||
return $obj->generalID??0;
|
||||
}
|
||||
|
||||
@@ -367,7 +373,7 @@ class Session
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if ($this->userID) {
|
||||
return true;
|
||||
} else {
|
||||
|
||||
+26
-26
@@ -156,7 +156,7 @@ class Util extends \utilphp\util
|
||||
else{
|
||||
$text = str_replace("_tK_{$key}_", $value, $text);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
file_put_contents($destFilePath, $text);
|
||||
|
||||
@@ -182,7 +182,7 @@ class Util extends \utilphp\util
|
||||
else{
|
||||
$head[] = "class $newClassName extends $srcClassName";
|
||||
}
|
||||
|
||||
|
||||
$head[] = '{';
|
||||
$head[] = '';
|
||||
$head = join("\n", $head);
|
||||
@@ -203,7 +203,7 @@ class Util extends \utilphp\util
|
||||
}
|
||||
$result = file_put_contents($destFilePath, $head.join("\n", $body).$tail, LOCK_EX);
|
||||
assert($result);
|
||||
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -281,12 +281,12 @@ class Util extends \utilphp\util
|
||||
public static function convertArrayToDict($arr, $keyName)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
|
||||
foreach ($arr as $obj) {
|
||||
$key = $obj[$keyName];
|
||||
$result[$key] = $obj;
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -309,7 +309,7 @@ class Util extends \utilphp\util
|
||||
public static function convertDictToArray($dict, bool $withKey=true)
|
||||
{
|
||||
$result = [];
|
||||
|
||||
|
||||
foreach($dict as $key=>$value){
|
||||
if($withKey){
|
||||
$result[] = [$key, $value];
|
||||
@@ -318,7 +318,7 @@ class Util extends \utilphp\util
|
||||
$result[] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ class Util extends \utilphp\util
|
||||
foreach($dict as $dictKey=>$value){
|
||||
$result[$dictKey] = $value[$key];
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -354,7 +354,7 @@ class Util extends \utilphp\util
|
||||
}
|
||||
$idx = $key + 1;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -368,20 +368,20 @@ class Util extends \utilphp\util
|
||||
if ($dict === null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if (is_array($dict) && empty($dict)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
if ($depth <= 0) {
|
||||
return $dict;
|
||||
}
|
||||
|
||||
|
||||
foreach ($dict as $key=>$value) {
|
||||
if ($value === null) {
|
||||
unset($dict[$key]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!Util::isDict($value)) {
|
||||
continue;
|
||||
}
|
||||
@@ -393,7 +393,7 @@ class Util extends \utilphp\util
|
||||
$dict[$key] = $newValue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $dict;
|
||||
}
|
||||
|
||||
@@ -465,7 +465,7 @@ class Util extends \utilphp\util
|
||||
|
||||
return (float)$matches[1] / 100;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* $min과 $max 사이의 값으로 교정
|
||||
@@ -552,7 +552,7 @@ class Util extends \utilphp\util
|
||||
|
||||
/**
|
||||
* 2중 배열에서 특정 키의 합
|
||||
*
|
||||
*
|
||||
* @param array $array 배열. 1차원 배열 또는 2차원 배열
|
||||
* @param int|string|null $key 2차원 배열에서 참조할 키.
|
||||
* @return int|float 합계
|
||||
@@ -570,14 +570,14 @@ class Util extends \utilphp\util
|
||||
|
||||
/**
|
||||
* 특정 키를 가진 값으로 묶음
|
||||
*
|
||||
*
|
||||
* @param array $array 배열. 1차원 배열 또는 2차원 배열
|
||||
* @param int|string|null $key 2차원 배열에서 참조할 키.
|
||||
* @return array
|
||||
*/
|
||||
public static function arrayGroupBy(array $array, $key, bool $preserveRowKey=false) {
|
||||
$result = array();
|
||||
|
||||
|
||||
if($preserveRowKey){
|
||||
foreach($array as $rowKey=>$val) {
|
||||
if(key_exists($key, $val)){
|
||||
@@ -596,7 +596,7 @@ class Util extends \utilphp\util
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -618,7 +618,7 @@ class Util extends \utilphp\util
|
||||
*
|
||||
* @param array $items 선택하고자 하는 배열
|
||||
*
|
||||
* @return int|float|string|object 선택된 value값.
|
||||
* @return int|float|string|array|object 선택된 value값.
|
||||
*/
|
||||
public static function choiceRandom(array $items)
|
||||
{
|
||||
@@ -700,7 +700,7 @@ class Util extends \utilphp\util
|
||||
else{
|
||||
throw new \InvalidArgumentException('$lhs is not Traversable');
|
||||
}
|
||||
|
||||
|
||||
if($rhs instanceof \Traversable){
|
||||
$rhsIter = new \IteratorIterator($rhs);
|
||||
}
|
||||
@@ -778,11 +778,11 @@ class Util extends \utilphp\util
|
||||
|
||||
/**
|
||||
* Python 3의 range와 동일
|
||||
* @param int $from
|
||||
* @param null|int $to
|
||||
* @param null|int $step
|
||||
* @param int $from
|
||||
* @param null|int $to
|
||||
* @param null|int $step
|
||||
* @return \Traversable
|
||||
* @throws \InvalidArgumentException
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public static function range(int $from, ?int $to=null, ?int $step=null):\Traversable{
|
||||
if($to === null){
|
||||
@@ -809,5 +809,5 @@ class Util extends \utilphp\util
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
../nesbot/carbon/bin/carbon
|
||||
+154
-5
@@ -29,7 +29,7 @@ private static $installed = array (
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '5310c2e7f6f872cbb923ed71b72ef01b8df4aaaf',
|
||||
'reference' => 'cf3f40b5787b2a1aed9255775143108ef5b1f278',
|
||||
'name' => 'sammo-hid/sammo',
|
||||
),
|
||||
'versions' =>
|
||||
@@ -70,6 +70,15 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => '84674dd3a7575ba617f5a76d7e9e29a7d3891339',
|
||||
),
|
||||
'doctrine/inflector' =>
|
||||
array (
|
||||
'pretty_version' => '2.0.3',
|
||||
'version' => '2.0.3.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '9cf661f4eb38f7c881cac67c75ea9b00bf97b210',
|
||||
),
|
||||
'erusev/parsedown' =>
|
||||
array (
|
||||
'pretty_version' => '1.7.4',
|
||||
@@ -142,6 +151,87 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91',
|
||||
),
|
||||
'illuminate/bus' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '808097c0dfd893309bd77b00139586c516b965c9',
|
||||
),
|
||||
'illuminate/collections' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '18fa841df912ec56849351dd6ca8928e8a98b69d',
|
||||
),
|
||||
'illuminate/container' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '862b64ea4ab56e307a1676104a1b93295d347ad0',
|
||||
),
|
||||
'illuminate/contracts' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913',
|
||||
),
|
||||
'illuminate/database' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'acc11d6839ddb3b694bc6585177fa5141b70c693',
|
||||
),
|
||||
'illuminate/events' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '7def78033f29cd0c0383513b27c291d233a7f90e',
|
||||
),
|
||||
'illuminate/macroable' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '300aa13c086f25116b5f3cde3ca54ff5c822fb05',
|
||||
),
|
||||
'illuminate/pipeline' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '23aeff5b26ae4aee3f370835c76bd0f4e93f71d2',
|
||||
),
|
||||
'illuminate/support' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'b0a21c41163381dd9a5abbd68fe85ed7b4247d30',
|
||||
),
|
||||
'league/plates' =>
|
||||
array (
|
||||
'pretty_version' => 'v3.4.0',
|
||||
@@ -169,6 +259,15 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => 'c6b00f05152ae2c9b04a448f99c7590beb6042f5',
|
||||
),
|
||||
'nesbot/carbon' =>
|
||||
array (
|
||||
'pretty_version' => '2.53.1',
|
||||
'version' => '2.53.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'f4655858a784988f880c1b8c7feabbf02dfdf045',
|
||||
),
|
||||
'netresearch/jsonmapper' =>
|
||||
array (
|
||||
'pretty_version' => 'v4.0.0',
|
||||
@@ -216,12 +315,12 @@ private static $installed = array (
|
||||
),
|
||||
'phan/phan' =>
|
||||
array (
|
||||
'pretty_version' => '5.0.0',
|
||||
'version' => '5.0.0.0',
|
||||
'pretty_version' => '5.2.1',
|
||||
'version' => '5.2.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'f36b6b9a2f4143a25f35ce94d712ceb0527e9d90',
|
||||
'reference' => 'd724bbb8fc3ba89179868bb5220ecdf6a9c1636b',
|
||||
),
|
||||
'php-extended/php-system' =>
|
||||
array (
|
||||
@@ -277,6 +376,13 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
||||
),
|
||||
'psr/container-implementation' =>
|
||||
array (
|
||||
'provided' =>
|
||||
array (
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'psr/http-message' =>
|
||||
array (
|
||||
'pretty_version' => '1.0.1',
|
||||
@@ -310,6 +416,15 @@ private static $installed = array (
|
||||
1 => '1.0|2.0',
|
||||
),
|
||||
),
|
||||
'psr/simple-cache' =>
|
||||
array (
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
|
||||
),
|
||||
'ralouphie/getallheaders' =>
|
||||
array (
|
||||
'pretty_version' => '3.0.3',
|
||||
@@ -335,7 +450,7 @@ private static $installed = array (
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '5310c2e7f6f872cbb923ed71b72ef01b8df4aaaf',
|
||||
'reference' => 'cf3f40b5787b2a1aed9255775143108ef5b1f278',
|
||||
),
|
||||
'scssphp/scssphp' =>
|
||||
array (
|
||||
@@ -472,6 +587,31 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => 'bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1',
|
||||
),
|
||||
'symfony/translation' =>
|
||||
array (
|
||||
'pretty_version' => 'v5.3.7',
|
||||
'version' => '5.3.7.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6',
|
||||
),
|
||||
'symfony/translation-contracts' =>
|
||||
array (
|
||||
'pretty_version' => 'v2.4.0',
|
||||
'version' => '2.4.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '95c812666f3e91db75385749fe219c5e494c7f95',
|
||||
),
|
||||
'symfony/translation-implementation' =>
|
||||
array (
|
||||
'provided' =>
|
||||
array (
|
||||
0 => '2.3',
|
||||
),
|
||||
),
|
||||
'tysonandre/var_representation_polyfill' =>
|
||||
array (
|
||||
'pretty_version' => '0.0.2',
|
||||
@@ -490,6 +630,15 @@ private static $installed = array (
|
||||
),
|
||||
'reference' => '5ebd5d7af82cc0a9d798e816a2ecad63f1b59ceb',
|
||||
),
|
||||
'voku/portable-ascii' =>
|
||||
array (
|
||||
'pretty_version' => '1.5.6',
|
||||
'version' => '1.5.6.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '80953678b19901e5165c56752d087fc11526017c',
|
||||
),
|
||||
'webmozart/assert' =>
|
||||
array (
|
||||
'pretty_version' => '1.10.0',
|
||||
|
||||
Vendored
+5
-1
@@ -8,12 +8,15 @@ $baseDir = dirname($vendorDir);
|
||||
return array(
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => $vendorDir . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => $vendorDir . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => $vendorDir . '/symfony/deprecation-contracts/function.php',
|
||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => $vendorDir . '/symfony/polyfill-php73/bootstrap.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
|
||||
'60799491728b879e74601d83e38b2cad' => $vendorDir . '/illuminate/collections/helpers.php',
|
||||
'a1105708a18b76903365ca1c4aa61b02' => $vendorDir . '/symfony/translation/Resources/functions.php',
|
||||
'72579e7bd17821bb1321b87411366eae' => $vendorDir . '/illuminate/support/helpers.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => $vendorDir . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => $vendorDir . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => $vendorDir . '/sabre/event/lib/Promise/functions.php',
|
||||
@@ -25,6 +28,7 @@ return array(
|
||||
'f598d06aa772fa33d905e87be6398fb1' => $vendorDir . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'6714be961f4a45ae8b9a99d5d55c5d07' => $vendorDir . '/tysonandre/var_representation_polyfill/src/var_representation.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => $vendorDir . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'ef65a1626449d89d0811cf9befce46f0' => $vendorDir . '/illuminate/events/functions.php',
|
||||
'5b154887902198b16314243c6e0e3e19' => $vendorDir . '/pguardiario/phpuri/phpuri.php',
|
||||
'870dc64919afa8b0f700701bb2c6a783' => $baseDir . '/f_config/config.php',
|
||||
);
|
||||
|
||||
Vendored
+13
@@ -6,6 +6,7 @@ $vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'voku\\' => array($vendorDir . '/voku/portable-ascii/src/voku'),
|
||||
'sammo\\' => array($baseDir . '/src/sammo'),
|
||||
'phpDocumentor\\Reflection\\' => array($vendorDir . '/phpdocumentor/reflection-common/src', $vendorDir . '/phpdocumentor/reflection-docblock/src', $vendorDir . '/phpdocumentor/type-resolver/src'),
|
||||
'kakao\\' => array($baseDir . '/src/kakao'),
|
||||
@@ -20,12 +21,15 @@ return array(
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
|
||||
'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\\Lock\\' => array($vendorDir . '/symfony/lock'),
|
||||
'Symfony\\Component\\Console\\' => array($vendorDir . '/symfony/console'),
|
||||
'ScssPhp\\ScssPhp\\' => array($vendorDir . '/scssphp/scssphp/src'),
|
||||
'Sabre\\Event\\' => array($vendorDir . '/sabre/event/lib'),
|
||||
'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'),
|
||||
'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'),
|
||||
'Psr\\Http\\Message\\' => array($vendorDir . '/psr/http-message/src'),
|
||||
'Psr\\Container\\' => array($vendorDir . '/psr/container/src'),
|
||||
@@ -36,10 +40,19 @@ return array(
|
||||
'Microsoft\\PhpParser\\' => array($vendorDir . '/microsoft/tolerant-php-parser/src'),
|
||||
'Medoo\\' => array($vendorDir . '/catfan/medoo/src'),
|
||||
'League\\Plates\\' => array($vendorDir . '/league/plates/src'),
|
||||
'Illuminate\\Support\\' => array($vendorDir . '/illuminate/collections', $vendorDir . '/illuminate/macroable', $vendorDir . '/illuminate/support'),
|
||||
'Illuminate\\Pipeline\\' => array($vendorDir . '/illuminate/pipeline'),
|
||||
'Illuminate\\Events\\' => array($vendorDir . '/illuminate/events'),
|
||||
'Illuminate\\Database\\' => array($vendorDir . '/illuminate/database'),
|
||||
'Illuminate\\Contracts\\' => array($vendorDir . '/illuminate/contracts'),
|
||||
'Illuminate\\Container\\' => array($vendorDir . '/illuminate/container'),
|
||||
'Illuminate\\Bus\\' => array($vendorDir . '/illuminate/bus'),
|
||||
'GuzzleHttp\\Psr7\\' => array($vendorDir . '/guzzlehttp/psr7/src'),
|
||||
'GuzzleHttp\\Promise\\' => array($vendorDir . '/guzzlehttp/promises/src'),
|
||||
'GuzzleHttp\\' => array($vendorDir . '/guzzlehttp/guzzle/src'),
|
||||
'Doctrine\\Inflector\\' => array($vendorDir . '/doctrine/inflector/lib/Doctrine/Inflector'),
|
||||
'Composer\\XdebugHandler\\' => array($vendorDir . '/composer/xdebug-handler/src'),
|
||||
'Composer\\Semver\\' => array($vendorDir . '/composer/semver/src'),
|
||||
'Carbon\\' => array($vendorDir . '/nesbot/carbon/src/Carbon'),
|
||||
'AdvancedJsonRpc\\' => array($vendorDir . '/felixfbecker/advanced-json-rpc/lib'),
|
||||
);
|
||||
|
||||
Vendored
+81
-1
@@ -9,12 +9,15 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
public static $files = array (
|
||||
'a4a119a56e50fbb293281d9a48007e0e' => __DIR__ . '/..' . '/symfony/polyfill-php80/bootstrap.php',
|
||||
'0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php',
|
||||
'e69f7f6ee287b969198c3c9d6777bd38' => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer/bootstrap.php',
|
||||
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
|
||||
'6e3fae29631ef280660b3cdad06f25a8' => __DIR__ . '/..' . '/symfony/deprecation-contracts/function.php',
|
||||
'0d59ee240a4cd96ddbb4ff164fccea4d' => __DIR__ . '/..' . '/symfony/polyfill-php73/bootstrap.php',
|
||||
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
|
||||
'60799491728b879e74601d83e38b2cad' => __DIR__ . '/..' . '/illuminate/collections/helpers.php',
|
||||
'a1105708a18b76903365ca1c4aa61b02' => __DIR__ . '/..' . '/symfony/translation/Resources/functions.php',
|
||||
'72579e7bd17821bb1321b87411366eae' => __DIR__ . '/..' . '/illuminate/support/helpers.php',
|
||||
'2b9d0f43f9552984cfa82fee95491826' => __DIR__ . '/..' . '/sabre/event/lib/coroutine.php',
|
||||
'd81bab31d3feb45bfe2f283ea3c8fdf7' => __DIR__ . '/..' . '/sabre/event/lib/Loop/functions.php',
|
||||
'a1cce3d26cc15c00fcd0b3354bd72c88' => __DIR__ . '/..' . '/sabre/event/lib/Promise/functions.php',
|
||||
@@ -26,11 +29,16 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
'f598d06aa772fa33d905e87be6398fb1' => __DIR__ . '/..' . '/symfony/polyfill-intl-idn/bootstrap.php',
|
||||
'6714be961f4a45ae8b9a99d5d55c5d07' => __DIR__ . '/..' . '/tysonandre/var_representation_polyfill/src/var_representation.php',
|
||||
'37a3dc5111fe8f707ab4c132ef1dbc62' => __DIR__ . '/..' . '/guzzlehttp/guzzle/src/functions_include.php',
|
||||
'ef65a1626449d89d0811cf9befce46f0' => __DIR__ . '/..' . '/illuminate/events/functions.php',
|
||||
'5b154887902198b16314243c6e0e3e19' => __DIR__ . '/..' . '/pguardiario/phpuri/phpuri.php',
|
||||
'870dc64919afa8b0f700701bb2c6a783' => __DIR__ . '/../..' . '/f_config/config.php',
|
||||
);
|
||||
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'v' =>
|
||||
array (
|
||||
'voku\\' => 5,
|
||||
),
|
||||
's' =>
|
||||
array (
|
||||
'sammo\\' => 6,
|
||||
@@ -62,7 +70,9 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
|
||||
'Symfony\\Polyfill\\Intl\\Grapheme\\' => 31,
|
||||
'Symfony\\Polyfill\\Ctype\\' => 23,
|
||||
'Symfony\\Contracts\\Translation\\' => 30,
|
||||
'Symfony\\Contracts\\Service\\' => 26,
|
||||
'Symfony\\Component\\Translation\\' => 30,
|
||||
'Symfony\\Component\\String\\' => 25,
|
||||
'Symfony\\Component\\Lock\\' => 23,
|
||||
'Symfony\\Component\\Console\\' => 26,
|
||||
@@ -71,6 +81,7 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
),
|
||||
'P' =>
|
||||
array (
|
||||
'Psr\\SimpleCache\\' => 16,
|
||||
'Psr\\Log\\' => 8,
|
||||
'Psr\\Http\\Message\\' => 17,
|
||||
'Psr\\Container\\' => 14,
|
||||
@@ -88,16 +99,31 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
'League\\Plates\\' => 14,
|
||||
),
|
||||
'I' =>
|
||||
array (
|
||||
'Illuminate\\Support\\' => 19,
|
||||
'Illuminate\\Pipeline\\' => 20,
|
||||
'Illuminate\\Events\\' => 18,
|
||||
'Illuminate\\Database\\' => 20,
|
||||
'Illuminate\\Contracts\\' => 21,
|
||||
'Illuminate\\Container\\' => 21,
|
||||
'Illuminate\\Bus\\' => 15,
|
||||
),
|
||||
'G' =>
|
||||
array (
|
||||
'GuzzleHttp\\Psr7\\' => 16,
|
||||
'GuzzleHttp\\Promise\\' => 19,
|
||||
'GuzzleHttp\\' => 11,
|
||||
),
|
||||
'D' =>
|
||||
array (
|
||||
'Doctrine\\Inflector\\' => 19,
|
||||
),
|
||||
'C' =>
|
||||
array (
|
||||
'Composer\\XdebugHandler\\' => 23,
|
||||
'Composer\\Semver\\' => 16,
|
||||
'Carbon\\' => 7,
|
||||
),
|
||||
'A' =>
|
||||
array (
|
||||
@@ -106,6 +132,10 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'voku\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/voku/portable-ascii/src/voku',
|
||||
),
|
||||
'sammo\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/../..' . '/src/sammo',
|
||||
@@ -164,10 +194,18 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/polyfill-ctype',
|
||||
),
|
||||
'Symfony\\Contracts\\Translation\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/translation-contracts',
|
||||
),
|
||||
'Symfony\\Contracts\\Service\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/service-contracts',
|
||||
),
|
||||
'Symfony\\Component\\Translation\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/translation',
|
||||
),
|
||||
'Symfony\\Component\\String\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/symfony/string',
|
||||
@@ -188,6 +226,10 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/sabre/event/lib',
|
||||
),
|
||||
'Psr\\SimpleCache\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/simple-cache/src',
|
||||
),
|
||||
'Psr\\Log\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/psr/log/Psr/Log',
|
||||
@@ -228,6 +270,36 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/league/plates/src',
|
||||
),
|
||||
'Illuminate\\Support\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/collections',
|
||||
1 => __DIR__ . '/..' . '/illuminate/macroable',
|
||||
2 => __DIR__ . '/..' . '/illuminate/support',
|
||||
),
|
||||
'Illuminate\\Pipeline\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/pipeline',
|
||||
),
|
||||
'Illuminate\\Events\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/events',
|
||||
),
|
||||
'Illuminate\\Database\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/database',
|
||||
),
|
||||
'Illuminate\\Contracts\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/contracts',
|
||||
),
|
||||
'Illuminate\\Container\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/container',
|
||||
),
|
||||
'Illuminate\\Bus\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/illuminate/bus',
|
||||
),
|
||||
'GuzzleHttp\\Psr7\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src',
|
||||
@@ -240,6 +312,10 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src',
|
||||
),
|
||||
'Doctrine\\Inflector\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/doctrine/inflector/lib/Doctrine/Inflector',
|
||||
),
|
||||
'Composer\\XdebugHandler\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/xdebug-handler/src',
|
||||
@@ -248,6 +324,10 @@ class ComposerStaticInit67b09c83b85c3bc0027caefe5bba171a
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/composer/semver/src',
|
||||
),
|
||||
'Carbon\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/nesbot/carbon/src/Carbon',
|
||||
),
|
||||
'AdvancedJsonRpc\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/felixfbecker/advanced-json-rpc/lib',
|
||||
|
||||
Vendored
+1031
-8
@@ -267,6 +267,104 @@
|
||||
],
|
||||
"install-path": "./xdebug-handler"
|
||||
},
|
||||
{
|
||||
"name": "doctrine/inflector",
|
||||
"version": "2.0.3",
|
||||
"version_normalized": "2.0.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/doctrine/inflector.git",
|
||||
"reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/doctrine/inflector/zipball/9cf661f4eb38f7c881cac67c75ea9b00bf97b210",
|
||||
"reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/coding-standard": "^7.0",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpstan/phpstan-phpunit": "^0.11",
|
||||
"phpstan/phpstan-strict-rules": "^0.11",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"time": "2020-05-29T15:13:26+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"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"
|
||||
}
|
||||
],
|
||||
"description": "PHP Doctrine Inflector is a small library that can perform string manipulations with regard to upper/lowercase and singular/plural forms of words.",
|
||||
"homepage": "https://www.doctrine-project.org/projects/inflector.html",
|
||||
"keywords": [
|
||||
"inflection",
|
||||
"inflector",
|
||||
"lowercase",
|
||||
"manipulation",
|
||||
"php",
|
||||
"plural",
|
||||
"singular",
|
||||
"strings",
|
||||
"uppercase",
|
||||
"words"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/doctrine/inflector/issues",
|
||||
"source": "https://github.com/doctrine/inflector/tree/2.0.x"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.doctrine-project.org/sponsorship.html",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/phpdoctrine",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/doctrine%2Finflector",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../doctrine/inflector"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
"version": "1.7.4",
|
||||
@@ -720,6 +818,524 @@
|
||||
},
|
||||
"install-path": "../guzzlehttp/psr7"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/bus",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/bus.git",
|
||||
"reference": "808097c0dfd893309bd77b00139586c516b965c9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/bus/zipball/808097c0dfd893309bd77b00139586c516b965c9",
|
||||
"reference": "808097c0dfd893309bd77b00139586c516b965c9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/pipeline": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/queue": "Required to use closures when chaining jobs (^7.0)."
|
||||
},
|
||||
"time": "2021-08-10T16:49:48+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Bus\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Bus package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/bus"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/collections",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/collections.git",
|
||||
"reference": "18fa841df912ec56849351dd6ca8928e8a98b69d"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/collections/zipball/18fa841df912ec56849351dd6ca8928e8a98b69d",
|
||||
"reference": "18fa841df912ec56849351dd6ca8928e8a98b69d",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/var-dumper": "Required to use the dump method (^5.1.4)."
|
||||
},
|
||||
"time": "2021-09-08T12:48:16+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Collections package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/collections"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/container",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/container.git",
|
||||
"reference": "862b64ea4ab56e307a1676104a1b93295d347ad0"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/container/zipball/862b64ea4ab56e307a1676104a1b93295d347ad0",
|
||||
"reference": "862b64ea4ab56e307a1676104a1b93295d347ad0",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"php": "^7.3|^8.0",
|
||||
"psr/container": "^1.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/container-implementation": "1.0"
|
||||
},
|
||||
"time": "2021-09-09T13:55:23+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Container\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Container package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/container"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/contracts",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/contracts.git",
|
||||
"reference": "ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/contracts/zipball/ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913",
|
||||
"reference": "ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0",
|
||||
"psr/container": "^1.0",
|
||||
"psr/simple-cache": "^1.0"
|
||||
},
|
||||
"time": "2021-09-08T12:09:40+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Contracts\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Contracts package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/contracts"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/database",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/database.git",
|
||||
"reference": "acc11d6839ddb3b694bc6585177fa5141b70c693"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/database/zipball/acc11d6839ddb3b694bc6585177fa5141b70c693",
|
||||
"reference": "acc11d6839ddb3b694bc6585177fa5141b70c693",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/container": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0",
|
||||
"symfony/console": "^5.1.4"
|
||||
},
|
||||
"suggest": {
|
||||
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6|^3.0).",
|
||||
"fakerphp/faker": "Required to use the eloquent factory builder (^1.9.1).",
|
||||
"illuminate/console": "Required to use the database commands (^8.0).",
|
||||
"illuminate/events": "Required to use the observers with Eloquent (^8.0).",
|
||||
"illuminate/filesystem": "Required to use the migrations (^8.0).",
|
||||
"illuminate/pagination": "Required to paginate the result set (^8.0).",
|
||||
"symfony/finder": "Required to use Eloquent model factories (^5.1.4)."
|
||||
},
|
||||
"time": "2021-09-13T18:43:43+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Database\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Database package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"keywords": [
|
||||
"database",
|
||||
"laravel",
|
||||
"orm",
|
||||
"sql"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/database"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/events",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/events.git",
|
||||
"reference": "7def78033f29cd0c0383513b27c291d233a7f90e"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/events/zipball/7def78033f29cd0c0383513b27c291d233a7f90e",
|
||||
"reference": "7def78033f29cd0c0383513b27c291d233a7f90e",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/bus": "^8.0",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/container": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"time": "2021-08-16T21:45:47+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Events\\": ""
|
||||
},
|
||||
"files": [
|
||||
"functions.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Events package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/events"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/macroable",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/macroable.git",
|
||||
"reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/macroable/zipball/300aa13c086f25116b5f3cde3ca54ff5c822fb05",
|
||||
"reference": "300aa13c086f25116b5f3cde3ca54ff5c822fb05",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"time": "2020-10-27T15:20:30+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Macroable package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/macroable"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/pipeline",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/pipeline.git",
|
||||
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/pipeline/zipball/23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
|
||||
"reference": "23aeff5b26ae4aee3f370835c76bd0f4e93f71d2",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/support": "^8.0",
|
||||
"php": "^7.3|^8.0"
|
||||
},
|
||||
"time": "2021-03-26T18:39:16+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Pipeline\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Pipeline package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/pipeline"
|
||||
},
|
||||
{
|
||||
"name": "illuminate/support",
|
||||
"version": "v8.61.0",
|
||||
"version_normalized": "8.61.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/illuminate/support.git",
|
||||
"reference": "b0a21c41163381dd9a5abbd68fe85ed7b4247d30"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/illuminate/support/zipball/b0a21c41163381dd9a5abbd68fe85ed7b4247d30",
|
||||
"reference": "b0a21c41163381dd9a5abbd68fe85ed7b4247d30",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"doctrine/inflector": "^1.4|^2.0",
|
||||
"ext-json": "*",
|
||||
"ext-mbstring": "*",
|
||||
"illuminate/collections": "^8.0",
|
||||
"illuminate/contracts": "^8.0",
|
||||
"illuminate/macroable": "^8.0",
|
||||
"nesbot/carbon": "^2.31",
|
||||
"php": "^7.3|^8.0",
|
||||
"voku/portable-ascii": "^1.4.8"
|
||||
},
|
||||
"conflict": {
|
||||
"tightenco/collect": "<5.5.33"
|
||||
},
|
||||
"suggest": {
|
||||
"illuminate/filesystem": "Required to use the composer class (^8.0).",
|
||||
"league/commonmark": "Required to use Str::markdown() and Stringable::markdown() (^1.3|^2.0).",
|
||||
"ramsey/uuid": "Required to use Str::uuid() (^4.0).",
|
||||
"symfony/process": "Required to use the composer class (^5.1.4).",
|
||||
"symfony/var-dumper": "Required to use the dd function (^5.1.4).",
|
||||
"vlucas/phpdotenv": "Required to use the Env class and env helper (^5.2)."
|
||||
},
|
||||
"time": "2021-09-13T18:43:43+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "8.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Illuminate\\Support\\": ""
|
||||
},
|
||||
"files": [
|
||||
"helpers.php"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Taylor Otwell",
|
||||
"email": "taylor@laravel.com"
|
||||
}
|
||||
],
|
||||
"description": "The Illuminate Support package.",
|
||||
"homepage": "https://laravel.com",
|
||||
"support": {
|
||||
"issues": "https://github.com/laravel/framework/issues",
|
||||
"source": "https://github.com/laravel/framework"
|
||||
},
|
||||
"install-path": "../illuminate/support"
|
||||
},
|
||||
{
|
||||
"name": "league/plates",
|
||||
"version": "v3.4.0",
|
||||
@@ -924,6 +1540,103 @@
|
||||
],
|
||||
"install-path": "../monolog/monolog"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "2.53.1",
|
||||
"version_normalized": "2.53.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/briannesbitt/Carbon.git",
|
||||
"reference": "f4655858a784988f880c1b8c7feabbf02dfdf045"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/f4655858a784988f880c1b8c7feabbf02dfdf045",
|
||||
"reference": "f4655858a784988f880c1b8c7feabbf02dfdf045",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-json": "*",
|
||||
"php": "^7.1.8 || ^8.0",
|
||||
"symfony/polyfill-mbstring": "^1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation": "^3.4 || ^4.0 || ^5.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"doctrine/orm": "^2.7",
|
||||
"friendsofphp/php-cs-fixer": "^3.0",
|
||||
"kylekatarnls/multi-tester": "^2.0",
|
||||
"phpmd/phpmd": "^2.9",
|
||||
"phpstan/extension-installer": "^1.0",
|
||||
"phpstan/phpstan": "^0.12.54",
|
||||
"phpunit/phpunit": "^7.5.20 || ^8.5.14",
|
||||
"squizlabs/php_codesniffer": "^3.4"
|
||||
},
|
||||
"time": "2021-09-06T09:29:23+00:00",
|
||||
"bin": [
|
||||
"bin/carbon"
|
||||
],
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-3.x": "3.x-dev",
|
||||
"dev-master": "2.x-dev"
|
||||
},
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Carbon\\Laravel\\ServiceProvider"
|
||||
]
|
||||
},
|
||||
"phpstan": {
|
||||
"includes": [
|
||||
"extension.neon"
|
||||
]
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Carbon\\": "src/Carbon/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Brian Nesbitt",
|
||||
"email": "brian@nesbot.com",
|
||||
"homepage": "https://markido.com"
|
||||
},
|
||||
{
|
||||
"name": "kylekatarnls",
|
||||
"homepage": "https://github.com/kylekatarnls"
|
||||
}
|
||||
],
|
||||
"description": "An API extension for DateTime that supports 281 different languages.",
|
||||
"homepage": "https://carbon.nesbot.com",
|
||||
"keywords": [
|
||||
"date",
|
||||
"datetime",
|
||||
"time"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/briannesbitt/Carbon/issues",
|
||||
"source": "https://github.com/briannesbitt/Carbon"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://opencollective.com/Carbon",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/nesbot/carbon",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../nesbot/carbon"
|
||||
},
|
||||
{
|
||||
"name": "netresearch/jsonmapper",
|
||||
"version": "v4.0.0",
|
||||
@@ -1235,17 +1948,17 @@
|
||||
},
|
||||
{
|
||||
"name": "phan/phan",
|
||||
"version": "5.0.0",
|
||||
"version_normalized": "5.0.0.0",
|
||||
"version": "5.2.1",
|
||||
"version_normalized": "5.2.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/phan/phan.git",
|
||||
"reference": "f36b6b9a2f4143a25f35ce94d712ceb0527e9d90"
|
||||
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/phan/phan/zipball/f36b6b9a2f4143a25f35ce94d712ceb0527e9d90",
|
||||
"reference": "f36b6b9a2f4143a25f35ce94d712ceb0527e9d90",
|
||||
"url": "https://api.github.com/repos/phan/phan/zipball/d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
|
||||
"reference": "d724bbb8fc3ba89179868bb5220ecdf6a9c1636b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -1262,7 +1975,7 @@
|
||||
"symfony/console": "^3.2|^4.0|^5.0",
|
||||
"symfony/polyfill-mbstring": "^1.11.0",
|
||||
"symfony/polyfill-php80": "^1.20.0",
|
||||
"tysonandre/var_representation_polyfill": "^0.0.2"
|
||||
"tysonandre/var_representation_polyfill": "^0.0.2|^0.1.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^8.5.0"
|
||||
@@ -1275,7 +1988,7 @@
|
||||
"ext-tokenizer": "Needed for fallback/polyfill parser support and file/line-based suppressions.",
|
||||
"ext-var_representation": "Suggested for converting values to strings in issue messages"
|
||||
},
|
||||
"time": "2021-08-01T18:17:28+00:00",
|
||||
"time": "2021-09-15T00:08:40+00:00",
|
||||
"bin": [
|
||||
"phan",
|
||||
"phan_client",
|
||||
@@ -1311,7 +2024,7 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/phan/phan/issues",
|
||||
"source": "https://github.com/phan/phan/tree/5.0.0"
|
||||
"source": "https://github.com/phan/phan/tree/5.2.1"
|
||||
},
|
||||
"install-path": "../phan/phan"
|
||||
},
|
||||
@@ -1729,6 +2442,60 @@
|
||||
},
|
||||
"install-path": "../psr/log"
|
||||
},
|
||||
{
|
||||
"name": "psr/simple-cache",
|
||||
"version": "1.0.1",
|
||||
"version_normalized": "1.0.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/php-fig/simple-cache.git",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/php-fig/simple-cache/zipball/408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"reference": "408d5eafb83c57f6365a3ca330ff23aa4a5fa39b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"time": "2017-10-23T01:57:42+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "1.0.x-dev"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Psr\\SimpleCache\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "PHP-FIG",
|
||||
"homepage": "http://www.php-fig.org/"
|
||||
}
|
||||
],
|
||||
"description": "Common interfaces for simple caching",
|
||||
"keywords": [
|
||||
"cache",
|
||||
"caching",
|
||||
"psr",
|
||||
"psr-16",
|
||||
"simple-cache"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/php-fig/simple-cache/tree/master"
|
||||
},
|
||||
"install-path": "../psr/simple-cache"
|
||||
},
|
||||
{
|
||||
"name": "ralouphie/getallheaders",
|
||||
"version": "3.0.3",
|
||||
@@ -3062,6 +3829,185 @@
|
||||
],
|
||||
"install-path": "../symfony/string"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation",
|
||||
"version": "v5.3.7",
|
||||
"version_normalized": "5.3.7.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation.git",
|
||||
"reference": "4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation/zipball/4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6",
|
||||
"reference": "4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5",
|
||||
"symfony/deprecation-contracts": "^2.1",
|
||||
"symfony/polyfill-mbstring": "~1.0",
|
||||
"symfony/polyfill-php80": "^1.16",
|
||||
"symfony/translation-contracts": "^2.3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/config": "<4.4",
|
||||
"symfony/dependency-injection": "<5.0",
|
||||
"symfony/http-kernel": "<5.0",
|
||||
"symfony/twig-bundle": "<5.0",
|
||||
"symfony/yaml": "<4.4"
|
||||
},
|
||||
"provide": {
|
||||
"symfony/translation-implementation": "2.3"
|
||||
},
|
||||
"require-dev": {
|
||||
"psr/log": "^1|^2|^3",
|
||||
"symfony/config": "^4.4|^5.0",
|
||||
"symfony/console": "^4.4|^5.0",
|
||||
"symfony/dependency-injection": "^5.0",
|
||||
"symfony/finder": "^4.4|^5.0",
|
||||
"symfony/http-kernel": "^5.0",
|
||||
"symfony/intl": "^4.4|^5.0",
|
||||
"symfony/polyfill-intl-icu": "^1.21",
|
||||
"symfony/service-contracts": "^1.1.2|^2",
|
||||
"symfony/yaml": "^4.4|^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"psr/log-implementation": "To use logging capability in translator",
|
||||
"symfony/config": "",
|
||||
"symfony/yaml": ""
|
||||
},
|
||||
"time": "2021-08-26T08:22:53+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"Resources/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Symfony\\Component\\Translation\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides tools to internationalize your application",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation/tree/v5.3.7"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/translation"
|
||||
},
|
||||
{
|
||||
"name": "symfony/translation-contracts",
|
||||
"version": "v2.4.0",
|
||||
"version_normalized": "2.4.0.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/translation-contracts.git",
|
||||
"reference": "95c812666f3e91db75385749fe219c5e494c7f95"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95",
|
||||
"reference": "95c812666f3e91db75385749fe219c5e494c7f95",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.2.5"
|
||||
},
|
||||
"suggest": {
|
||||
"symfony/translation-implementation": ""
|
||||
},
|
||||
"time": "2021-03-23T23:28:01+00:00",
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "2.4-dev"
|
||||
},
|
||||
"thanks": {
|
||||
"name": "symfony/contracts",
|
||||
"url": "https://github.com/symfony/contracts"
|
||||
}
|
||||
},
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Contracts\\Translation\\": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nicolas Grekas",
|
||||
"email": "p@tchwork.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Generic abstractions related to translation",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"abstractions",
|
||||
"contracts",
|
||||
"decoupling",
|
||||
"interfaces",
|
||||
"interoperability",
|
||||
"standards"
|
||||
],
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/translation-contracts/tree/v2.4.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../symfony/translation-contracts"
|
||||
},
|
||||
{
|
||||
"name": "tysonandre/var_representation_polyfill",
|
||||
"version": "0.0.2",
|
||||
@@ -3178,6 +4124,83 @@
|
||||
],
|
||||
"install-path": "../vlucas/valitron"
|
||||
},
|
||||
{
|
||||
"name": "voku/portable-ascii",
|
||||
"version": "1.5.6",
|
||||
"version_normalized": "1.5.6.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/voku/portable-ascii.git",
|
||||
"reference": "80953678b19901e5165c56752d087fc11526017c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/voku/portable-ascii/zipball/80953678b19901e5165c56752d087fc11526017c",
|
||||
"reference": "80953678b19901e5165c56752d087fc11526017c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=7.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~6.0 || ~7.0 || ~9.0"
|
||||
},
|
||||
"suggest": {
|
||||
"ext-intl": "Use Intl for transliterator_transliterate() support"
|
||||
},
|
||||
"time": "2020-11-12T00:07:28+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"voku\\": "src/voku/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Lars Moelleken",
|
||||
"homepage": "http://www.moelleken.org/"
|
||||
}
|
||||
],
|
||||
"description": "Portable ASCII library - performance optimized (ascii) string functions for php.",
|
||||
"homepage": "https://github.com/voku/portable-ascii",
|
||||
"keywords": [
|
||||
"ascii",
|
||||
"clean",
|
||||
"php"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/voku/portable-ascii/issues",
|
||||
"source": "https://github.com/voku/portable-ascii/tree/1.5.6"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://www.paypal.me/moelleken",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/voku",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://opencollective.com/portable-ascii",
|
||||
"type": "open_collective"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/voku",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"install-path": "../voku/portable-ascii"
|
||||
},
|
||||
{
|
||||
"name": "webmozart/assert",
|
||||
"version": "1.10.0",
|
||||
|
||||
Vendored
+154
-5
@@ -6,7 +6,7 @@
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '5310c2e7f6f872cbb923ed71b72ef01b8df4aaaf',
|
||||
'reference' => 'cf3f40b5787b2a1aed9255775143108ef5b1f278',
|
||||
'name' => 'sammo-hid/sammo',
|
||||
),
|
||||
'versions' =>
|
||||
@@ -47,6 +47,15 @@
|
||||
),
|
||||
'reference' => '84674dd3a7575ba617f5a76d7e9e29a7d3891339',
|
||||
),
|
||||
'doctrine/inflector' =>
|
||||
array (
|
||||
'pretty_version' => '2.0.3',
|
||||
'version' => '2.0.3.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '9cf661f4eb38f7c881cac67c75ea9b00bf97b210',
|
||||
),
|
||||
'erusev/parsedown' =>
|
||||
array (
|
||||
'pretty_version' => '1.7.4',
|
||||
@@ -119,6 +128,87 @@
|
||||
),
|
||||
'reference' => 'dc960a912984efb74d0a90222870c72c87f10c91',
|
||||
),
|
||||
'illuminate/bus' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '808097c0dfd893309bd77b00139586c516b965c9',
|
||||
),
|
||||
'illuminate/collections' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '18fa841df912ec56849351dd6ca8928e8a98b69d',
|
||||
),
|
||||
'illuminate/container' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '862b64ea4ab56e307a1676104a1b93295d347ad0',
|
||||
),
|
||||
'illuminate/contracts' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'ab4bb4ec3b36905ccf972c84f9aaa2bdd1153913',
|
||||
),
|
||||
'illuminate/database' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'acc11d6839ddb3b694bc6585177fa5141b70c693',
|
||||
),
|
||||
'illuminate/events' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '7def78033f29cd0c0383513b27c291d233a7f90e',
|
||||
),
|
||||
'illuminate/macroable' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '300aa13c086f25116b5f3cde3ca54ff5c822fb05',
|
||||
),
|
||||
'illuminate/pipeline' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '23aeff5b26ae4aee3f370835c76bd0f4e93f71d2',
|
||||
),
|
||||
'illuminate/support' =>
|
||||
array (
|
||||
'pretty_version' => 'v8.61.0',
|
||||
'version' => '8.61.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'b0a21c41163381dd9a5abbd68fe85ed7b4247d30',
|
||||
),
|
||||
'league/plates' =>
|
||||
array (
|
||||
'pretty_version' => 'v3.4.0',
|
||||
@@ -146,6 +236,15 @@
|
||||
),
|
||||
'reference' => 'c6b00f05152ae2c9b04a448f99c7590beb6042f5',
|
||||
),
|
||||
'nesbot/carbon' =>
|
||||
array (
|
||||
'pretty_version' => '2.53.1',
|
||||
'version' => '2.53.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'f4655858a784988f880c1b8c7feabbf02dfdf045',
|
||||
),
|
||||
'netresearch/jsonmapper' =>
|
||||
array (
|
||||
'pretty_version' => 'v4.0.0',
|
||||
@@ -193,12 +292,12 @@
|
||||
),
|
||||
'phan/phan' =>
|
||||
array (
|
||||
'pretty_version' => '5.0.0',
|
||||
'version' => '5.0.0.0',
|
||||
'pretty_version' => '5.2.1',
|
||||
'version' => '5.2.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => 'f36b6b9a2f4143a25f35ce94d712ceb0527e9d90',
|
||||
'reference' => 'd724bbb8fc3ba89179868bb5220ecdf6a9c1636b',
|
||||
),
|
||||
'php-extended/php-system' =>
|
||||
array (
|
||||
@@ -254,6 +353,13 @@
|
||||
),
|
||||
'reference' => '8622567409010282b7aeebe4bb841fe98b58dcaf',
|
||||
),
|
||||
'psr/container-implementation' =>
|
||||
array (
|
||||
'provided' =>
|
||||
array (
|
||||
0 => '1.0',
|
||||
),
|
||||
),
|
||||
'psr/http-message' =>
|
||||
array (
|
||||
'pretty_version' => '1.0.1',
|
||||
@@ -287,6 +393,15 @@
|
||||
1 => '1.0|2.0',
|
||||
),
|
||||
),
|
||||
'psr/simple-cache' =>
|
||||
array (
|
||||
'pretty_version' => '1.0.1',
|
||||
'version' => '1.0.1.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '408d5eafb83c57f6365a3ca330ff23aa4a5fa39b',
|
||||
),
|
||||
'ralouphie/getallheaders' =>
|
||||
array (
|
||||
'pretty_version' => '3.0.3',
|
||||
@@ -312,7 +427,7 @@
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '5310c2e7f6f872cbb923ed71b72ef01b8df4aaaf',
|
||||
'reference' => 'cf3f40b5787b2a1aed9255775143108ef5b1f278',
|
||||
),
|
||||
'scssphp/scssphp' =>
|
||||
array (
|
||||
@@ -449,6 +564,31 @@
|
||||
),
|
||||
'reference' => 'bd53358e3eccec6a670b5f33ab680d8dbe1d4ae1',
|
||||
),
|
||||
'symfony/translation' =>
|
||||
array (
|
||||
'pretty_version' => 'v5.3.7',
|
||||
'version' => '5.3.7.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '4d595a6d15fd3a2c67f6f31d14d15d3b7356d7a6',
|
||||
),
|
||||
'symfony/translation-contracts' =>
|
||||
array (
|
||||
'pretty_version' => 'v2.4.0',
|
||||
'version' => '2.4.0.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '95c812666f3e91db75385749fe219c5e494c7f95',
|
||||
),
|
||||
'symfony/translation-implementation' =>
|
||||
array (
|
||||
'provided' =>
|
||||
array (
|
||||
0 => '2.3',
|
||||
),
|
||||
),
|
||||
'tysonandre/var_representation_polyfill' =>
|
||||
array (
|
||||
'pretty_version' => '0.0.2',
|
||||
@@ -467,6 +607,15 @@
|
||||
),
|
||||
'reference' => '5ebd5d7af82cc0a9d798e816a2ecad63f1b59ceb',
|
||||
),
|
||||
'voku/portable-ascii' =>
|
||||
array (
|
||||
'pretty_version' => '1.5.6',
|
||||
'version' => '1.5.6.0',
|
||||
'aliases' =>
|
||||
array (
|
||||
),
|
||||
'reference' => '80953678b19901e5165c56752d087fc11526017c',
|
||||
),
|
||||
'webmozart/assert' =>
|
||||
array (
|
||||
'pretty_version' => '1.10.0',
|
||||
|
||||
Vendored
+2
-2
@@ -4,8 +4,8 @@
|
||||
|
||||
$issues = array();
|
||||
|
||||
if (!(PHP_VERSION_ID >= 70205)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.2.5". You are running ' . PHP_VERSION . '.';
|
||||
if (!(PHP_VERSION_ID >= 70300)) {
|
||||
$issues[] = 'Your Composer dependencies require a PHP version ">= 7.3.0". You are running ' . PHP_VERSION . '.';
|
||||
}
|
||||
|
||||
if ($issues) {
|
||||
|
||||
Vendored
+19
@@ -0,0 +1,19 @@
|
||||
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.
|
||||
Vendored
+8
@@ -0,0 +1,8 @@
|
||||
# Doctrine Inflector
|
||||
|
||||
Doctrine Inflector is a small library that can perform string manipulations
|
||||
with regard to uppercase/lowercase and singular/plural forms of words.
|
||||
|
||||
[](https://travis-ci.org/doctrine/inflector)
|
||||
[](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master)
|
||||
[](https://scrutinizer-ci.com/g/doctrine/inflector/?branch=master)
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"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": "^7.0",
|
||||
"phpstan/phpstan": "^0.11",
|
||||
"phpstan/phpstan-phpunit": "^0.11",
|
||||
"phpstan/phpstan-strict-rules": "^0.11",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Inflector\\": "lib/Doctrine/Inflector"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Doctrine\\Tests\\Inflector\\": "tests/Doctrine/Tests/Inflector"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "2.0.x-dev"
|
||||
}
|
||||
}
|
||||
}
|
||||
+226
@@ -0,0 +1,226 @@
|
||||
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>`_
|
||||
@@ -0,0 +1,24 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
<?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;
|
||||
}
|
||||
@@ -0,0 +1,506 @@
|
||||
<?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);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?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
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?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()
|
||||
{
|
||||
}
|
||||
}
|
||||
+33
@@ -0,0 +1,33 @@
|
||||
<?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;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Doctrine\Inflector;
|
||||
|
||||
class NoopWordInflector implements WordInflector
|
||||
{
|
||||
public function inflect(string $word) : string
|
||||
{
|
||||
return $word;
|
||||
}
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
<?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$'), '\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('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('axe'), new Word('axes'));
|
||||
yield new Substitution(new Word('beef'), new Word('beefs'));
|
||||
yield new Substitution(new Word('brother'), new Word('brothers'));
|
||||
yield new Substitution(new Word('cafe'), new Word('cafes'));
|
||||
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('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('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('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'));
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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())
|
||||
);
|
||||
}
|
||||
}
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
<?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('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('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');
|
||||
}
|
||||
}
|
||||
+49
@@ -0,0 +1,49 @@
|
||||
<?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('/al$/'), 'aux');
|
||||
yield new Transformation(new Pattern('/(bleu|émeu|landau|lieu|pneu|sarrau)$/'), '\1s');
|
||||
yield new Transformation(new Pattern('/(bijou|caillou|chou|genou|hibou|joujou|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'));
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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())
|
||||
);
|
||||
}
|
||||
}
|
||||
+34
@@ -0,0 +1,34 @@
|
||||
<?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('');
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
<?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'));
|
||||
}
|
||||
}
|
||||
Vendored
+21
@@ -0,0 +1,21 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?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())
|
||||
);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
+104
@@ -0,0 +1,104 @@
|
||||
<?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'));
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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())
|
||||
);
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
<?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'));
|
||||
}
|
||||
}
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
<?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();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
<?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())
|
||||
);
|
||||
}
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
<?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');
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user