修复登陆日志入库错误,升级部分composer依赖项;

临时修复登陆通知邮件不能多发的问题;
This commit is contained in:
fm453 2024-10-27 08:54:53 +08:00
parent 314745edf8
commit 39282ec584
93 changed files with 6407 additions and 6806 deletions

2
.gitignore vendored
View File

@ -36,6 +36,7 @@ Temporary Items
.well-known
.gitee
runtime
YII.sublime-project
YII.sublime-workspace
YII2改造开发手记.docx
@ -64,3 +65,4 @@ private.html
/ctms-admin/web/assets/
/assets/
/admins/web/assets/
/logs/

1
.idea/php.xml generated
View File

@ -60,7 +60,6 @@
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
<path value="$PROJECT_DIR$/vendor/cebe/markdown" />
<path value="$PROJECT_DIR$/vendor/symfony/string" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
<path value="$PROJECT_DIR$/vendor/aliyun/dysms" />
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />

File diff suppressed because one or more lines are too long

View File

@ -16,6 +16,7 @@ $config = [
'password' => 'ejxsrxZCP34xNjF2',
'charset' => 'utf8',
'tablePrefix' => '',
// 'attributes' => [PDO::ATTR_CASE => PDO::CASE_LOWER], //解决mysql8列值字母大小不一
],
'ac' => [
'class' => 'yii\db\Connection',

View File

@ -24,12 +24,12 @@ return [
// for the mailer to send real emails.
'useFileTransport' => false,
'transport' => [
// 'class' => 'Swift_SmtpTransport', //使用的类
'scheme' => 'smtps',
'host' => 'smtp.qq.com', //邮箱服务一地址
'username' => '393213759@qq.com',//邮箱地址,发送的邮箱
'password' => 'oqqkcnstydagbigd', //QQ邮箱授权码
'port' => '465', //服务器端口
'dsn' => 'native://default',
'encryption' => 'ssl', //加密方式
],
'messageConfig'=>[

View File

@ -28,8 +28,9 @@ class CLog extends \yii\db\ActiveRecord
public function rules()
{
return [
[['username', 'create_time'], 'string', 'max' => 32],
[['ip', 'data'], 'string', 'max' => 64],
[['username'], 'string', 'max' => 32],
[['ip'], 'string', 'max' => 64],
[['data'], 'string', 'max' => 500],
];
}

View File

@ -23,6 +23,11 @@ class Common extends Controller
$get = Yii::$app->request->get();
$session = Yii::$app->session;
$this->pid = $session->get('pid');
if (isset($_GET['pid']) && (int)$_GET['pid'] > 0) {
$session->set('pid', (int)$_GET['pid']);
$this->pid = (int)$_GET['pid'];
}
if (!$this->pid) {
return Yii::$app->response->redirect(['index/index']);
}

View File

@ -51,7 +51,7 @@ class IndexController extends \yii\web\Controller
$plats[$p->id] = $p->toArray();
}
}else{
$plats[] = ['id'=>1,'title'=>'安诚捷顺','thumb'=>'http://public.hiluker.com/qichetuoyun/logo.png'];
$plats[] = ['id' => 1, 'title' => '安邮车联', 'thumb' => 'http://public.hiluker.com/qichetuoyun/logo.png'];
}
if(isset($_GET['pid'])){
@ -59,7 +59,6 @@ class IndexController extends \yii\web\Controller
if($pid>0){
$session->set('pid',$pid);
return $this->actionWelcome();
exit;
}else{
return $this->render('index',['plats'=>$plats]);
}

View File

@ -7,7 +7,8 @@
namespace backend\controllers;
use addons\models\AcNewsCat;use Yii;
use Yii;
use addons\models\AcNewsCat;
class NewscatController extends Common{
public $enableCsrfValidation = false;

View File

@ -28,22 +28,8 @@ use common\models\CVcode;
use addons\models\AcContact;
use common\models\Fans;
class OrderController extends \yii\web\Controller
class OrderController extends Common
{
//替代常规的_construct 析构函数;其他方法调用前执行
public function init()
{
parent::init();
$session = Yii::$app->session;
if (isset($_GET['pid']) && (int)$_GET['pid']>0) {
$session->set('pid', (int)$_GET['pid']);
}
$pid = $session->get('pid');
if (!$pid) {
return Yii::$app->response->redirect(['index/index']);
}
}
//主界面
public function actionIndex()
{
@ -55,7 +41,7 @@ class OrderController extends \yii\web\Controller
public function actionList()
{
global $_HI,$_FM;
$pid = Yii::$app->session->get('pid');
$pid = $this->pid;
$session = Yii::$app->session;
$model = new AcOrder();
$where = [];

View File

@ -103,7 +103,14 @@ class LoginForm extends Model
public function loginLog(){
$request = Yii::$app->getRequest();
$nowFile = $request -> getScriptFile();
$data = "登陆系统|途径:".$nowFile;
$url = $request->getUrl();
$hostInfo = $request->getHostInfo();
$port = $request->getPort();
$data = "登陆系统:";
$data .= "|域名:" . $hostInfo;
$data .= "|端口:" . $port;
$data .= "|网址:" . $url;
$data .= "|脚本:" . $nowFile;
$model = new CLog();
$model->username = $this->username;
@ -111,23 +118,34 @@ class LoginForm extends Model
$model->data = $data;
$model->create_time = time();
$model->save();
// $res = $model->getErrors(); //数据保存报错时可以用此打印出错误
//编制邮件发送通知
//编制邮件发送通知(并发问题导致502错误故暂只发一个邮件
$messages = [];
$message = Yii::$app->mailer->compose();
$message->setFrom(Yii::$app->params['noticeEmail']);
//给登陆者发送
// $message->setFrom(Yii::$app->params['noticeEmail']);
//message 给登陆者发送
$subject = "账号登陆提醒";
$body = "您的账号【".$this->username."】刚刚登陆了网站:".Yii::$app->getRequest()->absoluteUrl;
$message->setTo(Yii::$app->user->identity->email)
->setSubject($subject)
->setTextBody($body)
->send();
//给管理人员发送
$body = "您的账号【" . $this->username . "】刚刚登陆了网站:" . $request->absoluteUrl;
$message->setTo(Yii::$app->user->identity->email);
$message->setSubject($subject);
$message->setTextBody($body);
// $message->send(); //单发时可用该方法群发时会导致页面卡停报502错
$messages[] = $message;
//message2 给管理人员发送
$message2 = Yii::$app->mailer->compose();
$subject = "账号登陆提醒";
$body = "运维账号【".$this->username."】刚刚登陆了网站:".Yii::$app->getRequest()->absoluteUrl;
$message->setTo('1280880631@qq.com')
->setSubject($subject)
->setTextBody($body)
->send();
$body = "运维账号【" . $this->username . "】刚刚登陆了网站:" . $request->absoluteUrl;
$message2->setTo('1280880631@qq.com');
$message2->setSubject($subject);
$message2->setTextBody($body);
$message2->send();
$messages[] = $message2;
//群发
// Yii::$app->mailer->sendMultiple($messages);
}
}

File diff suppressed because it is too large Load Diff

27
ctms-admin/web/404.html Executable file
View File

@ -0,0 +1,27 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>404</title>
<style>
body {
background-color: #444;
font-size: 14px;
}
h3 {
font-size: 60px;
color: #eee;
text-align: center;
padding-top: 30px;
font-weight: normal;
}
</style>
</head>
<body>
<h3>404您请求的文件不存在!</h3>
</body>
</html>

View File

@ -1,8 +0,0 @@
<div class="site-error">
<div style="margin-top: 100px;text-align: center;">
<h1>温馨提示</h1><br>
</div>
<h4 style="margin: 10px auto;text-align: center;background-color: #1ab394; color: #ffffff;width: 500px;height: 50px;line-height: 50px;border-radius: 5px;">
<i class="fa fa-spinner fa-spin"></i> 功能尚未开放,敬请稍候……</h4>
</div>

View File

@ -1,211 +0,0 @@
<?php
/* @var $this \yii\web\View */
/* @var $content string */
use backend\assets\AppAsset;
use yii\helpers\Html;
use yii\helpers\Url;
use yii\bootstrap\Nav;
use yii\bootstrap\NavBar;
use yii\widgets\Breadcrumbs;
use common\widgets\Alert;
// AppAsset::register($this);
$keywords = '';
$description = '';
$routes = ['data']; //自添加的controllers列表集用于为新添加的控制器在渲染视图时自动加入HTML代码段以便兼容h+的后台模板
?>
<?php $this->beginPage() ?>
<!DOCTYPE html>
<html lang="<?= Yii::$app->language ?>">
<head>
<meta charset="<?= Yii::$app->charset ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?= Html::csrfMetaTags() ?>
<title><?= Html::encode($this->title) ?></title>
<meta name="renderer" content="webkit">
<meta http-equiv="Cache-Control" content="no-siteapp"/>
<meta name="keywords" content="<?php echo $keywords ?>">
<meta name="description" content="<?php echo $description ?>">
<!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;ie.html"/>
<![endif]-->
<link rel="shortcut icon" href="<?= Url::to('@web/favicon.ico'); ?>">
<?= Html::cssFile('@web/css/bootstrap.min.css') ?>
<?= Html::cssFile('@web/css/font-awesome.css') ?>
<?= Html::cssFile('@web/css/animate.min.css') ?>
<?= Html::cssFile('@web/css/site.css') ?>
<?= Html::cssFile('@web/css/style.min.css') ?>
<?= Html::jsFile('@web/js/jquery.min.js?v=2.1.4') ?>
<?= Html::jsFile('@web/js/bootstrap.min.js?v=3.3.6') ?>
<?= Html::jsFile('@web/js/plugins/layer/layer.js') ?>
<?= Html::jsFile('@web/js/admin.js') ?>
<?= Html::cssFile('@web/css/plugins/iCheck/custom.css') ?>
<?= Html::cssFile('@web/css/plugins/awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css') ?>
<?php $this->head() ?>
</head>
<body class="fixed-sidebar full-height-layout gray-bg animated">
<?php $this->beginBody() ?>
<?php if ((Yii::$app->controller->module->defaultRoute != "site") || (Yii::$app->controller->module->defaultRoute == "site" && Yii::$app->controller->module->requestedRoute != ""
&& Yii::$app->controller->module->requestedRoute != "site/login")): ?>
<nav class="breadcrumb fix_top hidden-sm hidden-xs" id="_HiQuickMenu"
style="background-color:#ccc;width: 55px;padding-top: 15px;padding-left: 10px;position:fixed;top:40%;right:15px;z-index:9999;">
<div class="pull-right">
<a class="btn btn-primary radius goback" style="line-height:1.6em;margin-top:3px"
href="javascript:history.go(-1);" title="后退">
<span class="fa fa-reply"></span>
</a>
<br>
<a class="btn btn-primary radius refresh" style="line-height:1.6em;margin-top:3px"
href="javascript:location.replace(location.href);" title="刷新">
<span class="fa fa-refresh"></span>
</a>
<br>
<a class="btn btn-warning radius" style="line-height:1.6em;margin-top:3px"
href="<?php echo url::toRoute(['error/report', 'url' => urlDecode(Url::current())]); ?>"
title="报错反馈">
<span class="fa fa-at"></span>
</a>
<br>
<button class="btn btn-danger radius lockscreen" style="line-height:1.6em;margin-top:3px" title="锁屏">
<span class="fa fa-expeditedssl"></span>
</button>
&nbsp;
</div>
</nav>
<?php endif; ?>
<?php if (in_array(Yii::$app->controller->module->id, $routes)): ?>
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-12">
<div class="ibox float-e-margins">
<div class="ibox-content">
<?php endif; ?>
<?= Alert::widget() ?>
<?= $content ?>
<?php if (in_array(Yii::$app->controller->module->id, $routes)): ?>
</div>
</div>
</div>
</div>
</div>
<?php endif; ?>
<?php $this->endBody() ?>
<style>
.modal-backdrop.in {
opacity: .7;
}
</style>
<div class="modal inmodal" id="myModal" tabindex="-1" role="dialog" aria-hidden="true" data-keyboard='false'
data-backdrop="static" style="z-index:9999;">
<div class="modal-dialog">
<div class="modal-content animated bounceInRight">
<div class="modal-header">
<i class="fa fa-laptop modal-icon"></i>
<h4 class="modal-title">屏幕解锁</h4>
<small class="font-bold"><?php echo date('Y-m-d H:i:s'); ?></small>
</div>
<div class="modal-body">
<p id="_LockScreenTips"></p>
<form class="form-horizontal m-t" id="commentForm" novalidate="novalidate">
<div class="form-group">
<label class="col-sm-3 control-label">口令:</label>
<div class="col-sm-8">
<input id="_ScreenLockCode" name="code" type="password" class="form-control" required=""
aria-required="true">
</div>
</div>
<div class="form-group">
<div class="col-sm-4 col-sm-offset-3">
<button type="button" class="btn btn-white unlockscreen">验证</button>
<button type="reset" class="btn btn-warning">再等等</button>
</div>
</div>
</form>
</div>
<div class="modal-footer" style="text-align: center;">
<button type="button" class="hidden btn btn-primary closelockscreen" data-dismiss="modal">
现在点我,立即解锁
</button>
</div>
</div>
</div>
</div>
<script>
//锁屏
$(function () {
var modalId = 'myModal';
sessionStorage.unLockScreen = true;
$('.lockscreen').bind('click', function () {
layer.confirm('您确认要锁屏吗?', {
btn: ['确认', '算了'], //按钮
shade: true //是否显示遮罩
}, function (index) {
layer.close(index);
layer.prompt(
{
title: '输入解锁屏幕时要用的口令(仅数字与字母)后按确认,即可锁屏',
formType: 0 //prompt风格支持0-2
},
function (value, index, elem) {
layer.close(index);
var code1 = value;
sessionStorage.unLockScreen = false;
sessionStorage.LockScreenCode = code1;
var msg = '锁屏完成,您的口令是:' + code1 + ' ;如果您不小心忘记锁屏密码,请重新登陆;如果您有可能未保存的页面数据,可通过浏览器的网页开发调试工具,清除会话缓存中的锁屏键;如果您不会操作,可联系微信客服<?php echo Yii::$app->params["developerWx"];?>获取付费协助';
var msg2 = '锁屏完成;如果您不小心忘记锁屏密码,请重新登陆;如果您有可能未保存的页面数据,可通过浏览器的网页开发调试工具,清除会话缓存中的锁屏键;如果您不会操作,可联系微信客服<?php echo Yii::$app->params["developerWx"];?>获取付费协助';
$('#_LockScreenTips').html(msg2);
$('#' + modalId).modal('show');
}
);
}, function () {
layer.msg('您取消了锁屏操作', {shift: 6});
});
$('#' + modalId).on('hide.bs.modal',
function () {
$('.closelockscreen').addClass('hidden').hide();
layer.msg('好的,您已成功解锁');
});
});
$('.unlockscreen').bind('click', function () {
var code = $('#_ScreenLockCode').val();
var LockScreenCode = sessionStorage.LockScreenCode;
if (code == LockScreenCode) {
sessionStorage.unLockScreen = true;
$('.closelockscreen').removeClass('hidden').show();
} else {
layer.msg('口令错误,请重新输入');
}
});
if (!sessionStorage.unLockScreen) {
if (sessionStorage.LockScreenCode) {
$('#' + modalId).modal('show');
}
return;
}
});
</script>
<script>
var HOME_URL = '<?php echo Url::home();?>'; //定义首页位置用于content.min.js中快速跳转首页按钮
</script>
<!-- 以下js必须放在页尾顺序不可更换 -->
<?= Html::jsFile('@web/js/bootstrap.min.js?v=3.3.6') ?>
<?= Html::jsFile('@web/js/plugins/layer/layer.js') ?>
<?= Html::jsFile('@web/js/content.min.js') ?>
</body>
</html>
<?php $this->endPage() ?>

View File

@ -1,32 +0,0 @@
<?php
use yii\helpers\Html;
use yii\helpers\Url;
$this->title = isset($title) ? $title : '提示';
$content = isset($content) ? $content : '';
$class = isset($class) ? $class : 'info';
$class = in_array($class, ['danger', 'warning', 'success', 'info']) ? $class : 'info';
$buttons = isset($buttons) ? $buttons : [['title' => '好的,我知道了', 'class' => 'primary', 'url' => FALSE]];
?>
<div class="site-index" style="text-align: center;width:80%;margin-left:10%;">
<div style="margin-top: 100px;">
<h1><?= Html::encode($this->title) ?></h1><br>
</div>
<div class="alert alert-<?php echo $class; ?> fade in" role="alert">
<?php echo $content; ?>
</div>
<?php foreach ($buttons as $btn) { ?>
<a <?php if ($btn['url']) { ?> href="<?php echo $btn['url']; ?>" <?php } ?>
class="btn btn-<?php if ($btn['class']) {
echo $btn['class'];
} else {
echo 'primary';
} ?>"><?php if ($btn['title']) {
echo $btn['title'];
} else {
echo '点击按钮';
} ?></a>
<?php } ?>
</div>

View File

@ -10,7 +10,7 @@
defined('YII_ENV') or define('YII_ENV', 'prod');
date_default_timezone_set('PRC'); //设置时区为中国
define('TIMESTAMP', time());
define('HI_APP', 'ctms'); //给子项目设置的统一短标识
define('HI_APP', 'dacms'); //给子项目设置的统一短标识
//跨域设置
require(__DIR__ . '/../../addons-' . HI_APP . '/access.php');
require(__DIR__ . '/../../cors.php');

View File

@ -10,7 +10,7 @@
defined('YII_ENV') or define('YII_ENV', 'dev');
date_default_timezone_set('PRC'); //设置时区为中国
define('TIMESTAMP', time());
define('HI_APP', 'ctms'); //给子项目设置的统一短标识
define('HI_APP', 'dacms'); //给子项目设置的统一短标识
//跨域设置
require(__DIR__ . '/../../addons-' . HI_APP . '/access.php');
require(__DIR__ . '/../../cors.php');

View File

@ -1,2 +1,2 @@
/index.php
/index-test.php
assets
.well-known

View File

@ -1,2 +1 @@
/index.php
/index-test.php
assets

17
vendor/autoload.php vendored
View File

@ -3,8 +3,21 @@
// autoload.php @generated by Composer
if (PHP_VERSION_ID < 50600) {
echo 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running '.PHP_VERSION.', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.'.PHP_EOL;
exit(1);
if (!headers_sent()) {
header('HTTP/1.1 500 Internal Server Error');
}
$err = 'Composer 2.3.0 dropped support for autoloading on PHP <5.6 and you are running ' . PHP_VERSION . ', please upgrade PHP or use Composer 2.2 LTS via "composer self-update --2.2". Aborting.' . PHP_EOL;
if (!ini_get('display_errors')) {
if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') {
fwrite(STDERR, $err);
} else if (!headers_sent()) {
echo $err;
}
}
trigger_error(
$err,
E_USER_ERROR
);
}
require_once __DIR__ . '/composer/autoload_real.php';

View File

@ -1,47 +0,0 @@
name: Build
on:
push:
branches: [master]
pull_request:
release:
types: [created]
jobs:
tests:
runs-on: ubuntu-latest
name: Build and test
strategy:
fail-fast: false
matrix:
php: [7.2, 7.3, 7.4, 8.0, 8.1]
composer-flags: [ "" ]
symfony-version: [ "" ]
include:
- php: 7.2
symfony-version: '3.*'
- php: 7.3
symfony-version: '4.*'
- php: 7.4
symfony-version: '5.*'
- php: 8.0
symfony-version: '5.*'
steps:
- uses: actions/checkout@v2
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: "${{ matrix.php }}"
coverage: none
- name: Update Symfony version
if: matrix.symfony-version != ''
run: composer require --no-update "symfony/symfony:${{ matrix.symfony-version }}"
- name: Install dependencies
run: composer update ${{ matrix.composer-flags }}
- name: Run tests (phpunit)
run: ./vendor/bin/phpunit

View File

@ -1,49 +0,0 @@
name: Update Cucumber
on:
schedule:
- cron: '0 7 * * *'
jobs:
cucumber-update:
runs-on: ubuntu-latest
name: Upstream cucumber update
steps:
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: 7.4
coverage: none
- uses: actions/checkout@v2
- name: Install dependencies
run: composer update
- name: Update cucumber tag
id: cucumber
run: bin/update_cucumber
- name: Re-install dependencies
run: composer update
if: steps.cucumber.outputs.cucumber_version
- name: Update translations
run: bin/update_i18n
if: steps.cucumber.outputs.cucumber_version
- name: Find changelog
id: changelog
run: bin/cucumber_changelog ${{ steps.cucumber.outputs.cucumber_version }}
if: steps.cucumber.outputs.cucumber_version
- name: Open a PR
uses: peter-evans/create-pull-request@v3
if: steps.cucumber.outputs.cucumber_version
with:
commit-message: Automatic Cucumber tag update to ${{ steps.cucumber.outputs.cucumber_version }}
branch: cucumber-update-${{ steps.cucumber.outputs.cucumber_version }}
delete-branch: true
title: Cucumber update ${{ steps.cucumber.outputs.cucumber_version }}
body: ${{ steps.changelog.outputs.changelog }}
base: 'master'

View File

@ -1,442 +1,380 @@
4.9.0 / 2021-10-12
==================
# 4.10.0 / 2024-10-19
* Simplify the boolean condition for the tag matching by @stof in https://github.com/Behat/Gherkin/pull/219
* Remove symfony phpunit bridge by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/220
* Ignore the bin folder in archives by @stof in https://github.com/Behat/Gherkin/pull/226
* Cast table node exceptions into ParserExceptions when throwing by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/216
* Cucumber changelog in PRs and using correct hash by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/225
* Support alternative docstrings format (```) by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/214
* Fix DocBlocks (Boolean -> bool) by @simonhammes in https://github.com/Behat/Gherkin/pull/237
* Tag parsing by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/215
* Remove test - cucumber added an example with Rule which is not supported by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/239
* Add PHP 8.1 support by @javer in https://github.com/Behat/Gherkin/pull/242
* Fix main branch alias version by @mvorisek in https://github.com/Behat/Gherkin/pull/244
- Add support for Symfony 6 and 7 thanks to @tacman
- Sync with Cucumber 24.1.0
- Fix exception when filter string is empty thanks to @magikid
- Fix nullable parameters warning in PHP 8.4 thanks to @heiglandreas and @jrfnl
- Fix parsing of scenario outline rows with trailing backslashes
- Fix PHPUnit 10 deprecation messages
- A lot of great CI work by @heiglandreas and @jrfnl
4.8.0 / 2021-02-04
==================
# 4.9.0 / 2021-10-12
* Drop support for PHP before version 7.2
- Simplify the boolean condition for the tag matching by @stof in https://github.com/Behat/Gherkin/pull/219
- Remove symfony phpunit bridge by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/220
- Ignore the bin folder in archives by @stof in https://github.com/Behat/Gherkin/pull/226
- Cast table node exceptions into ParserExceptions when throwing by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/216
- Cucumber changelog in PRs and using correct hash by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/225
- Support alternative docstrings format (```) by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/214
- Fix DocBlocks (Boolean -> bool) by @simonhammes in https://github.com/Behat/Gherkin/pull/237
- Tag parsing by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/215
- Remove test - cucumber added an example with Rule which is not supported by @ciaranmcnulty in https://github.com/Behat/Gherkin/pull/239
- Add PHP 8.1 support by @javer in https://github.com/Behat/Gherkin/pull/242
- Fix main branch alias version by @mvorisek in https://github.com/Behat/Gherkin/pull/244
4.7.3 / 2021-02-04
==================
# 4.8.0 / 2021-02-04
* Refactored comments parsing to avoid Maximum function nesting level errors
- Drop support for PHP before version 7.2
4.7.2 / 2021-02-03
==================
# 4.7.3 / 2021-02-04
* Issue where Scenario Outline title was not populated into Examples
* Updated translations from cucumber 16.0.0
- Refactored comments parsing to avoid Maximum function nesting level errors
4.7.1 / 2021-01-26
==================
# 4.7.2 / 2021-02-03
* Issue parsing comments before scenarios when following an Examples table
- Issue where Scenario Outline title was not populated into Examples
- Updated translations from cucumber 16.0.0
4.7.0 / 2021-01-24
==================
# 4.7.1 / 2021-01-26
* Provides better messages for TableNode construct errors
* Now allows single character steps
* Supports multiple Example Tables with tags
- Issue parsing comments before scenarios when following an Examples table
4.6.2 / 2020-03-17
==================
# 4.7.0 / 2021-01-24
* Fixed issues due to incorrect cache key
- Provides better messages for TableNode construct errors
- Now allows single character steps
- Supports multiple Example Tables with tags
4.6.1 / 2020-02-27
==================
# 4.6.2 / 2020-03-17
* Fix AZ translations
* Correctly filter features, now that the base path is correctly set
- Fixed issues due to incorrect cache key
4.6.0 / 2019-01-16
==================
# 4.6.1 / 2020-02-27
* Updated translations (including 'Example' as synonym for 'Scenario' in `en`)
- Fix AZ translations
- Correctly filter features, now that the base path is correctly set
4.5.1 / 2017-08-30
==================
# 4.6.0 / 2019-01-16
* Fix regression in `PathsFilter`
- Updated translations (including 'Example' as synonym for 'Scenario' in `en`)
4.5.0 / 2017-08-30
==================
# 4.5.1 / 2017-08-30
* Sync i18n with Cucumber Gherkin
* Drop support for HHVM tests on Travis
* Add `TableNode::fromList()` method (thanks @TravisCarden)
* Add `ExampleNode::getOutlineTitle()` method (thanks @duxet)
* Use realpath, so the feature receives the cwd prefixed (thanks @glennunipro)
* Explicitly handle non-two-dimensional arrays in TableNode (thanks @TravisCarden)
* Fix to line/linefilter scenario runs which take relative paths to files (thanks @generalconsensus)
- Fix regression in `PathsFilter`
4.4.5 / 2016-10-30
==================
# 4.5.0 / 2017-08-30
* Fix partial paths matching in `PathsFilter`
- Sync i18n with Cucumber Gherkin
- Drop support for HHVM tests on Travis
- Add `TableNode::fromList()` method (thanks @TravisCarden)
- Add `ExampleNode::getOutlineTitle()` method (thanks @duxet)
- Use realpath, so the feature receives the cwd prefixed (thanks @glennunipro)
- Explicitly handle non-two-dimensional arrays in TableNode (thanks @TravisCarden)
- Fix to line/linefilter scenario runs which take relative paths to files (thanks @generalconsensus)
4.4.4 / 2016-09-18
==================
# 4.4.5 / 2016-10-30
* Provide clearer exception for non-writeable cache directories
- Fix partial paths matching in `PathsFilter`
4.4.3 / 2016-09-18
==================
# 4.4.4 / 2016-09-18
* Ensure we reset tags between features
- Provide clearer exception for non-writeable cache directories
4.4.2 / 2016-09-03
==================
# 4.4.3 / 2016-09-18
* Sync 18n with gherkin 3
- Ensure we reset tags between features
4.4.1 / 2015-12-30
==================
# 4.4.2 / 2016-09-03
* Ensure keywords are trimmed when syncing translations
* Sync 18n with cucumber
- Sync 18n with gherkin 3
4.4.0 / 2015-09-19
==================
# 4.4.1 / 2015-12-30
* Added validation enforcing that all rows of a `TableNode` have the same number of columns
* Added `TableNode::getColumn` to get a column from the table
* Sync 18n with cucumber
- Ensure keywords are trimmed when syncing translations
- Sync 18n with cucumber
4.3.0 / 2014-06-06
==================
# 4.4.0 / 2015-09-19
* Added `setFilters(array)` method to `Gherkin` class
* Added `NarrativeFilter` for non-english `RoleFilter` lovers
- Added validation enforcing that all rows of a `TableNode` have the same number of columns
- Added `TableNode::getColumn` to get a column from the table
- Sync 18n with cucumber
4.2.1 / 2014-06-06
==================
# 4.3.0 / 2014-06-06
* Fix parsing of features without line feed at the end
- Added `setFilters(array)` method to `Gherkin` class
- Added `NarrativeFilter` for non-english `RoleFilter` lovers
4.2.0 / 2014-05-27
==================
# 4.2.1 / 2014-06-06
* Added `getKeyword()` and `getKeywordType()` methods to `StepNode`, deprecated `getType()`.
- Fix parsing of features without line feed at the end
# 4.2.0 / 2014-05-27
- Added `getKeyword()` and `getKeywordType()` methods to `StepNode`, deprecated `getType()`.
Thanks to @kibao
4.1.3 / 2014-05-25
==================
# 4.1.3 / 2014-05-25
* Properly handle tables with rows terminating in whitespace
- Properly handle tables with rows terminating in whitespace
4.1.2 / 2014-05-14
==================
# 4.1.2 / 2014-05-14
* Handle case where Gherkin cache is broken
- Handle case where Gherkin cache is broken
4.1.1 / 2014-05-05
==================
# 4.1.1 / 2014-05-05
* Fixed the compatibility with PHP 5.6-beta by avoiding to use the broken PHP array function
* The YamlFileLoader no longer extend from ArrayLoader but from AbstractFileLoader
- Fixed the compatibility with PHP 5.6-beta by avoiding to use the broken PHP array function
- The YamlFileLoader no longer extend from ArrayLoader but from AbstractFileLoader
4.1.0 / 2014-04-20
==================
# 4.1.0 / 2014-04-20
* Fixed scenario tag filtering
* Do not allow multiple multiline step arguments
* Sync 18n with cucumber
- Fixed scenario tag filtering
- Do not allow multiple multiline step arguments
- Sync 18n with cucumber
4.0.0 / 2014-01-05
==================
# 4.0.0 / 2014-01-05
* Changed the behavior when no loader can be found for the resource. Instead of throwing an exception, the
- Changed the behavior when no loader can be found for the resource. Instead of throwing an exception, the
Gherkin class now returns an empty array.
3.1.3 / 2014-01-04
==================
# 3.1.3 / 2014-01-04
* Dropped the dependency on the Symfony Finder by using SPL iterators directly
* Added testing on HHVM on Travis. HHVM is officially supported (previous release was actually already compatible)
- Dropped the dependency on the Symfony Finder by using SPL iterators directly
- Added testing on HHVM on Travis. HHVM is officially supported (previous release was actually already compatible)
3.1.2 / 2014-01-01
==================
# 3.1.2 / 2014-01-01
* All paths passed to PathsFilter are converted using realpath
- All paths passed to PathsFilter are converted using realpath
3.1.1 / 2013-12-31
==================
# 3.1.1 / 2013-12-31
* Add `ComplexFilterInterace` that has complex behavior for scenarios and requires to pass
- Add `ComplexFilterInterace` that has complex behavior for scenarios and requires to pass
feature too
* `TagFilter` is an instance of a `ComplexFilterInterace` now
- `TagFilter` is an instance of a `ComplexFilterInterace` now
3.1.0 / 2013-12-31
==================
# 3.1.0 / 2013-12-31
* Example node is a scenario
* Nodes do not have uprefs (memory usage fix)
* Scenario filters do not depend on feature nodes
- Example node is a scenario
- Nodes do not have uprefs (memory usage fix)
- Scenario filters do not depend on feature nodes
3.0.5 / 2014-01-01
==================
# 3.0.5 / 2014-01-01
* All paths passed to PathsFilter are converted using realpath
- All paths passed to PathsFilter are converted using realpath
3.0.4 / 2013-12-31
==================
# 3.0.4 / 2013-12-31
* TableNode is now traversable using foreach
* All possibly thrown exceptions implement Gherkin\Exception interface
* Sync i18n with cucumber
- TableNode is now traversable using foreach
- All possibly thrown exceptions implement Gherkin\Exception interface
- Sync i18n with cucumber
3.0.3 / 2013-09-15
==================
# 3.0.3 / 2013-09-15
* Extend ExampleNode with additional methods
- Extend ExampleNode with additional methods
3.0.2 / 2013-09-14
==================
# 3.0.2 / 2013-09-14
* Extract `KeywordNodeInterface` and `ScenarioLikeInterface`
* Add `getIndex()` methods to scenarios, outlines, steps and examples
* Throw proper exception for fractured node tree
- Extract `KeywordNodeInterface` and `ScenarioLikeInterface`
- Add `getIndex()` methods to scenarios, outlines, steps and examples
- Throw proper exception for fractured node tree
3.0.1 / 2013-09-14
==================
# 3.0.1 / 2013-09-14
* Use versioned subfolder in FileCache
- Use versioned subfolder in FileCache
3.0.0 / 2013-09-14
==================
# 3.0.0 / 2013-09-14
* A lot of optimizations in Parser and Lexer
* Node tree is now immutable by nature (no setters)
* Example nodes are now part of the node tree. They are lazily generated by Outline node
* Sync with latest cucumber i18n
- A lot of optimizations in Parser and Lexer
- Node tree is now immutable by nature (no setters)
- Example nodes are now part of the node tree. They are lazily generated by Outline node
- Sync with latest cucumber i18n
2.3.4 / 2013-08-11
==================
# 2.3.4 / 2013-08-11
* Fix leaks in memory cache
- Fix leaks in memory cache
2.3.3 / 2013-08-11
==================
# 2.3.3 / 2013-08-11
* Fix encoding bug introduced with previous release
* Sync i18n with cucumber
- Fix encoding bug introduced with previous release
- Sync i18n with cucumber
2.3.2 / 2013-08-11
==================
# 2.3.2 / 2013-08-11
* Explicitly use utf8 encoding
- Explicitly use utf8 encoding
2.3.1 / 2013-08-10
==================
# 2.3.1 / 2013-08-10
* Support `an` prefix with RoleFilter
- Support `an` prefix with RoleFilter
2.3.0 / 2013-08-04
==================
# 2.3.0 / 2013-08-04
* Add RoleFilter
* Add PathsFilter
* Add MemoryCache
- Add RoleFilter
- Add PathsFilter
- Add MemoryCache
2.2.9 / 2013-03-02
==================
# 2.2.9 / 2013-03-02
* Fix dependency version requirement
- Fix dependency version requirement
2.2.8 / 2013-03-02
==================
# 2.2.8 / 2013-03-02
* Features filtering behavior change. Now emptified (by filtering) features
- Features filtering behavior change. Now emptified (by filtering) features
that do not match filter themselves are removed from resultset.
* Small potential bug fix in TableNode
- Small potential bug fix in TableNode
2.2.7 / 2013-01-27
==================
# 2.2.7 / 2013-01-27
* Fixed bug in i18n syncing script
* Resynced Gherkin i18n
- Fixed bug in i18n syncing script
- Resynced Gherkin i18n
2.2.6 / 2013-01-26
==================
# 2.2.6 / 2013-01-26
* Support long row hashes in tables ([see](https://github.com/Behat/Gherkin/issues/40))
* Synced Gherkin i18n
- Support long row hashes in tables ([see](https://github.com/Behat/Gherkin/issues/40))
- Synced Gherkin i18n
2.2.5 / 2012-09-26
==================
# 2.2.5 / 2012-09-26
* Fixed issue with loading empty features
* Synced Gherkin i18n
- Fixed issue with loading empty features
- Synced Gherkin i18n
2.2.4 / 2012-08-03
==================
# 2.2.4 / 2012-08-03
* Fixed exception message for "no loader found"
- Fixed exception message for "no loader found"
2.2.3 / 2012-08-03
==================
# 2.2.3 / 2012-08-03
* Fixed minor loader bug with empty base path
* Synced Gherkin i18n
- Fixed minor loader bug with empty base path
- Synced Gherkin i18n
2.2.2 / 2012-07-01
==================
# 2.2.2 / 2012-07-01
* Added ability to filter outline scenarios by line and range filters
* Synced Gherkin i18n
* Refactored table parser to read row line numbers too
- Added ability to filter outline scenarios by line and range filters
- Synced Gherkin i18n
- Refactored table parser to read row line numbers too
2.2.1 / 2012-05-04
==================
# 2.2.1 / 2012-05-04
* Fixed StepNode `getLanguage()` and `getFile()`
- Fixed StepNode `getLanguage()` and `getFile()`
2.2.0 / 2012-05-03
==================
# 2.2.0 / 2012-05-03
* Features freeze after parsing
* Implemented GherkinDumper (@Halleck45)
* Synced i18n with Cucumber
* Updated inline documentation
- Features freeze after parsing
- Implemented GherkinDumper (@Halleck45)
- Synced i18n with Cucumber
- Updated inline documentation
2.1.1 / 2012-03-09
==================
# 2.1.1 / 2012-03-09
* Fixed caching bug, where `isFresh()` always returned false
- Fixed caching bug, where `isFresh()` always returned false
2.1.0 / 2012-03-09
==================
# 2.1.0 / 2012-03-09
* Added parser caching layer
* Added support for table delimiter escaping (use `\|` for that)
* Added LineRangeFilter (thanks @headrevision)
* Synced i18n dictionary with cucumber/gherkin
- Added parser caching layer
- Added support for table delimiter escaping (use `\|` for that)
- Added LineRangeFilter (thanks @headrevision)
- Synced i18n dictionary with cucumber/gherkin
2.0.2 / 2012-02-04
==================
# 2.0.2 / 2012-02-04
* Synced i18n dictionary with cucumber/gherkin
- Synced i18n dictionary with cucumber/gherkin
2.0.1 / 2012-01-26
==================
# 2.0.1 / 2012-01-26
* Fixed issue about parsing features without indentation
- Fixed issue about parsing features without indentation
2.0.0 / 2012-01-19
==================
# 2.0.0 / 2012-01-19
* Background titles support
* Correct parsing of titles/descriptions (hirarchy lexing)
* Migration to the cucumber/gherkin i18n dictionary
* Speed optimizations
* Refactored KeywordsDumper
* New loaders
* Bugfixes
- Background titles support
- Correct parsing of titles/descriptions (hirarchy lexing)
- Migration to the cucumber/gherkin i18n dictionary
- Speed optimizations
- Refactored KeywordsDumper
- New loaders
- Bugfixes
1.1.4 / 2012-01-08
==================
# 1.1.4 / 2012-01-08
* Read feature description even if it looks like a step
- Read feature description even if it looks like a step
1.1.3 / 2011-12-14
==================
# 1.1.3 / 2011-12-14
* Removed file loading routines from Parser (fixes `is_file()` issue on some systems - thanks
- Removed file loading routines from Parser (fixes `is_file()` issue on some systems - thanks
@flodocteurklein)
1.1.2 / 2011-12-01
==================
# 1.1.2 / 2011-12-01
* Updated spanish trasnaltion (@anbotero)
* Integration with Composer and Travis CI
- Updated spanish trasnaltion (@anbotero)
- Integration with Composer and Travis CI
1.1.1 / 2011-07-29
==================
# 1.1.1 / 2011-07-29
* Updated pt language step types (@danielcsgomes)
* Updated vendors
- Updated pt language step types (@danielcsgomes)
- Updated vendors
1.1.0 / 2011-07-16
==================
# 1.1.0 / 2011-07-16
* Return all tags, including inherited in `Scenario::getTags()`
* New `Feature::getOwnTags()` and `Scenario::getOwnTags()` method added,
- Return all tags, including inherited in `Scenario::getTags()`
- New `Feature::getOwnTags()` and `Scenario::getOwnTags()` method added,
which returns only own tags
1.0.8 / 2011-06-29
==================
# 1.0.8 / 2011-06-29
* Fixed comments parsing.
- Fixed comments parsing.
You cant have comments at the end of a line # like this
# But you can still have comments at the beginning of a line
1.0.7 / 2011-06-28
==================
# 1.0.7 / 2011-06-28
* Added `getRaw()` method to PyStringNode
* Updated vendors
- Added `getRaw()` method to PyStringNode
- Updated vendors
1.0.6 / 2011-06-17
==================
# 1.0.6 / 2011-06-17
* Updated vendors
- Updated vendors
1.0.5 / 2011-06-10
==================
# 1.0.5 / 2011-06-10
* Fixed bug, introduced with 1.0.4 - hash in PyStrings
- Fixed bug, introduced with 1.0.4 - hash in PyStrings
1.0.4 / 2011-06-10
==================
# 1.0.4 / 2011-06-10
* Fixed inability to comment pystrings
- Fixed inability to comment pystrings
1.0.3 / 2011-04-21
==================
# 1.0.3 / 2011-04-21
* Fixed introduced with 1.0.2 pystring parsing bug
- Fixed introduced with 1.0.2 pystring parsing bug
1.0.2 / 2011-04-18
==================
# 1.0.2 / 2011-04-18
* Fixed bugs in text with comments parsing
- Fixed bugs in text with comments parsing
1.0.1 / 2011-04-01
==================
# 1.0.1 / 2011-04-01
* Updated vendors
- Updated vendors
1.0.0 / 2011-03-08
==================
# 1.0.0 / 2011-03-08
* Updated vendors
- Updated vendors
1.0.0RC2 / 2011-02-25
=====================
# 1.0.0RC2 / 2011-02-25
* Windows support
* Missing phpunit config
- Windows support
- Missing phpunit config
1.0.0RC1 / 2011-02-15
=====================
# 1.0.0RC1 / 2011-02-15
* Huge optimizations to Lexer & Parser
* Additional loaders (Yaml, Array, Directory)
* Filters (Tag, Name, Line)
* Code refactoring
* Nodes optimizations
* Additional tests for exceptions and translations
* Keywords dumper
- Huge optimizations to Lexer & Parser
- Additional loaders (Yaml, Array, Directory)
- Filters (Tag, Name, Line)
- Code refactoring
- Nodes optimizations
- Additional tests for exceptions and translations
- Keywords dumper
0.2.0 / 2011-01-05
==================
# 0.2.0 / 2011-01-05
* New Parser & Lexer (based on AST)
* New verbose parsing exception handling
* New translation mechanics
* 47 brand new translations (see i18n)
* Full test suite for everything from AST nodes to translations
- New Parser & Lexer (based on AST)
- New verbose parsing exception handling
- New translation mechanics
- 47 brand new translations (see i18n)
- Full test suite for everything from AST nodes to translations

View File

@ -18,9 +18,9 @@
},
"require-dev": {
"symfony/yaml": "~3|~4|~5",
"symfony/yaml": "~3|~4|~5|~6|~7",
"phpunit/phpunit": "~8|~9",
"cucumber/cucumber": "dev-gherkin-24.0.0"
"cucumber/cucumber": "dev-gherkin-24.1.0"
},
"suggest": {
@ -50,16 +50,16 @@
"type": "package",
"package": {
"name": "cucumber/cucumber",
"version": "dev-gherkin-24.0.0",
"version": "dev-gherkin-24.1.0",
"source": {
"type": "git",
"url": "https://github.com/cucumber/cucumber.git",
"reference": "effd4cf5273798c74793a63f9c88a14a1047346d"
"reference": "1bd907bfcd246275e6d11f62c0885e654cec58cf"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cucumber/cucumber/zipball/effd4cf5273798c74793a63f9c88a14a1047346d",
"reference": "effd4cf5273798c74793a63f9c88a14a1047346d"
"url": "https://api.github.com/repos/cucumber/cucumber/zipball/1bd907bfcd246275e6d11f62c0885e654cec58cf",
"reference": "1bd907bfcd246275e6d11f62c0885e654cec58cf"
}
}
}

View File

@ -1220,7 +1220,7 @@ return array (
'given' => '假如<|假定<|假设<|*',
'name' => 'Chinese simplified',
'native' => '简体中文',
'rule' => 'Rule',
'rule' => 'Rule|规则',
'scenario' => '剧本|场景',
'scenario_outline' => '剧本大纲|场景大纲',
'then' => '那么<|*',

View File

@ -507,7 +507,7 @@ class Lexer
$token = $this->takeToken('TableRow');
$line = mb_substr($line, 1, mb_strlen($line, 'utf8') - 2, 'utf8');
$columns = array_map(function ($column) {
return trim(str_replace('\\|', '|', $column));
return trim(str_replace(['\\|', '\\\\'], ['|', '\\'], $column));
}, preg_split('/(?<!\\\)\|/u', $line));
$token['columns'] = $columns;

View File

@ -30,7 +30,7 @@ class GherkinFileLoader extends AbstractFileLoader
* @param Parser $parser Parser
* @param CacheInterface $cache Cache layer
*/
public function __construct(Parser $parser, CacheInterface $cache = null)
public function __construct(Parser $parser, ?CacheInterface $cache = null)
{
$this->parser = $parser;
$this->cache = $cache;

View File

@ -71,7 +71,7 @@ class FeatureNode implements KeywordNodeInterface, TaggedNodeInterface
$title,
$description,
array $tags,
BackgroundNode $background = null,
?BackgroundNode $background,
array $scenarios,
$keyword,
$language,

10
vendor/bin/codecept vendored
View File

@ -108,10 +108,12 @@ if (PHP_VERSION_ID < 80000) {
}
}
if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) {
include("phpvfscomposer://" . __DIR__ . '/..'.'/codeception/codeception/codecept');
exit(0);
if (
(function_exists('stream_get_wrappers') && in_array('phpvfscomposer', stream_get_wrappers(), TRUE))
|| (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper'))
) {
return include("phpvfscomposer://" . __DIR__ . '/..' . '/codeception/codeception/codecept');
}
}
include __DIR__ . '/..'.'/codeception/codeception/codecept';
return include __DIR__ . '/..' . '/codeception/codeception/codecept';

View File

@ -97,7 +97,7 @@ class ModuleContainer
if (!class_exists($moduleClass)) {
if (isset(self::$packages[$moduleName])) {
$package = self::$packages[$moduleName];
throw new ConfigurationException("Codeception's module {$moduleName} not found. Install it with:\n\ncomposer require {$package} --dev");
throw new ConfigurationException("Module {$moduleName} is not installed.\nUse Composer to install corresponding package:\n\ncomposer require {$package} --dev");
}
throw new ConfigurationException("Module {$moduleName} could not be found and loaded");
}

View File

@ -64,7 +64,7 @@ class ReportPrinter implements ConsolePrinter
public function testFailure(FailEvent $event): void
{
$this->printTestResult($event->getTest(), "FAIL");
$this->printTestResult($event->getTest(), "\033[41;37mFAIL\033[0m");
$this->failureCount++;
}

View File

@ -42,35 +42,37 @@ namespace Composer\Autoload;
*/
class ClassLoader
{
/** @var ?string */
/** @var \Closure(string):void */
private static $includeFile;
/** @var string|null */
private $vendorDir;
// PSR-4
/**
* @var array[]
* @psalm-var array<string, array<string, int>>
* @var array<string, array<string, int>>
*/
private $prefixLengthsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, array<int, string>>
* @var array<string, list<string>>
*/
private $prefixDirsPsr4 = array();
/**
* @var array[]
* @psalm-var array<string, string>
* @var list<string>
*/
private $fallbackDirsPsr4 = array();
// PSR-0
/**
* @var array[]
* @psalm-var array<string, array<string, string[]>>
* List of PSR-0 prefixes
*
* Structured as array('F (first letter)' => array('Foo\Bar (full prefix)' => array('path', 'path2')))
*
* @var array<string, array<string, list<string>>>
*/
private $prefixesPsr0 = array();
/**
* @var array[]
* @psalm-var array<string, string>
* @var list<string>
*/
private $fallbackDirsPsr0 = array();
@ -78,8 +80,7 @@ class ClassLoader
private $useIncludePath = false;
/**
* @var string[]
* @psalm-var array<string, string>
* @var array<string, string>
*/
private $classMap = array();
@ -87,29 +88,29 @@ class ClassLoader
private $classMapAuthoritative = false;
/**
* @var bool[]
* @psalm-var array<string, bool>
* @var array<string, bool>
*/
private $missingClasses = array();
/** @var ?string */
/** @var string|null */
private $apcuPrefix;
/**
* @var self[]
* @var array<string, self>
*/
private static $registeredLoaders = array();
/**
* @param ?string $vendorDir
* @param string|null $vendorDir
*/
public function __construct($vendorDir = null)
{
$this->vendorDir = $vendorDir;
self::initializeIncludeClosure();
}
/**
* @return string[]
* @return array<string, list<string>>
*/
public function getPrefixes()
{
@ -121,8 +122,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, array<int, string>>
* @return array<string, list<string>>
*/
public function getPrefixesPsr4()
{
@ -130,8 +130,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, string>
* @return list<string>
*/
public function getFallbackDirs()
{
@ -139,8 +138,7 @@ class ClassLoader
}
/**
* @return array[]
* @psalm-return array<string, string>
* @return list<string>
*/
public function getFallbackDirsPsr4()
{
@ -148,8 +146,7 @@ class ClassLoader
}
/**
* @return string[] Array of classname => path
* @psalm-return array<string, string>
* @return array<string, string> Array of classname => path
*/
public function getClassMap()
{
@ -157,8 +154,7 @@ class ClassLoader
}
/**
* @param string[] $classMap Class to filename map
* @psalm-param array<string, string> $classMap
* @param array<string, string> $classMap Class to filename map
*
* @return void
*/
@ -176,23 +172,24 @@ class ClassLoader
* appending or prepending to the ones previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 root directories
* @param list<string>|string $paths The PSR-0 root directories
* @param bool $prepend Whether to prepend the directories
*
* @return void
*/
public function add($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
if ($prepend) {
$this->fallbackDirsPsr0 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr0
);
} else {
$this->fallbackDirsPsr0 = array_merge(
$this->fallbackDirsPsr0,
(array) $paths
$paths
);
}
@ -201,19 +198,19 @@ class ClassLoader
$first = $prefix[0];
if (!isset($this->prefixesPsr0[$first][$prefix])) {
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
$this->prefixesPsr0[$first][$prefix] = $paths;
return;
}
if ($prepend) {
$this->prefixesPsr0[$first][$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixesPsr0[$first][$prefix]
);
} else {
$this->prefixesPsr0[$first][$prefix] = array_merge(
$this->prefixesPsr0[$first][$prefix],
(array) $paths
$paths
);
}
}
@ -223,7 +220,7 @@ class ClassLoader
* appending or prepending to the ones previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param list<string>|string $paths The PSR-4 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
@ -232,17 +229,18 @@ class ClassLoader
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
$paths = (array) $paths;
if (!$prefix) {
// Register directories for the root namespace.
if ($prepend) {
$this->fallbackDirsPsr4 = array_merge(
(array) $paths,
$paths,
$this->fallbackDirsPsr4
);
} else {
$this->fallbackDirsPsr4 = array_merge(
$this->fallbackDirsPsr4,
(array) $paths
$paths
);
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
@ -252,18 +250,18 @@ class ClassLoader
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
$this->prefixDirsPsr4[$prefix] = $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
(array) $paths,
$paths,
$this->prefixDirsPsr4[$prefix]
);
} else {
// Append directories for an already registered namespace.
$this->prefixDirsPsr4[$prefix] = array_merge(
$this->prefixDirsPsr4[$prefix],
(array) $paths
$paths
);
}
}
@ -273,7 +271,7 @@ class ClassLoader
* replacing any others previously set for this prefix.
*
* @param string $prefix The prefix
* @param string[]|string $paths The PSR-0 base directories
* @param list<string>|string $paths The PSR-0 base directories
*
* @return void
*/
@ -291,7 +289,7 @@ class ClassLoader
* replacing any others previously set for this namespace.
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param string[]|string $paths The PSR-4 base directories
* @param list<string>|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*
@ -425,7 +423,8 @@ class ClassLoader
public function loadClass($class)
{
if ($file = $this->findFile($class)) {
includeFile($file);
$includeFile = self::$includeFile;
$includeFile($file);
return true;
}
@ -476,9 +475,9 @@ class ClassLoader
}
/**
* Returns the currently registered loaders indexed by their corresponding vendor directories.
* Returns the currently registered loaders keyed by their corresponding vendor directories.
*
* @return self[]
* @return array<string, self>
*/
public static function getRegisteredLoaders()
{
@ -555,6 +554,14 @@ class ClassLoader
return false;
}
/**
* @return void
*/
private static function initializeIncludeClosure()
{
if (self::$includeFile !== null) {
return;
}
/**
@ -564,9 +571,9 @@ class ClassLoader
*
* @param string $file
* @return void
* @private
*/
function includeFile($file)
{
self::$includeFile = \Closure::bind(static function($file) {
include $file;
}, null, null);
}
}

View File

@ -28,7 +28,7 @@ class InstalledVersions
{
/**
* @var mixed[]|null
* @psalm-var array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}|array{}|null
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
*/
private static $installed;
@ -39,7 +39,7 @@ class InstalledVersions
/**
* @var array[]
* @psalm-var array<string, array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
* @psalm-var array<string, array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static $installedByVendor = array();
@ -98,7 +98,7 @@ class InstalledVersions
{
foreach (self::getInstalled() as $installed) {
if (isset($installed['versions'][$packageName])) {
return $includeDevRequirements || empty($installed['versions'][$packageName]['dev_requirement']);
return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false;
}
}
@ -119,7 +119,7 @@ class InstalledVersions
*/
public static function satisfies(VersionParser $parser, $packageName, $constraint)
{
$constraint = $parser->parseConstraints($constraint);
$constraint = $parser->parseConstraints((string) $constraint);
$provided = $parser->parseConstraints(self::getVersionRanges($packageName));
return $provided->matches($constraint);
@ -243,7 +243,7 @@ class InstalledVersions
/**
* @return array
* @psalm-return array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}
* @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}
*/
public static function getRootPackage()
{
@ -257,7 +257,7 @@ class InstalledVersions
*
* @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect.
* @return array[]
* @psalm-return array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}
* @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}
*/
public static function getRawData()
{
@ -280,7 +280,7 @@ class InstalledVersions
* Returns the raw data of all installed.php which are currently loaded for custom implementations
*
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
public static function getAllRawData()
{
@ -303,7 +303,7 @@ class InstalledVersions
* @param array[] $data A vendor/composer/installed.php data set
* @return void
*
* @psalm-param array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>} $data
* @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $data
*/
public static function reload($data)
{
@ -313,7 +313,7 @@ class InstalledVersions
/**
* @return array[]
* @psalm-return list<array{root: array{name: string, version: string, reference: string, pretty_version: string, aliases: string[], dev: bool, install_path: string, type: string}, versions: array<string, array{dev_requirement: bool, pretty_version?: string, version?: string, aliases?: string[], reference?: string, replaced?: string[], provided?: string[], install_path?: string, type?: string}>}>
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
*/
private static function getInstalled()
{
@ -328,7 +328,9 @@ class InstalledVersions
if (isset(self::$installedByVendor[$vendorDir])) {
$installed[] = self::$installedByVendor[$vendorDir];
} elseif (is_file($vendorDir.'/composer/installed.php')) {
$installed[] = self::$installedByVendor[$vendorDir] = require $vendorDir.'/composer/installed.php';
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require $vendorDir.'/composer/installed.php';
$installed[] = self::$installedByVendor[$vendorDir] = $required;
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
self::$installed = $installed[count($installed) - 1];
}
@ -340,12 +342,17 @@ class InstalledVersions
// only require the installed.php file if this file is loaded from its dumped location,
// and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937
if (substr(__DIR__, -8, 1) !== 'C') {
self::$installed = require __DIR__ . '/installed.php';
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
$required = require __DIR__ . '/installed.php';
self::$installed = $required;
} else {
self::$installed = array();
}
}
if (self::$installed !== array()) {
$installed[] = self::$installed;
}
return $installed;
}

View File

@ -14,7 +14,6 @@ return array(
'8825ede83f2f289127722d4e842cf7e8' => $vendorDir . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => $vendorDir . '/symfony/string/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => $vendorDir . '/symfony/var-dumper/Resources/functions/dump.php',
'25072dd6e2470089de65ae7bf11d3109' => $vendorDir . '/symfony/polyfill-php72/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => $vendorDir . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'5255c38a0faeba867671b61dfda6d864' => $vendorDir . '/paragonie/random_compat/lib/random.php',
'801c31d8ed748cfa537fa45402288c95' => $vendorDir . '/psy/psysh/src/functions.php',

View File

@ -17,7 +17,6 @@ return array(
'common\\tests\\' => array($baseDir . '/common/tests', $baseDir . '/common/tests/_support'),
'cebe\\markdown\\' => array($vendorDir . '/cebe/markdown'),
'backend\\tests\\' => array($baseDir . '/backend/tests', $baseDir . '/backend/tests/_support'),
'Symfony\\Polyfill\\Php72\\' => array($vendorDir . '/symfony/polyfill-php72'),
'Symfony\\Polyfill\\Mbstring\\' => array($vendorDir . '/symfony/polyfill-mbstring'),
'Symfony\\Polyfill\\Intl\\Normalizer\\' => array($vendorDir . '/symfony/polyfill-intl-normalizer'),
'Symfony\\Polyfill\\Intl\\Idn\\' => array($vendorDir . '/symfony/polyfill-intl-idn'),
@ -50,5 +49,5 @@ return array(
'Doctrine\\Common\\Lexer\\' => array($vendorDir . '/doctrine/lexer/src'),
'DeepCopy\\' => array($vendorDir . '/myclabs/deep-copy/src/DeepCopy'),
'Codeception\\Extension\\' => array($vendorDir . '/codeception/codeception/ext'),
'Codeception\\' => array($vendorDir . '/codeception/codeception/src/Codeception', $vendorDir . '/codeception/stub/src', $vendorDir . '/codeception/verify/src/Codeception'),
'Codeception\\' => array($vendorDir . '/codeception/stub/src', $vendorDir . '/codeception/verify/src/Codeception', $vendorDir . '/codeception/codeception/src/Codeception'),
);

View File

@ -33,25 +33,18 @@ class ComposerAutoloaderInitcf8142ffb616573c604f92b052bd5895
$loader->register(true);
$includeFiles = \Composer\Autoload\ComposerStaticInitcf8142ffb616573c604f92b052bd5895::$files;
foreach ($includeFiles as $fileIdentifier => $file) {
composerRequirecf8142ffb616573c604f92b052bd5895($fileIdentifier, $file);
}
return $loader;
}
}
/**
* @param string $fileIdentifier
* @param string $file
* @return void
*/
function composerRequirecf8142ffb616573c604f92b052bd5895($fileIdentifier, $file)
{
$filesToLoad = \Composer\Autoload\ComposerStaticInitcf8142ffb616573c604f92b052bd5895::$files;
$requireFile = \Closure::bind(static function ($fileIdentifier, $file) {
if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {
$GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;
require $file;
}
}, null, null);
foreach ($filesToLoad as $fileIdentifier => $file) {
$requireFile($fileIdentifier, $file);
}
return $loader;
}
}

View File

@ -15,7 +15,6 @@ class ComposerStaticInitcf8142ffb616573c604f92b052bd5895
'8825ede83f2f289127722d4e842cf7e8' => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme/bootstrap.php',
'b6b991a57620e2fb6b2f66f03fe9ddc2' => __DIR__ . '/..' . '/symfony/string/Resources/functions.php',
'667aeda72477189d0494fecd327c3641' => __DIR__ . '/..' . '/symfony/var-dumper/Resources/functions/dump.php',
'25072dd6e2470089de65ae7bf11d3109' => __DIR__ . '/..' . '/symfony/polyfill-php72/bootstrap.php',
'2cffec82183ee1cea088009cef9a6fc3' => __DIR__ . '/..' . '/ezyang/htmlpurifier/library/HTMLPurifier.composer.php',
'5255c38a0faeba867671b61dfda6d864' => __DIR__ . '/..' . '/paragonie/random_compat/lib/random.php',
'801c31d8ed748cfa537fa45402288c95' => __DIR__ . '/..' . '/psy/psysh/src/functions.php',
@ -52,7 +51,6 @@ class ComposerStaticInitcf8142ffb616573c604f92b052bd5895
),
'S' =>
array (
'Symfony\\Polyfill\\Php72\\' => 23,
'Symfony\\Polyfill\\Mbstring\\' => 26,
'Symfony\\Polyfill\\Intl\\Normalizer\\' => 33,
'Symfony\\Polyfill\\Intl\\Idn\\' => 26,
@ -155,10 +153,6 @@ class ComposerStaticInitcf8142ffb616573c604f92b052bd5895
0 => __DIR__ . '/../..' . '/backend/tests',
1 => __DIR__ . '/../..' . '/backend/tests/_support',
),
'Symfony\\Polyfill\\Php72\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-php72',
),
'Symfony\\Polyfill\\Mbstring\\' =>
array (
0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring',
@ -290,9 +284,9 @@ class ComposerStaticInitcf8142ffb616573c604f92b052bd5895
),
'Codeception\\' =>
array (
0 => __DIR__ . '/..' . '/codeception/codeception/src/Codeception',
1 => __DIR__ . '/..' . '/codeception/stub/src',
2 => __DIR__ . '/..' . '/codeception/verify/src/Codeception',
0 => __DIR__ . '/..' . '/codeception/stub/src',
1 => __DIR__ . '/..' . '/codeception/verify/src/Codeception',
2 => __DIR__ . '/..' . '/codeception/codeception/src/Codeception',
),
);

View File

@ -7,12 +7,12 @@
"source": {
"type": "git",
"url": "https://github.com/Behat/Gherkin.git",
"reference": "01379b1f9bc67a9040a472d069f1ee34cbe1b1b3"
"reference": "3ce7eec6f4bfad9f9f80e6b116f25aed2e66cf06"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/01379b1f9bc67a9040a472d069f1ee34cbe1b1b3",
"reference": "01379b1f9bc67a9040a472d069f1ee34cbe1b1b3",
"url": "https://api.github.com/repos/Behat/Gherkin/zipball/3ce7eec6f4bfad9f9f80e6b116f25aed2e66cf06",
"reference": "3ce7eec6f4bfad9f9f80e6b116f25aed2e66cf06",
"shasum": "",
"mirrors": [
{
@ -25,14 +25,14 @@
"php": "~7.2|~8.0"
},
"require-dev": {
"cucumber/cucumber": "dev-gherkin-24.0.0",
"cucumber/cucumber": "dev-gherkin-24.1.0",
"phpunit/phpunit": "~8|~9",
"symfony/yaml": "~3|~4|~5"
"symfony/yaml": "~3|~4|~5|~6|~7"
},
"suggest": {
"symfony/yaml": "If you want to parse features, represented in YAML files"
},
"time": "2022-07-07T14:25:02+00:00",
"time": "2024-10-19T14:47:56+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -254,17 +254,17 @@
},
{
"name": "codeception/codeception",
"version": "5.1.x-dev",
"version_normalized": "5.1.9999999.9999999-dev",
"version": "5.1.2",
"version_normalized": "5.1.2.0",
"source": {
"type": "git",
"url": "https://github.com/Codeception/Codeception.git",
"reference": "0297b0b030b05a3163bbb80153e0d5e0a234bae0"
"reference": "3b2d7d1a88e7e1d9dc0acb6d3c8f0acda0a37374"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/0297b0b030b05a3163bbb80153e0d5e0a234bae0",
"reference": "0297b0b030b05a3163bbb80153e0d5e0a234bae0",
"url": "https://api.github.com/repos/Codeception/Codeception/zipball/3b2d7d1a88e7e1d9dc0acb6d3c8f0acda0a37374",
"reference": "3b2d7d1a88e7e1d9dc0acb6d3c8f0acda0a37374",
"shasum": "",
"mirrors": [
{
@ -327,8 +327,7 @@
"symfony/phpunit-bridge": "For phpunit-bridge support",
"vlucas/phpdotenv": "For loading params from .env files"
},
"time": "2024-05-16T16:56:36+00:00",
"default-branch": true,
"time": "2024-03-07T07:19:42+00:00",
"bin": [
"codecept"
],
@ -368,7 +367,7 @@
],
"support": {
"issues": "https://github.com/Codeception/Codeception/issues",
"source": "https://github.com/Codeception/Codeception/tree/5.1"
"source": "https://github.com/Codeception/Codeception/tree/5.1.2"
},
"funding": [
{
@ -1514,17 +1513,17 @@
},
{
"name": "nikic/php-parser",
"version": "v5.1.0",
"version_normalized": "5.1.0.0",
"version": "v5.3.0",
"version_normalized": "5.3.0.0",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1"
"reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"reference": "683130c2ff8c2739f4822ff7ac5c873ec529abd1",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/3abf7425cd284141dc5d8d14a9ee444de3345d1a",
"reference": "3abf7425cd284141dc5d8d14a9ee444de3345d1a",
"shasum": "",
"mirrors": [
{
@ -1543,7 +1542,7 @@
"ircmaxell/php-yacc": "^0.0.7",
"phpunit/phpunit": "^9.0"
},
"time": "2024-07-01T20:03:41+00:00",
"time": "2024-09-29T13:56:26+00:00",
"bin": [
"bin/php-parse"
],
@ -1575,7 +1574,7 @@
],
"support": {
"issues": "https://github.com/nikic/PHP-Parser/issues",
"source": "https://github.com/nikic/PHP-Parser/tree/v5.1.0"
"source": "https://github.com/nikic/PHP-Parser/tree/v5.3.0"
},
"install-path": "../nikic/php-parser"
},
@ -1586,12 +1585,12 @@
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
"reference": "64f3265002e9e181436942aac2fbd482e186dc55"
"reference": "bf95de2af7feb426f91eee6c66d6ad8661c38e29"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/64f3265002e9e181436942aac2fbd482e186dc55",
"reference": "64f3265002e9e181436942aac2fbd482e186dc55",
"url": "https://api.github.com/repos/paragonie/random_compat/zipball/bf95de2af7feb426f91eee6c66d6ad8661c38e29",
"reference": "bf95de2af7feb426f91eee6c66d6ad8661c38e29",
"shasum": "",
"mirrors": [
{
@ -1609,7 +1608,7 @@
"suggest": {
"ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
},
"time": "2022-06-19T18:08:39+00:00",
"time": "2024-09-10T09:24:43+00:00",
"default-branch": true,
"type": "library",
"installation-source": "dist",
@ -1831,12 +1830,12 @@
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-code-coverage.git",
"reference": "cfa5f0972763e046de8750b40947df259bf1ad5c"
"reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/cfa5f0972763e046de8750b40947df259bf1ad5c",
"reference": "cfa5f0972763e046de8750b40947df259bf1ad5c",
"url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5",
"reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5",
"shasum": "",
"mirrors": [
{
@ -1849,16 +1848,16 @@
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
"nikic/php-parser": "^4.18 || ^5.0",
"nikic/php-parser": "^4.19.1 || ^5.1.0",
"php": ">=7.3",
"phpunit/php-file-iterator": "^3.0.3",
"phpunit/php-text-template": "^2.0.2",
"sebastian/code-unit-reverse-lookup": "^2.0.2",
"sebastian/complexity": "^2.0",
"sebastian/environment": "^5.1.2",
"sebastian/lines-of-code": "^1.0.3",
"sebastian/version": "^3.0.1",
"theseer/tokenizer": "^1.2.0"
"phpunit/php-file-iterator": "^3.0.6",
"phpunit/php-text-template": "^2.0.4",
"sebastian/code-unit-reverse-lookup": "^2.0.3",
"sebastian/complexity": "^2.0.3",
"sebastian/environment": "^5.1.5",
"sebastian/lines-of-code": "^1.0.4",
"sebastian/version": "^3.0.2",
"theseer/tokenizer": "^1.2.3"
},
"require-dev": {
"phpunit/phpunit": "^9.6"
@ -1867,7 +1866,7 @@
"ext-pcov": "PHP extension that provides line coverage",
"ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage"
},
"time": "2024-07-17T05:07:06+00:00",
"time": "2024-08-22T04:23:01+00:00",
"type": "library",
"extra": {
"branch-alias": {
@ -1901,7 +1900,7 @@
"support": {
"issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
"security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2"
"source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32"
},
"funding": [
{
@ -2559,12 +2558,12 @@
"source": {
"type": "git",
"url": "https://github.com/php-fig/log.git",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001"
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001",
"reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001",
"url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
"shasum": "",
"mirrors": [
{
@ -2576,7 +2575,7 @@
"require": {
"php": ">=8.0.0"
},
"time": "2021-07-14T16:46:02+00:00",
"time": "2024-09-11T13:17:53+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -2608,7 +2607,7 @@
"psr-3"
],
"support": {
"source": "https://github.com/php-fig/log/tree/3.0.0"
"source": "https://github.com/php-fig/log/tree/3.0.2"
},
"install-path": "../psr/log"
},
@ -2619,12 +2618,12 @@
"source": {
"type": "git",
"url": "https://github.com/bobthecow/psysh.git",
"reference": "4fd21e6417e86047a0699f764262371484d4faae"
"reference": "5c196904f494bb97ad9935fe4b2cb509857bbe5a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/4fd21e6417e86047a0699f764262371484d4faae",
"reference": "4fd21e6417e86047a0699f764262371484d4faae",
"url": "https://api.github.com/repos/bobthecow/psysh/zipball/5c196904f494bb97ad9935fe4b2cb509857bbe5a",
"reference": "5c196904f494bb97ad9935fe4b2cb509857bbe5a",
"shasum": "",
"mirrors": [
{
@ -2652,7 +2651,7 @@
"ext-pdo-sqlite": "The doc command requires SQLite to work.",
"ext-posix": "If you have PCNTL, you'll want the POSIX extension as well."
},
"time": "2024-07-19T07:29:18+00:00",
"time": "2024-09-29T21:42:50+00:00",
"default-branch": true,
"bin": [
"bin/psysh"
@ -4703,12 +4702,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
"reference": "0424dff1c58f028c451efff2045f5d92410bd540"
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/0424dff1c58f028c451efff2045f5d92410bd540",
"reference": "0424dff1c58f028c451efff2045f5d92410bd540",
"url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638",
"reference": "a3cc8b044a6ea513310cbd48ef7333b384945638",
"shasum": "",
"mirrors": [
{
@ -4718,7 +4717,7 @@
]
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-ctype": "*"
@ -4726,7 +4725,7 @@
"suggest": {
"ext-ctype": "For best performance"
},
"time": "2024-05-31T15:07:36+00:00",
"time": "2024-09-09T11:45:10+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -4767,7 +4766,7 @@
"portable"
],
"support": {
"source": "https://github.com/symfony/polyfill-ctype/tree/1.x"
"source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0"
},
"funding": [
{
@ -4792,12 +4791,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
"reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a"
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/64647a7c30b2283f5d49b874d84a18fc22054b7a",
"reference": "64647a7c30b2283f5d49b874d84a18fc22054b7a",
"url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
"reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe",
"shasum": "",
"mirrors": [
{
@ -4807,12 +4806,12 @@
]
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2024-05-31T15:07:36+00:00",
"time": "2024-09-09T11:45:10+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -4855,7 +4854,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.30.0"
"source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0"
},
"funding": [
{
@ -4880,12 +4879,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-idn.git",
"reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c"
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
"reference": "a6e83bdeb3c84391d1dfe16f42e40727ce524a5c",
"url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/c36586dcf89a12315939e00ec9b4474adcb1d773",
"reference": "c36586dcf89a12315939e00ec9b4474adcb1d773",
"shasum": "",
"mirrors": [
{
@ -4895,14 +4894,13 @@
]
},
"require": {
"php": ">=7.1",
"symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php72": "^1.10"
"php": ">=7.2",
"symfony/polyfill-intl-normalizer": "^1.10"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2024-05-31T15:07:36+00:00",
"time": "2024-09-09T11:45:10+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -4949,7 +4947,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.30.0"
"source": "https://github.com/symfony/polyfill-intl-idn/tree/v1.31.0"
},
"funding": [
{
@ -4974,12 +4972,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb"
"reference": "3833d7255cc303546435cb650316bff708a1c75c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/a95281b0be0d9ab48050ebd988b967875cdb9fdb",
"reference": "a95281b0be0d9ab48050ebd988b967875cdb9fdb",
"url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c",
"reference": "3833d7255cc303546435cb650316bff708a1c75c",
"shasum": "",
"mirrors": [
{
@ -4989,12 +4987,12 @@
]
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"suggest": {
"ext-intl": "For best performance"
},
"time": "2024-05-31T15:07:36+00:00",
"time": "2024-09-09T11:45:10+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -5040,7 +5038,7 @@
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.30.0"
"source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0"
},
"funding": [
{
@ -5065,12 +5063,12 @@
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
"reference": "8740a072b86292957feb42703edde77fcfca84fb"
"reference": "2369cb908b33d7b7518cce042615de430142497f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8740a072b86292957feb42703edde77fcfca84fb",
"reference": "8740a072b86292957feb42703edde77fcfca84fb",
"url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2369cb908b33d7b7518cce042615de430142497f",
"reference": "2369cb908b33d7b7518cce042615de430142497f",
"shasum": "",
"mirrors": [
{
@ -5080,7 +5078,7 @@
]
},
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"
@ -5088,7 +5086,7 @@
"suggest": {
"ext-mbstring": "For best performance"
},
"time": "2024-06-20T08:18:00+00:00",
"time": "2024-09-10T14:38:51+00:00",
"default-branch": true,
"type": "library",
"extra": {
@ -5148,89 +5146,6 @@
],
"install-path": "../symfony/polyfill-mbstring"
},
{
"name": "symfony/polyfill-php72",
"version": "1.x-dev",
"version_normalized": "1.9999999.9999999.9999999-dev",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
"reference": "10112722600777e02d2745716b70c5db4ca70442"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/10112722600777e02d2745716b70c5db4ca70442",
"reference": "10112722600777e02d2745716b70c5db4ca70442",
"shasum": "",
"mirrors": [
{
"url": "https://mirrors.aliyun.com/composer/dists/%package%/%reference%.%type%",
"preferred": true
}
]
},
"require": {
"php": ">=7.1"
},
"time": "2024-06-19T12:30:46+00:00",
"default-branch": true,
"type": "library",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
"installation-source": "dist",
"autoload": {
"files": [
"bootstrap.php"
],
"psr-4": {
"Symfony\\Polyfill\\Php72\\": ""
}
},
"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": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"homepage": "https://symfony.com",
"keywords": [
"compatibility",
"polyfill",
"portable",
"shim"
],
"support": {
"source": "https://github.com/symfony/polyfill-php72/tree/v1.30.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/polyfill-php72"
},
{
"name": "symfony/service-contracts",
"version": "3.0.x-dev",

View File

@ -1,143 +1,143 @@
<?php return array(
'root' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'name' => 'yiisoft/yii2-app-advanced',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '15f92bfe43d92c2e068ab846da7c76b482c205cc',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => NULL,
'name' => 'yiisoft/yii2-app-advanced',
'dev' => true,
),
'versions' => array(
'behat/gherkin' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '3ce7eec6f4bfad9f9f80e6b116f25aed2e66cf06',
'type' => 'library',
'install_path' => __DIR__ . '/../behat/gherkin',
'aliases' => array(
0 => '4.x-dev',
),
'reference' => '01379b1f9bc67a9040a472d069f1ee34cbe1b1b3',
'dev_requirement' => true,
),
'bower-asset/bootstrap' => array(
'pretty_version' => 'v5.3.3',
'version' => '5.3.3.0',
'reference' => '6e1f75f420f68e1d52733b8e407fc7c3766c9dba',
'type' => 'bower-asset',
'install_path' => __DIR__ . '/../bower-asset/bootstrap',
'aliases' => array(),
'reference' => '6e1f75f420f68e1d52733b8e407fc7c3766c9dba',
'dev_requirement' => false,
),
'bower-asset/inputmask' => array(
'pretty_version' => '3.3.11',
'version' => '3.3.11.0',
'reference' => '5e670ad62f50c738388d4dcec78d2888505ad77b',
'type' => 'bower-asset',
'install_path' => __DIR__ . '/../bower-asset/inputmask',
'aliases' => array(),
'reference' => '5e670ad62f50c738388d4dcec78d2888505ad77b',
'dev_requirement' => false,
),
'bower-asset/jquery' => array(
'pretty_version' => '3.7.1',
'version' => '3.7.1.0',
'reference' => 'fde1f76e2799dd877c176abde0ec836553246991',
'type' => 'bower-asset',
'install_path' => __DIR__ . '/../bower-asset/jquery',
'aliases' => array(),
'reference' => 'fde1f76e2799dd877c176abde0ec836553246991',
'dev_requirement' => false,
),
'bower-asset/punycode' => array(
'pretty_version' => 'v1.3.2',
'version' => '1.3.2.0',
'reference' => '38c8d3131a82567bfef18da09f7f4db68c84f8a3',
'type' => 'bower-asset',
'install_path' => __DIR__ . '/../bower-asset/punycode',
'aliases' => array(),
'reference' => '38c8d3131a82567bfef18da09f7f4db68c84f8a3',
'dev_requirement' => false,
),
'bower-asset/yii2-pjax' => array(
'pretty_version' => '2.0.8',
'version' => '2.0.8.0',
'reference' => 'a9298d57da63d14a950f1b94366a864bc62264fb',
'type' => 'bower-asset',
'install_path' => __DIR__ . '/../bower-asset/yii2-pjax',
'aliases' => array(),
'reference' => 'a9298d57da63d14a950f1b94366a864bc62264fb',
'dev_requirement' => false,
),
'cebe/markdown' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2b2461bed9e15305486319ee552bafca75d1cdaa',
'type' => 'library',
'install_path' => __DIR__ . '/../cebe/markdown',
'aliases' => array(
0 => '1.2.x-dev',
),
'reference' => '2b2461bed9e15305486319ee552bafca75d1cdaa',
'dev_requirement' => false,
),
'codeception/codeception' => array(
'pretty_version' => '5.1.x-dev',
'version' => '5.1.9999999.9999999-dev',
'pretty_version' => '5.1.2',
'version' => '5.1.2.0',
'reference' => '3b2d7d1a88e7e1d9dc0acb6d3c8f0acda0a37374',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/codeception',
'aliases' => array(),
'reference' => '0297b0b030b05a3163bbb80153e0d5e0a234bae0',
'dev_requirement' => true,
),
'codeception/lib-asserts' => array(
'pretty_version' => '2.1.0',
'version' => '2.1.0.0',
'reference' => 'b8c7dff552249e560879c682ba44a4b963af91bc',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/lib-asserts',
'aliases' => array(),
'reference' => 'b8c7dff552249e560879c682ba44a4b963af91bc',
'dev_requirement' => true,
),
'codeception/lib-innerbrowser' => array(
'pretty_version' => '3.x-dev',
'version' => '3.9999999.9999999.9999999-dev',
'reference' => '10482f7e34c0537bf5b87bc82a3d65a1842a8b4f',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/lib-innerbrowser',
'aliases' => array(),
'reference' => '10482f7e34c0537bf5b87bc82a3d65a1842a8b4f',
'dev_requirement' => true,
),
'codeception/lib-web' => array(
'pretty_version' => '1.0.5',
'version' => '1.0.5.0',
'reference' => 'cea9d53c9cd665498632acc417c9a96bff7eb2b0',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/lib-web',
'aliases' => array(),
'reference' => 'cea9d53c9cd665498632acc417c9a96bff7eb2b0',
'dev_requirement' => true,
),
'codeception/module-asserts' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => '1b6b150b30586c3614e7e5761b31834ed7968603',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/module-asserts',
'aliases' => array(),
'reference' => '1b6b150b30586c3614e7e5761b31834ed7968603',
'dev_requirement' => true,
),
'codeception/module-filesystem' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => '326ef1c1edf90f52ceec2965ff240a8d93c1ba63',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/module-filesystem',
'aliases' => array(),
'reference' => '326ef1c1edf90f52ceec2965ff240a8d93c1ba63',
'dev_requirement' => true,
),
'codeception/module-yii2' => array(
'pretty_version' => '1.1.10',
'version' => '1.1.10.0',
'reference' => '2971f1fb44cd3088f7ecbe78bc51161c037a6551',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/module-yii2',
'aliases' => array(),
'reference' => '2971f1fb44cd3088f7ecbe78bc51161c037a6551',
'dev_requirement' => true,
),
'codeception/phpunit-wrapper' => array(
@ -149,216 +149,216 @@
'codeception/stub' => array(
'pretty_version' => '4.1.3',
'version' => '4.1.3.0',
'reference' => '4fcad2c165f365377486dc3fd8703b07f1f2fcae',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/stub',
'aliases' => array(),
'reference' => '4fcad2c165f365377486dc3fd8703b07f1f2fcae',
'dev_requirement' => true,
),
'codeception/verify' => array(
'pretty_version' => '3.0.0',
'version' => '3.0.0.0',
'reference' => '25b84a96f0fe7dcf28e8021f02b57643b751a707',
'type' => 'library',
'install_path' => __DIR__ . '/../codeception/verify',
'aliases' => array(),
'reference' => '25b84a96f0fe7dcf28e8021f02b57643b751a707',
'dev_requirement' => true,
),
'doctrine/deprecations' => array(
'pretty_version' => '1.1.x-dev',
'version' => '1.1.9999999.9999999-dev',
'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/deprecations',
'aliases' => array(),
'reference' => 'dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab',
'dev_requirement' => false,
),
'doctrine/instantiator' => array(
'pretty_version' => '1.5.x-dev',
'version' => '1.5.9999999.9999999-dev',
'reference' => '12be2483e1f0e850b353e26869e4e6c038459501',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/instantiator',
'aliases' => array(),
'reference' => '12be2483e1f0e850b353e26869e4e6c038459501',
'dev_requirement' => true,
),
'doctrine/lexer' => array(
'pretty_version' => '2.1.x-dev',
'version' => '2.1.9999999.9999999-dev',
'reference' => '861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6',
'type' => 'library',
'install_path' => __DIR__ . '/../doctrine/lexer',
'aliases' => array(),
'reference' => '861c870e8b75f7c8f69c146c7f89cc1c0f1b49b6',
'dev_requirement' => false,
),
'egulias/email-validator' => array(
'pretty_version' => '3.x-dev',
'version' => '3.9999999.9999999.9999999-dev',
'reference' => 'e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7',
'type' => 'library',
'install_path' => __DIR__ . '/../egulias/email-validator',
'aliases' => array(),
'reference' => 'e5997fa97e8790cdae03a9cbd5e78e45e3c7bda7',
'dev_requirement' => false,
),
'ezyang/htmlpurifier' => array(
'pretty_version' => 'v4.16.0',
'version' => '4.16.0.0',
'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8',
'type' => 'library',
'install_path' => __DIR__ . '/../ezyang/htmlpurifier',
'aliases' => array(),
'reference' => '523407fb06eb9e5f3d59889b3978d5bfe94299c8',
'dev_requirement' => false,
),
'fakerphp/faker' => array(
'pretty_version' => '1.23.x-dev',
'version' => '1.23.9999999.9999999-dev',
'reference' => '4dae775c9fbd5d734f5307b73e29d34adf289e50',
'type' => 'library',
'install_path' => __DIR__ . '/../fakerphp/faker',
'aliases' => array(),
'reference' => '4dae775c9fbd5d734f5307b73e29d34adf289e50',
'dev_requirement' => true,
),
'guzzlehttp/psr7' => array(
'pretty_version' => '2.7.x-dev',
'version' => '2.7.9999999.9999999-dev',
'reference' => 'a70f5c95fb43bc83f07c9c948baa0dc1829bf201',
'type' => 'library',
'install_path' => __DIR__ . '/../guzzlehttp/psr7',
'aliases' => array(),
'reference' => 'a70f5c95fb43bc83f07c9c948baa0dc1829bf201',
'dev_requirement' => true,
),
'myclabs/deep-copy' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => '2f5294676c802a62b0549f6bc8983f14294ce369',
'type' => 'library',
'install_path' => __DIR__ . '/../myclabs/deep-copy',
'aliases' => array(),
'reference' => '2f5294676c802a62b0549f6bc8983f14294ce369',
'dev_requirement' => true,
),
'nikic/php-parser' => array(
'pretty_version' => 'v5.1.0',
'version' => '5.1.0.0',
'pretty_version' => 'v5.3.0',
'version' => '5.3.0.0',
'reference' => '3abf7425cd284141dc5d8d14a9ee444de3345d1a',
'type' => 'library',
'install_path' => __DIR__ . '/../nikic/php-parser',
'aliases' => array(),
'reference' => '683130c2ff8c2739f4822ff7ac5c873ec529abd1',
'dev_requirement' => true,
),
'paragonie/random_compat' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'bf95de2af7feb426f91eee6c66d6ad8661c38e29',
'type' => 'library',
'install_path' => __DIR__ . '/../paragonie/random_compat',
'aliases' => array(
0 => '9999999-dev',
),
'reference' => '64f3265002e9e181436942aac2fbd482e186dc55',
'dev_requirement' => false,
),
'phar-io/manifest' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '54750ef60c58e43759730615a392c31c80e23176',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/manifest',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => '54750ef60c58e43759730615a392c31c80e23176',
'dev_requirement' => true,
),
'phar-io/version' => array(
'pretty_version' => '3.2.1',
'version' => '3.2.1.0',
'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74',
'type' => 'library',
'install_path' => __DIR__ . '/../phar-io/version',
'aliases' => array(),
'reference' => '4f7fd7836c6f332bb2933569e566a0d6c4cbed74',
'dev_requirement' => true,
),
'phpspec/php-diff' => array(
'pretty_version' => 'v1.1.3',
'version' => '1.1.3.0',
'reference' => 'fc1156187f9f6c8395886fe85ed88a0a245d72e9',
'type' => 'library',
'install_path' => __DIR__ . '/../phpspec/php-diff',
'aliases' => array(),
'reference' => 'fc1156187f9f6c8395886fe85ed88a0a245d72e9',
'dev_requirement' => true,
),
'phpunit/php-code-coverage' => array(
'pretty_version' => '9.2.x-dev',
'version' => '9.2.9999999.9999999-dev',
'reference' => '85402a822d1ecf1db1096959413d35e1c37cf1a5',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-code-coverage',
'aliases' => array(),
'reference' => 'cfa5f0972763e046de8750b40947df259bf1ad5c',
'dev_requirement' => true,
),
'phpunit/php-file-iterator' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => '38b24367e1b340aa78b96d7cab042942d917bb84',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-file-iterator',
'aliases' => array(),
'reference' => '38b24367e1b340aa78b96d7cab042942d917bb84',
'dev_requirement' => true,
),
'phpunit/php-invoker' => array(
'pretty_version' => '3.1.1',
'version' => '3.1.1.0',
'reference' => '5a10147d0aaf65b58940a0b72f71c9ac0423cc67',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-invoker',
'aliases' => array(),
'reference' => '5a10147d0aaf65b58940a0b72f71c9ac0423cc67',
'dev_requirement' => true,
),
'phpunit/php-text-template' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => '5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-text-template',
'aliases' => array(),
'reference' => '5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28',
'dev_requirement' => true,
),
'phpunit/php-timer' => array(
'pretty_version' => '5.0.3',
'version' => '5.0.3.0',
'reference' => '5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/php-timer',
'aliases' => array(),
'reference' => '5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2',
'dev_requirement' => true,
),
'phpunit/phpunit' => array(
'pretty_version' => '9.5.28',
'version' => '9.5.28.0',
'reference' => '954ca3113a03bf780d22f07bf055d883ee04b65e',
'type' => 'library',
'install_path' => __DIR__ . '/../phpunit/phpunit',
'aliases' => array(),
'reference' => '954ca3113a03bf780d22f07bf055d883ee04b65e',
'dev_requirement' => true,
),
'psr/container' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '707984727bd5b2b670e59559d3ed2500240cf875',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/container',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => '707984727bd5b2b670e59559d3ed2500240cf875',
'dev_requirement' => false,
),
'psr/event-dispatcher' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '977ffcf551e3bfb73d90aac3e8e1583fd8d2f89a',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/event-dispatcher',
'aliases' => array(
0 => '1.0.x-dev',
),
'reference' => '977ffcf551e3bfb73d90aac3e8e1583fd8d2f89a',
'dev_requirement' => false,
),
'psr/event-dispatcher-implementation' => array(
@ -370,12 +370,12 @@
'psr/http-factory' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '7037f4b0950474e9d1350e8df89b15f1842085f6',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-factory',
'aliases' => array(
0 => '1.0.x-dev',
),
'reference' => '7037f4b0950474e9d1350e8df89b15f1842085f6',
'dev_requirement' => true,
),
'psr/http-factory-implementation' => array(
@ -387,12 +387,12 @@
'psr/http-message' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/http-message',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => '402d35bcb92c70c026d1a6a9883f06b2ead23d71',
'dev_requirement' => true,
),
'psr/http-message-implementation' => array(
@ -404,12 +404,12 @@
'psr/log' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'f16e1d5863e37f8d8c2a01719f5b34baa2b714d3',
'type' => 'library',
'install_path' => __DIR__ . '/../psr/log',
'aliases' => array(
0 => '3.x-dev',
),
'reference' => 'fe5ea303b0887d5caefd3d431c3e61ad47037001',
'dev_requirement' => false,
),
'psr/log-implementation' => array(
@ -421,230 +421,230 @@
'psy/psysh' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => '5c196904f494bb97ad9935fe4b2cb509857bbe5a',
'type' => 'library',
'install_path' => __DIR__ . '/../psy/psysh',
'aliases' => array(
0 => '0.12.x-dev',
),
'reference' => '4fd21e6417e86047a0699f764262371484d4faae',
'dev_requirement' => true,
),
'ralouphie/getallheaders' => array(
'pretty_version' => '3.0.3',
'version' => '3.0.3.0',
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'type' => 'library',
'install_path' => __DIR__ . '/../ralouphie/getallheaders',
'aliases' => array(),
'reference' => '120b605dfeb996808c31b6477290a714d356e822',
'dev_requirement' => true,
),
'sebastian/cli-parser' => array(
'pretty_version' => '1.0.x-dev',
'version' => '1.0.9999999.9999999-dev',
'reference' => '2b56bea83a09de3ac06bb18b92f068e60cc6f50b',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/cli-parser',
'aliases' => array(),
'reference' => '2b56bea83a09de3ac06bb18b92f068e60cc6f50b',
'dev_requirement' => true,
),
'sebastian/code-unit' => array(
'pretty_version' => '1.0.8',
'version' => '1.0.8.0',
'reference' => '1fc9f64c0927627ef78ba436c9b17d967e68e120',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/code-unit',
'aliases' => array(),
'reference' => '1fc9f64c0927627ef78ba436c9b17d967e68e120',
'dev_requirement' => true,
),
'sebastian/code-unit-reverse-lookup' => array(
'pretty_version' => '2.0.3',
'version' => '2.0.3.0',
'reference' => 'ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/code-unit-reverse-lookup',
'aliases' => array(),
'reference' => 'ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5',
'dev_requirement' => true,
),
'sebastian/comparator' => array(
'pretty_version' => '4.0.x-dev',
'version' => '4.0.9999999.9999999-dev',
'reference' => 'b247957a1c8dc81a671770f74b479c0a78a818f1',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/comparator',
'aliases' => array(),
'reference' => 'b247957a1c8dc81a671770f74b479c0a78a818f1',
'dev_requirement' => true,
),
'sebastian/complexity' => array(
'pretty_version' => '2.0.x-dev',
'version' => '2.0.9999999.9999999-dev',
'reference' => '25f207c40d62b8b7aa32f5ab026c53561964053a',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/complexity',
'aliases' => array(),
'reference' => '25f207c40d62b8b7aa32f5ab026c53561964053a',
'dev_requirement' => true,
),
'sebastian/diff' => array(
'pretty_version' => '4.0.x-dev',
'version' => '4.0.9999999.9999999-dev',
'reference' => 'ba01945089c3a293b01ba9badc29ad55b106b0bc',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/diff',
'aliases' => array(),
'reference' => 'ba01945089c3a293b01ba9badc29ad55b106b0bc',
'dev_requirement' => true,
),
'sebastian/environment' => array(
'pretty_version' => '5.1.x-dev',
'version' => '5.1.9999999.9999999-dev',
'reference' => '830c43a844f1f8d5b7a1f6d6076b784454d8b7ed',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/environment',
'aliases' => array(),
'reference' => '830c43a844f1f8d5b7a1f6d6076b784454d8b7ed',
'dev_requirement' => true,
),
'sebastian/exporter' => array(
'pretty_version' => '4.0.x-dev',
'version' => '4.0.9999999.9999999-dev',
'reference' => '78c00df8f170e02473b682df15bfcdacc3d32d72',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/exporter',
'aliases' => array(),
'reference' => '78c00df8f170e02473b682df15bfcdacc3d32d72',
'dev_requirement' => true,
),
'sebastian/global-state' => array(
'pretty_version' => '5.0.x-dev',
'version' => '5.0.9999999.9999999-dev',
'reference' => 'bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/global-state',
'aliases' => array(),
'reference' => 'bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9',
'dev_requirement' => true,
),
'sebastian/lines-of-code' => array(
'pretty_version' => '1.0.x-dev',
'version' => '1.0.9999999.9999999-dev',
'reference' => 'e1e4a170560925c26d424b6a03aed157e7dcc5c5',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/lines-of-code',
'aliases' => array(),
'reference' => 'e1e4a170560925c26d424b6a03aed157e7dcc5c5',
'dev_requirement' => true,
),
'sebastian/object-enumerator' => array(
'pretty_version' => '4.0.4',
'version' => '4.0.4.0',
'reference' => '5c9eeac41b290a3712d88851518825ad78f45c71',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-enumerator',
'aliases' => array(),
'reference' => '5c9eeac41b290a3712d88851518825ad78f45c71',
'dev_requirement' => true,
),
'sebastian/object-reflector' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => 'b4f479ebdbf63ac605d183ece17d8d7fe49c15c7',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/object-reflector',
'aliases' => array(),
'reference' => 'b4f479ebdbf63ac605d183ece17d8d7fe49c15c7',
'dev_requirement' => true,
),
'sebastian/recursion-context' => array(
'pretty_version' => '4.0.x-dev',
'version' => '4.0.9999999.9999999-dev',
'reference' => 'e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/recursion-context',
'aliases' => array(),
'reference' => 'e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1',
'dev_requirement' => true,
),
'sebastian/resource-operations' => array(
'pretty_version' => 'dev-main',
'version' => 'dev-main',
'reference' => 'ff553e7482dcee39fa4acc2b175d6ddeb0f7bc25',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/resource-operations',
'aliases' => array(
0 => '3.0.x-dev',
),
'reference' => 'ff553e7482dcee39fa4acc2b175d6ddeb0f7bc25',
'dev_requirement' => true,
),
'sebastian/type' => array(
'pretty_version' => '3.2.x-dev',
'version' => '3.2.9999999.9999999-dev',
'reference' => '75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/type',
'aliases' => array(),
'reference' => '75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7',
'dev_requirement' => true,
),
'sebastian/version' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => 'c6c1022351a901512170118436c764e473f6de8c',
'type' => 'library',
'install_path' => __DIR__ . '/../sebastian/version',
'aliases' => array(),
'reference' => 'c6c1022351a901512170118436c764e473f6de8c',
'dev_requirement' => true,
),
'symfony/browser-kit' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => '4d1bf7886e2af0a194332486273debcd6662cfc9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/browser-kit',
'aliases' => array(),
'reference' => '4d1bf7886e2af0a194332486273debcd6662cfc9',
'dev_requirement' => true,
),
'symfony/console' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'c3ebc83d031b71c39da318ca8b7a07ecc67507ed',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/console',
'aliases' => array(),
'reference' => 'c3ebc83d031b71c39da318ca8b7a07ecc67507ed',
'dev_requirement' => true,
),
'symfony/css-selector' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'f1d00bddb83a4cb2138564b2150001cb6ce272b1',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/css-selector',
'aliases' => array(),
'reference' => 'f1d00bddb83a4cb2138564b2150001cb6ce272b1',
'dev_requirement' => true,
),
'symfony/deprecation-contracts' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => 'c30dd04b9a303689a26d7986f7cffce04203a107',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/deprecation-contracts',
'aliases' => array(),
'reference' => 'c30dd04b9a303689a26d7986f7cffce04203a107',
'dev_requirement' => true,
),
'symfony/dom-crawler' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => '622578ff158318b1b49d95068bd6b66c713601e9',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/dom-crawler',
'aliases' => array(),
'reference' => '622578ff158318b1b49d95068bd6b66c713601e9',
'dev_requirement' => true,
),
'symfony/event-dispatcher' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => '2eaf8e63bc5b8cefabd4a800157f0d0c094f677a',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher',
'aliases' => array(),
'reference' => '2eaf8e63bc5b8cefabd4a800157f0d0c094f677a',
'dev_requirement' => false,
),
'symfony/event-dispatcher-contracts' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => 'dea993e5425eb355355e2c5f28685559535dda6c',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/event-dispatcher-contracts',
'aliases' => array(),
'reference' => 'dea993e5425eb355355e2c5f28685559535dda6c',
'dev_requirement' => false,
),
'symfony/event-dispatcher-implementation' => array(
@ -656,205 +656,196 @@
'symfony/finder' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => '5cc9cac6586fc0c28cd173780ca696e419fefa11',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/finder',
'aliases' => array(),
'reference' => '5cc9cac6586fc0c28cd173780ca696e419fefa11',
'dev_requirement' => true,
),
'symfony/mailer' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'cd60799210c488f545ddde2444dc1aa548322872',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mailer',
'aliases' => array(),
'reference' => 'cd60799210c488f545ddde2444dc1aa548322872',
'dev_requirement' => false,
),
'symfony/mime' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'd7052547a0070cbeadd474e172b527a00d657301',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/mime',
'aliases' => array(),
'reference' => 'd7052547a0070cbeadd474e172b527a00d657301',
'dev_requirement' => false,
),
'symfony/polyfill-ctype' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-ctype',
'aliases' => array(),
'reference' => '0424dff1c58f028c451efff2045f5d92410bd540',
'dev_requirement' => true,
),
'symfony/polyfill-intl-grapheme' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => 'b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme',
'aliases' => array(),
'reference' => '64647a7c30b2283f5d49b874d84a18fc22054b7a',
'dev_requirement' => true,
),
'symfony/polyfill-intl-idn' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => 'c36586dcf89a12315939e00ec9b4474adcb1d773',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-idn',
'aliases' => array(),
'reference' => 'a6e83bdeb3c84391d1dfe16f42e40727ce524a5c',
'dev_requirement' => false,
),
'symfony/polyfill-intl-normalizer' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => '3833d7255cc303546435cb650316bff708a1c75c',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-intl-normalizer',
'aliases' => array(),
'reference' => 'a95281b0be0d9ab48050ebd988b967875cdb9fdb',
'dev_requirement' => false,
),
'symfony/polyfill-mbstring' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'reference' => '2369cb908b33d7b7518cce042615de430142497f',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-mbstring',
'aliases' => array(),
'reference' => '8740a072b86292957feb42703edde77fcfca84fb',
'dev_requirement' => false,
),
'symfony/polyfill-php72' => array(
'pretty_version' => '1.x-dev',
'version' => '1.9999999.9999999.9999999-dev',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/polyfill-php72',
'aliases' => array(),
'reference' => '10112722600777e02d2745716b70c5db4ca70442',
'dev_requirement' => false,
),
'symfony/service-contracts' => array(
'pretty_version' => '3.0.x-dev',
'version' => '3.0.9999999.9999999-dev',
'reference' => '24ce74899f476f56d7e6c148c809afef0b7de19c',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/service-contracts',
'aliases' => array(),
'reference' => '24ce74899f476f56d7e6c148c809afef0b7de19c',
'dev_requirement' => false,
),
'symfony/string' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'd9e72497367c23e08bf94176d2be45b00a9d232a',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/string',
'aliases' => array(),
'reference' => 'd9e72497367c23e08bf94176d2be45b00a9d232a',
'dev_requirement' => true,
),
'symfony/var-dumper' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'eb980457fa6899840fe1687e8627a03a7d8a3d52',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/var-dumper',
'aliases' => array(),
'reference' => 'eb980457fa6899840fe1687e8627a03a7d8a3d52',
'dev_requirement' => true,
),
'symfony/yaml' => array(
'pretty_version' => '6.0.x-dev',
'version' => '6.0.9999999.9999999-dev',
'reference' => 'deec3a812a0305a50db8ae689b183f43d915c884',
'type' => 'library',
'install_path' => __DIR__ . '/../symfony/yaml',
'aliases' => array(),
'reference' => 'deec3a812a0305a50db8ae689b183f43d915c884',
'dev_requirement' => true,
),
'theseer/tokenizer' => array(
'pretty_version' => '1.2.3',
'version' => '1.2.3.0',
'reference' => '737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2',
'type' => 'library',
'install_path' => __DIR__ . '/../theseer/tokenizer',
'aliases' => array(),
'reference' => '737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2',
'dev_requirement' => true,
),
'yiisoft/yii2' => array(
'pretty_version' => '2.0.49.x-dev',
'version' => '2.0.49.9999999-dev',
'reference' => 'deec9b7330a09e06ab9e002c8718a8b478524dda',
'type' => 'library',
'install_path' => __DIR__ . '/../yiisoft/yii2',
'aliases' => array(),
'reference' => 'deec9b7330a09e06ab9e002c8718a8b478524dda',
'dev_requirement' => false,
),
'yiisoft/yii2-app-advanced' => array(
'pretty_version' => '1.0.0+no-version-set',
'version' => '1.0.0.0',
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '15f92bfe43d92c2e068ab846da7c76b482c205cc',
'type' => 'project',
'install_path' => __DIR__ . '/../../',
'aliases' => array(),
'reference' => NULL,
'dev_requirement' => false,
),
'yiisoft/yii2-bootstrap5' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '1a4f4d66c9ef3a076dc327999f8dc8b52caa5ac0',
'type' => 'yii2-extension',
'install_path' => __DIR__ . '/../yiisoft/yii2-bootstrap5',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => '1a4f4d66c9ef3a076dc327999f8dc8b52caa5ac0',
'dev_requirement' => false,
),
'yiisoft/yii2-composer' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => '2cd6eee19e94b9e98f3516340138041683350fcf',
'type' => 'composer-plugin',
'install_path' => __DIR__ . '/../yiisoft/yii2-composer',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => '2cd6eee19e94b9e98f3516340138041683350fcf',
'dev_requirement' => false,
),
'yiisoft/yii2-debug' => array(
'pretty_version' => '2.1.25',
'version' => '2.1.25.0',
'reference' => '4d011b9bfc83bde71cde43c9f6837f5a74685ea7',
'type' => 'yii2-extension',
'install_path' => __DIR__ . '/../yiisoft/yii2-debug',
'aliases' => array(),
'reference' => '4d011b9bfc83bde71cde43c9f6837f5a74685ea7',
'dev_requirement' => true,
),
'yiisoft/yii2-faker' => array(
'pretty_version' => 'dev-master',
'version' => 'dev-master',
'reference' => 'e269bfd508588b8dbc2a70b852e4a0e37e31afea',
'type' => 'yii2-extension',
'install_path' => __DIR__ . '/../yiisoft/yii2-faker',
'aliases' => array(
0 => '2.0.x-dev',
),
'reference' => 'e269bfd508588b8dbc2a70b852e4a0e37e31afea',
'dev_requirement' => true,
),
'yiisoft/yii2-gii' => array(
'pretty_version' => '2.2.6',
'version' => '2.2.6.0',
'reference' => 'ac574e7e2c29fd865145c8688719f252d19aae23',
'type' => 'yii2-extension',
'install_path' => __DIR__ . '/../yiisoft/yii2-gii',
'aliases' => array(),
'reference' => 'ac574e7e2c29fd865145c8688719f252d19aae23',
'dev_requirement' => true,
),
'yiisoft/yii2-symfonymailer' => array(
'pretty_version' => '2.0.4',
'version' => '2.0.4.0',
'reference' => '82f5902551a160633c4734b5096977ce76a809d9',
'type' => 'yii2-extension',
'install_path' => __DIR__ . '/../yiisoft/yii2-symfonymailer',
'aliases' => array(),
'reference' => '82f5902551a160633c4734b5096977ce76a809d9',
'dev_requirement' => false,
),
),

View File

@ -6,7 +6,7 @@ PHP Parser
This is a PHP parser written in PHP. Its purpose is to simplify static code analysis and
manipulation.
[**Documentation for version 5.x**][doc_master] (current; for running on PHP >= 7.4; for parsing PHP 7.0 to PHP 8.3, with limited support for parsing PHP 5.x).
[**Documentation for version 5.x**][doc_master] (current; for running on PHP >= 7.4; for parsing PHP 7.0 to PHP 8.4, with limited support for parsing PHP 5.x).
[Documentation for version 4.x][doc_4_x] (supported; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.3).

View File

@ -28,7 +28,7 @@ class ClassConst implements PhpParser\Builder {
* Creates a class constant builder
*
* @param string|Identifier $name Name
* @param Node\Expr|bool|null|int|float|string|array $value Value
* @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
*/
public function __construct($name, $value) {
$this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))];
@ -38,7 +38,7 @@ class ClassConst implements PhpParser\Builder {
* Add another constant to const group
*
* @param string|Identifier $name Name
* @param Node\Expr|bool|null|int|float|string|array $value Value
* @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value
*
* @return $this The builder instance (for fluid interface)
*/

View File

@ -13,7 +13,6 @@ use PhpParser\Node\Stmt;
class EnumCase implements PhpParser\Builder {
/** @var Identifier|string */
protected $name;
/** @var ?Node\Expr */
protected ?Node\Expr $value = null;
/** @var array<string, mixed> */
protected array $attributes = [];

View File

@ -122,6 +122,28 @@ class Param implements PhpParser\Builder {
return $this;
}
/**
* Gives the promoted property private(set) visibility.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePrivateSet() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
return $this;
}
/**
* Gives the promoted property protected(set) visibility.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeProtectedSet() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
return $this;
}
/**
* Adds an attribute group.
*

View File

@ -23,6 +23,8 @@ class Property implements PhpParser\Builder {
protected ?Node $type = null;
/** @var list<Node\AttributeGroup> */
protected array $attributeGroups = [];
/** @var list<Node\PropertyHook> */
protected array $hooks = [];
/**
* Creates a property builder.
@ -88,6 +90,50 @@ class Property implements PhpParser\Builder {
return $this;
}
/**
* Makes the property abstract. Requires at least one property hook to be specified as well.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeAbstract() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::ABSTRACT);
return $this;
}
/**
* Makes the property final.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeFinal() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::FINAL);
return $this;
}
/**
* Gives the property private(set) visibility.
*
* @return $this The builder instance (for fluid interface)
*/
public function makePrivateSet() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PRIVATE_SET);
return $this;
}
/**
* Gives the property protected(set) visibility.
*
* @return $this The builder instance (for fluid interface)
*/
public function makeProtectedSet() {
$this->flags = BuilderHelpers::addModifier($this->flags, Modifiers::PROTECTED_SET);
return $this;
}
/**
* Sets default value for the property.
*
@ -142,12 +188,27 @@ class Property implements PhpParser\Builder {
return $this;
}
/**
* Adds a property hook.
*
* @return $this The builder instance (for fluid interface)
*/
public function addHook(Node\PropertyHook $hook) {
$this->hooks[] = $hook;
return $this;
}
/**
* Returns the built class node.
*
* @return Stmt\Property The built property node
*/
public function getNode(): PhpParser\Node {
if ($this->flags & Modifiers::ABSTRACT && !$this->hooks) {
throw new PhpParser\Error('Only hooked properties may be declared abstract');
}
return new Stmt\Property(
$this->flags !== 0 ? $this->flags : Modifiers::PUBLIC,
[
@ -155,7 +216,8 @@ class Property implements PhpParser\Builder {
],
$this->attributes,
$this->type,
$this->attributeGroups
$this->attributeGroups,
$this->hooks
);
}
}

View File

@ -210,7 +210,7 @@ class BuilderFactory {
/**
* Creates node a for a literal value.
*
* @param Expr|bool|null|int|float|string|array $value $value
* @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value
*/
public function val($value): Expr {
return BuilderHelpers::normalizeValue($value);

View File

@ -6,6 +6,7 @@ use PhpParser\Node\ComplexType;
use PhpParser\Node\Expr;
use PhpParser\Node\Identifier;
use PhpParser\Node\Name;
use PhpParser\Node\Name\FullyQualified;
use PhpParser\Node\NullableType;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt;
@ -214,7 +215,7 @@ final class BuilderHelpers {
* Normalizes a value: Converts nulls, booleans, integers,
* floats, strings and arrays into their respective nodes
*
* @param Node\Expr|bool|null|int|float|string|array $value The value to normalize
* @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value The value to normalize
*
* @return Expr The normalized value
*/
@ -268,6 +269,10 @@ final class BuilderHelpers {
return new Expr\Array_($items);
}
if ($value instanceof \UnitEnum) {
return new Expr\ClassConstFetch(new FullyQualified(\get_class($value)), new Identifier($value->name));
}
throw new \LogicException('Invalid value');
}

View File

@ -20,9 +20,9 @@ class TokenStream {
*
* @param Token[] $tokens Tokens in PhpToken::tokenize() format
*/
public function __construct(array $tokens) {
public function __construct(array $tokens, int $tabWidth) {
$this->tokens = $tokens;
$this->indentMap = $this->calcIndentMap();
$this->indentMap = $this->calcIndentMap($tabWidth);
}
/**
@ -248,7 +248,7 @@ class TokenStream {
*
* @return int[] Token position to indentation map
*/
private function calcIndentMap(): array {
private function calcIndentMap(int $tabWidth): array {
$indentMap = [];
$indent = 0;
foreach ($this->tokens as $i => $token) {
@ -258,11 +258,11 @@ class TokenStream {
$content = $token->text;
$newlinePos = \strrpos($content, "\n");
if (false !== $newlinePos) {
$indent = \strlen($content) - $newlinePos - 1;
$indent = $this->getIndent(\substr($content, $newlinePos + 1), $tabWidth);
} elseif ($i === 1 && $this->tokens[0]->id === \T_OPEN_TAG &&
$this->tokens[0]->text[\strlen($this->tokens[0]->text) - 1] === "\n") {
// Special case: Newline at the end of opening tag followed by whitespace.
$indent = \strlen($content);
$indent = $this->getIndent($content, $tabWidth);
}
}
}
@ -272,4 +272,11 @@ class TokenStream {
return $indentMap;
}
private function getIndent(string $ws, int $tabWidth): int {
$spaces = \substr_count($ws, " ");
$tabs = \substr_count($ws, "\t");
assert(\strlen($ws) === $spaces + $tabs);
return $spaces + $tabs * $tabWidth;
}
}

View File

@ -5,15 +5,13 @@ namespace PhpParser\Lexer;
use PhpParser\Error;
use PhpParser\ErrorHandler;
use PhpParser\Lexer;
use PhpParser\Lexer\TokenEmulator\AsymmetricVisibilityTokenEmulator;
use PhpParser\Lexer\TokenEmulator\AttributeEmulator;
use PhpParser\Lexer\TokenEmulator\EnumTokenEmulator;
use PhpParser\Lexer\TokenEmulator\CoaleseEqualTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ExplicitOctalEmulator;
use PhpParser\Lexer\TokenEmulator\FlexibleDocStringEmulator;
use PhpParser\Lexer\TokenEmulator\FnTokenEmulator;
use PhpParser\Lexer\TokenEmulator\MatchTokenEmulator;
use PhpParser\Lexer\TokenEmulator\NullsafeTokenEmulator;
use PhpParser\Lexer\TokenEmulator\NumericLiteralSeparatorEmulator;
use PhpParser\Lexer\TokenEmulator\PropertyTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ReadonlyFunctionTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ReadonlyTokenEmulator;
use PhpParser\Lexer\TokenEmulator\ReverseEmulator;
@ -47,6 +45,8 @@ class Emulative extends Lexer {
new ReadonlyTokenEmulator(),
new ExplicitOctalEmulator(),
new ReadonlyFunctionTokenEmulator(),
new PropertyTokenEmulator(),
new AsymmetricVisibilityTokenEmulator(),
];
// Collect emulators that are relevant for the PHP version we're running

View File

@ -14,8 +14,12 @@ abstract class KeywordEmulator extends TokenEmulator {
/** @param Token[] $tokens */
protected function isKeywordContext(array $tokens, int $pos): bool {
$previousNonSpaceToken = $this->getPreviousNonSpaceToken($tokens, $pos);
return $previousNonSpaceToken === null || $previousNonSpaceToken->id !== \T_OBJECT_OPERATOR;
$prevToken = $this->getPreviousNonSpaceToken($tokens, $pos);
if ($prevToken === null) {
return false;
}
return $prevToken->id !== \T_OBJECT_OPERATOR
&& $prevToken->id !== \T_NULLSAFE_OBJECT_OPERATOR;
}
public function emulate(string $code, array $tokens): array {

View File

@ -14,23 +14,47 @@ final class Modifiers {
public const ABSTRACT = 16;
public const FINAL = 32;
public const READONLY = 64;
public const PUBLIC_SET = 128;
public const PROTECTED_SET = 256;
public const PRIVATE_SET = 512;
public const VISIBILITY_MASK = 1 | 2 | 4;
public const VISIBILITY_MASK = self::PUBLIC | self::PROTECTED | self::PRIVATE;
public const VISIBILITY_SET_MASK = self::PUBLIC_SET | self::PROTECTED_SET | self::PRIVATE_SET;
private const TO_STRING_MAP = [
self::PUBLIC => 'public',
self::PROTECTED => 'protected',
self::PRIVATE => 'private',
self::STATIC => 'static',
self::ABSTRACT => 'abstract',
self::FINAL => 'final',
self::READONLY => 'readonly',
self::PUBLIC_SET => 'public(set)',
self::PROTECTED_SET => 'protected(set)',
self::PRIVATE_SET => 'private(set)',
];
public static function toString(int $modifier): string {
if (!isset(self::TO_STRING_MAP[$modifier])) {
throw new \InvalidArgumentException("Unknown modifier $modifier");
}
return self::TO_STRING_MAP[$modifier];
}
private static function isValidModifier(int $modifier): bool {
$isPow2 = ($modifier & ($modifier - 1)) == 0 && $modifier != 0;
return $isPow2 && $modifier <= self::PRIVATE_SET;
}
/**
* @internal
*/
public static function verifyClassModifier(int $a, int $b): void {
if ($a & Modifiers::ABSTRACT && $b & Modifiers::ABSTRACT) {
throw new Error('Multiple abstract modifiers are not allowed');
}
if ($a & Modifiers::FINAL && $b & Modifiers::FINAL) {
throw new Error('Multiple final modifiers are not allowed');
}
if ($a & Modifiers::READONLY && $b & Modifiers::READONLY) {
throw new Error('Multiple readonly modifiers are not allowed');
assert(self::isValidModifier($b));
if (($a & $b) != 0) {
throw new Error(
'Multiple ' . self::toString($b) . ' modifiers are not allowed');
}
if ($a & 48 && $b & 48) {
@ -42,24 +66,16 @@ final class Modifiers {
* @internal
*/
public static function verifyModifier(int $a, int $b): void {
if ($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK) {
assert(self::isValidModifier($b));
if (($a & Modifiers::VISIBILITY_MASK && $b & Modifiers::VISIBILITY_MASK) ||
($a & Modifiers::VISIBILITY_SET_MASK && $b & Modifiers::VISIBILITY_SET_MASK)
) {
throw new Error('Multiple access type modifiers are not allowed');
}
if ($a & Modifiers::ABSTRACT && $b & Modifiers::ABSTRACT) {
throw new Error('Multiple abstract modifiers are not allowed');
}
if ($a & Modifiers::STATIC && $b & Modifiers::STATIC) {
throw new Error('Multiple static modifiers are not allowed');
}
if ($a & Modifiers::FINAL && $b & Modifiers::FINAL) {
throw new Error('Multiple final modifiers are not allowed');
}
if ($a & Modifiers::READONLY && $b & Modifiers::READONLY) {
throw new Error('Multiple readonly modifiers are not allowed');
if (($a & $b) != 0) {
throw new Error(
'Multiple ' . self::toString($b) . ' modifiers are not allowed');
}
if ($a & 48 && $b & 48) {

View File

@ -185,7 +185,7 @@ class NameContext {
// Check for relevant type-specific use statements
foreach ($this->origAliases[$type] as $alias => $orig) {
if ($type === Stmt\Use_::TYPE_CONSTANT) {
// Constants are are complicated-sensitive
// Constants are complicated-sensitive
$normalizedOrig = $this->normalizeConstName($orig->toString());
if ($normalizedOrig === $this->normalizeConstName($name)) {
$possibleNames[] = new Name($alias);

View File

@ -21,6 +21,8 @@ class Param extends NodeAbstract {
public int $flags;
/** @var AttributeGroup[] PHP attribute groups */
public array $attrGroups;
/** @var PropertyHook[] Property hooks for promoted properties */
public array $hooks;
/**
* Constructs a parameter node.
@ -33,13 +35,15 @@ class Param extends NodeAbstract {
* @param array<string, mixed> $attributes Additional attributes
* @param int $flags Optional visibility flags
* @param list<AttributeGroup> $attrGroups PHP attribute groups
* @param PropertyHook[] $hooks Property hooks for promoted properties
*/
public function __construct(
Expr $var, ?Expr $default = null, ?Node $type = null,
bool $byRef = false, bool $variadic = false,
array $attributes = [],
int $flags = 0,
array $attrGroups = []
array $attrGroups = [],
array $hooks = []
) {
$this->attributes = $attributes;
$this->type = $type;
@ -49,10 +53,11 @@ class Param extends NodeAbstract {
$this->default = $default;
$this->flags = $flags;
$this->attrGroups = $attrGroups;
$this->hooks = $hooks;
}
public function getSubNodeNames(): array {
return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default'];
return ['attrGroups', 'flags', 'type', 'byRef', 'variadic', 'var', 'default', 'hooks'];
}
public function getType(): string {
@ -81,4 +86,25 @@ class Param extends NodeAbstract {
public function isReadonly(): bool {
return (bool) ($this->flags & Modifiers::READONLY);
}
/**
* Whether the promoted property has explicit public(set) visibility.
*/
public function isPublicSet(): bool {
return (bool) ($this->flags & Modifiers::PUBLIC_SET);
}
/**
* Whether the promoted property has explicit protected(set) visibility.
*/
public function isProtectedSet(): bool {
return (bool) ($this->flags & Modifiers::PROTECTED_SET);
}
/**
* Whether the promoted property has explicit private(set) visibility.
*/
public function isPrivateSet(): bool {
return (bool) ($this->flags & Modifiers::PRIVATE_SET);
}
}

View File

@ -0,0 +1,15 @@
<?php declare(strict_types=1);
namespace PhpParser\Node\Scalar\MagicConst;
use PhpParser\Node\Scalar\MagicConst;
class Property extends MagicConst {
public function getName(): string {
return '__PROPERTY__';
}
public function getType(): string {
return 'Scalar_MagicConst_Property';
}
}

View File

@ -18,6 +18,8 @@ class Property extends Node\Stmt {
public ?Node $type;
/** @var Node\AttributeGroup[] PHP attribute groups */
public array $attrGroups;
/** @var Node\PropertyHook[] Property hooks */
public array $hooks;
/**
* Constructs a class property list node.
@ -27,17 +29,19 @@ class Property extends Node\Stmt {
* @param array<string, mixed> $attributes Additional attributes
* @param null|Identifier|Name|ComplexType $type Type declaration
* @param Node\AttributeGroup[] $attrGroups PHP attribute groups
* @param Node\PropertyHook[] $hooks Property hooks
*/
public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = []) {
public function __construct(int $flags, array $props, array $attributes = [], ?Node $type = null, array $attrGroups = [], array $hooks = []) {
$this->attributes = $attributes;
$this->flags = $flags;
$this->props = $props;
$this->type = $type;
$this->attrGroups = $attrGroups;
$this->hooks = $hooks;
}
public function getSubNodeNames(): array {
return ['attrGroups', 'flags', 'type', 'props'];
return ['attrGroups', 'flags', 'type', 'props', 'hooks'];
}
/**
@ -76,6 +80,27 @@ class Property extends Node\Stmt {
return (bool) ($this->flags & Modifiers::READONLY);
}
/**
* Whether the property has explicit public(set) visibility.
*/
public function isPublicSet(): bool {
return (bool) ($this->flags & Modifiers::PUBLIC_SET);
}
/**
* Whether the property has explicit protected(set) visibility.
*/
public function isProtectedSet(): bool {
return (bool) ($this->flags & Modifiers::PROTECTED_SET);
}
/**
* Whether the property has explicit private(set) visibility.
*/
public function isPrivateSet(): bool {
return (bool) ($this->flags & Modifiers::PRIVATE_SET);
}
public function getType(): string {
return 'Stmt_Property';
}

View File

@ -185,6 +185,15 @@ class NodeDumper {
if ($flags & Modifiers::READONLY) {
$strs[] = 'READONLY';
}
if ($flags & Modifiers::PUBLIC_SET) {
$strs[] = 'PUBLIC_SET';
}
if ($flags & Modifiers::PROTECTED_SET) {
$strs[] = 'PROTECTED_SET';
}
if ($flags & Modifiers::PRIVATE_SET) {
$strs[] = 'PRIVATE_SET';
}
if ($strs) {
return implode(' | ', $strs) . ' (' . $flags . ')';

View File

@ -110,6 +110,12 @@ class NameResolver extends NodeVisitorAbstract {
$node->type = $this->resolveType($node->type);
}
$this->resolveAttrGroups($node);
} elseif ($node instanceof Node\PropertyHook) {
foreach ($node->params as $param) {
$param->type = $this->resolveType($param->type);
$this->resolveAttrGroups($param);
}
$this->resolveAttrGroups($node);
} elseif ($node instanceof Stmt\Const_) {
foreach ($node->consts as $const) {
$this->addNamespacedName($const);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -7,6 +7,7 @@ namespace PhpParser;
* turn is based on work by Masato Bito.
*/
use PhpParser\Node\Arg;
use PhpParser\Node\Expr;
use PhpParser\Node\Expr\Array_;
use PhpParser\Node\Expr\Cast\Double;
@ -14,6 +15,7 @@ use PhpParser\Node\Identifier;
use PhpParser\Node\InterpolatedStringPart;
use PhpParser\Node\Name;
use PhpParser\Node\Param;
use PhpParser\Node\PropertyHook;
use PhpParser\Node\Scalar\InterpolatedString;
use PhpParser\Node\Scalar\Int_;
use PhpParser\Node\Scalar\String_;
@ -1137,32 +1139,12 @@ abstract class ParserAbstract implements Parser {
}
protected function checkClassConst(ClassConst $node, int $modifierPos): void {
if ($node->flags & Modifiers::STATIC) {
foreach ([Modifiers::STATIC, Modifiers::ABSTRACT, Modifiers::READONLY] as $modifier) {
if ($node->flags & $modifier) {
$this->emitError(new Error(
"Cannot use 'static' as constant modifier",
"Cannot use '" . Modifiers::toString($modifier) . "' as constant modifier",
$this->getAttributesAt($modifierPos)));
}
if ($node->flags & Modifiers::ABSTRACT) {
$this->emitError(new Error(
"Cannot use 'abstract' as constant modifier",
$this->getAttributesAt($modifierPos)));
}
if ($node->flags & Modifiers::READONLY) {
$this->emitError(new Error(
"Cannot use 'readonly' as constant modifier",
$this->getAttributesAt($modifierPos)));
}
}
protected function checkProperty(Property $node, int $modifierPos): void {
if ($node->flags & Modifiers::ABSTRACT) {
$this->emitError(new Error('Properties cannot be declared abstract',
$this->getAttributesAt($modifierPos)));
}
if ($node->flags & Modifiers::FINAL) {
$this->emitError(new Error('Properties cannot be declared final',
$this->getAttributesAt($modifierPos)));
}
}
@ -1178,6 +1160,68 @@ abstract class ParserAbstract implements Parser {
}
}
/** @param PropertyHook[] $hooks */
protected function checkPropertyHookList(array $hooks, int $hookPos): void {
if (empty($hooks)) {
$this->emitError(new Error(
'Property hook list cannot be empty', $this->getAttributesAt($hookPos)));
}
}
protected function checkPropertyHook(PropertyHook $hook, ?int $paramListPos): void {
$name = $hook->name->toLowerString();
if ($name !== 'get' && $name !== 'set') {
$this->emitError(new Error(
'Unknown hook "' . $hook->name . '", expected "get" or "set"',
$hook->name->getAttributes()));
}
if ($name === 'get' && $paramListPos !== null) {
$this->emitError(new Error(
'get hook must not have a parameter list', $this->getAttributesAt($paramListPos)));
}
}
protected function checkPropertyHookModifiers(int $a, int $b, int $modifierPos): void {
try {
Modifiers::verifyModifier($a, $b);
} catch (Error $error) {
$error->setAttributes($this->getAttributesAt($modifierPos));
$this->emitError($error);
}
if ($b != Modifiers::FINAL) {
$this->emitError(new Error(
'Cannot use the ' . Modifiers::toString($b) . ' modifier on a property hook',
$this->getAttributesAt($modifierPos)));
}
}
/** @param array<Node\Arg|Node\VariadicPlaceholder> $args */
private function isSimpleExit(array $args): bool {
if (\count($args) === 0) {
return true;
}
if (\count($args) === 1) {
$arg = $args[0];
return $arg instanceof Arg && $arg->name === null &&
$arg->byRef === false && $arg->unpack === false;
}
return false;
}
/**
* @param array<Node\Arg|Node\VariadicPlaceholder> $args
* @param array<string, mixed> $attrs
*/
protected function createExitExpr(string $name, int $namePos, array $args, array $attrs): Expr {
if ($this->isSimpleExit($args)) {
// Create Exit node for backwards compatibility.
$attrs['kind'] = strtolower($name) === 'exit' ? Expr\Exit_::KIND_EXIT : Expr\Exit_::KIND_DIE;
return new Expr\Exit_(\count($args) === 1 ? $args[0]->value : null, $attrs);
}
return new Expr\FuncCall(new Name($name, $this->getAttributesAt($namePos)), $args, $attrs);
}
/**
* Creates the token map.
*
@ -1190,42 +1234,23 @@ abstract class ParserAbstract implements Parser {
protected function createTokenMap(): array {
$tokenMap = [];
for ($i = 0; $i < 1000; ++$i) {
if ($i < 256) {
// Single-char tokens use an identity mapping.
for ($i = 0; $i < 256; ++$i) {
$tokenMap[$i] = $i;
} elseif (\T_DOUBLE_COLON === $i) {
// T_DOUBLE_COLON is equivalent to T_PAAMAYIM_NEKUDOTAYIM
$tokenMap[$i] = static::T_PAAMAYIM_NEKUDOTAYIM;
} elseif (\T_OPEN_TAG_WITH_ECHO === $i) {
}
foreach ($this->symbolToName as $name) {
if ($name[0] === 'T') {
$tokenMap[\constant($name)] = constant(static::class . '::' . $name);
}
}
// T_OPEN_TAG_WITH_ECHO with dropped T_OPEN_TAG results in T_ECHO
$tokenMap[$i] = static::T_ECHO;
} elseif (\T_CLOSE_TAG === $i) {
$tokenMap[\T_OPEN_TAG_WITH_ECHO] = static::T_ECHO;
// T_CLOSE_TAG is equivalent to ';'
$tokenMap[$i] = ord(';');
} elseif ('UNKNOWN' !== $name = token_name($i)) {
if (defined($name = static::class . '::' . $name)) {
// Other tokens can be mapped directly
$tokenMap[$i] = constant($name);
}
}
}
$tokenMap[\T_CLOSE_TAG] = ord(';');
// Assign tokens for which we define compatibility constants, as token_name() does not know them.
$tokenMap[\T_FN] = static::T_FN;
$tokenMap[\T_COALESCE_EQUAL] = static::T_COALESCE_EQUAL;
$tokenMap[\T_NAME_QUALIFIED] = static::T_NAME_QUALIFIED;
$tokenMap[\T_NAME_FULLY_QUALIFIED] = static::T_NAME_FULLY_QUALIFIED;
$tokenMap[\T_NAME_RELATIVE] = static::T_NAME_RELATIVE;
$tokenMap[\T_MATCH] = static::T_MATCH;
$tokenMap[\T_NULLSAFE_OBJECT_OPERATOR] = static::T_NULLSAFE_OBJECT_OPERATOR;
$tokenMap[\T_ATTRIBUTE] = static::T_ATTRIBUTE;
$tokenMap[\T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG;
$tokenMap[\T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG] = static::T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG;
$tokenMap[\T_ENUM] = static::T_ENUM;
$tokenMap[\T_READONLY] = static::T_READONLY;
// We have create a map from PHP token IDs to external symbol IDs.
// We have created a map from PHP token IDs to external symbol IDs.
// Now map them to the internal symbol ID.
$fullTokenMap = [];
foreach ($tokenMap as $phpToken => $extSymbol) {

View File

@ -43,7 +43,7 @@ class PhpVersion {
* if it is still under development.
*/
public static function getNewestSupported(): self {
return self::fromComponents(8, 3);
return self::fromComponents(8, 4);
}
/**

View File

@ -23,7 +23,8 @@ class Standard extends PrettyPrinterAbstract {
. ($node->byRef ? '&' : '')
. ($node->variadic ? '...' : '')
. $this->p($node->var)
. ($node->default ? ' = ' . $this->p($node->default) : '');
. ($node->default ? ' = ' . $this->p($node->default) : '')
. ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : '');
}
protected function pArg(Node\Arg $node): string {
@ -125,6 +126,10 @@ class Standard extends PrettyPrinterAbstract {
return '__TRAIT__';
}
protected function pScalar_MagicConst_Property(MagicConst\Property $node): string {
return '__PROPERTY__';
}
// Scalars
private function indentString(string $str): string {
@ -827,7 +832,8 @@ class Standard extends PrettyPrinterAbstract {
return $this->pAttrGroups($node->attrGroups)
. (0 === $node->flags ? 'var ' : $this->pModifiers($node->flags))
. ($node->type ? $this->p($node->type) . ' ' : '')
. $this->pCommaSeparated($node->props) . ';';
. $this->pCommaSeparated($node->props)
. ($node->hooks ? ' {' . $this->pStmts($node->hooks) . $this->nl . '}' : ';');
}
protected function pPropertyItem(Node\PropertyItem $node): string {
@ -835,6 +841,15 @@ class Standard extends PrettyPrinterAbstract {
. (null !== $node->default ? ' = ' . $this->p($node->default) : '');
}
protected function pPropertyHook(Node\PropertyHook $node): string {
return $this->pAttrGroups($node->attrGroups)
. $this->pModifiers($node->flags)
. ($node->byRef ? '&' : '') . $node->name
. ($node->params ? '(' . $this->pMaybeMultiline($node->params, $this->phpVersion->supportsTrailingCommaInParamList()) . ')' : '')
. (\is_array($node->body) ? ' {' . $this->pStmts($node->body) . $this->nl . '}'
: ($node->body !== null ? ' => ' . $this->p($node->body) : '') . ';');
}
protected function pStmt_ClassMethod(Stmt\ClassMethod $node): string {
return $this->pAttrGroups($node->attrGroups)
. $this->pModifiers($node->flags)

View File

@ -14,6 +14,7 @@ use PhpParser\Node\Expr\Cast;
use PhpParser\Node\IntersectionType;
use PhpParser\Node\MatchArm;
use PhpParser\Node\Param;
use PhpParser\Node\PropertyHook;
use PhpParser\Node\Scalar;
use PhpParser\Node\Stmt;
use PhpParser\Node\UnionType;
@ -105,6 +106,15 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
/** @var int Current indentation level. */
protected int $indentLevel;
/** @var string String for single level of indentation */
private string $indent;
/** @var int Width in spaces to indent by. */
private int $indentWidth;
/** @var bool Whether to use tab indentation. */
private bool $useTabs;
/** @var int Width in spaces of one tab. */
private int $tabWidth = 4;
/** @var string Newline style. Does not include current indentation. */
protected string $newline;
/** @var string Newline including current indentation. */
@ -169,12 +179,14 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
* PHP version while specifying an older target (but the result will
* of course not be compatible with the older version in that case).
* * string $newline: The newline style to use. Should be "\n" (default) or "\r\n".
* * string $indent: The indentation to use. Should either be all spaces or a single
* tab. Defaults to four spaces (" ").
* * bool $shortArraySyntax: Whether to use [] instead of array() as the default array
* syntax, if the node does not specify a format. Defaults to whether
* the phpVersion support short array syntax.
*
* @param array{
* phpVersion?: PhpVersion, newline?: string, shortArraySyntax?: bool
* phpVersion?: PhpVersion, newline?: string, indent?: string, shortArraySyntax?: bool
* } $options Dictionary of formatting options
*/
public function __construct(array $options = []) {
@ -189,6 +201,17 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
$options['shortArraySyntax'] ?? $this->phpVersion->supportsShortArraySyntax();
$this->docStringEndToken =
$this->phpVersion->supportsFlexibleHeredoc() ? null : '_DOC_STRING_END_' . mt_rand();
$this->indent = $indent = $options['indent'] ?? ' ';
if ($indent === "\t") {
$this->useTabs = true;
$this->indentWidth = $this->tabWidth;
} elseif ($indent === \str_repeat(' ', \strlen($indent))) {
$this->useTabs = false;
$this->indentWidth = \strlen($indent);
} else {
throw new \LogicException('Option "indent" must either be all spaces or a single tab');
}
}
/**
@ -207,24 +230,29 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
*/
protected function setIndentLevel(int $level): void {
$this->indentLevel = $level;
if ($this->useTabs) {
$tabs = \intdiv($level, $this->tabWidth);
$spaces = $level % $this->tabWidth;
$this->nl = $this->newline . \str_repeat("\t", $tabs) . \str_repeat(' ', $spaces);
} else {
$this->nl = $this->newline . \str_repeat(' ', $level);
}
}
/**
* Increase indentation level.
*/
protected function indent(): void {
$this->indentLevel += 4;
$this->nl .= ' ';
$this->indentLevel += $this->indentWidth;
$this->nl .= $this->indent;
}
/**
* Decrease indentation level.
*/
protected function outdent(): void {
assert($this->indentLevel >= 4);
$this->indentLevel -= 4;
$this->nl = $this->newline . str_repeat(' ', $this->indentLevel);
assert($this->indentLevel >= $this->indentWidth);
$this->setIndentLevel($this->indentLevel - $this->indentWidth);
}
/**
@ -536,7 +564,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
$this->initializeModifierChangeMap();
$this->resetState();
$this->origTokens = new TokenStream($origTokens);
$this->origTokens = new TokenStream($origTokens, $this->tabWidth);
$this->preprocessNodes($stmts);
@ -708,7 +736,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
$result .= $extraLeft;
$origIndentLevel = $this->indentLevel;
$this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment);
$this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0));
// If it's the same node that was previously in this position, it certainly doesn't
// need fixup. It's important to check this here, because our fixup checks are more
@ -811,7 +839,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
\assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos);
$origIndentLevel = $this->indentLevel;
$lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment;
$lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0);
$this->setIndentLevel($lastElemIndentLevel);
$comments = $arrItem->getComments();
@ -1195,6 +1223,9 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
. ($modifiers & Modifiers::PUBLIC ? 'public ' : '')
. ($modifiers & Modifiers::PROTECTED ? 'protected ' : '')
. ($modifiers & Modifiers::PRIVATE ? 'private ' : '')
. ($modifiers & Modifiers::PUBLIC_SET ? 'public(set) ' : '')
. ($modifiers & Modifiers::PROTECTED_SET ? 'protected(set) ' : '')
. ($modifiers & Modifiers::PRIVATE_SET ? 'private(set) ' : '')
. ($modifiers & Modifiers::STATIC ? 'static ' : '')
. ($modifiers & Modifiers::READONLY ? 'readonly ' : '');
}
@ -1517,6 +1548,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
Stmt\UseUse::class . '->uses' => ', ',
MatchArm::class . '->conds' => ', ',
AttributeGroup::class . '->attrs' => ', ',
PropertyHook::class . '->params' => ', ',
// statement lists
Expr\Closure::class . '->stmts' => "\n",
@ -1554,10 +1586,15 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
Expr\Closure::class . '->attrGroups' => ' ',
Expr\ArrowFunction::class . '->attrGroups' => ' ',
Param::class . '->attrGroups' => ' ',
PropertyHook::class . '->attrGroups' => ' ',
Stmt\Switch_::class . '->cases' => "\n",
Stmt\TraitUse::class . '->adaptations' => "\n",
Stmt\TryCatch::class . '->stmts' => "\n",
Stmt\While_::class . '->stmts' => "\n",
PropertyHook::class . '->body' => "\n",
Stmt\Property::class . '->hooks' => "\n",
Param::class . '->hooks' => "\n",
// dummy for top-level context
'File->stmts' => "\n",
@ -1641,6 +1678,7 @@ abstract class PrettyPrinterAbstract implements PrettyPrinter {
Stmt\Property::class . '->flags' => ['pModifiers', \T_VARIABLE],
PrintableNewAnonClassNode::class . '->flags' => ['pModifiers', \T_CLASS],
Param::class . '->flags' => ['pModifiers', \T_VARIABLE],
PropertyHook::class . '->flags' => ['pModifiers', \T_STRING],
Expr\Closure::class . '->static' => ['pStatic', \T_FUNCTION],
Expr\ArrowFunction::class . '->static' => ['pStatic', \T_FN],
//Stmt\TraitUseAdaptation\Alias::class . '->newModifier' => 0, // TODO

View File

@ -17,6 +17,11 @@ if (!\function_exists('PhpParser\defineCompatibilityTokens')) {
'T_AMPERSAND_NOT_FOLLOWED_BY_VAR_OR_VARARG',
'T_AMPERSAND_FOLLOWED_BY_VAR_OR_VARARG',
'T_READONLY',
// PHP 8.4
'T_PROPERTY_C',
'T_PUBLIC_SET',
'T_PROTECTED_SET',
'T_PRIVATE_SET',
];
// PHP-Parser might be used together with another library that also emulates some or all

View File

@ -2,6 +2,12 @@
All notable changes are documented in this file using the [Keep a CHANGELOG](http://keepachangelog.com/) principles.
## [9.2.32] - 2024-08-22
### Changed
* Updated dependencies (so that users that install using Composer's `--prefer-lowest` CLI option also get recent versions)
## [9.2.31] - 2024-03-02
### Changed
@ -511,6 +517,7 @@ All notable changes are documented in this file using the [Keep a CHANGELOG](htt
* This component is no longer supported on PHP 7.1
[9.2.32]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.31...9.2.32
[9.2.31]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.30...9.2.31
[9.2.30]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.29...9.2.30
[9.2.29]: https://github.com/sebastianbergmann/php-code-coverage/compare/9.2.28...9.2.29

View File

@ -33,15 +33,15 @@
"ext-dom": "*",
"ext-libxml": "*",
"ext-xmlwriter": "*",
"nikic/php-parser": "^4.18 || ^5.0",
"phpunit/php-file-iterator": "^3.0.3",
"phpunit/php-text-template": "^2.0.2",
"sebastian/code-unit-reverse-lookup": "^2.0.2",
"sebastian/complexity": "^2.0",
"sebastian/environment": "^5.1.2",
"sebastian/lines-of-code": "^1.0.3",
"sebastian/version": "^3.0.1",
"theseer/tokenizer": "^1.2.0"
"nikic/php-parser": "^4.19.1 || ^5.1.0",
"phpunit/php-file-iterator": "^3.0.6",
"phpunit/php-text-template": "^2.0.4",
"sebastian/code-unit-reverse-lookup": "^2.0.3",
"sebastian/complexity": "^2.0.3",
"sebastian/environment": "^5.1.5",
"sebastian/lines-of-code": "^1.0.4",
"sebastian/version": "^3.0.2",
"theseer/tokenizer": "^1.2.3"
},
"require-dev": {
"phpunit/phpunit": "^9.6"

View File

@ -22,7 +22,7 @@ final class Version
public static function id(): string
{
if (self::$version === null) {
self::$version = (new VersionId('9.2.31', dirname(__DIR__)))->getVersion();
self::$version = (new VersionId('9.2.32', dirname(__DIR__)))->getVersion();
}
return self::$version;

View File

@ -9,10 +9,6 @@ interface LoggerAwareInterface
{
/**
* Sets a logger instance on the object.
*
* @param LoggerInterface $logger
*
* @return void
*/
public function setLogger(LoggerInterface $logger): void;
}

View File

@ -9,15 +9,11 @@ trait LoggerAwareTrait
{
/**
* The logger instance.
*
* @var LoggerInterface|null
*/
protected ?LoggerInterface $logger = null;
/**
* Sets a logger.
*
* @param LoggerInterface $logger
*/
public function setLogger(LoggerInterface $logger): void
{

View File

@ -22,10 +22,7 @@ interface LoggerInterface
/**
* System is unusable.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function emergency(string|\Stringable $message, array $context = []): void;
@ -35,10 +32,7 @@ interface LoggerInterface
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function alert(string|\Stringable $message, array $context = []): void;
@ -47,10 +41,7 @@ interface LoggerInterface
*
* Example: Application component unavailable, unexpected exception.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function critical(string|\Stringable $message, array $context = []): void;
@ -58,10 +49,7 @@ interface LoggerInterface
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function error(string|\Stringable $message, array $context = []): void;
@ -71,20 +59,14 @@ interface LoggerInterface
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function warning(string|\Stringable $message, array $context = []): void;
/**
* Normal but significant events.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function notice(string|\Stringable $message, array $context = []): void;
@ -93,20 +75,14 @@ interface LoggerInterface
*
* Example: User logs in, SQL logs.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function info(string|\Stringable $message, array $context = []): void;
/**
* Detailed debug information.
*
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*/
public function debug(string|\Stringable $message, array $context = []): void;
@ -114,11 +90,8 @@ interface LoggerInterface
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param mixed[] $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/
public function log($level, string|\Stringable $message, array $context = []): void;

View File

@ -14,11 +14,6 @@ trait LoggerTrait
{
/**
* System is unusable.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function emergency(string|\Stringable $message, array $context = []): void
{
@ -30,11 +25,6 @@ trait LoggerTrait
*
* Example: Entire website down, database unavailable, etc. This should
* trigger the SMS alerts and wake you up.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function alert(string|\Stringable $message, array $context = []): void
{
@ -45,11 +35,6 @@ trait LoggerTrait
* Critical conditions.
*
* Example: Application component unavailable, unexpected exception.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function critical(string|\Stringable $message, array $context = []): void
{
@ -59,11 +44,6 @@ trait LoggerTrait
/**
* Runtime errors that do not require immediate action but should typically
* be logged and monitored.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function error(string|\Stringable $message, array $context = []): void
{
@ -75,11 +55,6 @@ trait LoggerTrait
*
* Example: Use of deprecated APIs, poor use of an API, undesirable things
* that are not necessarily wrong.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function warning(string|\Stringable $message, array $context = []): void
{
@ -88,11 +63,6 @@ trait LoggerTrait
/**
* Normal but significant events.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function notice(string|\Stringable $message, array $context = []): void
{
@ -103,11 +73,6 @@ trait LoggerTrait
* Interesting events.
*
* Example: User logs in, SQL logs.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function info(string|\Stringable $message, array $context = []): void
{
@ -116,11 +81,6 @@ trait LoggerTrait
/**
* Detailed debug information.
*
* @param string|\Stringable $message
* @param array $context
*
* @return void
*/
public function debug(string|\Stringable $message, array $context = []): void
{
@ -131,10 +91,6 @@ trait LoggerTrait
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param array $context
*
* @return void
*
* @throws \Psr\Log\InvalidArgumentException
*/

View File

@ -15,11 +15,7 @@ class NullLogger extends AbstractLogger
/**
* Logs with an arbitrary level.
*
* @param mixed $level
* @param string|\Stringable $message
* @param array $context
*
* @return void
* @param mixed[] $context
*
* @throws \Psr\Log\InvalidArgumentException
*/

View File

@ -140,9 +140,11 @@ abstract class Command extends BaseCommand
$default = '';
}
$name = $argument->getName();
$pad = \str_pad('', $max - \strlen($name));
$description = \str_replace("\n", "\n".\str_pad('', $max + 2, ' '), $argument->getDescription());
$messages[] = \sprintf(" <info>%-{$max}s</info> %s%s", $argument->getName(), $description, $default);
$messages[] = \sprintf(' <info>%s</info>%s %s%s', $name, $pad, $description, $default);
}
$messages[] = '';

View File

@ -1023,7 +1023,11 @@ class Configuration
*/
public function setErrorLoggingLevel($errorLoggingLevel)
{
if (\PHP_VERSION_ID < 80400) {
$this->errorLoggingLevel = (\E_ALL | \E_STRICT) & $errorLoggingLevel;
} else {
$this->errorLoggingLevel = \E_ALL & $errorLoggingLevel;
}
}
/**
@ -1263,10 +1267,12 @@ class Configuration
// let's not use it by default.
//
// See https://github.com/bobthecow/psysh/issues/778
if (@\is_link($less)) {
$link = @\readlink($less);
if ($link !== false && \strpos($link, 'busybox') !== false) {
return false;
}
}
$this->pager = $less.' -R -F -X';
}

View File

@ -37,10 +37,6 @@ class ErrorException extends \ErrorException implements Exception
}
switch ($severity) {
case \E_STRICT:
$type = 'Strict error';
break;
case \E_NOTICE:
case \E_USER_NOTICE:
$type = 'Notice';
@ -63,6 +59,10 @@ class ErrorException extends \ErrorException implements Exception
break;
default:
if (\PHP_VERSION_ID < 80400 && $severity === \E_STRICT) {
$type = 'Strict error';
break;
}
$type = 'Error';
break;
}

View File

@ -919,7 +919,23 @@ class Shell extends Application
$input = new ShellInput(\str_replace('\\', '\\\\', \rtrim($input, " \t\n\r\0\x0B;")));
if ($input->hasParameterOption(['--help', '-h'])) {
if (!$input->hasParameterOption(['--help', '-h'])) {
try {
return $command->run($input, $this->output);
} catch (\Exception $e) {
if (!self::needsInputHelp($e)) {
throw $e;
}
$this->writeException($e);
$this->output->writeln('--');
if (!$this->config->theme()->compact()) {
$this->output->writeln('');
}
}
}
$helpCommand = $this->get('help');
if (!$helpCommand instanceof Command\HelpCommand) {
throw new RuntimeException('Invalid help command instance');
@ -929,7 +945,32 @@ class Shell extends Application
return $helpCommand->run(new StringInput(''), $this->output);
}
return $command->run($input, $this->output);
/**
* Check whether a given input error would benefit from --help.
*
* @return bool
*/
private static function needsInputHelp(\Exception $e): bool
{
if (!($e instanceof \RuntimeException || $e instanceof SymfonyConsoleException)) {
return false;
}
$inputErrors = [
'Not enough arguments',
'option does not accept a value',
'option does not exist',
'option requires a value',
];
$msg = $e->getMessage();
foreach ($inputErrors as $errorMsg) {
if (\strpos($msg, $errorMsg) !== false) {
return true;
}
}
return false;
}
/**
@ -1261,10 +1302,13 @@ class Shell extends Application
case \E_USER_NOTICE:
case \E_USER_DEPRECATED:
case \E_DEPRECATED:
case \E_STRICT:
return 'warning';
default:
if ((\PHP_VERSION_ID < 80400) && $severity === \E_STRICT) {
return 'warning';
}
return 'error';
}
} else {

View File

@ -74,7 +74,7 @@ class AutoCompleter
$matches = [];
foreach ($this->matchers as $matcher) {
if ($matcher->hasMatched($tokens)) {
$matches = \array_merge($matcher->getMatches($tokens), $matches);
$matches = \array_merge($matcher->getMatches($tokens, $info), $matches);
}
}

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-ctype": "*"

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"autoload": {
"psr-4": { "Symfony\\Polyfill\\Intl\\Grapheme\\": "" },

View File

@ -145,7 +145,7 @@ final class Idn
*/
public static function idn_to_ascii($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
{
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
@trigger_error('idn_to_ascii(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
}
@ -198,7 +198,7 @@ final class Idn
*/
public static function idn_to_utf8($domainName, $options = self::IDNA_DEFAULT, $variant = self::INTL_IDNA_VARIANT_UTS46, &$idna_info = [])
{
if (\PHP_VERSION_ID >= 70200 && self::INTL_IDNA_VARIANT_2003 === $variant) {
if (self::INTL_IDNA_VARIANT_2003 === $variant) {
@trigger_error('idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated', \E_USER_DEPRECATED);
}

View File

@ -20,9 +20,8 @@
}
],
"require": {
"php": ">=7.1",
"symfony/polyfill-intl-normalizer": "^1.10",
"symfony/polyfill-php72": "^1.10"
"php": ">=7.2",
"symfony/polyfill-intl-normalizer": "^1.10"
},
"autoload": {
"psr-4": { "Symfony\\Polyfill\\Intl\\Idn\\": "" },

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"autoload": {
"psr-4": { "Symfony\\Polyfill\\Intl\\Normalizer\\": "" },

View File

@ -86,12 +86,6 @@ final class Mbstring
public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null)
{
if (\is_array($s)) {
if (\PHP_VERSION_ID < 70200) {
trigger_error('mb_convert_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
return null;
}
$r = [];
foreach ($s as $str) {
$r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding);
@ -430,12 +424,6 @@ final class Mbstring
public static function mb_check_encoding($var = null, $encoding = null)
{
if (\PHP_VERSION_ID < 70200 && \is_array($var)) {
trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING);
return null;
}
if (null === $encoding) {
if (null === $var) {
return false;

View File

@ -93,7 +93,7 @@ if (!function_exists('mb_strstr')) {
function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); }
}
if (!function_exists('mb_get_info')) {
function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); }
function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); }
}
if (!function_exists('mb_http_output')) {
function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); }
@ -133,11 +133,11 @@ if (!function_exists('mb_str_pad')) {
}
if (!function_exists('mb_ucfirst')) {
function mb_ucfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); }
}
if (!function_exists('mb_lcfirst')) {
function mb_lcfirst($string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); }
}
if (!function_exists('mb_trim')) {

View File

@ -16,7 +16,7 @@
}
],
"require": {
"php": ">=7.1"
"php": ">=7.2"
},
"provide": {
"ext-mbstring": "*"

View File

@ -1,19 +0,0 @@
Copyright (c) 2015-present Fabien Potencier
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.

View File

@ -1,218 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Polyfill\Php72;
/**
* @author Nicolas Grekas <p@tchwork.com>
* @author Dariusz Rumiński <dariusz.ruminski@gmail.com>
*
* @internal
*/
final class Php72
{
private static $hashMask;
public static function utf8_encode($s)
{
$s .= $s;
$len = \strlen($s);
for ($i = $len >> 1, $j = 0; $i < $len; ++$i, ++$j) {
switch (true) {
case $s[$i] < "\x80": $s[$j] = $s[$i]; break;
case $s[$i] < "\xC0": $s[$j] = "\xC2"; $s[++$j] = $s[$i]; break;
default: $s[$j] = "\xC3"; $s[++$j] = \chr(\ord($s[$i]) - 64); break;
}
}
return substr($s, 0, $j);
}
public static function utf8_decode($s)
{
$s = (string) $s;
$len = \strlen($s);
for ($i = 0, $j = 0; $i < $len; ++$i, ++$j) {
switch ($s[$i] & "\xF0") {
case "\xC0":
case "\xD0":
$c = (\ord($s[$i] & "\x1F") << 6) | \ord($s[++$i] & "\x3F");
$s[$j] = $c < 256 ? \chr($c) : '?';
break;
case "\xF0":
++$i;
// no break
case "\xE0":
$s[$j] = '?';
$i += 2;
break;
default:
$s[$j] = $s[$i];
}
}
return substr($s, 0, $j);
}
public static function php_os_family()
{
if ('\\' === \DIRECTORY_SEPARATOR) {
return 'Windows';
}
$map = [
'Darwin' => 'Darwin',
'DragonFly' => 'BSD',
'FreeBSD' => 'BSD',
'NetBSD' => 'BSD',
'OpenBSD' => 'BSD',
'Linux' => 'Linux',
'SunOS' => 'Solaris',
];
return $map[\PHP_OS] ?? 'Unknown';
}
public static function spl_object_id($object)
{
if (null === self::$hashMask) {
self::initHashMask();
}
if (null === $hash = spl_object_hash($object)) {
return;
}
// On 32-bit systems, PHP_INT_SIZE is 4,
return self::$hashMask ^ hexdec(substr($hash, 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function sapi_windows_vt100_support($stream, $enable = null)
{
if (!\is_resource($stream)) {
trigger_error('sapi_windows_vt100_support() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
return false;
}
$meta = stream_get_meta_data($stream);
if ('STDIO' !== $meta['stream_type']) {
trigger_error('sapi_windows_vt100_support() was not able to analyze the specified stream', \E_USER_WARNING);
return false;
}
// We cannot actually disable vt100 support if it is set
if (false === $enable || !self::stream_isatty($stream)) {
return false;
}
// The native function does not apply to stdin
$meta = array_map('strtolower', $meta);
$stdin = 'php://stdin' === $meta['uri'] || 'php://fd/0' === $meta['uri'];
return !$stdin
&& (false !== getenv('ANSICON')
|| 'ON' === getenv('ConEmuANSI')
|| 'xterm' === getenv('TERM')
|| 'Hyper' === getenv('TERM_PROGRAM'));
}
public static function stream_isatty($stream)
{
if (!\is_resource($stream)) {
trigger_error('stream_isatty() expects parameter 1 to be resource, '.\gettype($stream).' given', \E_USER_WARNING);
return false;
}
if ('\\' === \DIRECTORY_SEPARATOR) {
$stat = @fstat($stream);
// Check if formatted mode is S_IFCHR
return $stat ? 0020000 === ($stat['mode'] & 0170000) : false;
}
return \function_exists('posix_isatty') && @posix_isatty($stream);
}
private static function initHashMask()
{
$obj = (object) [];
self::$hashMask = -1;
// check if we are nested in an output buffering handler to prevent a fatal error with ob_start() below
$obFuncs = ['ob_clean', 'ob_end_clean', 'ob_flush', 'ob_end_flush', 'ob_get_contents', 'ob_get_flush'];
foreach (debug_backtrace(\PHP_VERSION_ID >= 50400 ? \DEBUG_BACKTRACE_IGNORE_ARGS : false) as $frame) {
if (isset($frame['function'][0]) && !isset($frame['class']) && 'o' === $frame['function'][0] && \in_array($frame['function'], $obFuncs)) {
$frame['line'] = 0;
break;
}
}
if (!empty($frame['line'])) {
ob_start();
debug_zval_dump($obj);
self::$hashMask = (int) substr(ob_get_clean(), 17);
}
self::$hashMask ^= hexdec(substr(spl_object_hash($obj), 16 - (\PHP_INT_SIZE * 2 - 1), \PHP_INT_SIZE * 2 - 1));
}
public static function mb_chr($code, $encoding = null)
{
if (0x80 > $code %= 0x200000) {
$s = \chr($code);
} elseif (0x800 > $code) {
$s = \chr(0xC0 | $code >> 6).\chr(0x80 | $code & 0x3F);
} elseif (0x10000 > $code) {
$s = \chr(0xE0 | $code >> 12).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
} else {
$s = \chr(0xF0 | $code >> 18).\chr(0x80 | $code >> 12 & 0x3F).\chr(0x80 | $code >> 6 & 0x3F).\chr(0x80 | $code & 0x3F);
}
if ('UTF-8' !== $encoding = $encoding ?? mb_internal_encoding()) {
$s = mb_convert_encoding($s, $encoding, 'UTF-8');
}
return $s;
}
public static function mb_ord($s, $encoding = null)
{
if (null === $encoding) {
$s = mb_convert_encoding($s, 'UTF-8');
} elseif ('UTF-8' !== $encoding) {
$s = mb_convert_encoding($s, 'UTF-8', $encoding);
}
if (1 === \strlen($s)) {
return \ord($s);
}
$code = ($s = unpack('C*', substr($s, 0, 4))) ? $s[1] : 0;
if (0xF0 <= $code) {
return (($code - 0xF0) << 18) + (($s[2] - 0x80) << 12) + (($s[3] - 0x80) << 6) + $s[4] - 0x80;
}
if (0xE0 <= $code) {
return (($code - 0xE0) << 12) + (($s[2] - 0x80) << 6) + $s[3] - 0x80;
}
if (0xC0 <= $code) {
return (($code - 0xC0) << 6) + $s[2] - 0x80;
}
return $code;
}
}

View File

@ -1,35 +0,0 @@
Symfony Polyfill / Php72
========================
This component provides functions added to PHP 7.2 core:
- [`spl_object_id`](https://php.net/spl_object_id)
- [`stream_isatty`](https://php.net/stream_isatty)
And also functions added to PHP 7.2 mbstring:
- [`mb_ord`](https://php.net/mb_ord)
- [`mb_chr`](https://php.net/mb_chr)
- [`mb_scrub`](https://php.net/mb_scrub)
On Windows only:
- [`sapi_windows_vt100_support`](https://php.net/sapi_windows_vt100_support)
Moved to core since 7.2 (was in the optional XML extension earlier):
- [`utf8_encode`](https://php.net/utf8_encode)
- [`utf8_decode`](https://php.net/utf8_decode)
Also, it provides constants added to PHP 7.2:
- [`PHP_FLOAT_*`](https://php.net/reserved.constants#constant.php-float-dig)
- [`PHP_OS_FAMILY`](https://php.net/reserved.constants#constant.php-os-family)
More information can be found in the
[main Polyfill README](https://github.com/symfony/polyfill/blob/main/README.md).
License
=======
This library is released under the [MIT license](LICENSE).

View File

@ -1,57 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Symfony\Polyfill\Php72 as p;
if (\PHP_VERSION_ID >= 70200) {
return;
}
if (!defined('PHP_FLOAT_DIG')) {
define('PHP_FLOAT_DIG', 15);
}
if (!defined('PHP_FLOAT_EPSILON')) {
define('PHP_FLOAT_EPSILON', 2.2204460492503E-16);
}
if (!defined('PHP_FLOAT_MIN')) {
define('PHP_FLOAT_MIN', 2.2250738585072E-308);
}
if (!defined('PHP_FLOAT_MAX')) {
define('PHP_FLOAT_MAX', 1.7976931348623157E+308);
}
if (!defined('PHP_OS_FAMILY')) {
define('PHP_OS_FAMILY', p\Php72::php_os_family());
}
if ('\\' === \DIRECTORY_SEPARATOR && !function_exists('sapi_windows_vt100_support')) {
function sapi_windows_vt100_support($stream, $enable = null) { return p\Php72::sapi_windows_vt100_support($stream, $enable); }
}
if (!function_exists('stream_isatty')) {
function stream_isatty($stream) { return p\Php72::stream_isatty($stream); }
}
if (!function_exists('utf8_encode')) {
function utf8_encode($string) { return p\Php72::utf8_encode($string); }
}
if (!function_exists('utf8_decode')) {
function utf8_decode($string) { return p\Php72::utf8_decode($string); }
}
if (!function_exists('spl_object_id')) {
function spl_object_id($object) { return p\Php72::spl_object_id($object); }
}
if (!function_exists('mb_ord')) {
function mb_ord($string, $encoding = null) { return p\Php72::mb_ord($string, $encoding); }
}
if (!function_exists('mb_chr')) {
function mb_chr($codepoint, $encoding = null) { return p\Php72::mb_chr($codepoint, $encoding); }
}
if (!function_exists('mb_scrub')) {
function mb_scrub($string, $encoding = null) { $encoding = null === $encoding ? mb_internal_encoding() : $encoding; return mb_convert_encoding($string, $encoding, $encoding); }
}

View File

@ -1,32 +0,0 @@
{
"name": "symfony/polyfill-php72",
"type": "library",
"description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions",
"keywords": ["polyfill", "shim", "compatibility", "portable"],
"homepage": "https://symfony.com",
"license": "MIT",
"authors": [
{
"name": "Nicolas Grekas",
"email": "p@tchwork.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"require": {
"php": ">=7.1"
},
"autoload": {
"psr-4": { "Symfony\\Polyfill\\Php72\\": "" },
"files": [ "bootstrap.php" ]
},
"minimum-stability": "dev",
"extra": {
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
}
}

View File

@ -20,3 +20,10 @@ CHANGE COLUMN `username` `mobile` varchar(15) CHARACTER SET utf8 COLLATE utf8_un
ALTER TABLE `c_sms`
MODIFY COLUMN `uid` int NOT NULL DEFAULT 0 COMMENT '管理用户ID' AFTER `pid`,
MODIFY COLUMN `mid` int NOT NULL DEFAULT 0 COMMENT '会员用户ID' AFTER `uid`;
-- 2024.10.24
ALTER TABLE `c_log`
MODIFY COLUMN `username` varchar (32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `id`,
MODIFY COLUMN `ip` varchar (64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `username`,
MODIFY COLUMN `data` text CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL AFTER `ip`,
MODIFY COLUMN `create_time` varchar (32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL AFTER `data`;