From e182786c7c4f73e510d69093d10736a234de0259 Mon Sep 17 00:00:00 2001 From: Benn Oshrin Date: Sat, 4 Mar 2023 20:36:48 -0500 Subject: [PATCH] Initial implementation of Jobs (CFM-245) --- app/composer.json | 2 +- app/composer.lock | 1533 +++--- app/config/schema/schema.json | 56 +- app/resources/locales/en_US/command.po | 51 + app/resources/locales/en_US/controller.po | 6 + app/resources/locales/en_US/enumeration.po | 21 + app/resources/locales/en_US/error.po | 30 + app/resources/locales/en_US/field.po | 54 + app/resources/locales/en_US/result.po | 9 + app/src/Command/JobCommand.php | 275 ++ app/src/Command/SetupCommand.php | 2 +- app/src/Command/TransmogrifyCommand.php | 45 + app/src/Controller/AppController.php | 6 +- .../JobHistoryRecordsController.php | 62 + app/src/Controller/JobsController.php | 61 + app/src/Lib/Enum/JobStatusEnum.php | 40 + app/src/Lib/Enum/TableTypeEnum.php | 38 + app/src/Lib/Traits/PluggableModelTrait.php | 81 +- app/src/Lib/Traits/PrimaryLinkTrait.php | 11 +- app/src/Lib/Traits/TableMetaTrait.php | 31 +- app/src/Model/Entity/Job.php | 67 + app/src/Model/Entity/JobHistoryRecord.php | 54 + app/src/Model/Table/AdHocAttributesTable.php | 3 +- app/src/Model/Table/AddressesTable.php | 3 +- app/src/Model/Table/ApiUsersTable.php | 3 +- .../Model/Table/AuthenticationEventsTable.php | 3 +- app/src/Model/Table/CoSettingsTable.php | 3 +- app/src/Model/Table/CosTable.php | 6 +- app/src/Model/Table/CousTable.php | 3 +- app/src/Model/Table/DashboardsTable.php | 3 +- app/src/Model/Table/EmailAddressesTable.php | 3 +- .../Model/Table/ExternalIdentitiesTable.php | 6 +- .../Table/ExternalIdentityRolesTable.php | 3 +- app/src/Model/Table/GroupMembersTable.php | 3 +- app/src/Model/Table/GroupNestingsTable.php | 3 +- app/src/Model/Table/GroupOwnersTable.php | 3 +- app/src/Model/Table/GroupsTable.php | 3 +- app/src/Model/Table/HistoryRecordsTable.php | 3 +- app/src/Model/Table/IdentifiersTable.php | 3 +- .../Model/Table/JobHistoryRecordsTable.php | 200 + app/src/Model/Table/JobsTable.php | 730 +++ app/src/Model/Table/MetaTable.php | 3 +- app/src/Model/Table/NamesTable.php | 3 +- app/src/Model/Table/PeopleTable.php | 6 +- app/src/Model/Table/PersonRolesTable.php | 3 +- app/src/Model/Table/PluginsTable.php | 29 +- app/src/Model/Table/PronounsTable.php | 3 +- app/src/Model/Table/TelephoneNumbersTable.php | 3 +- app/src/Model/Table/TypesTable.php | 3 +- app/src/Model/Table/UrlsTable.php | 3 +- app/src/View/Helper/FieldHelper.php | 2 +- app/templates/JobHistoryRecords/columns.inc | 50 + app/templates/JobHistoryRecords/fields.inc | 70 + app/templates/Jobs/columns.inc | 50 + app/templates/Jobs/fields-links.inc | 51 + app/templates/Jobs/fields.inc | 78 + app/templates/Standard/add-edit-view.php | 25 +- app/templates/element/breadcrumbs.php | 12 +- app/vendor/autoload.php | 5 - app/vendor/bin/composer | 118 +- app/vendor/bin/doctrine-dbal | 118 +- app/vendor/bin/phinx | 118 +- app/vendor/bin/php-parse | 118 +- app/vendor/bin/phpcbf | 118 +- app/vendor/bin/phpcs | 118 +- app/vendor/bin/phpunit | 121 +- app/vendor/bin/psysh | 118 +- app/vendor/bin/var-dump-server | 118 +- app/vendor/brick/varexporter/CHANGELOG.md | 120 + app/vendor/brick/varexporter/composer.json | 2 +- .../src/Internal/GenericExporter.php | 34 +- .../ObjectExporter/AnyObjectExporter.php | 34 +- .../ObjectExporter/ClosureExporter.php | 2 +- .../Internal/ObjectExporter/EnumExporter.php | 39 + .../ObjectExporter/InternalClassExporter.php | 2 +- .../ObjectExporter/SerializeExporter.php | 2 +- .../ObjectExporter/SetStateExporter.php | 2 +- .../ObjectExporter/StdClassExporter.php | 2 +- .../brick/varexporter/src/VarExporter.php | 20 +- app/vendor/cakephp-plugins.php | 1 + app/vendor/cakephp/bake/composer.json | 5 +- .../cakephp/bake/src/CodeGen/ClassBuilder.php | 89 + .../cakephp/bake/src/CodeGen/CodeParser.php | 255 + .../cakephp/bake/src/CodeGen/FileBuilder.php | 114 + .../cakephp/bake/src/CodeGen/ImportHelper.php | 88 + .../bake/src/CodeGen/ParseException.php | 23 + .../cakephp/bake/src/CodeGen/ParsedClass.php | 64 + .../cakephp/bake/src/CodeGen/ParsedFile.php | 69 + .../cakephp/bake/src/Command/BakeCommand.php | 61 + .../cakephp/bake/src/Command/CellCommand.php | 2 +- .../bake/src/Command/ControllerCommand.php | 10 +- .../bake/src/Command/FixtureCommand.php | 15 +- .../cakephp/bake/src/Command/ModelCommand.php | 203 +- .../bake/src/Command/PluginCommand.php | 37 +- .../bake/src/Command/SimpleBakeCommand.php | 11 +- .../bake/src/Command/TemplateCommand.php | 23 +- .../cakephp/bake/src/Command/TestCommand.php | 51 +- .../bake/src/Utility/CommonOptionsTrait.php | 9 +- .../bake/src/Utility/TemplateRenderer.php | 6 +- app/vendor/cakephp/bake/src/View/BakeView.php | 7 +- .../bake/src/View/Helper/BakeHelper.php | 110 + .../bake/templates/bake/Command/command.twig | 18 +- .../bake/templates/bake/Command/helper.twig | 12 +- .../templates/bake/Controller/component.twig | 14 +- .../templates/bake/Controller/controller.twig | 12 +- .../bake/templates/bake/Form/form.twig | 16 +- .../bake/templates/bake/Mailer/mailer.twig | 12 +- .../templates/bake/Middleware/middleware.twig | 18 +- .../bake/templates/bake/Model/behavior.twig | 14 +- .../bake/templates/bake/Model/entity.twig | 29 +- .../bake/templates/bake/Model/table.twig | 32 +- .../bake/Plugin/phpunit.xml.dist.twig | 2 +- .../src/Controller/AppController.php.twig | 12 +- .../templates/bake/Plugin/src/Plugin.php.twig | 26 +- .../bake/Plugin/tests/bootstrap.php.twig | 9 +- .../bake/templates/bake/Shell/helper.twig | 12 +- .../bake/templates/bake/Template/index.twig | 2 +- .../bake/templates/bake/View/cell.twig | 12 +- .../bake/templates/bake/View/helper.twig | 14 +- .../templates/bake/element/file_header.twig | 4 + .../bake/templates/bake/tests/fixture.twig | 12 +- .../bake/templates/bake/tests/test_case.twig | 13 +- app/vendor/cakephp/bake/tests/schema.php | 23 + .../.github/workflows/ci.yml | 4 +- .../cakephp-codesniffer/CakePHP/ruleset.xml | 1 + .../cakephp/cakephp-codesniffer/composer.json | 7 +- app/vendor/cakephp/cakephp/README.md | 5 +- app/vendor/cakephp/cakephp/VERSION.txt | 2 +- app/vendor/cakephp/cakephp/composer.json | 12 +- .../cakephp/cakephp/config/bootstrap.php | 2 +- .../cakephp/cakephp/src/Cache/CacheEngine.php | 5 +- .../cakephp/src/Cache/Engine/ArrayEngine.php | 2 +- .../cakephp/src/Cache/Engine/FileEngine.php | 11 +- .../cakephp/src/Cache/Engine/RedisEngine.php | 50 +- .../cakephp/cakephp/src/Cache/composer.json | 2 +- .../cakephp/src/Collection/Collection.php | 9 +- .../cakephp/src/Collection/composer.json | 2 +- .../cakephp/cakephp/src/Command/Command.php | 8 + .../src/Command/I18nExtractCommand.php | 8 +- .../src/Command/RoutesCheckCommand.php | 2 +- .../cakephp/src/Command/RoutesCommand.php | 50 +- .../cakephp/src/Console/BaseCommand.php | 17 +- .../cakephp/cakephp/src/Console/Command.php | 6 +- .../src/Console/Command/HelpCommand.php | 12 +- .../cakephp/src/Console/CommandCollection.php | 10 +- .../CommandCollectionAwareInterface.php | 10 +- .../cakephp/src/Console/CommandFactory.php | 10 +- .../src/Console/CommandFactoryInterface.php | 10 +- .../cakephp/src/Console/CommandRunner.php | 10 +- .../cakephp/src/Console/CommandScanner.php | 10 +- .../src/Console/ConsoleErrorHandler.php | 5 +- .../src/Console/ConsoleInputArgument.php | 3 +- .../src/Console/ConsoleInputOption.php | 38 +- .../cakephp/cakephp/src/Console/ConsoleIo.php | 1 + .../src/Console/ConsoleOptionParser.php | 34 +- .../cakephp/src/Console/ConsoleOutput.php | 24 +- .../cakephp/cakephp/src/Console/Shell.php | 7 +- .../cakephp/src/Console/ShellDispatcher.php | 4 +- .../TestSuite/ConsoleIntegrationTestTrait.php | 345 ++ .../TestSuite/Constraint/ContentsBase.php | 48 + .../TestSuite/Constraint/ContentsContain.php | 45 + .../Constraint/ContentsContainRow.php | 61 + .../TestSuite/Constraint/ContentsEmpty.php | 56 + .../Constraint/ContentsNotContain.php | 45 + .../TestSuite/Constraint/ContentsRegExp.php | 54 + .../Console/TestSuite/Constraint/ExitCode.php | 62 + .../Console/TestSuite/LegacyCommandRunner.php | 39 + .../TestSuite/LegacyShellDispatcher.php | 64 + .../MissingConsoleInputException.php | 39 + .../Console/TestSuite/StubConsoleInput.php | 88 + .../Console/TestSuite/StubConsoleOutput.php | 84 + .../cakephp/cakephp/src/Console/composer.json | 2 +- .../cakephp/src/Controller/Component.php | 1 + .../Component/CheckHttpCacheComponent.php | 54 + .../Component/PaginatorComponent.php | 41 +- .../Component/RequestHandlerComponent.php | 30 +- .../cakephp/src/Controller/Controller.php | 132 +- .../src/Controller/ControllerFactory.php | 9 +- .../cakephp/cakephp/src/Core/Configure.php | 8 +- .../cakephp/cakephp/src/Core/Container.php | 3 - .../Core/ContainerApplicationInterface.php | 3 - .../cakephp/src/Core/ContainerInterface.php | 3 - .../cakephp/src/Core/PluginCollection.php | 23 +- .../cakephp/src/Core/ServiceProvider.php | 3 - .../src/Core/TestSuite/ContainerStubTrait.php | 174 + .../cakephp/cakephp/src/Core/composer.json | 2 +- .../cakephp/cakephp/src/Core/functions.php | 4 +- .../cakephp/src/Database/Connection.php | 51 +- .../cakephp/src/Database/Driver/Sqlite.php | 29 +- .../cakephp/src/Database/Driver/Sqlserver.php | 8 + .../Exception/MissingDriverException.php | 2 +- .../Expression/CaseExpressionTrait.php | 3 + .../Database/Expression/QueryExpression.php | 6 +- .../Expression/WhenThenExpression.php | 2 +- .../Database/Expression/WindowExpression.php | 4 +- .../src/Database/FieldTypeConverter.php | 2 +- .../cakephp/src/Database/IdentifierQuoter.php | 6 +- .../src/Database/Log/LoggingStatement.php | 10 +- .../cakephp/src/Database/Log/QueryLogger.php | 2 +- .../cakephp/cakephp/src/Database/Query.php | 51 +- .../cakephp/cakephp/src/Database/README.md | 26 +- .../src/Database/Retry/ReconnectStrategy.php | 4 +- .../Database/Schema/MysqlSchemaDialect.php | 4 +- .../Database/Schema/SqlGeneratorInterface.php | 10 +- .../src/Database/Schema/TableSchema.php | 2 +- .../Schema/TableSchemaAwareInterface.php | 10 +- .../Database/Schema/TableSchemaInterface.php | 10 +- .../Database/Type/BatchCastingInterface.php | 2 +- .../cakephp/src/Database/Type/BoolType.php | 16 +- .../src/Database/Type/DateTimeType.php | 8 +- .../cakephp/src/Database/Type/IntegerType.php | 2 +- .../cakephp/cakephp/src/Database/TypeMap.php | 22 +- .../cakephp/src/Database/TypeMapTrait.php | 4 +- .../cakephp/src/Database/composer.json | 5 +- .../src/Datasource/ConnectionInterface.php | 4 +- .../cakephp/src/Datasource/EntityTrait.php | 8 +- .../Exception/PageOutOfBoundsException.php | 29 +- .../cakephp/src/Datasource/FactoryLocator.php | 27 +- .../Datasource/InvalidPropertyInterface.php | 2 +- .../Datasource/Locator/AbstractLocator.php | 2 +- .../cakephp/src/Datasource/Paginator.php | 680 +-- .../src/Datasource/PaginatorInterface.php | 42 +- .../Exception/PageOutOfBoundsException.php | 32 + .../Datasource/Paging/NumericPaginator.php | 689 +++ .../Datasource/Paging/PaginatorInterface.php | 50 + .../src/Datasource/Paging/SimplePaginator.php | 49 + .../cakephp/src/Datasource/QueryInterface.php | 4 +- .../cakephp/src/Datasource/QueryTrait.php | 12 +- .../src/Datasource/RepositoryInterface.php | 2 +- .../cakephp/src/Datasource/RuleInvoker.php | 2 +- .../src/Datasource/SchemaInterface.php | 10 +- .../src/Datasource/SimplePaginator.php | 41 +- .../cakephp/src/Datasource/composer.json | 2 +- .../cakephp/src/Error/BaseErrorHandler.php | 11 + .../cakephp/src/Error/ConsoleErrorHandler.php | 7 + .../cakephp/cakephp/src/Error/Debugger.php | 77 +- .../cakephp/src/Error/ErrorHandler.php | 2 +- .../cakephp/cakephp/src/Error/ErrorLogger.php | 82 +- .../src/Error/ErrorLoggerInterface.php | 7 + .../src/Error/ErrorRendererInterface.php | 43 + .../cakephp/cakephp/src/Error/ErrorTrap.php | 208 + .../cakephp/src/Error/ExceptionRenderer.php | 455 +- .../src/Error/ExceptionRendererInterface.php | 6 +- .../cakephp/src/Error/ExceptionTrap.php | 391 ++ .../Middleware/ErrorHandlerMiddleware.php | 111 +- .../cakephp/cakephp/src/Error/PhpError.php | 191 + .../Error/Renderer/ConsoleErrorRenderer.php | 84 + .../Renderer/ConsoleExceptionRenderer.php | 137 + .../src/Error/Renderer/HtmlErrorRenderer.php | 104 + .../src/Error/Renderer/TextErrorRenderer.php | 56 + .../Error/Renderer/TextExceptionRenderer.php | 73 + .../Error/Renderer/WebExceptionRenderer.php | 504 ++ .../cakephp/cakephp/src/Event/Event.php | 5 +- .../cakephp/src/Event/EventInterface.php | 3 + .../cakephp/src/Event/EventManager.php | 5 +- .../src/Event/EventManagerInterface.php | 10 +- .../cakephp/cakephp/src/Event/composer.json | 2 +- .../cakephp/src/Filesystem/Filesystem.php | 4 +- .../cakephp/cakephp/src/Filesystem/Folder.php | 5 +- .../cakephp/src/Filesystem/composer.json | 2 +- .../cakephp/cakephp/src/Form/composer.json | 2 +- .../cakephp/src/Http/BaseApplication.php | 7 +- .../src/Http/Client/Adapter/Stream.php | 8 +- .../cakephp/src/Http/Client/FormData.php | 12 +- .../cakephp/src/Http/Client/Response.php | 2 +- .../src/Http/ContentTypeNegotiation.php | 165 + .../cakephp/src/Http/Cookie/Cookie.php | 14 +- .../src/Http/Cookie/CookieCollection.php | 10 +- .../src/Http/Cookie/CookieInterface.php | 10 +- .../src/Http/Exception/HttpException.php | 6 +- .../Exception/MissingControllerException.php | 7 + .../Http/Middleware/BodyParserMiddleware.php | 10 +- .../src/Http/Middleware/CspMiddleware.php | 10 +- .../Middleware/CsrfProtectionMiddleware.php | 14 +- .../Middleware/EncryptedCookieMiddleware.php | 10 +- .../Middleware/HttpsEnforcerMiddleware.php | 49 +- .../Middleware/SecurityHeadersMiddleware.php | 12 +- .../SessionCsrfProtectionMiddleware.php | 12 +- .../cakephp/cakephp/src/Http/Response.php | 59 +- .../cakephp/cakephp/src/Http/Runner.php | 13 +- .../cakephp/src/Http/ServerRequest.php | 149 +- .../cakephp/src/Http/ServerRequestFactory.php | 52 +- .../cakephp/cakephp/src/Http/Session.php | 14 +- .../cakephp/src/Http/Session/CacheSession.php | 2 +- .../src/Http/TestSuite/HttpClientTrait.php | 117 + app/vendor/cakephp/cakephp/src/Http/Uri.php | 255 + .../cakephp/cakephp/src/Http/composer.json | 2 +- app/vendor/cakephp/cakephp/src/I18n/Date.php | 6 +- .../cakephp/src/I18n/DateFormatTrait.php | 35 +- .../cakephp/src/I18n/FormatterLocator.php | 11 +- .../cakephp/cakephp/src/I18n/FrozenDate.php | 6 +- .../cakephp/cakephp/src/I18n/FrozenTime.php | 6 +- .../src/I18n/I18nDateTimeInterface.php | 4 +- .../cakephp/src/I18n/PackageLocator.php | 8 +- app/vendor/cakephp/cakephp/src/I18n/Time.php | 6 +- .../cakephp/cakephp/src/I18n/Translator.php | 5 + .../cakephp/src/I18n/TranslatorRegistry.php | 5 +- .../cakephp/cakephp/src/I18n/composer.json | 2 +- .../cakephp/src/Log/Engine/ArrayLog.php | 2 +- app/vendor/cakephp/cakephp/src/Log/README.md | 20 +- .../cakephp/cakephp/src/Log/composer.json | 2 +- .../cakephp/cakephp/src/Mailer/Email.php | 12 +- .../cakephp/cakephp/src/Mailer/Mailer.php | 7 + .../src/Mailer/Transport/SmtpTransport.php | 73 +- .../cakephp/cakephp/src/Network/Socket.php | 4 +- .../cakephp/cakephp/src/ORM/Association.php | 59 +- .../src/ORM/Association/BelongsToMany.php | 33 +- .../ORM/Association/DependentDeleteHelper.php | 10 +- .../ORM/Association/Loader/SelectLoader.php | 2 +- .../cakephp/src/ORM/AssociationCollection.php | 9 +- .../Translate/ShadowTableStrategy.php | 9 +- .../Translate/TranslateStrategyInterface.php | 10 +- .../cakephp/src/ORM/Behavior/TreeBehavior.php | 14 +- .../cakephp/src/ORM/BehaviorRegistry.php | 4 +- .../cakephp/cakephp/src/ORM/EagerLoadable.php | 6 +- .../cakephp/cakephp/src/ORM/EagerLoader.php | 5 +- .../cakephp/src/ORM/LazyEagerLoader.php | 4 +- .../src/ORM/Locator/LocatorAwareTrait.php | 8 +- .../cakephp/src/ORM/Locator/TableLocator.php | 2 - .../cakephp/cakephp/src/ORM/Marshaller.php | 2 +- app/vendor/cakephp/cakephp/src/ORM/Query.php | 4 +- .../cakephp/cakephp/src/ORM/ResultSet.php | 15 +- .../cakephp/cakephp/src/ORM/Rule/IsUnique.php | 2 +- .../cakephp/src/ORM/SaveOptionsBuilder.php | 7 +- app/vendor/cakephp/cakephp/src/ORM/Table.php | 98 +- .../cakephp/cakephp/src/ORM/composer.json | 2 +- .../Exception/FailedRouteCacheException.php | 26 + .../Exception/MissingControllerException.php | 5 +- .../Routing/Middleware/AssetMiddleware.php | 4 +- .../Routing/Middleware/RoutingMiddleware.php | 33 +- .../cakephp/src/Routing/Route/Route.php | 19 +- .../cakephp/src/Routing/RouteBuilder.php | 8 +- .../cakephp/src/Routing/RouteCollection.php | 64 +- .../cakephp/cakephp/src/Routing/Router.php | 14 +- .../TestSuite/ConsoleIntegrationTestCase.php | 10 +- .../TestSuite/ConsoleIntegrationTestTrait.php | 345 +- .../Constraint/Console/ContentsBase.php | 46 +- .../Constraint/Console/ContentsContain.php | 43 +- .../Constraint/Console/ContentsContainRow.php | 59 +- .../Constraint/Console/ContentsEmpty.php | 54 +- .../Constraint/Console/ContentsNotContain.php | 43 +- .../Constraint/Console/ContentsRegExp.php | 52 +- .../TestSuite/Constraint/Console/ExitCode.php | 60 +- .../Constraint/Email/MailSentWith.php | 9 +- .../src/TestSuite/Constraint/EventFired.php | 8 +- .../Constraint/Response/BodyContains.php | 8 +- .../Constraint/Response/BodyEmpty.php | 8 +- .../Constraint/Response/BodyEquals.php | 8 +- .../Constraint/Response/BodyNotContains.php | 8 +- .../Constraint/Response/BodyNotEmpty.php | 8 +- .../Constraint/Response/BodyNotEquals.php | 8 +- .../Constraint/Response/BodyNotRegExp.php | 8 +- .../Constraint/Response/BodyRegExp.php | 8 +- .../Constraint/Response/ContentType.php | 8 +- .../Response/CookieEncryptedEquals.php | 8 +- .../Constraint/Response/CookieEquals.php | 8 +- .../Constraint/Response/CookieNotSet.php | 8 +- .../Constraint/Response/CookieSet.php | 8 +- .../Constraint/Response/FileSent.php | 8 +- .../Constraint/Response/FileSentAs.php | 16 +- .../Constraint/Response/HeaderContains.php | 8 +- .../Constraint/Response/HeaderEquals.php | 8 +- .../Constraint/Response/HeaderNotContains.php | 8 +- .../Constraint/Response/HeaderNotSet.php | 8 +- .../Constraint/Response/HeaderSet.php | 8 +- .../Constraint/Response/ResponseBase.php | 8 +- .../Constraint/Response/StatusCode.php | 8 +- .../Constraint/Response/StatusCodeBase.php | 8 +- .../Constraint/Response/StatusError.php | 8 +- .../Constraint/Response/StatusFailure.php | 8 +- .../Constraint/Response/StatusOk.php | 8 +- .../Constraint/Response/StatusSuccess.php | 8 +- .../Constraint/Session/FlashParamEquals.php | 8 +- .../Constraint/Session/SessionEquals.php | 8 +- .../Constraint/Session/SessionHasKey.php | 8 +- .../Constraint/View/LayoutFileEquals.php | 8 +- .../Constraint/View/TemplateFileEquals.php | 8 +- .../src/TestSuite/ContainerStubTrait.php | 167 +- .../cakephp/src/TestSuite/EmailTrait.php | 4 +- .../src/TestSuite/Fixture/FixtureHelper.php | 4 +- .../cakephp/src/TestSuite/HttpClientTrait.php | 115 +- .../src/TestSuite/IntegrationTestTrait.php | 39 +- .../src/TestSuite/LegacyCommandRunner.php | 37 +- .../src/TestSuite/LegacyShellDispatcher.php | 62 +- .../src/TestSuite/MiddlewareDispatcher.php | 5 +- .../src/TestSuite/Stub/ConsoleInput.php | 86 +- .../src/TestSuite/Stub/ConsoleOutput.php | 82 +- .../Stub/MissingConsoleInputException.php | 33 +- .../TestSuite/Stub/TestExceptionRenderer.php | 23 +- .../src/TestSuite/TestEmailTransport.php | 3 +- .../cakephp/cakephp/src/Utility/Hash.php | 34 +- .../cakephp/cakephp/src/Utility/Inflector.php | 2 +- .../cakephp/cakephp/src/Utility/Security.php | 10 +- .../cakephp/cakephp/src/Utility/Text.php | 17 +- .../cakephp/cakephp/src/Utility/Xml.php | 4 +- .../cakephp/cakephp/src/Utility/composer.json | 2 +- .../src/Validation/ValidatableInterface.php | 2 + .../cakephp/src/Validation/Validation.php | 12 +- .../cakephp/src/Validation/ValidationRule.php | 4 +- .../cakephp/src/Validation/Validator.php | 6 +- .../Validation/ValidatorAwareInterface.php | 10 +- .../cakephp/src/Validation/composer.json | 2 +- .../cakephp/cakephp/src/View/AjaxView.php | 9 +- app/vendor/cakephp/cakephp/src/View/Cell.php | 1 + .../cakephp/cakephp/src/View/CellTrait.php | 3 +- .../cakephp/src/View/Form/ArrayContext.php | 2 +- .../cakephp/src/View/Form/EntityContext.php | 6 +- .../cakephp/src/View/Form/FormContext.php | 28 +- .../cakephp/cakephp/src/View/Helper.php | 1 + .../src/View/Helper/BreadcrumbsHelper.php | 4 +- .../cakephp/src/View/Helper/FormHelper.php | 37 +- .../cakephp/src/View/Helper/HtmlHelper.php | 4 +- .../cakephp/cakephp/src/View/JsonView.php | 17 +- .../src/View/NegotiationRequiredView.php | 62 + .../cakephp/src/View/SerializedView.php | 6 +- .../cakephp/src/View/StringTemplate.php | 6 +- app/vendor/cakephp/cakephp/src/View/View.php | 61 +- .../cakephp/cakephp/src/View/XmlView.php | 17 +- app/vendor/cakephp/cakephp/src/basics.php | 2 +- .../element/exception_stack_trace.php | 98 +- .../element/exception_stack_trace_nav.php | 52 +- .../cakephp/templates/layout/dev_error.php | 4 + .../Fixture/CompositeKeyArticlesFixture.php | 22 + .../CompositeKeyArticlesTagsFixture.php | 22 + .../Fixture/NumberTreesArticlesFixture.php | 48 + .../cakephp/tests/Fixture/ProfilesFixture.php | 10 +- app/vendor/cakephp/cakephp/tests/phpstan.neon | 17 + app/vendor/cakephp/cakephp/tests/schema.php | 82 + app/vendor/cakephp/chronos/composer.json | 12 +- app/vendor/cakephp/chronos/docs.Dockerfile | 10 +- .../chronos/src/DifferenceFormatter.php | 10 +- .../chronos/src/Traits/DifferenceTrait.php | 2 +- .../chronos/src/Traits/ModifierTrait.php | 46 +- app/vendor/cakephp/debug_kit/.eslintrc.json | 26 + app/vendor/cakephp/debug_kit/composer.json | 22 +- .../cakephp/debug_kit/config/bootstrap.php | 8 +- app/vendor/cakephp/debug_kit/docs.Dockerfile | 2 +- .../cakephp/debug_kit/docs/en/index.rst | 14 + .../cakephp/debug_kit/docs/pt/index.rst | 4 +- app/vendor/cakephp/debug_kit/package.json | 29 + .../cakephp/debug_kit/phpstan-baseline.neon | 36 + app/vendor/cakephp/debug_kit/phpstan.neon | 13 + .../cakephp/debug_kit/psalm-baseline.xml | 16 - app/vendor/cakephp/debug_kit/psalm.xml | 3 +- .../src/Cache/Engine/DebugEngine.php | 27 +- .../src/Command/BenchmarkCommand.php | 46 +- .../src/Controller/ComposerController.php | 12 +- .../src/Controller/DashboardController.php | 11 +- .../src/Controller/DebugKitController.php | 10 +- .../src/Controller/MailPreviewController.php | 30 +- .../src/Controller/PanelsController.php | 10 +- .../src/Controller/RequestsController.php | 10 +- .../src/Controller/ToolbarController.php | 24 +- .../debug_kit/src/Database/Log/DebugLog.php | 10 +- .../cakephp/debug_kit/src/DebugInclude.php | 10 +- .../cakephp/debug_kit/src/DebugMemory.php | 10 +- .../cakephp/debug_kit/src/DebugPanel.php | 10 +- app/vendor/cakephp/debug_kit/src/DebugSql.php | 20 +- .../cakephp/debug_kit/src/DebugTimer.php | 12 +- .../debug_kit/src/Locale/debug_kit.pot | 138 - .../src/Locale/eng/LC_MESSAGES/debug_kit.po | 135 - .../src/Locale/fra/LC_MESSAGES/debug_kit.po | 135 - .../src/Locale/lim/LC_MESSAGES/debug_kit.po | 136 - .../src/Locale/nld/LC_MESSAGES/debug_kit.po | 141 - .../src/Locale/pt_BR/LC_MESSAGES/debug_kit.po | 135 - .../src/Locale/spa/LC_MESSAGES/debug_kit.po | 135 - .../debug_kit/src/Log/Engine/DebugKitLog.php | 10 +- .../debug_kit/src/Mailer/AbstractResult.php | 10 +- .../debug_kit/src/Mailer/MailPreview.php | 14 +- .../debug_kit/src/Mailer/PreviewResult.php | 10 +- .../debug_kit/src/Mailer/SentMailResult.php | 10 +- .../Mailer/Transport/DebugKitTransport.php | 2 +- .../src/Middleware/DebugKitMiddleware.php | 9 +- .../src/Model/Behavior/TimedBehavior.php | 10 +- .../debug_kit/src/Model/Entity/Panel.php | 8 +- .../src/Model/Table/LazyTableTrait.php | 8 +- .../debug_kit/src/Model/Table/PanelsTable.php | 12 +- .../src/Model/Table/RequestsTable.php | 11 +- .../debug_kit/src/Panel/CachePanel.php | 11 +- .../debug_kit/src/Panel/DeprecationsPanel.php | 20 +- .../debug_kit/src/Panel/EnvironmentPanel.php | 14 +- .../debug_kit/src/Panel/HistoryPanel.php | 10 +- .../debug_kit/src/Panel/IncludePanel.php | 10 +- .../cakephp/debug_kit/src/Panel/LogPanel.php | 11 +- .../cakephp/debug_kit/src/Panel/MailPanel.php | 10 +- .../debug_kit/src/Panel/PackagesPanel.php | 10 +- .../debug_kit/src/Panel/PanelRegistry.php | 12 +- .../debug_kit/src/Panel/RequestPanel.php | 24 +- .../debug_kit/src/Panel/RoutesPanel.php | 10 +- .../debug_kit/src/Panel/SessionPanel.php | 12 +- .../debug_kit/src/Panel/SqlLogPanel.php | 10 +- .../debug_kit/src/Panel/TimerPanel.php | 10 +- .../debug_kit/src/Panel/VariablesPanel.php | 15 +- app/vendor/cakephp/debug_kit/src/Plugin.php | 62 +- .../cakephp/debug_kit/src/ToolbarService.php | 24 +- .../cakephp/debug_kit/src/View/AjaxView.php | 10 +- .../src/View/Helper/CredentialsHelper.php | 12 +- .../src/View/Helper/SimpleGraphHelper.php | 14 +- .../src/View/Helper/ToolbarHelper.php | 110 +- .../debug_kit/templates/Dashboard/index.php | 12 +- .../debug_kit/templates/MailPreview/email.php | 8 +- .../debug_kit/templates/MailPreview/index.php | 26 +- .../debug_kit/templates/Panels/view.php | 4 +- .../debug_kit/templates/Requests/view.php | 65 +- .../templates/element/cache_panel.php | 182 +- .../templates/element/deprecations_panel.php | 59 +- .../templates/element/environment_panel.php | 216 +- .../templates/element/history_panel.php | 226 +- .../templates/element/include_panel.php | 20 +- .../debug_kit/templates/element/log_panel.php | 54 +- .../templates/element/mail_panel.php | 93 +- .../templates/element/packages_panel.php | 218 +- .../templates/element/preview_header.php | 5 + .../templates/element/request_panel.php | 94 +- .../templates/element/routes_panel.php | 125 +- .../templates/element/session_panel.php | 14 +- .../templates/element/sql_log_panel.php | 122 +- .../templates/element/timer_panel.php | 162 +- .../templates/element/variables_panel.php | 86 +- .../debug_kit/templates/layout/dashboard.php | 2 +- .../debug_kit/templates/layout/mailer.php | 2 +- .../debug_kit/templates/layout/toolbar.php | 8 +- .../cakephp/debug_kit/webroot/css/reset.css | 37 +- .../cakephp/debug_kit/webroot/css/style.css | 693 +++ .../cakephp/debug_kit/webroot/css/toolbar.css | 651 --- .../cakephp/debug_kit/webroot/js/debug_kit.js | 25 - .../js/{toolbar.js => inject-iframe.js} | 91 +- .../cakephp/debug_kit/webroot/js/jquery.js | 6 +- .../cakephp/debug_kit/webroot/js/main.js | 24 + .../debug_kit/webroot/js/modules/Helper.js | 18 + .../debug_kit/webroot/js/modules/Keyboard.js | 41 + .../webroot/js/modules/Panels/CachePanel.js | 43 + .../webroot/js/modules/Panels/HistoryPanel.js | 74 + .../webroot/js/modules/Panels/MailPanel.js | 27 + .../js/modules/Panels/PackagesPanel.js | 63 + .../webroot/js/modules/Panels/RoutesPanel.js | 28 + .../js/modules/Panels/VariablesPanel.js | 24 + .../debug_kit/webroot/js/modules/Start.js | 28 + .../debug_kit/webroot/js/modules/Toolbar.js | 248 + .../debug_kit/webroot/js/toolbar-app.js | 329 -- app/vendor/cakephp/migrations/LICENSE.txt | 2 +- app/vendor/cakephp/migrations/README.md | 6 +- app/vendor/cakephp/migrations/composer.json | 14 +- .../cakephp/migrations/docs/en/index.rst | 30 +- .../cakephp/migrations/docs/fr/index.rst | 2 +- .../cakephp/migrations/docs/ja/index.rst | 4 +- .../cakephp/migrations/docs/ru/index.rst | 2 +- app/vendor/cakephp/migrations/phpcs.xml | 29 + .../cakephp/migrations/psalm-baseline.xml | 53 - app/vendor/cakephp/migrations/psalm.xml | 5 +- .../migrations/src/AbstractMigration.php | 14 +- .../cakephp/migrations/src/AbstractSeed.php | 8 +- .../cakephp/migrations/src/CakeAdapter.php | 13 +- .../cakephp/migrations/src/CakeManager.php | 63 +- .../src/Command/BakeMigrationCommand.php | 39 +- .../src/Command/BakeMigrationDiffCommand.php | 14 +- .../Command/BakeMigrationSnapshotCommand.php | 10 +- .../src/Command/BakeSeedCommand.php | 18 +- .../Command/BakeSimpleMigrationCommand.php | 14 +- .../Command/MigrationsCacheBuildCommand.php | 8 +- .../Command/MigrationsCacheClearCommand.php | 8 +- .../src/Command/MigrationsCommand.php | 22 +- .../src/Command/MigrationsCreateCommand.php | 8 +- .../src/Command/MigrationsDumpCommand.php | 8 +- .../Command/MigrationsMarkMigratedCommand.php | 8 +- .../src/Command/MigrationsMigrateCommand.php | 8 +- .../src/Command/MigrationsRollbackCommand.php | 8 +- .../src/Command/MigrationsSeedCommand.php | 8 +- .../src/Command/MigrationsStatusCommand.php | 8 +- .../src/Command/Phinx/CacheBuild.php | 4 +- .../src/Command/Phinx/CacheClear.php | 4 +- .../src/Command/Phinx/CommandTrait.php | 16 +- .../migrations/src/Command/Phinx/Create.php | 32 +- .../migrations/src/Command/Phinx/Dump.php | 12 +- .../src/Command/Phinx/MarkMigrated.php | 13 +- .../migrations/src/Command/Phinx/Migrate.php | 14 +- .../migrations/src/Command/Phinx/Rollback.php | 14 +- .../migrations/src/Command/Phinx/Seed.php | 14 +- .../migrations/src/Command/Phinx/Status.php | 21 +- .../migrations/src/Command/SnapshotTrait.php | 8 +- .../migrations/src/ConfigurationTrait.php | 113 +- .../cakephp/migrations/src/Migrations.php | 15 +- .../migrations/src/MigrationsDispatcher.php | 16 +- app/vendor/cakephp/migrations/src/Plugin.php | 31 +- .../src/Shell/Task/SimpleMigrationTask.php | 12 +- app/vendor/cakephp/migrations/src/Table.php | 12 +- .../migrations/src/TableFinderTrait.php | 17 +- .../migrations/src/TestSuite/Migrator.php | 8 +- .../migrations/src/Util/ColumnParser.php | 3 +- .../migrations/src/Util/SchemaTrait.php | 8 +- .../cakephp/migrations/src/Util/UtilTrait.php | 8 +- .../src/View/Helper/MigrationHelper.php | 16 +- .../templates/Phinx/create.php.template | 2 +- .../migrations/templates/bake/Seed/seed.twig | 12 +- .../templates/bake/config/diff.twig | 14 +- .../templates/bake/config/skeleton.twig | 14 +- .../templates/bake/config/snapshot.twig | 14 +- app/vendor/composer/ClassLoader.php | 2 +- app/vendor/composer/InstalledVersions.php | 2 - app/vendor/composer/autoload_classmap.php | 29 +- app/vendor/composer/autoload_files.php | 23 +- app/vendor/composer/autoload_namespaces.php | 2 +- app/vendor/composer/autoload_psr4.php | 16 +- app/vendor/composer/autoload_real.php | 40 +- app/vendor/composer/autoload_static.php | 114 +- app/vendor/composer/ca-bundle/res/cacert.pem | 818 ++-- .../class-map-generator}/LICENSE | 24 +- .../composer/class-map-generator/README.md | 66 + .../class-map-generator/composer.json | 48 + .../class-map-generator/src/ClassMap.php | 131 + .../src/ClassMapGenerator.php | 334 ++ .../class-map-generator/src/FileList.php | 42 + .../src/PhpFileCleaner.php | 247 + .../class-map-generator/src/PhpFileParser.php | 150 + app/vendor/composer/composer/.gitattributes | 3 +- .../composer/composer/.php-cs-fixer.php | 90 + app/vendor/composer/composer/CHANGELOG.md | 217 +- .../composer/composer/CODE_OF_CONDUCT.md | 153 +- app/vendor/composer/composer/README.md | 12 +- app/vendor/composer/composer/composer.json | 22 +- app/vendor/composer/composer/composer.lock | 565 ++- app/vendor/composer/composer/doc/00-intro.md | 41 +- .../composer/composer/doc/01-basic-usage.md | 10 +- app/vendor/composer/composer/doc/03-cli.md | 303 +- app/vendor/composer/composer/doc/04-schema.md | 37 +- .../composer/composer/doc/05-repositories.md | 29 +- app/vendor/composer/composer/doc/06-config.md | 16 +- .../composer/composer/doc/07-runtime.md | 4 + .../composer/composer/doc/08-community.md | 4 +- .../composer/composer/doc/articles/aliases.md | 4 +- .../authentication-for-private-packages.md | 104 +- .../composer-platform-dependencies.md | 77 + .../doc/articles/handling-private-packages.md | 150 +- .../composer/composer/doc/articles/plugins.md | 35 + .../doc/articles/resolving-merge-conflicts.md | 94 +- .../composer/composer/doc/articles/scripts.md | 78 +- .../composer/doc/articles/troubleshooting.md | 40 +- .../composer/doc/articles/vendor-binaries.md | 2 +- .../composer/doc/articles/versions.md | 10 +- ...ow-to-install-composer-programmatically.md | 4 +- ...ow-to-install-untrusted-packages-safely.md | 22 +- ...-unbound-version-constraints-a-bad-idea.md | 2 +- ...-composer-load-repositories-recursively.md | 35 + .../composer/composer/phpstan/rules.neon | 14 + .../composer/res/composer-schema.json | 48 +- .../src/Composer/Advisory/Auditor.php | 191 + .../Advisory/PartialSecurityAdvisory.php | 71 + .../Composer/Advisory/SecurityAdvisory.php | 76 + .../Composer/Autoload/AutoloadGenerator.php | 333 +- .../src/Composer/Autoload/ClassLoader.php | 41 +- .../Composer/Autoload/ClassMapGenerator.php | 277 +- .../src/Composer/Autoload/PhpFileCleaner.php | 36 +- .../composer/composer/src/Composer/Cache.php | 80 +- .../src/Composer/Command/AboutCommand.php | 5 +- .../src/Composer/Command/ArchiveCommand.php | 59 +- .../src/Composer/Command/AuditCommand.php | 92 + .../src/Composer/Command/BaseCommand.php | 83 +- .../Command/BaseDependencyCommand.php | 92 +- .../src/Composer/Command/BumpCommand.php | 246 + .../Command/CheckPlatformReqsCommand.php | 91 +- .../Composer/Command/ClearCacheCommand.php | 41 +- .../src/Composer/Command/CompletionTrait.php | 214 + .../src/Composer/Command/ConfigCommand.php | 520 +- .../Composer/Command/CreateProjectCommand.php | 140 +- .../src/Composer/Command/DependsCommand.php | 21 +- .../src/Composer/Command/DiagnoseCommand.php | 83 +- .../Composer/Command/DumpAutoloadCommand.php | 22 +- .../src/Composer/Command/ExecCommand.php | 83 +- .../src/Composer/Command/FundCommand.php | 23 +- .../src/Composer/Command/GlobalCommand.php | 59 +- .../src/Composer/Command/HomeCommand.php | 34 +- .../src/Composer/Command/InitCommand.php | 127 +- .../src/Composer/Command/InstallCommand.php | 25 +- .../src/Composer/Command/LicensesCommand.php | 99 +- .../src/Composer/Command/OutdatedCommand.php | 33 +- .../Command/PackageDiscoveryTrait.php | 451 ++ .../src/Composer/Command/ProhibitsCommand.php | 21 +- .../src/Composer/Command/ReinstallCommand.php | 29 +- .../src/Composer/Command/RemoveCommand.php | 65 +- .../src/Composer/Command/RequireCommand.php | 260 +- .../src/Composer/Command/RunScriptCommand.php | 88 +- .../Composer/Command/ScriptAliasCommand.php | 25 +- .../src/Composer/Command/SearchCommand.php | 25 +- .../Composer/Command/SelfUpdateCommand.php | 45 +- .../src/Composer/Command/ShowCommand.php | 482 +- .../src/Composer/Command/StatusCommand.php | 36 +- .../src/Composer/Command/SuggestsCommand.php | 25 +- .../src/Composer/Command/UpdateCommand.php | 97 +- .../src/Composer/Command/ValidateCommand.php | 63 +- .../composer/src/Composer/Compiler.php | 47 +- .../composer/src/Composer/Composer.php | 7 +- .../composer/composer/src/Composer/Config.php | 155 +- .../Composer/Config/ConfigSourceInterface.php | 24 - .../src/Composer/Config/JsonConfigSource.php | 62 +- .../src/Composer/Console/Application.php | 177 +- .../Composer/Console/GithubActionError.php | 15 - .../Composer/Console/HtmlOutputFormatter.php | 17 +- .../Composer/Console/Input/InputArgument.php | 69 + .../Composer/Console/Input/InputOption.php | 72 + .../Composer/DependencyResolver/Decisions.php | 82 +- .../DependencyResolver/DefaultPolicy.php | 26 +- .../DependencyResolver/GenericRule.php | 13 +- .../DependencyResolver/LockTransaction.php | 27 +- .../DependencyResolver/MultiConflictRule.php | 13 +- .../Operation/InstallOperation.php | 6 - .../Operation/MarkAliasInstalledOperation.php | 2 - .../MarkAliasUninstalledOperation.php | 2 - .../Operation/SolverOperation.php | 2 - .../Operation/UninstallOperation.php | 6 - .../Operation/UpdateOperation.php | 8 - .../DependencyResolver/PolicyInterface.php | 4 - .../src/Composer/DependencyResolver/Pool.php | 44 +- .../DependencyResolver/PoolBuilder.php | 104 +- .../DependencyResolver/PoolOptimizer.php | 475 ++ .../Composer/DependencyResolver/Problem.php | 156 +- .../Composer/DependencyResolver/Request.php | 45 +- .../src/Composer/DependencyResolver/Rule.php | 185 +- .../DependencyResolver/Rule2Literals.php | 12 +- .../Composer/DependencyResolver/RuleSet.php | 48 +- .../DependencyResolver/RuleSetGenerator.php | 54 +- .../DependencyResolver/RuleSetIterator.php | 4 +- .../DependencyResolver/RuleWatchChain.php | 3 - .../DependencyResolver/RuleWatchGraph.php | 10 +- .../DependencyResolver/RuleWatchNode.php | 8 +- .../Composer/DependencyResolver/Solver.php | 89 +- .../DependencyResolver/SolverBugException.php | 3 - .../SolverProblemsException.php | 26 +- .../DependencyResolver/Transaction.php | 47 +- .../Composer/Downloader/ArchiveDownloader.php | 27 +- .../Composer/Downloader/DownloadManager.php | 42 +- .../Downloader/DownloaderInterface.php | 12 +- .../Composer/Downloader/FileDownloader.php | 79 +- .../Downloader/FilesystemException.php | 7 +- .../Composer/Downloader/FossilDownloader.php | 2 +- .../src/Composer/Downloader/GitDownloader.php | 94 +- .../Composer/Downloader/GzipDownloader.php | 6 - .../src/Composer/Downloader/HgDownloader.php | 6 +- .../Composer/Downloader/PathDownloader.php | 31 +- .../Downloader/PerforceDownloader.php | 16 +- .../src/Composer/Downloader/SvnDownloader.php | 18 +- .../Downloader/TransportException.php | 13 +- .../src/Composer/Downloader/VcsDownloader.php | 34 +- .../src/Composer/Downloader/ZipDownloader.php | 40 +- .../src/Composer/EventDispatcher/Event.php | 4 +- .../EventDispatcher/EventDispatcher.php | 145 +- .../ScriptExecutionException.php | 2 + .../composer/src/Composer/Factory.php | 151 +- .../IgnoreAllPlatformRequirementFilter.php | 23 + .../IgnoreListPlatformRequirementFilter.php | 88 + ...IgnoreNothingPlatformRequirementFilter.php | 24 + .../PlatformRequirementFilterFactory.php | 47 + .../PlatformRequirementFilterInterface.php | 18 + .../composer/src/Composer/IO/BaseIO.php | 64 +- .../composer/src/Composer/IO/BufferIO.php | 17 +- .../composer/src/Composer/IO/ConsoleIO.php | 45 +- .../composer/src/Composer/IO/IOInterface.php | 6 +- .../src/Composer/InstalledVersions.php | 14 +- .../composer/src/Composer/Installer.php | 296 +- .../Composer/Installer/BinaryInstaller.php | 61 +- .../Installer/InstallationManager.php | 311 +- .../src/Composer/Installer/InstallerEvent.php | 22 - .../Composer/Installer/InstallerInterface.php | 8 +- .../Composer/Installer/LibraryInstaller.php | 32 +- .../Installer/MetapackageInstaller.php | 6 +- .../src/Composer/Installer/NoopInstaller.php | 6 +- .../src/Composer/Installer/PackageEvent.php | 20 - .../Composer/Installer/PluginInstaller.php | 17 +- .../Composer/Installer/ProjectInstaller.php | 13 +- .../Installer/SuggestedPackagesReporter.php | 38 +- .../composer/src/Composer/Json/JsonFile.php | 38 +- .../src/Composer/Json/JsonFormatter.php | 15 +- .../src/Composer/Json/JsonManipulator.php | 147 +- .../Composer/Json/JsonValidationException.php | 3 +- .../PHPStan/ConfigReturnTypeExtension.php | 194 + .../RuleReasonDataReturnTypeExtension.php | 69 + .../src/Composer/Package/AliasPackage.php | 10 +- .../Archiver/ArchivableFilesFilter.php | 12 +- .../Archiver/ArchivableFilesFinder.php | 13 +- .../Package/Archiver/ArchiveManager.php | 142 +- .../Package/Archiver/ArchiverInterface.php | 2 +- .../Package/Archiver/BaseExcludeFilter.php | 14 +- .../Package/Archiver/GitExcludeFilter.php | 8 +- .../Package/Archiver/PharArchiver.php | 10 +- .../Composer/Package/Archiver/ZipArchiver.php | 9 +- .../src/Composer/Package/BasePackage.php | 46 +- .../Composer/Package/Comparer/Comparer.php | 26 +- .../src/Composer/Package/CompletePackage.php | 16 +- .../Package/CompletePackageInterface.php | 22 - .../Composer/Package/Dumper/ArrayDumper.php | 12 +- .../composer/src/Composer/Package/Link.php | 27 +- .../Composer/Package/Loader/ArrayLoader.php | 55 +- .../Loader/InvalidPackageException.php | 12 +- .../Package/Loader/RootPackageLoader.php | 37 +- .../Package/Loader/ValidatingArrayLoader.php | 110 +- .../composer/src/Composer/Package/Locker.php | 138 +- .../composer/src/Composer/Package/Package.php | 122 +- .../src/Composer/Package/PackageInterface.php | 55 +- .../src/Composer/Package/RootAliasPackage.php | 4 +- .../src/Composer/Package/RootPackage.php | 10 +- .../Composer/Package/RootPackageInterface.php | 51 +- .../Package/Version/VersionBumper.php | 119 + .../Package/Version/VersionGuesser.php | 74 +- .../Package/Version/VersionParser.php | 22 +- .../Package/Version/VersionSelector.php | 154 +- .../composer/src/Composer/PartialComposer.php | 115 + .../src/Composer/Platform/HhvmDetector.php | 8 +- .../src/Composer/Platform/Runtime.php | 27 +- .../src/Composer/Platform/Version.php | 44 +- .../src/Composer/Plugin/CommandEvent.php | 10 +- .../Plugin/PluginBlockedException.php | 19 + .../src/Composer/Plugin/PluginInterface.php | 9 - .../src/Composer/Plugin/PluginManager.php | 294 +- .../Composer/Plugin/PostFileDownloadEvent.php | 8 - .../Composer/Plugin/PreCommandRunEvent.php | 5 - .../Composer/Plugin/PreFileDownloadEvent.php | 29 +- .../Composer/Plugin/PrePoolCreateEvent.php | 7 - .../Question/StrictConfirmationQuestion.php | 8 +- .../Repository/AdvisoryProviderInterface.php | 34 + .../Composer/Repository/ArrayRepository.php | 39 +- .../Repository/ArtifactRepository.php | 11 +- .../Repository/CanonicalPackagesTrait.php | 55 + .../Repository/ComposerRepository.php | 442 +- .../Repository/CompositeRepository.php | 40 +- .../Repository/FilesystemRepository.php | 126 +- .../Composer/Repository/FilterRepository.php | 46 +- .../Repository/InstalledRepository.php | 37 +- .../Repository/LockArrayRepository.php | 2 + .../Composer/Repository/PackageRepository.php | 2 +- .../Composer/Repository/PathRepository.php | 22 +- .../Repository/PlatformRepository.php | 121 +- .../Composer/Repository/RepositoryFactory.php | 74 +- .../Repository/RepositoryInterface.php | 2 +- .../Composer/Repository/RepositoryManager.php | 23 +- .../src/Composer/Repository/RepositorySet.php | 138 +- .../Composer/Repository/RepositoryUtils.php | 78 + .../Repository/RootPackageRepository.php | 2 +- .../Composer/Repository/Vcs/FossilDriver.php | 14 +- .../Repository/Vcs/GitBitbucketDriver.php | 65 +- .../src/Composer/Repository/Vcs/GitDriver.php | 25 +- .../Composer/Repository/Vcs/GitHubDriver.php | 87 +- .../Composer/Repository/Vcs/GitLabDriver.php | 71 +- .../src/Composer/Repository/Vcs/HgDriver.php | 20 +- .../Repository/Vcs/PerforceDriver.php | 14 +- .../src/Composer/Repository/Vcs/SvnDriver.php | 28 +- .../src/Composer/Repository/Vcs/VcsDriver.php | 11 +- .../Repository/Vcs/VcsDriverInterface.php | 13 - .../src/Composer/Repository/VcsRepository.php | 40 +- .../Repository/VersionCacheInterface.php | 2 - .../Repository/WritableArrayRepository.php | 34 +- .../composer/src/Composer/Script/Event.php | 12 +- .../composer/src/Composer/SelfUpdate/Keys.php | 9 +- .../src/Composer/SelfUpdate/Versions.php | 24 +- .../composer/src/Composer/Util/AuthHelper.php | 56 +- .../composer/src/Composer/Util/Bitbucket.php | 57 +- .../src/Composer/Util/ComposerMirror.php | 35 +- .../src/Composer/Util/ConfigValidator.php | 24 +- .../src/Composer/Util/ErrorHandler.php | 17 +- .../composer/src/Composer/Util/Filesystem.php | 88 +- .../composer/src/Composer/Util/Git.php | 127 +- .../composer/src/Composer/Util/GitHub.php | 39 +- .../composer/src/Composer/Util/GitLab.php | 149 +- .../composer/src/Composer/Util/Hg.php | 20 +- .../src/Composer/Util/Http/CurlDownloader.php | 213 +- .../src/Composer/Util/Http/CurlResponse.php | 2 +- .../src/Composer/Util/Http/ProxyHelper.php | 20 +- .../src/Composer/Util/Http/ProxyManager.php | 29 +- .../src/Composer/Util/Http/RequestProxy.php | 2 - .../src/Composer/Util/Http/Response.php | 15 +- .../src/Composer/Util/HttpDownloader.php | 90 +- .../composer/src/Composer/Util/IniHelper.php | 2 - .../composer/src/Composer/Util/Loop.php | 20 +- .../src/Composer/Util/NoProxyPattern.php | 79 +- .../src/Composer/Util/PackageInfo.php | 33 + .../src/Composer/Util/PackageSorter.php | 63 +- .../composer/src/Composer/Util/Perforce.php | 140 +- .../composer/src/Composer/Util/Platform.php | 33 +- .../src/Composer/Util/ProcessExecutor.php | 71 +- .../src/Composer/Util/RemoteFilesystem.php | 65 +- .../composer/src/Composer/Util/Silencer.php | 4 +- .../Composer/Util/StreamContextFactory.php | 28 +- .../composer/src/Composer/Util/Svn.php | 48 +- .../composer/src/Composer/Util/SyncHelper.php | 11 +- .../composer/src/Composer/Util/Tar.php | 11 +- .../composer/src/Composer/Util/TlsHelper.php | 25 +- .../composer/src/Composer/Util/Url.php | 28 +- .../composer/src/Composer/Util/Zip.php | 12 +- app/vendor/composer/installed.json | 1489 +++--- app/vendor/composer/installed.php | 420 +- app/vendor/composer/pcre/README.md | 17 + .../composer/pcre/phpstan-baseline.neon | 17 - .../composer/pcre/src/MatchAllResult.php | 4 +- .../pcre/src/MatchAllStrictGroupsResult.php | 46 + .../pcre/src/MatchAllWithOffsetsResult.php | 2 +- app/vendor/composer/pcre/src/MatchResult.php | 2 +- .../pcre/src/MatchStrictGroupsResult.php | 39 + .../pcre/src/MatchWithOffsetsResult.php | 2 +- app/vendor/composer/pcre/src/Preg.php | 211 +- app/vendor/composer/pcre/src/Regex.php | 90 +- .../composer/pcre/src/ReplaceResult.php | 3 +- .../pcre/src/UnexpectedNullMatchException.php | 20 + app/vendor/composer/platform_check.php | 4 +- .../workflows/continuous-integration.yml | 60 + .../spdx-licenses/.github/workflows/lint.yml | 30 + .../.github/workflows/phpstan.yml | 51 + .../composer/spdx-licenses/CHANGELOG.md | 3 +- .../composer/spdx-licenses/phpstan.neon.dist | 9 + .../spdx-licenses/res/spdx-licenses.json | 57 +- .../spdx-licenses/src/SpdxLicenses.php | 4 +- .../.remarkrc | 6 - .../.yamllint | 8 - .../CODE_OF_CONDUCT.md | 129 - .../LICENSE.md | 3 +- .../README.md | 28 +- .../composer.json | 30 +- .../src/Plugin.php | 80 +- app/vendor/doctrine/cache/UPGRADE-1.11.md | 12 + app/vendor/doctrine/cache/composer.json | 19 +- .../Common/Cache/Psr6/DoctrineProvider.php | 10 + app/vendor/doctrine/dbal/README.md | 28 +- .../doctrine/dbal/bin/doctrine-dbal.php | 4 +- app/vendor/doctrine/dbal/composer.json | 25 +- .../doctrine/dbal/src/ArrayParameterType.php | 37 + .../dbal/src/ArrayParameters/Exception.php | 4 +- .../Exception/MissingNamedParameter.php | 6 +- .../Exception/MissingPositionalParameter.php | 2 +- .../doctrine/dbal/src/Cache/ArrayResult.php | 21 +- .../dbal/src/Cache/CacheException.php | 12 +- .../dbal/src/Cache/QueryCacheProfile.php | 23 +- .../doctrine/dbal/src/Configuration.php | 73 +- app/vendor/doctrine/dbal/src/Connection.php | 369 +- .../doctrine/dbal/src/ConnectionException.php | 20 +- .../PrimaryReadReplicaConnection.php | 19 +- app/vendor/doctrine/dbal/src/Driver.php | 13 +- .../Driver/API/MySQL/ExceptionConverter.php | 4 +- .../src/Driver/API/OCI/ExceptionConverter.php | 8 +- .../API/PostgreSQL/ExceptionConverter.php | 10 +- .../Driver/API/SQLite/ExceptionConverter.php | 13 +- .../API/SQLite/UserDefinedFunctions.php | 32 + .../dbal/src/Driver/AbstractDB2Driver.php | 10 + .../dbal/src/Driver/AbstractException.php | 4 +- .../dbal/src/Driver/AbstractMySQLDriver.php | 51 +- .../dbal/src/Driver/AbstractOracleDriver.php | 12 +- .../EasyConnectString.php | 11 +- .../src/Driver/AbstractPostgreSQLDriver.php | 13 +- .../src/Driver/AbstractSQLServerDriver.php | 13 +- .../dbal/src/Driver/AbstractSQLiteDriver.php | 10 + .../Middleware/EnableForeignKeys.php | 31 + .../doctrine/dbal/src/Driver/Exception.php | 4 +- .../Driver/Exception/UnknownParameterType.php | 4 +- .../doctrine/dbal/src/Driver/FetchUtils.php | 4 +- .../dbal/src/Driver/IBMDB2/Connection.php | 6 +- .../dbal/src/Driver/IBMDB2/DataSourceName.php | 23 +- .../dbal/src/Driver/IBMDB2/Driver.php | 7 +- .../Exception/CannotCopyStreamToStream.php | 4 +- .../Exception/CannotCreateTemporaryFile.php | 4 +- .../Exception/CannotWriteToTemporaryFile.php | 29 - .../IBMDB2/Exception/ConnectionError.php | 4 +- .../Driver/IBMDB2/Exception/PrepareFailed.php | 4 +- .../IBMDB2/Exception/StatementError.php | 4 +- .../dbal/src/Driver/IBMDB2/Statement.php | 120 +- .../AbstractConnectionMiddleware.php | 11 +- .../Middleware/AbstractDriverMiddleware.php | 20 +- .../Middleware/AbstractResultMiddleware.php | 3 +- .../AbstractStatementMiddleware.php | 33 +- .../dbal/src/Driver/Mysqli/Connection.php | 11 +- .../dbal/src/Driver/Mysqli/Driver.php | 105 +- .../Mysqli/Exception/InvalidCharset.php | 4 +- .../Driver/Mysqli/Exception/InvalidOption.php | 6 +- .../NonStreamResourceUsedAsLargeObject.php | 2 +- .../dbal/src/Driver/Mysqli/Initializer.php | 4 +- .../src/Driver/Mysqli/Initializer/Charset.php | 3 +- .../src/Driver/Mysqli/Initializer/Options.php | 6 +- .../src/Driver/Mysqli/Initializer/Secure.php | 32 +- .../dbal/src/Driver/Mysqli/Result.php | 11 +- .../dbal/src/Driver/Mysqli/Statement.php | 54 +- .../dbal/src/Driver/OCI8/Connection.php | 17 +- .../ConvertPositionalToNamedPlaceholders.php | 8 +- .../doctrine/dbal/src/Driver/OCI8/Driver.php | 7 +- .../dbal/src/Driver/OCI8/Exception/Error.php | 4 +- .../Exception/NonTerminatedStringLiteral.php | 4 +- .../OCI8/Exception/UnknownParameterIndex.php | 2 +- .../dbal/src/Driver/OCI8/ExecutionMode.php | 3 +- .../OCI8/Middleware/InitializeSession.php | 39 + .../doctrine/dbal/src/Driver/OCI8/Result.php | 6 +- .../dbal/src/Driver/OCI8/Statement.php | 57 +- .../dbal/src/Driver/PDO/Connection.php | 36 +- .../dbal/src/Driver/PDO/Exception.php | 4 +- .../dbal/src/Driver/PDO/MySQL/Driver.php | 14 +- .../dbal/src/Driver/PDO/OCI/Driver.php | 12 +- .../dbal/src/Driver/PDO/PDOException.php | 33 + .../dbal/src/Driver/PDO/ParameterTypeMap.php | 47 + .../dbal/src/Driver/PDO/PgSQL/Driver.php | 35 +- .../doctrine/dbal/src/Driver/PDO/Result.php | 13 +- .../dbal/src/Driver/PDO/SQLSrv/Connection.php | 21 +- .../dbal/src/Driver/PDO/SQLSrv/Driver.php | 14 +- .../dbal/src/Driver/PDO/SQLSrv/Statement.php | 40 +- .../dbal/src/Driver/PDO/SQLite/Driver.php | 45 +- .../dbal/src/Driver/PDO/Statement.php | 84 +- .../dbal/src/Driver/PgSQL/Connection.php | 161 + .../src/Driver/PgSQL/ConvertParameters.php | 49 + .../doctrine/dbal/src/Driver/PgSQL/Driver.php | 85 + .../dbal/src/Driver/PgSQL/Exception.php | 30 + .../PgSQL/Exception/UnexpectedValue.php | 29 + .../PgSQL/Exception/UnknownParameter.php | 18 + .../doctrine/dbal/src/Driver/PgSQL/Result.php | 282 ++ .../dbal/src/Driver/PgSQL/Statement.php | 173 + .../dbal/src/Driver/SQLSrv/Connection.php | 6 +- .../dbal/src/Driver/SQLSrv/Driver.php | 7 +- .../src/Driver/SQLSrv/Exception/Error.php | 7 +- .../dbal/src/Driver/SQLSrv/Result.php | 4 +- .../dbal/src/Driver/SQLSrv/Statement.php | 52 +- .../dbal/src/Driver/SQLite3/Connection.php | 107 + .../dbal/src/Driver/SQLite3/Driver.php | 49 + .../dbal/src/Driver/SQLite3/Exception.php | 18 + .../dbal/src/Driver/SQLite3/Result.php | 91 + .../dbal/src/Driver/SQLite3/Statement.php | 119 + .../doctrine/dbal/src/Driver/Statement.php | 2 + .../doctrine/dbal/src/DriverManager.php | 307 +- .../dbal/src/Event/ConnectionEventArgs.php | 9 +- .../src/Event/Listeners/OracleSessionInit.php | 6 +- .../src/Event/Listeners/SQLSessionInit.php | 6 +- .../src/Event/Listeners/SQLiteSessionInit.php | 30 + .../SchemaAlterTableAddColumnEventArgs.php | 33 +- .../SchemaAlterTableChangeColumnEventArgs.php | 31 +- .../src/Event/SchemaAlterTableEventArgs.php | 23 +- .../SchemaAlterTableRemoveColumnEventArgs.php | 31 +- .../SchemaAlterTableRenameColumnEventArgs.php | 39 +- .../Event/SchemaColumnDefinitionEventArgs.php | 28 +- .../SchemaCreateTableColumnEventArgs.php | 31 +- .../src/Event/SchemaCreateTableEventArgs.php | 34 +- .../src/Event/SchemaDropTableEventArgs.php | 17 +- .../dbal/src/Event/SchemaEventArgs.php | 13 +- .../Event/SchemaIndexDefinitionEventArgs.php | 26 +- .../src/Event/TransactionBeginEventArgs.php | 1 + .../src/Event/TransactionCommitEventArgs.php | 1 + .../dbal/src/Event/TransactionEventArgs.php | 4 +- .../Event/TransactionRollBackEventArgs.php | 1 + app/vendor/doctrine/dbal/src/Events.php | 48 +- app/vendor/doctrine/dbal/src/Exception.php | 45 +- .../dbal/src/Exception/ConnectionLost.php | 4 +- .../src/Exception/DatabaseDoesNotExist.php | 4 +- .../dbal/src/Exception/DatabaseRequired.php | 18 + .../dbal/src/Exception/DriverException.php | 4 +- .../Exception/InvalidArgumentException.php | 4 +- .../dbal/src/Exception/InvalidLockMode.php | 8 +- .../src/Exception/MalformedDsnException.php | 14 + .../dbal/src/Exception/NoKeyValue.php | 4 +- .../dbal/src/Exception/SchemaDoesNotExist.php | 4 +- .../dbal/src/ExpandArrayParameters.php | 39 +- app/vendor/doctrine/dbal/src/FetchMode.php | 2 + .../doctrine/dbal/src/Id/TableGenerator.php | 11 +- .../src/Id/TableGeneratorSchemaVisitor.php | 8 +- .../doctrine/dbal/src/Logging/Connection.php | 9 +- .../doctrine/dbal/src/Logging/DebugStack.php | 2 +- .../doctrine/dbal/src/Logging/Driver.php | 22 +- .../doctrine/dbal/src/Logging/LoggerChain.php | 8 +- .../doctrine/dbal/src/Logging/Middleware.php | 3 +- .../doctrine/dbal/src/Logging/Statement.php | 44 +- .../src/Platforms/AbstractMySQLPlatform.php | 452 +- .../dbal/src/Platforms/AbstractPlatform.php | 1022 +++- .../dbal/src/Platforms/DB2Platform.php | 226 +- .../dbal/src/Platforms/DateIntervalUnit.php | 4 +- .../src/Platforms/Keywords/DB2Keywords.php | 10 + .../src/Platforms/Keywords/KeywordList.php | 8 +- .../Platforms/Keywords/MariaDBKeywords.php | 9 + .../Platforms/Keywords/MariaDb102Keywords.php | 9 + .../Platforms/Keywords/MySQL57Keywords.php | 10 + .../Platforms/Keywords/MySQL80Keywords.php | 10 + .../src/Platforms/Keywords/MySQLKeywords.php | 10 + .../src/Platforms/Keywords/OracleKeywords.php | 10 + .../Keywords/PostgreSQL100Keywords.php | 9 + .../Platforms/Keywords/PostgreSQLKeywords.php | 10 + .../Keywords/ReservedKeywordsValidator.php | 24 +- .../Platforms/Keywords/SQLServerKeywords.php | 10 + .../src/Platforms/Keywords/SQLiteKeywords.php | 10 + .../dbal/src/Platforms/MariaDBPlatform.php | 19 +- .../MySQL/CollationMetadataProvider.php | 11 + .../CachingCollationMetadataProvider.php | 33 + .../ConnectionCollationMetadataProvider.php | 41 + .../dbal/src/Platforms/MySQL/Comparator.php | 56 +- .../dbal/src/Platforms/MySQL57Platform.php | 11 +- .../dbal/src/Platforms/MySQL80Platform.php | 2 +- .../dbal/src/Platforms/OraclePlatform.php | 203 +- .../src/Platforms/PostgreSQL100Platform.php | 21 +- .../dbal/src/Platforms/PostgreSQLPlatform.php | 338 +- .../src/Platforms/SQLServer/Comparator.php | 33 +- .../dbal/src/Platforms/SQLServerPlatform.php | 349 +- .../dbal/src/Platforms/SQLite/Comparator.php | 30 +- .../dbal/src/Platforms/SqlitePlatform.php | 384 +- .../doctrine/dbal/src/Platforms/TrimMode.php | 4 +- .../dbal/src/Portability/Connection.php | 7 +- .../doctrine/dbal/src/Portability/Driver.php | 17 +- .../dbal/src/Portability/Middleware.php | 6 +- .../dbal/src/Portability/OptimizeFlags.php | 2 +- .../doctrine/dbal/src/Portability/Result.php | 19 +- .../dbal/src/Portability/Statement.php | 5 +- app/vendor/doctrine/dbal/src/Query.php | 16 +- .../Query/Expression/CompositeExpression.php | 8 +- .../Query/Expression/ExpressionBuilder.php | 8 +- .../doctrine/dbal/src/Query/QueryBuilder.php | 177 +- .../dbal/src/Query/QueryException.php | 4 +- app/vendor/doctrine/dbal/src/Result.php | 23 +- .../Builder/CreateSchemaObjectsSQLBuilder.php | 85 + .../Builder/DropSchemaObjectsSQLBuilder.php | 62 + app/vendor/doctrine/dbal/src/SQL/Parser.php | 3 +- .../dbal/src/Schema/AbstractAsset.php | 2 +- .../dbal/src/Schema/AbstractSchemaManager.php | 605 ++- .../doctrine/dbal/src/Schema/Column.php | 105 +- .../doctrine/dbal/src/Schema/ColumnDiff.php | 113 +- .../doctrine/dbal/src/Schema/Comparator.php | 283 +- .../doctrine/dbal/src/Schema/Constraint.php | 8 +- .../dbal/src/Schema/DB2SchemaManager.php | 252 +- .../Schema/DefaultSchemaManagerFactory.php | 20 + .../Schema/Exception/ColumnAlreadyExists.php | 21 + .../Schema/Exception/ColumnDoesNotExist.php | 21 + .../Exception/ForeignKeyDoesNotExist.php | 21 + .../Schema/Exception/IndexAlreadyExists.php | 21 + .../Schema/Exception/IndexDoesNotExist.php | 21 + .../src/Schema/Exception/IndexNameInvalid.php | 21 + .../src/Schema/Exception/InvalidTableName.php | 4 +- .../Exception/NamedForeignKeyRequired.php | 30 + .../Exception/NamespaceAlreadyExists.php | 21 + .../Exception/SequenceAlreadyExists.php | 21 + .../Schema/Exception/SequenceDoesNotExist.php | 21 + .../Schema/Exception/TableAlreadyExists.php | 21 + .../Schema/Exception/TableDoesNotExist.php | 21 + .../UniqueConstraintDoesNotExist.php | 21 + .../Schema/Exception/UnknownColumnOption.php | 6 +- app/vendor/doctrine/dbal/src/Schema/Index.php | 34 +- .../src/Schema/LegacySchemaManagerFactory.php | 19 + .../dbal/src/Schema/MySQLSchemaManager.php | 297 +- .../dbal/src/Schema/OracleSchemaManager.php | 260 +- .../src/Schema/PostgreSQLSchemaManager.php | 321 +- .../src/Schema/SQLServerSchemaManager.php | 354 +- .../doctrine/dbal/src/Schema/Schema.php | 49 +- .../doctrine/dbal/src/Schema/SchemaConfig.php | 8 +- .../doctrine/dbal/src/Schema/SchemaDiff.php | 205 +- .../dbal/src/Schema/SchemaException.php | 124 +- .../dbal/src/Schema/SchemaManagerFactory.php | 17 + .../doctrine/dbal/src/Schema/Sequence.php | 21 +- .../dbal/src/Schema/SqliteSchemaManager.php | 409 +- app/vendor/doctrine/dbal/src/Schema/Table.php | 148 +- .../doctrine/dbal/src/Schema/TableDiff.php | 261 +- .../dbal/src/Schema/UniqueConstraint.php | 14 +- app/vendor/doctrine/dbal/src/Schema/View.php | 4 +- .../src/Schema/Visitor/AbstractVisitor.php | 2 + .../Visitor/CreateSchemaSqlCollector.php | 25 +- .../Schema/Visitor/DropSchemaSqlCollector.php | 41 +- .../dbal/src/Schema/Visitor/Graphviz.php | 7 +- .../src/Schema/Visitor/NamespaceVisitor.php | 2 + .../Schema/Visitor/RemoveNamespacedAssets.php | 18 +- .../src/Schema/Visitor/SchemaDiffVisitor.php | 50 - .../dbal/src/Schema/Visitor/Visitor.php | 18 +- app/vendor/doctrine/dbal/src/Statement.php | 32 +- .../Console/Command/ReservedWordsCommand.php | 36 +- .../Tools/Console/Command/RunSqlCommand.php | 17 +- .../src/Tools/Console/ConnectionProvider.php | 4 +- .../SingleConnectionProvider.php | 6 +- .../dbal/src/Tools/Console/ConsoleRunner.php | 6 +- .../doctrine/dbal/src/Tools/DsnParser.php | 211 + .../dbal/src/TransactionIsolationLevel.php | 4 +- .../doctrine/dbal/src/Types/ArrayType.php | 19 + .../doctrine/dbal/src/Types/BigIntType.php | 6 + .../doctrine/dbal/src/Types/BooleanType.php | 16 + .../dbal/src/Types/ConversionException.php | 10 +- .../dbal/src/Types/DateImmutableType.php | 26 +- .../dbal/src/Types/DateIntervalType.php | 24 +- .../dbal/src/Types/DateTimeImmutableType.php | 26 +- .../doctrine/dbal/src/Types/DateTimeType.php | 14 +- .../src/Types/DateTimeTzImmutableType.php | 26 +- .../dbal/src/Types/DateTimeTzType.php | 16 +- .../doctrine/dbal/src/Types/DateType.php | 14 +- .../doctrine/dbal/src/Types/DecimalType.php | 3 +- .../doctrine/dbal/src/Types/FloatType.php | 6 + .../doctrine/dbal/src/Types/GuidType.php | 10 + .../doctrine/dbal/src/Types/IntegerType.php | 6 + .../doctrine/dbal/src/Types/JsonType.php | 16 + .../doctrine/dbal/src/Types/ObjectType.php | 16 + .../dbal/src/Types/SimpleArrayType.php | 18 + .../doctrine/dbal/src/Types/SmallIntType.php | 6 + .../doctrine/dbal/src/Types/StringType.php | 2 +- .../dbal/src/Types/TimeImmutableType.php | 26 +- .../doctrine/dbal/src/Types/TimeType.php | 14 +- app/vendor/doctrine/dbal/src/Types/Type.php | 29 +- .../doctrine/dbal/src/Types/TypeRegistry.php | 6 +- app/vendor/doctrine/dbal/src/Types/Types.php | 25 +- .../src/Types/VarDateTimeImmutableType.php | 24 +- .../dbal/src/Types/VarDateTimeType.php | 7 + ...ager-get-available-drivers-return-type.php | 18 + .../test_fixtures/vendor/doctrine/foo/Bar.php | 24 + .../test_fixtures/vendor/doctrine/foo/Baz.php | 14 + .../event-manager/.doctrine-project.json | 18 - app/vendor/doctrine/event-manager/README.md | 6 +- app/vendor/doctrine/event-manager/UPGRADE.md | 15 + .../doctrine/event-manager/composer.json | 62 +- .../doctrine/event-manager/phpstan.neon.dist | 5 + .../event-manager/psalm.xml} | 5 +- .../Doctrine/Common => src}/EventArgs.php | 14 +- .../Doctrine/Common => src}/EventManager.php | 77 +- .../Common => src}/EventSubscriber.php | 2 +- app/vendor/doctrine/instantiator/README.md | 2 +- .../doctrine/instantiator/composer.json | 14 +- app/vendor/doctrine/instantiator/psalm.xml | 16 + .../Exception/ExceptionInterface.php | 2 + .../Exception/InvalidArgumentException.php | 6 +- .../Exception/UnexpectedValueException.php | 14 +- .../Doctrine/Instantiator/Instantiator.php | 35 +- .../Instantiator/InstantiatorInterface.php | 6 +- .../laminas-diactoros/.laminas-ci.json | 8 - .../laminas/laminas-diactoros/composer.json | 21 +- .../laminas/laminas-diactoros/composer.lock | 4337 ----------------- .../laminas-diactoros/psalm-baseline.xml | 1350 ----- .../laminas/laminas-diactoros/psalm.xml.dist | 35 - .../src/AbstractSerializer.php | 12 +- .../laminas-diactoros/src/CallbackStream.php | 44 +- .../laminas-diactoros/src/ConfigProvider.php | 26 +- .../Exception/DeserializationException.php | 14 +- .../InvalidForwardedHeaderNameException.php | 28 + .../InvalidProxyAddressException.php | 32 + .../InvalidStreamPointerPositionException.php | 5 +- .../src/Exception/SerializationException.php | 4 +- .../Exception/UnreadableStreamException.php | 8 +- .../UnrecognizedProtocolVersionException.php | 2 +- .../Exception/UnrewindableStreamException.php | 2 +- .../Exception/UnseekableStreamException.php | 8 +- .../Exception/UntellableStreamException.php | 6 +- .../Exception/UnwritableStreamException.php | 8 +- .../UploadedFileAlreadyMovedException.php | 5 +- .../Exception/UploadedFileErrorException.php | 10 +- .../laminas-diactoros/src/HeaderSecurity.php | 34 +- .../laminas-diactoros/src/MessageTrait.php | 76 +- .../laminas-diactoros/src/PhpInputStream.php | 22 +- .../laminas-diactoros/src/RelativeStream.php | 55 +- .../laminas/laminas-diactoros/src/Request.php | 14 +- .../src/Request/ArraySerializer.php | 23 +- .../src/Request/Serializer.php | 37 +- .../laminas-diactoros/src/RequestFactory.php | 2 +- .../laminas-diactoros/src/RequestTrait.php | 53 +- .../laminas-diactoros/src/Response.php | 35 +- .../src/Response/ArraySerializer.php | 19 +- .../src/Response/EmptyResponse.php | 3 +- .../src/Response/HtmlResponse.php | 11 +- .../src/Response/InjectContentTypeTrait.php | 10 +- .../src/Response/JsonResponse.php | 58 +- .../src/Response/RedirectResponse.php | 5 +- .../src/Response/Serializer.php | 30 +- .../src/Response/TextResponse.php | 11 +- .../src/Response/XmlResponse.php | 11 +- .../laminas-diactoros/src/ResponseFactory.php | 2 +- .../laminas-diactoros/src/ServerRequest.php | 87 +- .../src/ServerRequestFactory.php | 39 +- .../src/ServerRequestFilter/DoNotFilter.php | 15 + .../FilterServerRequestInterface.php | 29 + .../FilterUsingXForwardedHeaders.php | 253 + .../src/ServerRequestFilter/IPRange.php | 118 + .../laminas/laminas-diactoros/src/Stream.php | 98 +- .../laminas-diactoros/src/StreamFactory.php | 8 +- .../laminas-diactoros/src/UploadedFile.php | 92 +- .../src/UploadedFileFactory.php | 8 +- .../laminas/laminas-diactoros/src/Uri.php | 203 +- .../laminas-diactoros/src/UriFactory.php | 234 +- .../functions/create_uploaded_file.legacy.php | 5 +- .../src/functions/create_uploaded_file.php | 9 +- .../marshal_headers_from_sapi.legacy.php | 3 +- .../functions/marshal_headers_from_sapi.php | 18 +- .../marshal_method_from_sapi.legacy.php | 3 +- .../functions/marshal_method_from_sapi.php | 2 +- ...shal_protocol_version_from_sapi.legacy.php | 3 +- .../marshal_protocol_version_from_sapi.php | 4 +- .../marshal_uri_from_sapi.legacy.php | 5 +- .../src/functions/marshal_uri_from_sapi.php | 53 +- .../src/functions/normalize_server.legacy.php | 3 +- .../src/functions/normalize_server.php | 5 +- .../normalize_uploaded_files.legacy.php | 5 +- .../functions/normalize_uploaded_files.php | 26 +- .../functions/parse_cookie_header.legacy.php | 8 +- .../src/functions/parse_cookie_header.php | 6 +- .../laminas-httphandlerrunner/CHANGELOG.md | 206 - .../laminas-httphandlerrunner/README.md | 16 + .../laminas-httphandlerrunner/composer.json | 26 +- .../psalm-baseline.xml | 180 - .../laminas-httphandlerrunner/psalm.xml.dist | 33 - .../src/ConfigProvider.php | 13 +- .../src/Emitter/EmitterInterface.php | 8 +- .../src/Emitter/EmitterStack.php | 27 +- .../src/Emitter/SapiEmitter.php | 10 +- .../src/Emitter/SapiEmitterTrait.php | 54 +- .../src/Emitter/SapiStreamEmitter.php | 35 +- .../src/Exception/EmitterException.php | 14 +- .../src/Exception/ExceptionInterface.php | 6 - .../src/Exception/InvalidEmitterException.php | 14 +- .../src/RequestHandlerRunner.php | 57 +- .../src/RequestHandlerRunnerInterface.php | 24 + .../.github/FUNDING.yml | 1 - .../workflows/continuous-integration.yml | 11 - .../workflows/release-on-milestone-closed.yml | 15 - .../.laminas-ci.json | 5 - .../laminas-zendframework-bridge/COPYRIGHT.md | 1 - .../laminas-zendframework-bridge/LICENSE.md | 26 - .../laminas-zendframework-bridge/README.md | 30 - .../composer.json | 64 - .../composer.lock | 3932 --------------- .../config/replacements.php | 372 -- .../psalm-baseline.xml | 185 - .../psalm.xml.dist | 34 - .../src/Autoloader.php | 185 - .../src/ConfigPostProcessor.php | 426 -- .../src/Module.php | 48 - .../src/Replacements.php | 40 - .../src/RewriteRules.php | 73 - .../src/autoload.php | 3 - .../mobiledetectlib}/LICENSE | 5 +- .../mobiledetectlib/Mobile_Detect.json | 2 +- .../mobiledetectlib/Mobile_Detect.php | 26 +- .../mobiledetect/mobiledetectlib/README.md | 2 + .../mobiledetectlib/docs/KNOWN_LIMITATIONS.md | 3 +- app/vendor/nikic/php-parser/README.md | 6 +- app/vendor/nikic/php-parser/grammar/php5.y | 22 +- app/vendor/nikic/php-parser/grammar/php7.y | 77 +- .../nikic/php-parser/grammar/phpyLang.php | 8 - .../lib/PhpParser/Builder/Class_.php | 10 +- .../lib/PhpParser/Builder/EnumCase.php | 85 + .../lib/PhpParser/Builder/Enum_.php | 117 + .../lib/PhpParser/BuilderHelpers.php | 24 +- .../lib/PhpParser/Internal/TokenStream.php | 5 + .../lib/PhpParser/Lexer/Emulative.php | 5 +- .../Lexer/TokenEmulator/KeywordEmulator.php | 2 +- .../ReadonlyFunctionTokenEmulator.php | 31 + .../TokenEmulator/ReadonlyTokenEmulator.php | 15 +- .../php-parser/lib/PhpParser/Node/Const_.php | 4 +- .../php-parser/lib/PhpParser/Node/Name.php | 2 +- .../lib/PhpParser/Node/Scalar/DNumber.php | 31 +- .../lib/PhpParser/Node/Scalar/LNumber.php | 4 +- .../lib/PhpParser/Node/Scalar/String_.php | 16 + .../lib/PhpParser/Node/Stmt/ClassLike.php | 2 +- .../lib/PhpParser/Node/Stmt/ClassMethod.php | 32 +- .../lib/PhpParser/Node/Stmt/Class_.php | 25 + .../lib/PhpParser/Node/Stmt/Function_.php | 2 +- .../lib/PhpParser/Node/UnionType.php | 4 +- .../PhpParser/NodeVisitor/NameResolver.php | 2 +- .../php-parser/lib/PhpParser/Parser/Php5.php | 1920 ++++---- .../php-parser/lib/PhpParser/Parser/Php7.php | 2002 ++++---- .../lib/PhpParser/ParserAbstract.php | 10 + .../lib/PhpParser/PrettyPrinter/Standard.php | 10 +- .../lib/PhpParser/PrettyPrinterAbstract.php | 21 +- .../reflection-common/.github/dependabot.yml | 7 - .../.github/workflows/push.yml | 223 - .../phpdocumentor/reflection-common/README.md | 11 - .../reflection-common/composer.json | 28 - .../reflection-common/src/Element.php | 30 - .../reflection-common/src/File.php | 35 - .../reflection-common/src/Fqsen.php | 89 - .../reflection-common/src/Location.php | 53 - .../reflection-common/src/Project.php | 25 - .../reflection-common/src/ProjectFactory.php | 28 - .../reflection-docblock/README.md | 75 - .../reflection-docblock/composer.json | 42 - .../reflection-docblock/src/DocBlock.php | 228 - .../src/DocBlock/Description.php | 115 - .../src/DocBlock/DescriptionFactory.php | 178 - .../src/DocBlock/ExampleFinder.php | 159 - .../src/DocBlock/Serializer.php | 157 - .../src/DocBlock/StandardTagFactory.php | 348 -- .../reflection-docblock/src/DocBlock/Tag.php | 31 - .../src/DocBlock/TagFactory.php | 84 - .../src/DocBlock/Tags/Author.php | 102 - .../src/DocBlock/Tags/BaseTag.php | 53 - .../src/DocBlock/Tags/Covers.php | 101 - .../src/DocBlock/Tags/Deprecated.php | 109 - .../src/DocBlock/Tags/Example.php | 200 - .../DocBlock/Tags/Factory/StaticMethod.php | 25 - .../src/DocBlock/Tags/Formatter.php | 24 - .../Tags/Formatter/AlignFormatter.php | 50 - .../Tags/Formatter/PassthroughFormatter.php | 30 - .../src/DocBlock/Tags/Generic.php | 89 - .../src/DocBlock/Tags/InvalidTag.php | 145 - .../src/DocBlock/Tags/Link.php | 78 - .../src/DocBlock/Tags/Method.php | 279 -- .../src/DocBlock/Tags/Param.php | 174 - .../src/DocBlock/Tags/Property.php | 121 - .../src/DocBlock/Tags/PropertyRead.php | 121 - .../src/DocBlock/Tags/PropertyWrite.php | 121 - .../src/DocBlock/Tags/Reference/Fqsen.php | 38 - .../src/DocBlock/Tags/Reference/Reference.php | 22 - .../src/DocBlock/Tags/Reference/Url.php | 36 - .../src/DocBlock/Tags/Return_.php | 64 - .../src/DocBlock/Tags/See.php | 106 - .../src/DocBlock/Tags/Since.php | 103 - .../src/DocBlock/Tags/Source.php | 116 - .../src/DocBlock/Tags/TagWithType.php | 66 - .../src/DocBlock/Tags/Throws.php | 64 - .../src/DocBlock/Tags/Uses.php | 100 - .../src/DocBlock/Tags/Var_.php | 122 - .../src/DocBlock/Tags/Version.php | 106 - .../src/DocBlockFactory.php | 287 -- .../src/DocBlockFactoryInterface.php | 23 - .../src/Exception/PcreException.php | 44 - .../reflection-docblock/src/Utils.php | 62 - .../phpdocumentor/type-resolver/README.md | 177 - .../phpdocumentor/type-resolver/composer.json | 35 - .../type-resolver/src/FqsenResolver.php | 80 - .../type-resolver/src/PseudoType.php | 19 - .../src/PseudoTypes/CallableString.php | 39 - .../type-resolver/src/PseudoTypes/False_.php | 40 - .../src/PseudoTypes/HtmlEscapedString.php | 39 - .../src/PseudoTypes/LiteralString.php | 39 - .../src/PseudoTypes/LowercaseString.php | 39 - .../PseudoTypes/NonEmptyLowercaseString.php | 39 - .../src/PseudoTypes/NonEmptyString.php | 39 - .../src/PseudoTypes/NumericString.php | 39 - .../src/PseudoTypes/PositiveInteger.php | 39 - .../src/PseudoTypes/TraitString.php | 39 - .../type-resolver/src/PseudoTypes/True_.php | 40 - .../phpdocumentor/type-resolver/src/Type.php | 25 - .../type-resolver/src/TypeResolver.php | 700 --- .../type-resolver/src/Types/AbstractList.php | 83 - .../src/Types/AggregatedType.php | 125 - .../type-resolver/src/Types/ArrayKey.php | 42 - .../type-resolver/src/Types/Array_.php | 29 - .../type-resolver/src/Types/Boolean.php | 32 - .../type-resolver/src/Types/Callable_.php | 32 - .../type-resolver/src/Types/ClassString.php | 62 - .../type-resolver/src/Types/Collection.php | 68 - .../type-resolver/src/Types/Compound.php | 38 - .../type-resolver/src/Types/Context.php | 95 - .../src/Types/ContextFactory.php | 420 -- .../type-resolver/src/Types/Expression.php | 51 - .../type-resolver/src/Types/Float_.php | 32 - .../type-resolver/src/Types/Integer.php | 32 - .../src/Types/InterfaceString.php | 56 - .../type-resolver/src/Types/Intersection.php | 37 - .../type-resolver/src/Types/Iterable_.php | 38 - .../type-resolver/src/Types/Mixed_.php | 32 - .../type-resolver/src/Types/Never_.php | 35 - .../type-resolver/src/Types/Null_.php | 32 - .../type-resolver/src/Types/Nullable.php | 51 - .../type-resolver/src/Types/Object_.php | 69 - .../type-resolver/src/Types/Parent_.php | 34 - .../type-resolver/src/Types/Resource_.php | 32 - .../type-resolver/src/Types/Scalar.php | 32 - .../type-resolver/src/Types/Self_.php | 34 - .../type-resolver/src/Types/Static_.php | 39 - .../type-resolver/src/Types/String_.php | 32 - .../type-resolver/src/Types/This.php | 35 - .../type-resolver/src/Types/Void_.php | 35 - app/vendor/phpspec/prophecy/CHANGES.md | 302 -- app/vendor/phpspec/prophecy/LICENSE | 23 - app/vendor/phpspec/prophecy/README.md | 411 -- app/vendor/phpspec/prophecy/composer.json | 50 - .../prophecy/src/Prophecy/Argument.php | 239 - .../Prophecy/Argument/ArgumentsWildcard.php | 101 - .../Prophecy/Argument/Token/AnyValueToken.php | 52 - .../Argument/Token/AnyValuesToken.php | 52 - .../Argument/Token/ApproximateValueToken.php | 55 - .../Argument/Token/ArrayCountToken.php | 86 - .../Argument/Token/ArrayEntryToken.php | 143 - .../Argument/Token/ArrayEveryEntryToken.php | 82 - .../Prophecy/Argument/Token/CallbackToken.php | 75 - .../Argument/Token/ExactValueToken.php | 118 - .../Argument/Token/IdenticalValueToken.php | 74 - .../Prophecy/Argument/Token/InArrayToken.php | 74 - .../Argument/Token/LogicalAndToken.php | 80 - .../Argument/Token/LogicalNotToken.php | 73 - .../Argument/Token/NotInArrayToken.php | 75 - .../Argument/Token/ObjectStateToken.php | 104 - .../Argument/Token/StringContainsToken.php | 67 - .../Argument/Token/TokenInterface.php | 43 - .../src/Prophecy/Argument/Token/TypeToken.php | 76 - .../prophecy/src/Prophecy/Call/Call.php | 162 - .../prophecy/src/Prophecy/Call/CallCenter.php | 240 - .../Prophecy/Comparator/ClosureComparator.php | 44 - .../src/Prophecy/Comparator/Factory.php | 47 - .../Comparator/ProphecyComparator.php | 31 - .../src/Prophecy/Doubler/CachedDoubler.php | 66 - .../ClassPatch/ClassPatchInterface.php | 48 - .../ClassPatch/DisableConstructorPatch.php | 76 - .../Doubler/ClassPatch/HhvmExceptionPatch.php | 63 - .../Doubler/ClassPatch/KeywordPatch.php | 68 - .../Doubler/ClassPatch/MagicCallPatch.php | 105 - .../ClassPatch/ProphecySubjectPatch.php | 113 - .../ReflectionClassNewInstancePatch.php | 57 - .../Doubler/ClassPatch/SplFileInfoPatch.php | 123 - .../Doubler/ClassPatch/ThrowablePatch.php | 95 - .../Doubler/ClassPatch/TraversablePatch.php | 98 - .../src/Prophecy/Doubler/DoubleInterface.php | 22 - .../prophecy/src/Prophecy/Doubler/Doubler.php | 146 - .../Doubler/Generator/ClassCodeGenerator.php | 110 - .../Doubler/Generator/ClassCreator.php | 67 - .../Doubler/Generator/ClassMirror.php | 254 - .../Doubler/Generator/Node/ArgumentNode.php | 133 - .../Generator/Node/ArgumentTypeNode.php | 10 - .../Doubler/Generator/Node/ClassNode.php | 169 - .../Doubler/Generator/Node/MethodNode.php | 210 - .../Doubler/Generator/Node/ReturnTypeNode.php | 45 - .../Generator/Node/TypeNodeAbstract.php | 97 - .../Doubler/Generator/ReflectionInterface.php | 22 - .../Doubler/Generator/TypeHintReference.php | 43 - .../src/Prophecy/Doubler/LazyDouble.php | 127 - .../src/Prophecy/Doubler/NameGenerator.php | 52 - .../Call/UnexpectedCallException.php | 40 - .../Doubler/ClassCreatorException.php | 31 - .../Doubler/ClassMirrorException.php | 31 - .../Doubler/ClassNotFoundException.php | 33 - .../Exception/Doubler/DoubleException.php | 18 - .../Exception/Doubler/DoublerException.php | 18 - .../Doubler/InterfaceNotFoundException.php | 20 - .../Doubler/MethodNotExtendableException.php | 41 - .../Doubler/MethodNotFoundException.php | 60 - .../Doubler/ReturnByReferenceException.php | 41 - .../src/Prophecy/Exception/Exception.php | 22 - .../Exception/InvalidArgumentException.php | 16 - .../Prediction/AggregateException.php | 51 - .../Prediction/FailedPredictionException.php | 24 - .../Exception/Prediction/NoCallsException.php | 18 - .../Prediction/PredictionException.php | 18 - .../UnexpectedCallsCountException.php | 31 - .../Prediction/UnexpectedCallsException.php | 32 - .../Prophecy/MethodProphecyException.php | 34 - .../Prophecy/ObjectProphecyException.php | 34 - .../Exception/Prophecy/ProphecyException.php | 18 - .../ClassAndInterfaceTagRetriever.php | 69 - .../PhpDocumentor/ClassTagRetriever.php | 60 - .../PhpDocumentor/LegacyClassTagRetriever.php | 35 - .../MethodTagRetrieverInterface.php | 30 - .../Prophecy/Prediction/CallPrediction.php | 86 - .../Prediction/CallTimesPrediction.php | 107 - .../Prediction/CallbackPrediction.php | 66 - .../Prophecy/Prediction/NoCallsPrediction.php | 68 - .../Prediction/PredictionInterface.php | 37 - .../src/Prophecy/Promise/CallbackPromise.php | 67 - .../src/Prophecy/Promise/PromiseInterface.php | 35 - .../Promise/ReturnArgumentPromise.php | 61 - .../src/Prophecy/Promise/ReturnPromise.php | 55 - .../src/Prophecy/Promise/ThrowPromise.php | 100 - .../src/Prophecy/Prophecy/MethodProphecy.php | 573 --- .../src/Prophecy/Prophecy/ObjectProphecy.php | 286 -- .../Prophecy/Prophecy/ProphecyInterface.php | 27 - .../Prophecy/ProphecySubjectInterface.php | 34 - .../src/Prophecy/Prophecy/Revealer.php | 44 - .../Prophecy/Prophecy/RevealerInterface.php | 29 - .../phpspec/prophecy/src/Prophecy/Prophet.php | 138 - .../prophecy/src/Prophecy/Util/ExportUtil.php | 210 - .../prophecy/src/Prophecy/Util/StringUtil.php | 99 - .../phpstan/phpdoc-parser/composer.json | 1 + .../Ast/ConstExpr/ConstExprArrayItemNode.php | 5 +- .../phpdoc-parser/src/Ast/NodeAttributes.php | 38 + .../Ast/PhpDoc/AssertTagMethodValueNode.php | 50 + .../Ast/PhpDoc/AssertTagPropertyValueNode.php | 50 + .../src/Ast/PhpDoc/AssertTagValueNode.php | 46 + .../src/Ast/PhpDoc/MethodTagValueNode.php | 10 +- .../src/Ast/PhpDoc/ParamOutTagValueNode.php | 35 + .../src/Ast/PhpDoc/PhpDocNode.php | 70 + .../src/Ast/PhpDoc/SelfOutTagValueNode.php | 32 + .../src/Ast/PhpDoc/TemplateTagValueNode.php | 9 +- .../PhpDoc/TypeAliasImportTagValueNode.php | 38 + .../src/Ast/PhpDoc/TypeAliasTagValueNode.php | 32 + .../Ast/PhpDoc/TypelessParamTagValueNode.php | 41 + .../src/Ast/Type/ArrayShapeNode.php | 14 +- .../Ast/Type/CallableTypeParameterNode.php | 3 +- .../Type/ConditionalTypeForParameterNode.php | 49 + .../src/Ast/Type/ConditionalTypeNode.php | 49 + .../src/Ast/Type/GenericTypeNode.php | 27 +- .../src/Ast/Type/OffsetAccessTypeNode.php | 29 + .../phpstan/phpdoc-parser/src/Lexer/Lexer.php | 52 +- .../src/Parser/ConstExprParser.php | 112 +- .../phpdoc-parser/src/Parser/PhpDocParser.php | 162 +- .../src/Parser/TokenIterator.php | 4 +- .../phpdoc-parser/src/Parser/TypeParser.php | 79 +- .../phpunit/php-code-coverage/ChangeLog.md | 75 + app/vendor/phpunit/php-code-coverage/LICENSE | 46 +- .../phpunit/php-code-coverage/composer.json | 2 +- .../php-code-coverage/src/CodeCoverage.php | 18 +- .../phpunit/php-code-coverage/src/Filter.php | 6 +- .../php-code-coverage/src/Node/CrapIndex.php | 50 + .../php-code-coverage/src/Node/Iterator.php | 2 - .../src/RawCodeCoverageData.php | 42 +- .../src/Report/Cobertura.php | 8 +- .../src/Report/Html/Renderer/Dashboard.php | 2 +- .../src/Report/Html/Renderer/File.php | 51 +- .../Renderer/Template/css/bootstrap.min.css | 8 +- .../Html/Renderer/Template/css/style.css | 8 + .../Renderer/Template/dashboard.html.dist | 12 +- .../Template/dashboard_branch.html.dist | 12 +- .../Renderer/Template/directory.html.dist | 6 +- .../Template/directory_branch.html.dist | 6 +- .../Html/Renderer/Template/file.html.dist | 14 +- .../Renderer/Template/file_branch.html.dist | 14 +- .../Renderer/Template/file_item.html.dist | 2 +- .../Template/file_item_branch.html.dist | 2 +- .../Renderer/Template/js/bootstrap.min.js | 6 +- .../Html/Renderer/Template/js/jquery.min.js | 4 +- .../Renderer/Template/method_item.html.dist | 2 +- .../Template/method_item_branch.html.dist | 2 +- .../php-code-coverage/src/Report/PHP.php | 11 +- .../src/Report/Xml/Coverage.php | 2 +- .../src/Report/Xml/Report.php | 2 +- .../src/Report/Xml/Source.php | 2 +- .../StaticAnalysis/CachingFileAnalyser.php | 184 + .../StaticAnalysis/CodeUnitFindingVisitor.php | 3 + .../ExecutableLinesFindingVisitor.php | 449 +- .../src/StaticAnalysis/FileAnalyser.php | 31 + .../IgnoredLinesFindingVisitor.php | 35 +- .../StaticAnalysis/ParsingFileAnalyser.php | 253 + .../php-code-coverage/src/Util/Filesystem.php | 37 + .../php-code-coverage/src/Util/Percentage.php | 66 + .../phpunit/php-code-coverage/src/Version.php | 2 +- app/vendor/phpunit/phpunit/ChangeLog-8.5.md | 49 + app/vendor/phpunit/phpunit/ChangeLog-9.5.md | 180 - app/vendor/phpunit/phpunit/ChangeLog-9.6.md | 36 + app/vendor/phpunit/phpunit/LICENSE | 46 +- app/vendor/phpunit/phpunit/README.md | 21 +- app/vendor/phpunit/phpunit/SECURITY.md | 11 + app/vendor/phpunit/phpunit/composer.json | 15 +- app/vendor/phpunit/phpunit/phpunit.xsd | 8 +- .../phpunit/phpunit/src/Framework/Assert.php | 78 + .../src/Framework/Assert/Functions.php | 7 + .../src/Framework/Constraint/Constraint.php | 1 + .../src/Framework/Constraint/IsIdentical.php | 13 +- .../JsonMatchesErrorMessageProvider.php | 6 + .../Constraint/Object/ClassHasAttribute.php | 4 +- .../Object/ClassHasStaticAttribute.php | 4 +- .../Constraint/Object/ObjectHasAttribute.php | 2 + .../src/Framework/ExceptionWrapper.php | 24 +- .../MockObject/Builder/InvocationMocker.php | 2 + .../Exception/ClassIsReadonlyException.php | 28 + .../Exception/DuplicateMethodException.php | 3 + .../IncompatibleReturnValueException.php | 3 + .../ReturnValueNotConfiguredException.php | 2 + .../src/Framework/MockObject/Generator.php | 42 +- .../MockObject/Generator/intersection.tpl | 5 + .../Generator/mocked_method_never_or_void.tpl | 20 + .../proxied_method_never_or_void.tpl | 22 + .../src/Framework/MockObject/Invocation.php | 76 +- .../src/Framework/MockObject/Matcher.php | 8 +- .../src/Framework/MockObject/MockBuilder.php | 5 +- .../src/Framework/MockObject/MockMethod.php | 72 +- .../MockObject/Rule/ConsecutiveParameters.php | 2 + .../MockObject/Rule/InvokedAtIndex.php | 1 + .../phpunit/src/Framework/TestCase.php | 122 +- .../TestListenerDefaultImplementation.php | 1 + .../phpunit/src/Framework/TestResult.php | 10 +- .../phpunit/src/Framework/TestSuite.php | 43 +- .../src/Framework/TestSuiteIterator.php | 2 + .../src/Runner/DefaultTestResultCache.php | 1 + .../src/Runner/Extension/ExtensionHandler.php | 3 +- .../src/Runner/Extension/PharLoader.php | 2 + .../src/Runner/StandardTestSuiteLoader.php | 77 +- .../phpunit/phpunit/src/Runner/Version.php | 4 +- .../src/TextUI/CliArguments/Builder.php | 2 +- .../src/TextUI/CliArguments/Configuration.php | 1 + .../phpunit/phpunit/src/TextUI/Command.php | 103 +- .../src/TextUI/DefaultResultPrinter.php | 3 +- .../phpunit/phpunit/src/TextUI/TestRunner.php | 50 +- .../phpunit/src/TextUI/TestSuiteMapper.php | 14 +- .../CodeCoverage/CodeCoverage.php | 1 + .../CodeCoverage/Filter/Directory.php | 1 + .../Filter/DirectoryCollection.php | 3 + .../Filter/DirectoryCollectionIterator.php | 2 + .../CodeCoverage/Report/Clover.php | 1 + .../CodeCoverage/Report/Cobertura.php | 1 + .../CodeCoverage/Report/Crap4j.php | 1 + .../CodeCoverage/Report/Html.php | 1 + .../CodeCoverage/Report/Php.php | 1 + .../CodeCoverage/Report/Text.php | 1 + .../CodeCoverage/Report/Xml.php | 1 + .../TextUI/XmlConfiguration/Configuration.php | 1 + .../XmlConfiguration/Filesystem/Directory.php | 1 + .../Filesystem/DirectoryCollection.php | 3 + .../DirectoryCollectionIterator.php | 2 + .../XmlConfiguration/Filesystem/File.php | 1 + .../Filesystem/FileCollection.php | 3 + .../Filesystem/FileCollectionIterator.php | 2 + .../TextUI/XmlConfiguration/Group/Group.php | 1 + .../Group/GroupCollection.php | 3 + .../Group/GroupCollectionIterator.php | 2 + .../TextUI/XmlConfiguration/Group/Groups.php | 1 + .../src/TextUI/XmlConfiguration/Loader.php | 4 +- .../TextUI/XmlConfiguration/Logging/Junit.php | 1 + .../XmlConfiguration/Logging/Logging.php | 1 + .../XmlConfiguration/Logging/TeamCity.php | 1 + .../XmlConfiguration/Logging/TestDox/Html.php | 1 + .../XmlConfiguration/Logging/TestDox/Text.php | 1 + .../XmlConfiguration/Logging/TestDox/Xml.php | 1 + .../TextUI/XmlConfiguration/Logging/Text.php | 1 + .../MoveWhitelistExcludesToCoverage.php | 2 + .../Migration/Migrations/RemoveLogTypes.php | 3 + .../TextUI/XmlConfiguration/PHP/Constant.php | 1 + .../PHP/ConstantCollection.php | 3 + .../PHP/ConstantCollectionIterator.php | 2 + .../XmlConfiguration/PHP/IniSetting.php | 1 + .../PHP/IniSettingCollection.php | 3 + .../PHP/IniSettingCollectionIterator.php | 2 + .../src/TextUI/XmlConfiguration/PHP/Php.php | 1 + .../TextUI/XmlConfiguration/PHP/Variable.php | 1 + .../PHP/VariableCollection.php | 3 + .../PHP/VariableCollectionIterator.php | 2 + .../XmlConfiguration/PHPUnit/Extension.php | 2 + .../PHPUnit/ExtensionCollection.php | 3 + .../PHPUnit/ExtensionCollectionIterator.php | 2 + .../XmlConfiguration/PHPUnit/PHPUnit.php | 1 + .../TestSuite/TestDirectory.php | 1 + .../TestSuite/TestDirectoryCollection.php | 3 + .../TestDirectoryCollectionIterator.php | 2 + .../XmlConfiguration/TestSuite/TestFile.php | 1 + .../TestSuite/TestFileCollection.php | 3 + .../TestSuite/TestFileCollectionIterator.php | 2 + .../XmlConfiguration/TestSuite/TestSuite.php | 1 + .../TestSuite/TestSuiteCollection.php | 3 + .../TestSuite/TestSuiteCollectionIterator.php | 2 + .../phpunit/src/Util/Annotation/DocBlock.php | 2 +- .../phpunit/src/Util/Annotation/Registry.php | 6 +- .../phpunit/phpunit/src/Util/Cloner.php | 34 + .../phpunit/phpunit/src/Util/ExcludeList.php | 81 +- .../phpunit/phpunit/src/Util/FileLoader.php | 1 + .../phpunit/phpunit/src/Util/Log/JUnit.php | 4 +- .../phpunit/phpunit/src/Util/Log/TeamCity.php | 2 +- .../phpunit/phpunit/src/Util/Reflection.php | 63 + app/vendor/phpunit/phpunit/src/Util/Test.php | 19 +- .../src/Util/TestDox/NamePrettifier.php | 4 +- .../src/Util/TestDox/XmlResultPrinter.php | 2 +- app/vendor/phpunit/phpunit/src/Util/Type.php | 13 - .../src/Util/VersionComparisonOperator.php | 1 + app/vendor/phpunit/phpunit/src/Util/Xml.php | 2 +- .../phpunit/src/Util/Xml/SnapshotNodeList.php | 3 + .../phpunit/src/Util/XmlTestListRenderer.php | 3 +- app/vendor/psy/psysh/LICENSE | 2 +- app/vendor/psy/psysh/README.md | 3 +- app/vendor/psy/psysh/bin/psysh | 2 +- app/vendor/psy/psysh/src/CodeCleaner.php | 15 +- .../src/CodeCleaner/AbstractClassPass.php | 6 +- .../CodeCleaner/AssignThisVariablePass.php | 4 +- .../CallTimePassByReferencePass.php | 4 +- .../psysh/src/CodeCleaner/CalledClassPass.php | 8 +- .../psysh/src/CodeCleaner/CodeCleanerPass.php | 2 +- .../CodeCleaner/EmptyArrayDimFetchPass.php | 7 +- .../psy/psysh/src/CodeCleaner/ExitPass.php | 4 +- .../psysh/src/CodeCleaner/FinalClassPass.php | 8 +- .../src/CodeCleaner/FunctionContextPass.php | 9 +- .../FunctionReturnInWriteContextPass.php | 4 +- .../src/CodeCleaner/ImplicitReturnPass.php | 4 +- .../psysh/src/CodeCleaner/InstanceOfPass.php | 4 +- .../psy/psysh/src/CodeCleaner/IssetPass.php | 4 +- .../src/CodeCleaner/LabelContextPass.php | 12 +- .../src/CodeCleaner/LeavePsyshAlonePass.php | 4 +- .../psy/psysh/src/CodeCleaner/ListPass.php | 6 +- .../psysh/src/CodeCleaner/LoopContextPass.php | 8 +- .../src/CodeCleaner/MagicConstantsPass.php | 2 +- .../src/CodeCleaner/NamespaceAwarePass.php | 8 +- .../psysh/src/CodeCleaner/NamespacePass.php | 5 +- .../psysh/src/CodeCleaner/NoReturnValue.php | 4 +- .../CodeCleaner/PassableByReferencePass.php | 4 +- .../psy/psysh/src/CodeCleaner/RequirePass.php | 4 +- .../psysh/src/CodeCleaner/ReturnTypePass.php | 11 +- .../psysh/src/CodeCleaner/StrictTypesPass.php | 5 +- .../src/CodeCleaner/UseStatementPass.php | 6 +- .../src/CodeCleaner/ValidClassNamePass.php | 20 +- .../src/CodeCleaner/ValidConstructorPass.php | 7 +- .../src/CodeCleaner/ValidFunctionNamePass.php | 6 +- .../psy/psysh/src/Command/BufferCommand.php | 14 +- .../psy/psysh/src/Command/ClearCommand.php | 4 +- app/vendor/psy/psysh/src/Command/Command.php | 22 +- .../psy/psysh/src/Command/DocCommand.php | 12 +- .../psy/psysh/src/Command/DumpCommand.php | 4 +- .../psy/psysh/src/Command/EditCommand.php | 8 +- .../psy/psysh/src/Command/ExitCommand.php | 4 +- .../psy/psysh/src/Command/HelpCommand.php | 4 +- .../psy/psysh/src/Command/HistoryCommand.php | 4 +- .../psy/psysh/src/Command/ListCommand.php | 6 +- .../ListCommand/ClassConstantEnumerator.php | 10 +- .../Command/ListCommand/ClassEnumerator.php | 2 +- .../ListCommand/ConstantEnumerator.php | 4 +- .../src/Command/ListCommand/Enumerator.php | 2 +- .../ListCommand/FunctionEnumerator.php | 2 +- .../ListCommand/GlobalVariableEnumerator.php | 2 +- .../Command/ListCommand/MethodEnumerator.php | 14 +- .../ListCommand/PropertyEnumerator.php | 16 +- .../ListCommand/VariableEnumerator.php | 2 +- .../psy/psysh/src/Command/ParseCommand.php | 4 +- .../psysh/src/Command/PsyVersionCommand.php | 2 +- .../psysh/src/Command/ReflectingCommand.php | 4 +- .../psy/psysh/src/Command/ShowCommand.php | 4 +- .../psy/psysh/src/Command/SudoCommand.php | 4 +- .../psy/psysh/src/Command/ThrowUpCommand.php | 7 +- .../psy/psysh/src/Command/TimeitCommand.php | 6 +- .../Command/TimeitCommand/TimeitVisitor.php | 12 +- .../psy/psysh/src/Command/TraceCommand.php | 10 +- .../psy/psysh/src/Command/WhereamiCommand.php | 6 +- .../psy/psysh/src/Command/WtfCommand.php | 4 +- app/vendor/psy/psysh/src/ConfigPaths.php | 42 +- app/vendor/psy/psysh/src/Configuration.php | 171 +- .../psy/psysh/src/ConsoleColorFactory.php | 39 - app/vendor/psy/psysh/src/Context.php | 20 +- app/vendor/psy/psysh/src/ContextAware.php | 2 +- app/vendor/psy/psysh/src/EnvInterface.php | 2 +- .../psysh/src/Exception/BreakException.php | 6 +- .../src/Exception/DeprecatedException.php | 2 +- .../psysh/src/Exception/ErrorException.php | 22 +- .../psy/psysh/src/Exception/Exception.php | 2 +- .../src/Exception/FatalErrorException.php | 8 +- .../src/Exception/ParseErrorException.php | 4 +- .../psysh/src/Exception/RuntimeException.php | 8 +- .../psysh/src/Exception/ThrowUpException.php | 14 +- .../src/Exception/TypeErrorException.php | 21 +- .../Exception/UnexpectedTargetException.php | 6 +- app/vendor/psy/psysh/src/ExecutionClosure.php | 2 +- .../src/ExecutionLoop/AbstractListener.php | 2 +- .../psy/psysh/src/ExecutionLoop/Listener.php | 4 +- .../psysh/src/ExecutionLoop/ProcessForker.php | 6 +- .../src/ExecutionLoop/RunkitReloader.php | 6 +- .../psy/psysh/src/ExecutionLoopClosure.php | 10 +- .../psy/psysh/src/Formatter/CodeFormatter.php | 10 +- .../psysh/src/Formatter/DocblockFormatter.php | 10 +- .../psy/psysh/src/Formatter/Formatter.php | 2 +- .../src/Formatter/ReflectorFormatter.php | 4 +- .../src/Formatter/SignatureFormatter.php | 10 +- .../psysh/src/Formatter/TraceFormatter.php | 2 +- .../psy/psysh/src/Input/CodeArgument.php | 2 +- .../psy/psysh/src/Input/FilterOptions.php | 8 +- app/vendor/psy/psysh/src/Input/ShellInput.php | 2 +- .../psy/psysh/src/Input/SilentInput.php | 4 +- .../psy/psysh/src/Output/OutputPager.php | 2 +- .../psy/psysh/src/Output/PassthruPager.php | 2 +- .../psy/psysh/src/Output/ProcOutputPager.php | 3 +- .../psy/psysh/src/Output/ShellOutput.php | 70 +- app/vendor/psy/psysh/src/Output/Theme.php | 285 ++ app/vendor/psy/psysh/src/ParserFactory.php | 6 +- .../psy/psysh/src/Readline/GNUReadline.php | 13 +- .../psysh/src/Readline/Hoa/Autocompleter.php | 57 + .../Readline/Hoa/AutocompleterAggregate.php | 118 + .../src/Readline/Hoa/AutocompleterPath.php | 194 + .../src/Readline/Hoa/AutocompleterWord.php | 119 + .../psy/psysh/src/Readline/Hoa/Console.php | 347 ++ .../psysh/src/Readline/Hoa/ConsoleCursor.php | 695 +++ .../src/Readline/Hoa/ConsoleException.php | 46 + .../psysh/src/Readline/Hoa/ConsoleInput.php | 168 + .../psysh/src/Readline/Hoa/ConsoleOutput.php | 208 + .../src/Readline/Hoa/ConsoleProcessus.php | 892 ++++ .../psysh/src/Readline/Hoa/ConsoleTput.php | 841 ++++ .../psysh/src/Readline/Hoa/ConsoleWindow.php | 529 ++ .../psy/psysh/src/Readline/Hoa/Event.php | 193 + .../psysh/src/Readline/Hoa/EventBucket.php | 109 + .../psysh/src/Readline/Hoa/EventException.php | 44 + .../src/Readline/Hoa/EventListenable.php | 48 + .../psysh/src/Readline/Hoa/EventListener.php | 137 + .../psysh/src/Readline/Hoa/EventListens.php | 83 + .../psysh/src/Readline/Hoa/EventSource.php | 44 + .../psy/psysh/src/Readline/Hoa/Exception.php | 79 + .../psysh/src/Readline/Hoa/ExceptionIdle.php | 267 + .../psy/psysh/src/Readline/Hoa/File.php | 278 ++ .../psysh/src/Readline/Hoa/FileDirectory.php | 221 + .../Hoa/FileDoesNotExistException.php | 48 + .../psysh/src/Readline/Hoa/FileException.php | 48 + .../psy/psysh/src/Readline/Hoa/FileFinder.php | 658 +++ .../psysh/src/Readline/Hoa/FileGeneric.php | 487 ++ .../psy/psysh/src/Readline/Hoa/FileLink.php | 149 + .../psysh/src/Readline/Hoa/FileLinkRead.php | 231 + .../src/Readline/Hoa/FileLinkReadWrite.php | 279 ++ .../psy/psysh/src/Readline/Hoa/FileRead.php | 177 + .../psysh/src/Readline/Hoa/FileReadWrite.php | 279 ++ .../psy/psysh/src/Readline/Hoa/IStream.php | 50 + .../src/Readline/Hoa/IteratorFileSystem.php | 86 + .../Hoa/IteratorRecursiveDirectory.php | 126 + .../src/Readline/Hoa/IteratorSplFileInfo.php | 122 + .../psy/psysh/src/Readline/Hoa/Protocol.php | 223 + .../src/Readline/Hoa/ProtocolException.php | 44 + .../psysh/src/Readline/Hoa/ProtocolNode.php | 323 ++ .../src/Readline/Hoa/ProtocolNodeLibrary.php | 90 + .../src/Readline/Hoa/ProtocolWrapper.php | 473 ++ .../psy/psysh/src/Readline/Hoa/Readline.php | 1032 ++++ .../psy/psysh/src/Readline/Hoa/Stream.php | 571 +++ .../src/Readline/Hoa/StreamBufferable.php | 73 + .../psysh/src/Readline/Hoa/StreamContext.php | 141 + .../src/Readline/Hoa/StreamException.php | 46 + .../psy/psysh/src/Readline/Hoa/StreamIn.php | 102 + .../psysh/src/Readline/Hoa/StreamLockable.php | 85 + .../psy/psysh/src/Readline/Hoa/StreamOut.php | 95 + .../psysh/src/Readline/Hoa/StreamPathable.php | 55 + .../src/Readline/Hoa/StreamPointable.php | 75 + .../psysh/src/Readline/Hoa/StreamStatable.php | 115 + .../src/Readline/Hoa/StreamTouchable.php | 110 + .../src/Readline/Hoa/Terminfo/77/windows-ansi | Bin 0 -> 1481 bytes .../psysh/src/Readline/Hoa/Terminfo/78/xterm | Bin 0 -> 3258 bytes .../Readline/Hoa/Terminfo/78/xterm-256color | Bin 0 -> 3322 bytes .../psy/psysh/src/Readline/Hoa/Ustring.php | 143 + .../psy/psysh/src/Readline/Hoa/Xcallable.php | 256 + .../psy/psysh/src/Readline/HoaConsole.php | 2 +- app/vendor/psy/psysh/src/Readline/Libedit.php | 4 +- .../psy/psysh/src/Readline/Readline.php | 15 +- .../psy/psysh/src/Readline/Transient.php | 2 +- .../psy/psysh/src/Readline/Userland.php | 165 + .../Reflection/ReflectionClassConstant.php | 10 +- .../src/Reflection/ReflectionConstant.php | 2 +- .../src/Reflection/ReflectionConstant_.php | 10 +- .../ReflectionLanguageConstruct.php | 10 +- .../ReflectionLanguageConstructParameter.php | 2 +- .../src/Reflection/ReflectionNamespace.php | 2 +- app/vendor/psy/psysh/src/Shell.php | 182 +- app/vendor/psy/psysh/src/Sudo.php | 40 +- app/vendor/psy/psysh/src/Sudo/SudoVisitor.php | 13 +- app/vendor/psy/psysh/src/SuperglobalsEnv.php | 2 +- .../psysh/src/TabCompletion/AutoCompleter.php | 2 +- .../Matcher/AbstractContextAwareMatcher.php | 2 +- .../AbstractDefaultParametersMatcher.php | 6 +- .../TabCompletion/Matcher/AbstractMatcher.php | 18 +- .../Matcher/ClassAttributesMatcher.php | 2 +- .../ClassMethodDefaultParametersMatcher.php | 2 +- .../Matcher/ClassMethodsMatcher.php | 2 +- .../Matcher/ClassNamesMatcher.php | 2 +- .../TabCompletion/Matcher/CommandsMatcher.php | 6 +- .../Matcher/ConstantsMatcher.php | 2 +- .../FunctionDefaultParametersMatcher.php | 2 +- .../Matcher/FunctionsMatcher.php | 2 +- .../TabCompletion/Matcher/KeywordsMatcher.php | 6 +- .../Matcher/MongoClientMatcher.php | 2 +- .../Matcher/MongoDatabaseMatcher.php | 2 +- .../Matcher/ObjectAttributesMatcher.php | 2 +- .../ObjectMethodDefaultParametersMatcher.php | 2 +- .../Matcher/ObjectMethodsMatcher.php | 2 +- .../Matcher/VariablesMatcher.php | 2 +- app/vendor/psy/psysh/src/Util/Docblock.php | 17 +- app/vendor/psy/psysh/src/Util/Json.php | 4 +- app/vendor/psy/psysh/src/Util/Mirror.php | 2 +- app/vendor/psy/psysh/src/Util/Str.php | 8 +- app/vendor/psy/psysh/src/VarDumper/Cloner.php | 2 +- app/vendor/psy/psysh/src/VarDumper/Dumper.php | 2 +- .../psy/psysh/src/VarDumper/Presenter.php | 8 +- .../psysh/src/VarDumper/PresenterAware.php | 2 +- .../psy/psysh/src/VersionUpdater/Checker.php | 8 +- .../psysh/src/VersionUpdater/Downloader.php | 43 + .../Downloader/CurlDownloader.php | 84 + .../src/VersionUpdater/Downloader/Factory.php | 31 + .../Downloader/FileDownloader.php | 56 + .../src/VersionUpdater/GitHubChecker.php | 10 +- .../psysh/src/VersionUpdater/Installer.php | 143 + .../src/VersionUpdater/IntervalChecker.php | 7 +- .../psysh/src/VersionUpdater/NoopChecker.php | 10 +- .../psysh/src/VersionUpdater/SelfUpdate.php | 186 + app/vendor/psy/psysh/src/functions.php | 30 +- app/vendor/robmorgan/phinx/README.md | 2 +- app/vendor/robmorgan/phinx/composer.json | 8 +- app/vendor/robmorgan/phinx/docs/config/all.py | 10 +- .../robmorgan/phinx/docs/en/configuration.rst | 109 +- .../robmorgan/phinx/docs/en/contents.rst | 1 - app/vendor/robmorgan/phinx/docs/en/index.rst | 2 + .../robmorgan/phinx/docs/en/migrations.rst | 103 +- .../robmorgan/phinx/docs/en/namespaces.rst | 6 +- .../robmorgan/phinx/docs/en/seeding.rst | 57 +- .../robmorgan/phinx/docs/es/commands.rst | 292 -- app/vendor/robmorgan/phinx/docs/es/conf.py | 9 - .../robmorgan/phinx/docs/es/contents.rst | 8 - .../robmorgan/phinx/docs/fr/commands.rst | 339 -- app/vendor/robmorgan/phinx/docs/fr/conf.py | 9 - .../robmorgan/phinx/docs/fr/configuration.rst | 308 -- .../robmorgan/phinx/docs/fr/contents.rst | 11 - app/vendor/robmorgan/phinx/docs/fr/index.rst | 57 - .../robmorgan/phinx/docs/fr/migrations.rst | 1305 ----- .../robmorgan/phinx/docs/fr/seeding.rst | 217 - .../robmorgan/phinx/docs/ja/commands.rst | 338 -- app/vendor/robmorgan/phinx/docs/ja/conf.py | 9 - .../robmorgan/phinx/docs/ja/configuration.rst | 305 -- .../robmorgan/phinx/docs/ja/contents.rst | 12 - app/vendor/robmorgan/phinx/docs/ja/index.rst | 60 - .../robmorgan/phinx/docs/ja/migrations.rst | 1293 ----- .../robmorgan/phinx/docs/ja/seeding.rst | 214 - .../robmorgan/phinx/phpstan-baseline.neon | 24 +- .../phinx/src/Phinx/Config/Config.php | 151 +- .../src/Phinx/Config/ConfigInterface.php | 45 +- .../phinx/src/Phinx/Config/FeatureFlags.php | 41 + .../Phinx/Config/NamespaceAwareInterface.php | 4 +- .../src/Phinx/Config/NamespaceAwareTrait.php | 10 +- .../Phinx/Console/Command/AbstractCommand.php | 57 +- .../src/Phinx/Console/Command/Breakpoint.php | 9 +- .../src/Phinx/Console/Command/Create.php | 30 +- .../phinx/src/Phinx/Console/Command/Init.php | 12 +- .../src/Phinx/Console/Command/ListAliases.php | 8 +- .../src/Phinx/Console/Command/Migrate.php | 12 +- .../src/Phinx/Console/Command/Rollback.php | 10 +- .../src/Phinx/Console/Command/SeedCreate.php | 28 +- .../src/Phinx/Console/Command/SeedRun.php | 10 +- .../src/Phinx/Console/Command/Status.php | 10 +- .../phinx/src/Phinx/Console/Command/Test.php | 11 +- .../src/Phinx/Console/PhinxApplication.php | 2 +- .../phinx/src/Phinx/Db/Action/Action.php | 2 +- .../phinx/src/Phinx/Db/Action/AddColumn.php | 10 +- .../src/Phinx/Db/Action/AddForeignKey.php | 8 +- .../phinx/src/Phinx/Db/Action/AddIndex.php | 12 +- .../src/Phinx/Db/Action/ChangeColumn.php | 18 +- .../src/Phinx/Db/Action/ChangeComment.php | 4 +- .../src/Phinx/Db/Action/DropForeignKey.php | 6 +- .../phinx/src/Phinx/Db/Action/DropIndex.php | 8 +- .../src/Phinx/Db/Action/RemoveColumn.php | 8 +- .../src/Phinx/Db/Action/RenameColumn.php | 16 +- .../phinx/src/Phinx/Db/Action/RenameTable.php | 6 +- .../src/Phinx/Db/Adapter/AbstractAdapter.php | 71 +- .../src/Phinx/Db/Adapter/AdapterFactory.php | 36 +- .../src/Phinx/Db/Adapter/AdapterInterface.php | 132 +- .../src/Phinx/Db/Adapter/AdapterWrapper.php | 117 +- .../Db/Adapter/DirectActionInterface.php | 28 +- .../src/Phinx/Db/Adapter/MysqlAdapter.php | 129 +- .../phinx/src/Phinx/Db/Adapter/PdoAdapter.php | 177 +- .../src/Phinx/Db/Adapter/PostgresAdapter.php | 271 +- .../src/Phinx/Db/Adapter/ProxyAdapter.php | 16 +- .../src/Phinx/Db/Adapter/SQLiteAdapter.php | 300 +- .../src/Phinx/Db/Adapter/SqlServerAdapter.php | 146 +- .../Phinx/Db/Adapter/TablePrefixAdapter.php | 70 +- .../Phinx/Db/Adapter/TimedOutputAdapter.php | 50 +- .../src/Phinx/Db/Adapter/WrapperInterface.php | 4 +- .../phinx/src/Phinx/Db/Plan/AlterTable.php | 6 +- .../phinx/src/Phinx/Db/Plan/Intent.php | 6 +- .../phinx/src/Phinx/Db/Plan/NewTable.php | 10 +- .../phinx/src/Phinx/Db/Plan/Plan.php | 43 +- .../Phinx/Db/Plan/Solver/ActionSplitter.php | 4 +- .../robmorgan/phinx/src/Phinx/Db/Table.php | 102 +- .../phinx/src/Phinx/Db/Table/Column.php | 205 +- .../phinx/src/Phinx/Db/Table/ForeignKey.php | 41 +- .../phinx/src/Phinx/Db/Table/Index.php | 40 +- .../phinx/src/Phinx/Db/Table/Table.php | 18 +- .../src/Phinx/Db/Util/AlterInstructions.php | 12 +- .../src/Phinx/Migration/AbstractMigration.php | 113 +- .../Migration/AbstractTemplateCreation.php | 8 +- .../src/Phinx/Migration/CreationInterface.php | 12 +- .../phinx/src/Phinx/Migration/Manager.php | 179 +- .../Phinx/Migration/Manager/Environment.php | 50 +- ...ist => Migration.change.template.php.dist} | 0 .../Migration.up_down.template.php.dist | 17 + .../Phinx/Migration/MigrationInterface.php | 107 +- .../phinx/src/Phinx/Seed/AbstractSeed.php | 75 +- .../src/Phinx/Seed/Seed.template.php.dist | 2 +- .../phinx/src/Phinx/Seed/SeedInterface.php | 66 +- .../phinx/src/Phinx/Util/Expression.php | 6 +- .../phinx/src/Phinx/Util/Literal.php | 6 +- .../robmorgan/phinx/src/Phinx/Util/Util.php | 35 +- .../phinx/src/Phinx/Wrapper/TextWrapper.php | 49 +- app/vendor/sebastian/comparator/ChangeLog.md | 41 +- .../comparator/src/DoubleComparator.php | 2 + .../sebastian/comparator/src/Factory.php | 1 - .../comparator/src/NumericComparator.php | 4 +- .../comparator/src/ScalarComparator.php | 3 +- app/vendor/sebastian/environment/ChangeLog.md | 7 + .../sebastian/environment/src/Console.php | 6 +- app/vendor/sebastian/exporter/ChangeLog.md | 14 + .../sebastian/exporter/src/Exporter.php | 20 +- .../recursion-context/.psalm/baseline.xml | 8 - .../sebastian/recursion-context/ChangeLog.md | 7 + .../sebastian/recursion-context/LICENSE | 2 +- .../sebastian/recursion-context/composer.json | 2 +- .../recursion-context/src/Context.php | 13 +- .../recursion-context/src/Exception.php | 2 +- .../src/InvalidArgumentException.php | 2 +- app/vendor/sebastian/type/ChangeLog.md | 27 +- app/vendor/sebastian/type/composer.json | 2 +- app/vendor/sebastian/type/src/Parameter.php | 42 + .../sebastian/type/src/ReflectionMapper.php | 143 +- .../sebastian/type/src/type/CallableType.php | 212 + .../sebastian/type/src/type/FalseType.php | 42 + .../type/src/type/GenericObjectType.php | 54 + .../type/src/type/IntersectionType.php | 126 + .../sebastian/type/src/type/IterableType.php | 84 + .../sebastian/type/src/type/MixedType.php | 41 + .../sebastian/type/src/type/NeverType.php | 36 + .../sebastian/type/src/type/NullType.php | 41 + .../sebastian/type/src/type/ObjectType.php | 74 + .../sebastian/type/src/type/SimpleType.php | 104 + .../sebastian/type/src/type/StaticType.php | 68 + .../sebastian/type/src/type/TrueType.php | 42 + app/vendor/sebastian/type/src/type/Type.php | 226 + .../sebastian/type/src/type/UnionType.php | 138 + .../sebastian/type/src/type/UnknownType.php | 41 + .../sebastian/type/src/type/VoidType.php | 36 + app/vendor/seld/phar-utils/src/Timestamps.php | 6 +- .../workflows/continuous-integration.yml | 56 + .../signal-handler/.github/workflows/lint.yml | 30 + .../.github/workflows/phpstan.yml | 46 + app/vendor/seld/signal-handler/.php_cs | 17 + .../seld/signal-handler/CHANGELOG.mdown | 31 + .../signal-handler}/LICENSE | 12 +- app/vendor/seld/signal-handler/README.mdown | 139 + app/vendor/seld/signal-handler/composer.json | 40 + .../seld/signal-handler/phpstan-baseline.neon | 6 + .../seld/signal-handler/phpstan.neon.dist | 15 + .../seld/signal-handler/phpunit.xml.dist | 24 + .../seld/signal-handler/src/SignalHandler.php | 567 +++ .../tests/SignalHandlerTest.php | 263 + app/vendor/slevomat/coding-standard/README.md | 1453 +----- .../Helpers/Annotation/AssertAnnotation.php | 87 + .../Helpers/Annotation/MethodAnnotation.php | 23 +- .../Annotation/ParameterAnnotation.php | 21 +- .../Annotation/ParameterOutAnnotation.php | 102 + .../Helpers/Annotation/SelfOutAnnotation.php | 94 + .../Helpers/Annotation/TemplateAnnotation.php | 11 + .../Annotation/TypeAliasAnnotation.php | 67 + .../Annotation/TypeImportAnnotation.php | 100 + .../Helpers/AnnotationHelper.php | 209 +- .../Helpers/AnnotationTypeHelper.php | 32 +- .../Helpers/Attribute.php | 60 + .../Helpers/AttributeHelper.php | 151 + .../Helpers/ClassHelper.php | 4 +- .../Helpers/CommentHelper.php | 9 +- .../Helpers/DocCommentHelper.php | 55 +- .../Helpers/FixerHelper.php | 26 +- .../Helpers/FunctionHelper.php | 59 +- .../Helpers/NamespaceHelper.php | 6 + .../Helpers/PropertyHelper.php | 20 +- .../Helpers/ReferencedNameHelper.php | 30 +- .../Helpers/SniffSettingsHelper.php | 8 + .../Helpers/SuppressHelper.php | 4 +- .../Helpers/TernaryOperatorHelper.php | 182 + .../Helpers/TokenHelper.php | 87 +- .../Helpers/TypeHelper.php | 6 +- .../Helpers/TypeHint.php | 59 + .../Helpers/TypeHintHelper.php | 123 +- .../Helpers/UseStatementHelper.php | 16 + .../Helpers/YodaHelper.php | 6 +- .../Arrays/SingleLineArrayWhitespaceSniff.php | 29 +- .../AttributeAndTargetSpacingSniff.php | 113 + .../Attributes/AttributesOrderSniff.php | 197 + .../DisallowAttributesJoiningSniff.php | 72 + ...DisallowMultipleAttributesPerLineSniff.php | 82 + .../RequireAttributeAfterDocCommentSniff.php | 86 + .../AbstractPropertyAndConstantSpacing.php | 23 +- .../Classes/BackedEnumTypeSpacingSniff.php | 121 + .../Classes/ClassConstantVisibilitySniff.php | 4 +- .../Sniffs/Classes/ClassLengthSniff.php | 64 + .../Classes/ClassMemberSpacingSniff.php | 35 +- .../Sniffs/Classes/ClassStructureSniff.php | 36 +- .../Sniffs/Classes/ConstantSpacingSniff.php | 4 +- ...allowConstructorPropertyPromotionSniff.php | 69 + .../DisallowMultiConstantDefinitionSniff.php | 18 +- .../DisallowMultiPropertyDefinitionSniff.php | 30 +- .../EmptyLinesAroundClassBracesSniff.php | 56 +- .../Classes/ForbiddenPublicPropertySniff.php | 77 + .../Sniffs/Classes/MethodSpacingSniff.php | 35 +- .../Classes/ModernClassNameReferenceSniff.php | 7 +- .../Sniffs/Classes/ParentCallSpacingSniff.php | 13 +- .../Classes/PropertyDeclarationSniff.php | 405 ++ .../Sniffs/Classes/PropertySpacingSniff.php | 11 +- .../Classes/RequireAbstractOrFinalSniff.php | 62 + ...quireConstructorPropertyPromotionSniff.php | 400 ++ .../RequireMultiLineMethodSignatureSniff.php | 14 +- .../RequireSingleLineMethodSignatureSniff.php | 10 +- .../Classes/TraitUseDeclarationSniff.php | 8 +- .../Sniffs/Classes/TraitUseSpacingSniff.php | 49 +- .../Classes/UselessLateStaticBindingSniff.php | 7 +- .../AbstractRequireOneLineDocComment.php | 6 +- .../DisallowCommentAfterCodeSniff.php | 23 +- .../Commenting/DocCommentSpacingSniff.php | 104 +- .../Sniffs/Commenting/EmptyCommentSniff.php | 16 +- .../Commenting/ForbiddenAnnotationsSniff.php | 10 +- .../Commenting/ForbiddenCommentsSniff.php | 9 +- .../InlineDocCommentDeclarationSniff.php | 198 +- .../UselessFunctionDocCommentSniff.php | 7 +- .../UselessInheritDocCommentSniff.php | 10 +- .../Sniffs/Complexity/CognitiveSniff.php | 291 ++ .../AbstractControlStructureSpacing.php | 29 +- .../AbstractLineCondition.php | 4 +- .../BlockControlStructureSpacingSniff.php | 13 +- .../DisallowNullSafeObjectOperatorSniff.php | 33 + .../ControlStructures/EarlyExitSniff.php | 26 +- .../JumpStatementsSpacingSniff.php | 28 +- .../NewWithoutParenthesesSniff.php | 14 +- .../RequireMultiLineConditionSniff.php | 18 +- .../RequireMultiLineTernaryOperatorSniff.php | 21 +- .../RequireNullCoalesceEqualOperatorSniff.php | 5 +- .../RequireNullCoalesceOperatorSniff.php | 17 +- .../RequireNullSafeObjectOperatorSniff.php | 454 ++ .../RequireShortTernaryOperatorSniff.php | 9 +- .../RequireSingleLineConditionSniff.php | 13 +- .../RequireTernaryOperatorSniff.php | 32 +- .../UnsupportedKeywordException.php | 17 + .../UselessIfConditionWithReturnSniff.php | 9 +- .../UselessTernaryOperatorSniff.php | 9 +- .../DisallowNonCapturingCatchSniff.php | 46 + .../ReferenceThrowableOnlySniff.php | 5 +- .../RequireNonCapturingCatchSniff.php | 155 + .../Sniffs/Files/FileLengthSniff.php | 63 + .../Sniffs/Files/FunctionLengthSniff.php | 12 + .../Files/TypeNameMatchesFileNameSniff.php | 9 +- .../ArrowFunctionDeclarationSniff.php | 49 +- .../Functions/DisallowNamedArgumentsSniff.php | 40 + .../DisallowTrailingCommaInCallSniff.php | 95 + ...DisallowTrailingCommaInClosureUseSniff.php | 86 + ...isallowTrailingCommaInDeclarationSniff.php | 74 + .../Sniffs/Functions/FunctionLengthSniff.php | 68 + .../Functions/RequireArrowFunctionSniff.php | 19 +- .../Functions/RequireMultiLineCallSniff.php | 10 +- .../Functions/RequireSingleLineCallSniff.php | 16 +- .../RequireTrailingCommaInCallSniff.php | 112 + .../RequireTrailingCommaInClosureUseSniff.php | 85 + ...RequireTrailingCommaInDeclarationSniff.php | 77 + ...dInheritedVariablePassedToClosureSniff.php | 10 +- .../AbstractFullyQualifiedGlobalReference.php | 2 +- .../AlphabeticallySortedUsesSniff.php | 8 +- ...llyQualifiedClassNameInAnnotationSniff.php | 49 +- .../FullyQualifiedExceptionsSniff.php | 6 +- .../Namespaces/NamespaceDeclarationSniff.php | 7 +- .../Namespaces/NamespaceSpacingSniff.php | 38 +- .../ReferenceUsedNamesOnlySniff.php | 48 +- .../Sniffs/Namespaces/UnusedUsesSniff.php | 50 +- .../Namespaces/UseFromSameNamespaceSniff.php | 7 +- .../Sniffs/Namespaces/UseSpacingSniff.php | 66 +- .../Sniffs/Namespaces/UselessAliasSniff.php | 7 +- .../RequireNumericLiteralSeparatorSniff.php | 6 +- .../NegationOperatorSpacingSniff.php | 9 +- ...RequireCombinedAssignmentOperatorSniff.php | 30 +- .../Operators/SpreadOperatorSpacingSniff.php | 23 +- .../DisallowDirectMagicInvokeCallSniff.php | 5 +- .../Sniffs/PHP/ForbiddenClassesSniff.php | 5 +- .../Sniffs/PHP/ReferenceSpacingSniff.php | 22 +- .../PHP/RequireExplicitAssertionSniff.php | 160 +- .../Sniffs/PHP/RequireNowdocSniff.php | 2 +- .../Sniffs/PHP/ShortListSniff.php | 5 +- .../Sniffs/PHP/TypeCastSniff.php | 5 +- .../Sniffs/PHP/UselessParenthesesSniff.php | 56 +- .../Sniffs/PHP/UselessSemicolonSniff.php | 7 +- .../TypeHints/DeclareStrictTypesSniff.php | 55 +- .../DisallowArrayTypeHintSyntaxSniff.php | 5 +- .../Sniffs/TypeHints/LongTypeHintsSniff.php | 5 +- .../NullTypeHintOnLastPositionSniff.php | 9 +- .../TypeHints/ParameterTypeHintSniff.php | 77 +- .../ParameterTypeHintSpacingSniff.php | 10 +- .../TypeHints/PropertyTypeHintSniff.php | 66 +- .../PropertyTypeHintSpacingSniff.php | 162 - .../Sniffs/TypeHints/ReturnTypeHintSniff.php | 96 +- .../TypeHints/ReturnTypeHintSpacingSniff.php | 17 +- .../TypeHints/UnionTypeHintFormatSniff.php | 249 + .../UselessConstantTypeHintSniff.php | 8 +- .../Sniffs/Variables/UselessVariableSniff.php | 63 +- .../Whitespaces/DuplicateSpacesSniff.php | 6 +- .../slevomat/coding-standard/composer.json | 23 +- .../slevomat/coding-standard/doc/arrays.md | 30 + .../coding-standard/doc/attributes.md | 47 + .../slevomat/coding-standard/doc/classes.md | 260 + .../coding-standard/doc/commenting.md | 109 + .../coding-standard/doc/complexity.md | 9 + .../coding-standard/doc/control-structures.md | 243 + .../coding-standard/doc/exceptions.md | 31 + .../slevomat/coding-standard/doc/files.md | 59 + .../slevomat/coding-standard/doc/functions.md | 132 + .../coding-standard/doc/namespaces.md | 182 + .../slevomat/coding-standard/doc/numbers.md | 16 + .../slevomat/coding-standard/doc/operators.md | 33 + .../slevomat/coding-standard/doc/php.md | 80 + .../coding-standard/doc/type-hints.md | 130 + .../slevomat/coding-standard/doc/variables.md | 27 + .../coding-standard/doc/whitespaces.md | 13 + .../php_codesniffer/CodeSniffer.conf | 2 +- .../php_codesniffer/CodeSniffer.conf.dist | 2 +- .../squizlabs/php_codesniffer/README.md | 65 +- .../squizlabs/php_codesniffer/src/Config.php | 8 +- .../php_codesniffer/src/Files/File.php | 88 +- .../php_codesniffer/src/Reports/Code.php | 2 +- .../php_codesniffer/src/Reports/Gitblame.php | 2 +- .../php_codesniffer/src/Reports/Hgblame.php | 2 +- .../php_codesniffer/src/Reports/Svnblame.php | 2 +- .../squizlabs/php_codesniffer/src/Runner.php | 97 +- .../php_codesniffer/src/Sniffs/Sniff.php | 2 +- .../AbstractClassNamePrefixStandard.xml | 23 + .../InterfaceNameSuffixStandard.xml | 23 + .../TraitNameSuffixStandard.xml | 23 + .../Classes/DuplicateClassNameSniff.php | 1 + .../Classes/OpeningBraceSameLineSniff.php | 1 + .../Sniffs/Files/OneClassPerFileSniff.php | 8 +- .../Sniffs/Files/OneInterfacePerFileSniff.php | 8 +- .../Files/OneObjectStructurePerFileSniff.php | 9 +- .../Sniffs/Files/OneTraitPerFileSniff.php | 8 +- .../Metrics/CyclomaticComplexitySniff.php | 25 +- .../AbstractClassNamePrefixSniff.php | 60 + .../InterfaceNameSuffixSniff.php | 54 + .../TraitNameSuffixSniff.php | 54 + .../Sniffs/PHP/LowerCaseConstantSniff.php | 106 +- .../Sniffs/PHP/LowerCaseKeywordSniff.php | 91 +- .../Generic/Sniffs/PHP/LowerCaseTypeSniff.php | 13 +- .../Sniffs/PHP/UpperCaseConstantSniff.php | 26 +- .../Sniffs/WhiteSpace/ScopeIndentSniff.php | 7 +- .../Classes/DuplicateClassNameUnitTest.1.inc | 5 +- .../Classes/DuplicateClassNameUnitTest.2.inc | 1 + .../Classes/DuplicateClassNameUnitTest.php | 6 +- .../Classes/OpeningBraceSameLineUnitTest.inc | 4 + .../OpeningBraceSameLineUnitTest.inc.fixed | 4 + .../Classes/OpeningBraceSameLineUnitTest.php | 1 + .../Tests/Files/EndFileNewlineUnitTest.6.inc | 1 + .../Files/EndFileNewlineUnitTest.6.inc.fixed | 1 + .../Tests/Files/EndFileNewlineUnitTest.7.inc | 1 + .../Files/EndFileNewlineUnitTest.7.inc.fixed | 1 + .../Tests/Files/EndFileNewlineUnitTest.8.inc | 1 + .../Files/EndFileNoNewlineUnitTest.10.inc | 1 + .../Files/EndFileNoNewlineUnitTest.8.inc | 1 + .../EndFileNoNewlineUnitTest.8.inc.fixed | 1 + .../Files/EndFileNoNewlineUnitTest.9.inc | 1 + .../EndFileNoNewlineUnitTest.9.inc.fixed | 1 + .../Tests/Files/ExecutableFileUnitTest.3.inc | 1 + .../Tests/Files/ExecutableFileUnitTest.4.inc | 1 + .../Tests/Files/ExecutableFileUnitTest.php | 2 +- .../Tests/Files/LineEndingsUnitTest.1.inc | 18 + .../Files/LineEndingsUnitTest.1.inc.fixed | 18 + .../Tests/Files/LineEndingsUnitTest.2.inc | 5 + .../Files/LineEndingsUnitTest.2.inc.fixed | 5 + .../Files/LowercasedFilenameUnitTest.1.inc | 7 + .../Files/LowercasedFilenameUnitTest.2.inc | 7 + .../OneObjectStructurePerFileUnitTest.inc | 9 +- .../OneObjectStructurePerFileUnitTest.php | 1 + .../Metrics/CyclomaticComplexityUnitTest.inc | 18 + .../Metrics/CyclomaticComplexityUnitTest.php | 1 + .../AbstractClassNamePrefixUnitTest.inc | 59 + .../AbstractClassNamePrefixUnitTest.php | 53 + .../CamelCapsFunctionNameUnitTest.inc | 18 + .../CamelCapsFunctionNameUnitTest.php | 4 + .../InterfaceNameSuffixUnitTest.inc | 27 + .../InterfaceNameSuffixUnitTest.php | 47 + .../TraitNameSuffixUnitTest.inc | 13 + .../TraitNameSuffixUnitTest.php | 50 + .../Tests/PHP/ClosingPHPTagUnitTest.1.inc | 10 + .../Tests/PHP/ClosingPHPTagUnitTest.2.inc | 5 + .../Tests/PHP/LowerCaseConstantUnitTest.inc | 17 + .../PHP/LowerCaseConstantUnitTest.inc.fixed | 17 + .../Tests/PHP/LowerCaseConstantUnitTest.php | 35 +- .../Tests/PHP/LowerCaseKeywordUnitTest.inc | 9 + .../PHP/LowerCaseKeywordUnitTest.inc.fixed | 9 + .../Tests/PHP/LowerCaseKeywordUnitTest.php | 3 + .../Tests/PHP/LowerCaseTypeUnitTest.inc | 8 + .../Tests/PHP/LowerCaseTypeUnitTest.inc.fixed | 8 + .../Tests/PHP/LowerCaseTypeUnitTest.php | 1 + .../Generic/Tests/PHP/SyntaxUnitTest.1.inc | 4 + .../Generic/Tests/PHP/SyntaxUnitTest.2.inc | 3 + .../Tests/PHP/UpperCaseConstantUnitTest.inc | 19 +- .../PHP/UpperCaseConstantUnitTest.inc.fixed | 19 +- .../Tests/PHP/UpperCaseConstantUnitTest.php | 7 + .../GitMergeConflictUnitTest.7.inc | 19 + .../DisallowSpaceIndentUnitTest.3.inc | 19 + .../DisallowSpaceIndentUnitTest.3.inc.fixed | 19 + .../DisallowTabIndentUnitTest.1.inc | 93 + .../DisallowTabIndentUnitTest.1.inc.fixed | 93 + .../DisallowTabIndentUnitTest.2.inc | 19 + .../DisallowTabIndentUnitTest.2.inc.fixed | 19 + .../WhiteSpace/ScopeIndentUnitTest.1.inc | 18 +- .../ScopeIndentUnitTest.1.inc.fixed | 18 +- .../WhiteSpace/ScopeIndentUnitTest.2.inc | 18 +- .../ScopeIndentUnitTest.2.inc.fixed | 18 +- .../Tests/WhiteSpace/ScopeIndentUnitTest.php | 8 +- .../Sniffs/Classes/ClassDeclarationSniff.php | 1 + .../Sniffs/Commenting/ClassCommentSniff.php | 1 + .../Sniffs/Commenting/FileCommentSniff.php | 1 + .../NamingConventions/ValidClassNameSniff.php | 1 + .../Classes/ClassDeclarationUnitTest.1.inc | 2 + .../ClassDeclarationUnitTest.1.inc.fixed | 4 + .../Classes/ClassDeclarationUnitTest.php | 1 + .../Tests/Commenting/ClassCommentUnitTest.inc | 10 + .../Tests/Commenting/ClassCommentUnitTest.php | 1 + .../Commenting/FileCommentUnitTest.1.inc | 53 + .../Commenting/FileCommentUnitTest.2.inc | 9 + .../Commenting/FileCommentUnitTest.3.inc | 8 + .../Tests/Commenting/FileCommentUnitTest.php | 3 + .../ValidClassNameUnitTest.inc | 22 + .../ValidClassNameUnitTest.php | 6 + .../ValidFunctionNameUnitTest.inc | 21 + .../ValidFunctionNameUnitTest.php | 4 + .../WhiteSpace/ScopeClosingBraceUnitTest.inc | 10 + .../ScopeClosingBraceUnitTest.inc.fixed | 11 + .../WhiteSpace/ScopeClosingBraceUnitTest.php | 2 + .../Sniffs/Classes/ClassDeclarationSniff.php | 5 +- .../PSR1/Sniffs/Files/SideEffectsSniff.php | 1 + .../Classes/ClassDeclarationUnitTest.3.inc | 3 + .../Tests/Files/SideEffectsUnitTest.1.inc | 6 + .../Sniffs/Classes/ClosingBraceSniff.php | 1 + .../Sniffs/Classes/OpeningBraceSpaceSniff.php | 80 + .../Properties/ConstantVisibilitySniff.php | 5 +- .../Tests/Classes/ClosingBraceUnitTest.inc | 5 + .../Tests/Classes/ClosingBraceUnitTest.php | 1 + .../Classes/OpeningBraceSpaceUnitTest.inc | 57 + .../OpeningBraceSpaceUnitTest.inc.fixed | 48 + .../Classes/OpeningBraceSpaceUnitTest.php | 55 + .../Tests/Files/FileHeaderUnitTest.17.inc | 13 + .../Tests/Files/ImportStatementUnitTest.inc | 7 + .../Files/ImportStatementUnitTest.inc.fixed | 7 + .../Properties/ConstantVisibilityUnitTest.inc | 15 + .../Properties/ConstantVisibilityUnitTest.php | 6 +- .../Tests/Traits/UseDeclarationUnitTest.inc | 12 + .../Traits/UseDeclarationUnitTest.inc.fixed | 10 + .../Tests/Traits/UseDeclarationUnitTest.php | 1 + .../Classes/PropertyDeclarationSniff.php | 1 + .../SwitchDeclarationSniff.php | 2 +- .../Sniffs/Namespaces/UseDeclarationSniff.php | 2 +- .../Classes/PropertyDeclarationUnitTest.inc | 10 + .../PropertyDeclarationUnitTest.inc.fixed | 10 + .../Classes/PropertyDeclarationUnitTest.php | 3 + .../SwitchDeclarationUnitTest.inc | 14 +- .../SwitchDeclarationUnitTest.inc.fixed | 14 +- .../Tests/Files/EndFileNewlineUnitTest.11.inc | 1 + .../Files/EndFileNewlineUnitTest.11.inc.fixed | 1 + .../Tests/Files/EndFileNewlineUnitTest.12.inc | 1 + .../Files/EndFileNewlineUnitTest.12.inc.fixed | 1 + .../Tests/Files/EndFileNewlineUnitTest.13.inc | 5 + .../Files/EndFileNewlineUnitTest.13.inc.fixed | 1 + .../Tests/Files/EndFileNewlineUnitTest.14.inc | 1 + .../Methods/MethodDeclarationUnitTest.inc | 9 + .../MethodDeclarationUnitTest.inc.fixed | 9 + .../Methods/MethodDeclarationUnitTest.php | 2 + .../Namespaces/UseDeclarationUnitTest.1.inc | 7 +- .../Sniffs/Arrays/ArrayDeclarationSniff.php | 1 + .../Sniffs/Classes/ClassFileNameSniff.php | 1 + .../Sniffs/Classes/ValidClassNameSniff.php | 3 +- .../Sniffs/Commenting/BlockCommentSniff.php | 2 + .../ClosingDeclarationCommentSniff.php | 5 +- .../Commenting/DocCommentAlignmentSniff.php | 3 + .../Sniffs/Commenting/FileCommentSniff.php | 1 + .../Commenting/FunctionCommentSniff.php | 2 + .../Sniffs/Commenting/InlineCommentSniff.php | 1 + .../Commenting/VariableCommentSniff.php | 1 + .../Squiz/Sniffs/Files/FileExtensionSniff.php | 2 +- .../Squiz/Sniffs/Scope/MethodScopeSniff.php | 13 +- .../Sniffs/Scope/StaticThisUsageSniff.php | 2 +- .../ControlStructureSpacingSniff.php | 1 + .../WhiteSpace/ScopeKeywordSpacingSniff.php | 1 + .../Arrays/ArrayDeclarationUnitTest.1.inc | 7 + .../ArrayDeclarationUnitTest.1.inc.fixed | 7 + .../Tests/Classes/ClassFileNameUnitTest.inc | 12 +- .../Tests/Classes/ClassFileNameUnitTest.php | 15 +- .../LowercaseClassKeywordsUnitTest.inc | 1 + .../LowercaseClassKeywordsUnitTest.inc.fixed | 1 + .../LowercaseClassKeywordsUnitTest.php | 5 +- .../Tests/Classes/ValidClassNameUnitTest.inc | 44 + .../Tests/Classes/ValidClassNameUnitTest.php | 5 + .../Tests/Commenting/BlockCommentUnitTest.inc | 19 + .../Commenting/BlockCommentUnitTest.inc.fixed | 19 + .../ClosingDeclarationCommentUnitTest.inc | 6 +- .../ClosingDeclarationCommentUnitTest.php | 1 + .../DocCommentAlignmentUnitTest.inc | 20 + .../DocCommentAlignmentUnitTest.inc.fixed | 20 + .../DocCommentAlignmentUnitTest.php | 6 + .../FileCommentUnitTest.1.inc.fixed | 2 +- .../Commenting/FileCommentUnitTest.1.js.fixed | 2 +- .../Commenting/FileCommentUnitTest.7.inc | 12 + .../Commenting/FileCommentUnitTest.8.inc | 9 + .../Commenting/FileCommentUnitTest.9.inc | 12 + .../Tests/Commenting/FileCommentUnitTest.php | 1 + .../Commenting/FunctionCommentUnitTest.inc | 5 + .../FunctionCommentUnitTest.inc.fixed | 5 + .../Commenting/InlineCommentUnitTest.inc | 8 + .../InlineCommentUnitTest.inc.fixed | 8 + .../Commenting/VariableCommentUnitTest.inc | 19 + .../VariableCommentUnitTest.inc.fixed | 19 + .../Commenting/VariableCommentUnitTest.php | 2 + .../SwitchDeclarationUnitTest.inc.fixed | 342 ++ .../Tests/Files/FileExtensionUnitTest.5.inc | 3 + .../ValidVariableNameUnitTest.inc | 9 + .../ValidVariableNameUnitTest.php | 2 + .../Tests/PHP/NonExecutableCodeUnitTest.2.inc | 6 + .../Tests/PHP/NonExecutableCodeUnitTest.php | 2 +- .../Squiz/Tests/Scope/MethodScopeUnitTest.inc | 15 + .../Squiz/Tests/Scope/MethodScopeUnitTest.php | 1 + .../Tests/Scope/StaticThisUsageUnitTest.inc | 10 + .../Tests/Scope/StaticThisUsageUnitTest.php | 25 +- .../ControlStructureSpacingUnitTest.inc | 6 + .../ControlStructureSpacingUnitTest.inc.fixed | 6 + .../WhiteSpace/MemberVarSpacingUnitTest.inc | 7 + .../MemberVarSpacingUnitTest.inc.fixed | 7 + .../WhiteSpace/ScopeClosingBraceUnitTest.inc | 12 + .../ScopeClosingBraceUnitTest.inc.fixed | 13 + .../WhiteSpace/ScopeClosingBraceUnitTest.php | 2 + .../ScopeKeywordSpacingUnitTest.inc | 13 + .../ScopeKeywordSpacingUnitTest.inc.fixed | 13 + .../ScopeKeywordSpacingUnitTest.php | 3 + .../ValidVariableNameUnitTest.inc | 9 + .../ValidVariableNameUnitTest.php | 2 + .../php_codesniffer/src/Tokenizers/PHP.php | 549 ++- .../php_codesniffer/src/Util/Common.php | 4 +- .../php_codesniffer/src/Util/Standards.php | 9 +- .../php_codesniffer/src/Util/Tokens.php | 93 + .../FindImplementedInterfaceNamesTest.inc | 9 + .../FindImplementedInterfaceNamesTest.php | 17 +- .../Core/File/FindStartOfStatementTest.inc | 123 + .../Core/File/FindStartOfStatementTest.php | 503 ++ .../Core/File/GetMemberPropertiesTest.inc | 46 + .../Core/File/GetMemberPropertiesTest.php | 159 + .../Core/File/GetMethodParametersTest.inc | 22 + .../Core/File/GetMethodParametersTest.php | 176 + .../Core/File/GetMethodPropertiesTest.inc | 26 +- .../Core/File/GetMethodPropertiesTest.php | 162 + .../tests/Core/Tokenizer/ArrayKeywordTest.inc | 35 + .../tests/Core/Tokenizer/ArrayKeywordTest.php | 170 + .../tests/Core/Tokenizer/AttributesTest.inc | 90 + .../tests/Core/Tokenizer/AttributesTest.php | 659 +++ .../tests/Core/Tokenizer/BackfillEnumTest.inc | 95 + .../tests/Core/Tokenizer/BackfillEnumTest.php | 229 + .../BackfillExplicitOctalNotationTest.inc | 28 + .../BackfillExplicitOctalNotationTest.php | 114 + .../Core/Tokenizer/BackfillMatchTokenTest.inc | 319 ++ .../Core/Tokenizer/BackfillMatchTokenTest.php | 529 ++ .../BackfillNumericSeparatorTest.inc | 12 + .../BackfillNumericSeparatorTest.php | 40 + .../Core/Tokenizer/BackfillReadonlyTest.inc | 100 + .../Core/Tokenizer/BackfillReadonlyTest.php | 236 + .../tests/Core/Tokenizer/BitwiseOrTest.inc | 134 + .../tests/Core/Tokenizer/BitwiseOrTest.php | 138 + .../ContextSensitiveKeywordsTest.inc | 227 + .../ContextSensitiveKeywordsTest.php | 509 ++ .../Core/Tokenizer/DefaultKeywordTest.inc | 203 + .../Core/Tokenizer/DefaultKeywordTest.php | 302 ++ .../tests/Core/Tokenizer/DoubleArrowTest.inc | 281 ++ .../tests/Core/Tokenizer/DoubleArrowTest.php | 237 + .../Core/Tokenizer/DoubleQuotedStringTest.inc | 52 + .../Core/Tokenizer/DoubleQuotedStringTest.php | 136 + .../tests/Core/Tokenizer/EnumCaseTest.inc | 95 + .../tests/Core/Tokenizer/EnumCaseTest.php | 157 + .../tests/Core/Tokenizer/FinallyTest.inc | 40 + .../tests/Core/Tokenizer/FinallyTest.php | 96 + .../tests/Core/Tokenizer/GotoLabelTest.inc | 56 + .../tests/Core/Tokenizer/GotoLabelTest.php | 175 + .../NamedFunctionCallArgumentsTest.inc | 404 ++ .../NamedFunctionCallArgumentsTest.php | 884 ++++ .../Core/Tokenizer/TypeIntersectionTest.inc | 120 + .../Core/Tokenizer/TypeIntersectionTest.php | 138 + .../symfony/config/Builder/ClassBuilder.php | 8 +- .../config/Builder/ConfigBuilderGenerator.php | 315 +- .../symfony/config/Builder/Property.php | 13 +- app/vendor/symfony/config/CHANGELOG.md | 14 + .../symfony/config/ConfigCacheFactory.php | 3 - .../symfony/config/Definition/ArrayNode.php | 27 +- .../symfony/config/Definition/BaseNode.php | 39 +- .../symfony/config/Definition/BooleanNode.php | 9 - .../Builder/ArrayNodeDefinition.php | 22 +- .../Builder/BooleanNodeDefinition.php | 5 - .../Definition/Builder/EnumNodeDefinition.php | 2 +- .../config/Definition/Builder/ExprBuilder.php | 50 +- .../config/Definition/Builder/NodeBuilder.php | 3 + .../Definition/Builder/NodeDefinition.php | 24 +- .../Builder/NormalizationBuilder.php | 1 + .../Builder/NumericNodeDefinition.php | 2 - .../config/Definition/Builder/TreeBuilder.php | 2 +- .../Builder/VariableNodeDefinition.php | 3 - .../Definition/ConfigurableInterface.php | 25 + .../config/Definition/Configuration.php | 45 + .../Configurator/DefinitionConfigurator.php | 47 + .../Definition/Dumper/XmlReferenceDumper.php | 35 +- .../Definition/Dumper/YamlReferenceDumper.php | 6 +- .../symfony/config/Definition/EnumNode.php | 13 +- .../symfony/config/Definition/FloatNode.php | 6 - .../symfony/config/Definition/IntegerNode.php | 6 - .../Loader/DefinitionFileLoader.php | 103 + .../symfony/config/Definition/NumericNode.php | 6 - .../symfony/config/Definition/Processor.php | 4 +- .../config/Definition/PrototypedArrayNode.php | 15 +- .../symfony/config/Definition/ScalarNode.php | 11 +- .../config/Definition/VariableNode.php | 21 - .../config/Exception/LoaderLoadException.php | 16 +- app/vendor/symfony/config/FileLocator.php | 3 - app/vendor/symfony/config/LICENSE | 2 +- .../config/Loader/DelegatingLoader.php | 6 - .../Loader/DirectoryAwareLoaderInterface.php | 22 + .../symfony/config/Loader/FileLoader.php | 12 +- .../symfony/config/Loader/GlobFileLoader.php | 6 - app/vendor/symfony/config/Loader/Loader.php | 6 - .../symfony/config/Loader/LoaderResolver.php | 3 - .../Resource/ClassExistenceResource.php | 7 +- .../config/Resource/ComposerResource.php | 3 - .../config/Resource/DirectoryResource.php | 5 +- .../config/Resource/FileExistenceResource.php | 3 - .../symfony/config/Resource/FileResource.php | 3 - .../symfony/config/Resource/GlobResource.php | 51 +- .../Resource/ReflectionClassResource.php | 63 +- .../Resource/SelfCheckingResourceChecker.php | 2 +- .../config/ResourceCheckerConfigCache.php | 9 +- .../ResourceCheckerConfigCacheFactory.php | 3 - app/vendor/symfony/config/Util/XmlUtils.php | 2 +- app/vendor/symfony/config/composer.json | 7 +- app/vendor/symfony/console/Application.php | 147 +- app/vendor/symfony/console/CHANGELOG.md | 19 + .../console/CI/GithubActionReporter.php | 2 +- app/vendor/symfony/console/Color.php | 49 +- .../symfony/console/Command/Command.php | 81 +- .../console/Command/CompleteCommand.php | 223 + .../console/Command/DumpCompletionCommand.php | 148 + .../symfony/console/Command/HelpCommand.php | 33 +- .../symfony/console/Command/LazyCommand.php | 25 +- .../symfony/console/Command/ListCommand.php | 31 +- .../symfony/console/Command/LockableTrait.php | 3 +- .../CommandLoader/ContainerCommandLoader.php | 11 +- .../CommandLoader/FactoryCommandLoader.php | 9 - .../console/Completion/CompletionInput.php | 246 + .../Completion/CompletionSuggestions.php | 97 + .../Output/BashCompletionOutput.php | 33 + .../Output/CompletionOutputInterface.php | 25 + .../Output/FishCompletionOutput.php | 33 + .../Completion/Output/ZshCompletionOutput.php | 36 + .../symfony/console/Completion/Suggestion.php | 41 + app/vendor/symfony/console/Cursor.php | 8 +- .../AddConsoleCommandPass.php | 6 +- .../Descriptor/ApplicationDescription.php | 4 +- .../symfony/console/Descriptor/Descriptor.php | 30 +- .../console/Descriptor/JsonDescriptor.php | 15 - .../console/Descriptor/MarkdownDescriptor.php | 21 - .../console/Descriptor/TextDescriptor.php | 18 - .../console/Descriptor/XmlDescriptor.php | 15 - .../console/Event/ConsoleErrorEvent.php | 1 - .../symfony/console/Event/ConsoleEvent.php | 4 +- .../console/EventListener/ErrorListener.php | 4 +- .../Exception/InvalidOptionException.php | 2 +- .../console/Formatter/NullOutputFormatter.php | 22 +- .../Formatter/NullOutputFormatterStyle.php | 24 +- .../console/Formatter/OutputFormatter.php | 27 +- .../Formatter/OutputFormatterStyle.php | 26 +- .../OutputFormatterStyleInterface.php | 4 +- .../Formatter/OutputFormatterStyleStack.php | 8 +- .../WrappableOutputFormatterInterface.php | 2 + .../console/Helper/DebugFormatterHelper.php | 3 - .../console/Helper/DescriptorHelper.php | 3 - app/vendor/symfony/console/Helper/Dumper.php | 29 +- .../console/Helper/FormatterHelper.php | 3 - app/vendor/symfony/console/Helper/Helper.php | 17 +- .../console/Helper/HelperInterface.php | 2 +- .../symfony/console/Helper/HelperSet.php | 6 +- .../console/Helper/InputAwareHelper.php | 3 - .../symfony/console/Helper/OutputWrapper.php | 76 + .../symfony/console/Helper/ProcessHelper.php | 3 - .../symfony/console/Helper/ProgressBar.php | 48 +- .../console/Helper/ProgressIndicator.php | 27 +- .../symfony/console/Helper/QuestionHelper.php | 12 +- .../console/Helper/SymfonyQuestionHelper.php | 6 - app/vendor/symfony/console/Helper/Table.php | 119 +- .../symfony/console/Input/ArgvInput.php | 14 +- .../symfony/console/Input/ArrayInput.php | 14 +- app/vendor/symfony/console/Input/Input.php | 42 - .../symfony/console/Input/InputArgument.php | 35 +- .../symfony/console/Input/InputDefinition.php | 4 +- .../symfony/console/Input/InputInterface.php | 3 + .../symfony/console/Input/InputOption.php | 36 +- .../symfony/console/Input/StringInput.php | 3 + app/vendor/symfony/console/LICENSE | 2 +- .../symfony/console/Logger/ConsoleLogger.php | 11 +- .../symfony/console/Output/AnsiColorMode.php | 124 + .../symfony/console/Output/BufferedOutput.php | 3 - .../symfony/console/Output/ConsoleOutput.php | 17 +- .../console/Output/ConsoleSectionOutput.php | 111 +- .../symfony/console/Output/NullOutput.php | 38 +- app/vendor/symfony/console/Output/Output.php | 38 +- .../console/Output/OutputInterface.php | 8 +- .../symfony/console/Output/StreamOutput.php | 7 +- .../console/Output/TrimmedBufferOutput.php | 3 - .../symfony/console/Question/Question.php | 14 +- app/vendor/symfony/console/README.md | 16 - .../symfony/console/Resources/completion.bash | 84 + .../symfony/console/Resources/completion.fish | 29 + .../symfony/console/Resources/completion.zsh | 80 + .../console/SignalRegistry/SignalRegistry.php | 12 +- .../symfony/console/Style/OutputStyle.php | 41 +- .../symfony/console/Style/SymfonyStyle.php | 104 +- app/vendor/symfony/console/Terminal.php | 71 +- .../console/Tester/ApplicationTester.php | 40 +- .../Tester/CommandCompletionTester.php | 56 + .../symfony/console/Tester/CommandTester.php | 2 +- .../Tester/Constraint/CommandIsSuccessful.php | 43 + .../symfony/console/Tester/TesterTrait.php | 6 +- app/vendor/symfony/console/composer.json | 3 +- .../symfony/deprecation-contracts/.gitignore | 3 - .../deprecation-contracts/composer.json | 4 +- .../filesystem/Exception/IOException.php | 3 - .../filesystem/Exception/RuntimeException.php | 19 + app/vendor/symfony/filesystem/Filesystem.php | 23 +- app/vendor/symfony/filesystem/LICENSE | 2 +- app/vendor/symfony/filesystem/Path.php | 819 ++++ app/vendor/symfony/filesystem/composer.json | 2 +- app/vendor/symfony/finder/CHANGELOG.md | 6 + .../symfony/finder/Comparator/Comparator.php | 22 +- .../finder/Comparator/DateComparator.php | 4 +- app/vendor/symfony/finder/Finder.php | 50 +- app/vendor/symfony/finder/Gitignore.php | 2 +- .../ExcludeDirectoryFilterIterator.php | 11 +- .../Iterator/FileTypeFilterIterator.php | 4 +- .../Iterator/FilecontentFilterIterator.php | 4 +- .../symfony/finder/Iterator/LazyIterator.php | 2 +- .../Iterator/MultiplePcreFilterIterator.php | 6 +- .../finder/Iterator/PathFilterIterator.php | 4 +- .../Iterator/RecursiveDirectoryIterator.php | 3 +- .../finder/Iterator/SortableIterator.php | 23 +- .../Iterator/VcsIgnoredFilterIterator.php | 178 + app/vendor/symfony/finder/LICENSE | 2 +- app/vendor/symfony/finder/composer.json | 5 +- app/vendor/symfony/polyfill-ctype/README.md | 2 +- .../symfony/polyfill-ctype/composer.json | 2 +- .../polyfill-intl-grapheme/Grapheme.php | 2 +- .../symfony/polyfill-intl-grapheme/README.md | 2 +- .../polyfill-intl-grapheme/composer.json | 2 +- .../polyfill-intl-normalizer/Normalizer.php | 2 +- .../polyfill-intl-normalizer/README.md | 2 +- .../polyfill-intl-normalizer/composer.json | 2 +- .../symfony/polyfill-mbstring/Mbstring.php | 63 +- .../symfony/polyfill-mbstring/README.md | 2 +- .../symfony/polyfill-mbstring/composer.json | 2 +- app/vendor/symfony/polyfill-php73/README.md | 2 +- .../symfony/polyfill-php73/composer.json | 2 +- .../symfony/polyfill-php80/PhpToken.php | 103 + app/vendor/symfony/polyfill-php80/README.md | 7 +- .../Resources/stubs/Attribute.php | 9 + .../Resources/stubs/PhpToken.php | 16 + .../Resources/stubs/Stringable.php | 9 + .../Resources/stubs/UnhandledMatchError.php | 9 + .../Resources/stubs/ValueError.php | 9 + .../symfony/polyfill-php80/composer.json | 2 +- app/vendor/symfony/polyfill-php81/README.md | 5 +- .../Resources/stubs/ReturnTypeWillChange.php | 9 + .../symfony/polyfill-php81/composer.json | 2 +- .../Exception/ProcessTimedOutException.php | 15 +- .../symfony/process/ExecutableFinder.php | 4 +- app/vendor/symfony/process/LICENSE | 2 +- app/vendor/symfony/process/PhpProcess.php | 6 - .../symfony/process/Pipes/AbstractPipes.php | 5 +- .../symfony/process/Pipes/UnixPipes.php | 17 +- .../symfony/process/Pipes/WindowsPipes.php | 18 - app/vendor/symfony/process/Process.php | 10 +- app/vendor/symfony/process/ProcessUtils.php | 2 +- app/vendor/symfony/process/README.md | 2 +- app/vendor/symfony/process/composer.json | 2 +- .../symfony/service-contracts/.gitignore | 3 - .../Attribute/SubscribedService.php | 47 + .../service-contracts/ServiceLocatorTrait.php | 9 - .../ServiceProviderInterface.php | 9 + .../ServiceSubscriberInterface.php | 13 +- .../ServiceSubscriberTrait.php | 28 +- .../symfony/service-contracts/composer.json | 9 +- app/vendor/symfony/string/AbstractString.php | 18 +- .../symfony/string/AbstractUnicodeString.php | 37 +- app/vendor/symfony/string/ByteString.php | 23 +- app/vendor/symfony/string/CHANGELOG.md | 5 + app/vendor/symfony/string/CodePointString.php | 2 +- .../string/Inflector/EnglishInflector.php | 10 +- .../string/Inflector/FrenchInflector.php | 10 +- app/vendor/symfony/string/LICENSE | 2 +- app/vendor/symfony/string/LazyString.php | 10 +- .../Resources/data/wcswidth_table_wide.php | 48 +- .../Resources/data/wcswidth_table_zero.php | 46 +- .../symfony/string/Resources/functions.php | 2 +- .../symfony/string/Slugger/AsciiSlugger.php | 51 +- app/vendor/symfony/string/UnicodeString.php | 4 +- app/vendor/symfony/string/composer.json | 3 +- app/vendor/symfony/var-dumper/CHANGELOG.md | 6 + .../symfony/var-dumper/Caster/ArgsStub.php | 4 +- .../symfony/var-dumper/Caster/Caster.php | 4 +- .../symfony/var-dumper/Caster/ClassStub.php | 4 +- .../symfony/var-dumper/Caster/CutStub.php | 2 +- .../symfony/var-dumper/Caster/DOMCaster.php | 37 - .../symfony/var-dumper/Caster/DateCaster.php | 10 +- .../var-dumper/Caster/ExceptionCaster.php | 6 +- .../symfony/var-dumper/Caster/FFICaster.php | 161 + .../symfony/var-dumper/Caster/FiberCaster.php | 43 + .../symfony/var-dumper/Caster/IntlCaster.php | 2 +- .../symfony/var-dumper/Caster/LinkStub.php | 5 +- .../var-dumper/Caster/MemcachedCaster.php | 6 +- .../var-dumper/Caster/MysqliCaster.php | 33 + .../symfony/var-dumper/Caster/PdoCaster.php | 2 +- .../var-dumper/Caster/RdKafkaCaster.php | 4 +- .../var-dumper/Caster/ReflectionCaster.php | 8 +- .../var-dumper/Caster/ResourceCaster.php | 11 +- .../symfony/var-dumper/Caster/SplCaster.php | 6 +- .../var-dumper/Caster/SymfonyCaster.php | 23 +- .../var-dumper/Caster/XmlReaderCaster.php | 2 +- .../var-dumper/Cloner/AbstractCloner.php | 13 +- .../symfony/var-dumper/Cloner/VarCloner.php | 47 +- .../Command/Descriptor/CliDescriptor.php | 2 +- .../Command/Descriptor/HtmlDescriptor.php | 2 +- .../var-dumper/Command/ServerDumpCommand.php | 2 +- .../var-dumper/Dumper/AbstractDumper.php | 4 +- .../symfony/var-dumper/Dumper/CliDumper.php | 47 +- .../RequestContextProvider.php | 4 +- .../ContextProvider/SourceContextProvider.php | 2 +- .../Dumper/ContextualizedDumper.php | 4 +- .../symfony/var-dumper/Dumper/HtmlDumper.php | 34 +- .../var-dumper/Dumper/ServerDumper.php | 7 +- .../Exception/ThrowingCasterException.php | 2 +- app/vendor/symfony/var-dumper/LICENSE | 2 +- .../var-dumper/Resources/bin/var-dump-server | 4 + .../symfony/var-dumper/Server/DumpServer.php | 14 +- app/vendor/symfony/var-dumper/VarDumper.php | 5 +- app/vendor/symfony/var-dumper/composer.json | 2 +- app/vendor/twig/markdown-extra/LICENSE | 2 +- app/vendor/twig/markdown-extra/composer.json | 4 +- app/vendor/twig/twig/.editorconfig | 18 - app/vendor/twig/twig/.gitattributes | 4 - app/vendor/twig/twig/.github/workflows/ci.yml | 146 - .../twig/.github/workflows/documentation.yml | 60 - app/vendor/twig/twig/.gitignore | 4 - app/vendor/twig/twig/.php-cs-fixer.dist.php | 20 - app/vendor/twig/twig/CHANGELOG | 31 + app/vendor/twig/twig/LICENSE | 2 +- app/vendor/twig/twig/composer.json | 2 +- app/vendor/twig/twig/src/Compiler.php | 11 +- app/vendor/twig/twig/src/Environment.php | 17 +- app/vendor/twig/twig/src/ExpressionParser.php | 8 +- .../twig/twig/src/Extension/CoreExtension.php | 65 +- .../twig/src/Extension/ExtensionInterface.php | 8 + .../twig/src/Extension/GlobalsInterface.php | 3 + app/vendor/twig/twig/src/ExtensionSet.php | 17 + .../twig/twig/src/Loader/FilesystemLoader.php | 4 +- .../Node/Expression/Binary/HasEveryBinary.php | 33 + .../Node/Expression/Binary/HasSomeBinary.php | 33 + .../Node/Expression/Binary/MatchesBinary.php | 2 +- .../src/Node/Expression/CallExpression.php | 19 +- app/vendor/twig/twig/src/Node/IfNode.php | 5 +- app/vendor/webmozart/assert/.editorconfig | 12 - .../assert/.github/workflows/ci.yaml | 120 - app/vendor/webmozart/assert/.php_cs | 24 - app/vendor/webmozart/assert/CHANGELOG.md | 190 - app/vendor/webmozart/assert/LICENSE | 20 - app/vendor/webmozart/assert/README.md | 287 -- app/vendor/webmozart/assert/composer.json | 43 - app/vendor/webmozart/assert/psalm.xml | 14 - app/vendor/webmozart/assert/src/Assert.php | 2066 -------- .../assert/src/InvalidArgumentException.php | 16 - app/vendor/webmozart/assert/src/Mixin.php | 2916 ----------- 2808 files changed, 89073 insertions(+), 72234 deletions(-) create mode 100644 app/src/Command/JobCommand.php create mode 100644 app/src/Controller/JobHistoryRecordsController.php create mode 100644 app/src/Controller/JobsController.php create mode 100644 app/src/Lib/Enum/JobStatusEnum.php create mode 100644 app/src/Lib/Enum/TableTypeEnum.php create mode 100644 app/src/Model/Entity/Job.php create mode 100644 app/src/Model/Entity/JobHistoryRecord.php create mode 100644 app/src/Model/Table/JobHistoryRecordsTable.php create mode 100644 app/src/Model/Table/JobsTable.php create mode 100644 app/templates/JobHistoryRecords/columns.inc create mode 100644 app/templates/JobHistoryRecords/fields.inc create mode 100644 app/templates/Jobs/columns.inc create mode 100644 app/templates/Jobs/fields-links.inc create mode 100644 app/templates/Jobs/fields.inc mode change 100755 => 120000 app/vendor/bin/composer mode change 100755 => 120000 app/vendor/bin/doctrine-dbal mode change 100755 => 120000 app/vendor/bin/phinx mode change 100755 => 120000 app/vendor/bin/php-parse mode change 100755 => 120000 app/vendor/bin/phpcbf mode change 100755 => 120000 app/vendor/bin/phpcs mode change 100755 => 120000 app/vendor/bin/phpunit mode change 100755 => 120000 app/vendor/bin/psysh mode change 100755 => 120000 app/vendor/bin/var-dump-server create mode 100644 app/vendor/brick/varexporter/CHANGELOG.md create mode 100644 app/vendor/brick/varexporter/src/Internal/ObjectExporter/EnumExporter.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/ClassBuilder.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/CodeParser.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/FileBuilder.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/ImportHelper.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/ParseException.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/ParsedClass.php create mode 100644 app/vendor/cakephp/bake/src/CodeGen/ParsedFile.php create mode 100644 app/vendor/cakephp/bake/templates/bake/element/file_header.twig create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/ConsoleIntegrationTestTrait.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsBase.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContain.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContainRow.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsEmpty.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsNotContain.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsRegExp.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ExitCode.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyCommandRunner.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyShellDispatcher.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/MissingConsoleInputException.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleInput.php create mode 100644 app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleOutput.php create mode 100644 app/vendor/cakephp/cakephp/src/Controller/Component/CheckHttpCacheComponent.php create mode 100644 app/vendor/cakephp/cakephp/src/Core/TestSuite/ContainerStubTrait.php create mode 100644 app/vendor/cakephp/cakephp/src/Datasource/Paging/Exception/PageOutOfBoundsException.php create mode 100644 app/vendor/cakephp/cakephp/src/Datasource/Paging/NumericPaginator.php create mode 100644 app/vendor/cakephp/cakephp/src/Datasource/Paging/PaginatorInterface.php create mode 100644 app/vendor/cakephp/cakephp/src/Datasource/Paging/SimplePaginator.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/ErrorRendererInterface.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/ErrorTrap.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/ExceptionTrap.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/PhpError.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleErrorRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleExceptionRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/HtmlErrorRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/TextErrorRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/TextExceptionRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Error/Renderer/WebExceptionRenderer.php create mode 100644 app/vendor/cakephp/cakephp/src/Http/ContentTypeNegotiation.php create mode 100644 app/vendor/cakephp/cakephp/src/Http/TestSuite/HttpClientTrait.php create mode 100644 app/vendor/cakephp/cakephp/src/Http/Uri.php create mode 100644 app/vendor/cakephp/cakephp/src/Routing/Exception/FailedRouteCacheException.php create mode 100644 app/vendor/cakephp/cakephp/src/View/NegotiationRequiredView.php create mode 100644 app/vendor/cakephp/cakephp/tests/Fixture/CompositeKeyArticlesFixture.php create mode 100644 app/vendor/cakephp/cakephp/tests/Fixture/CompositeKeyArticlesTagsFixture.php create mode 100644 app/vendor/cakephp/cakephp/tests/Fixture/NumberTreesArticlesFixture.php create mode 100644 app/vendor/cakephp/cakephp/tests/phpstan.neon create mode 100644 app/vendor/cakephp/debug_kit/.eslintrc.json create mode 100644 app/vendor/cakephp/debug_kit/package.json create mode 100644 app/vendor/cakephp/debug_kit/phpstan-baseline.neon create mode 100644 app/vendor/cakephp/debug_kit/phpstan.neon delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/debug_kit.pot delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/eng/LC_MESSAGES/debug_kit.po delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/fra/LC_MESSAGES/debug_kit.po delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/lim/LC_MESSAGES/debug_kit.po delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/nld/LC_MESSAGES/debug_kit.po delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/pt_BR/LC_MESSAGES/debug_kit.po delete mode 100644 app/vendor/cakephp/debug_kit/src/Locale/spa/LC_MESSAGES/debug_kit.po create mode 100644 app/vendor/cakephp/debug_kit/webroot/css/style.css delete mode 100644 app/vendor/cakephp/debug_kit/webroot/css/toolbar.css delete mode 100644 app/vendor/cakephp/debug_kit/webroot/js/debug_kit.js rename app/vendor/cakephp/debug_kit/webroot/js/{toolbar.js => inject-iframe.js} (54%) create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/main.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Helper.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Keyboard.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/CachePanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/HistoryPanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/MailPanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/PackagesPanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/RoutesPanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Panels/VariablesPanel.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Start.js create mode 100644 app/vendor/cakephp/debug_kit/webroot/js/modules/Toolbar.js delete mode 100644 app/vendor/cakephp/debug_kit/webroot/js/toolbar-app.js create mode 100644 app/vendor/cakephp/migrations/phpcs.xml rename app/vendor/{phpdocumentor/type-resolver => composer/class-map-generator}/LICENSE (52%) create mode 100644 app/vendor/composer/class-map-generator/README.md create mode 100644 app/vendor/composer/class-map-generator/composer.json create mode 100644 app/vendor/composer/class-map-generator/src/ClassMap.php create mode 100644 app/vendor/composer/class-map-generator/src/ClassMapGenerator.php create mode 100644 app/vendor/composer/class-map-generator/src/FileList.php create mode 100644 app/vendor/composer/class-map-generator/src/PhpFileCleaner.php create mode 100644 app/vendor/composer/class-map-generator/src/PhpFileParser.php create mode 100644 app/vendor/composer/composer/.php-cs-fixer.php create mode 100644 app/vendor/composer/composer/doc/articles/composer-platform-dependencies.md create mode 100644 app/vendor/composer/composer/doc/faqs/why-cant-composer-load-repositories-recursively.md create mode 100644 app/vendor/composer/composer/phpstan/rules.neon create mode 100644 app/vendor/composer/composer/src/Composer/Advisory/Auditor.php create mode 100644 app/vendor/composer/composer/src/Composer/Advisory/PartialSecurityAdvisory.php create mode 100644 app/vendor/composer/composer/src/Composer/Advisory/SecurityAdvisory.php create mode 100644 app/vendor/composer/composer/src/Composer/Command/AuditCommand.php create mode 100644 app/vendor/composer/composer/src/Composer/Command/BumpCommand.php create mode 100644 app/vendor/composer/composer/src/Composer/Command/CompletionTrait.php create mode 100644 app/vendor/composer/composer/src/Composer/Command/PackageDiscoveryTrait.php create mode 100644 app/vendor/composer/composer/src/Composer/Console/Input/InputArgument.php create mode 100644 app/vendor/composer/composer/src/Composer/Console/Input/InputOption.php create mode 100644 app/vendor/composer/composer/src/Composer/DependencyResolver/PoolOptimizer.php create mode 100644 app/vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreAllPlatformRequirementFilter.php create mode 100644 app/vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreListPlatformRequirementFilter.php create mode 100644 app/vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/IgnoreNothingPlatformRequirementFilter.php create mode 100644 app/vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterFactory.php create mode 100644 app/vendor/composer/composer/src/Composer/Filter/PlatformRequirementFilter/PlatformRequirementFilterInterface.php create mode 100644 app/vendor/composer/composer/src/Composer/PHPStan/ConfigReturnTypeExtension.php create mode 100644 app/vendor/composer/composer/src/Composer/PHPStan/RuleReasonDataReturnTypeExtension.php create mode 100644 app/vendor/composer/composer/src/Composer/Package/Version/VersionBumper.php create mode 100644 app/vendor/composer/composer/src/Composer/PartialComposer.php create mode 100644 app/vendor/composer/composer/src/Composer/Plugin/PluginBlockedException.php create mode 100644 app/vendor/composer/composer/src/Composer/Repository/AdvisoryProviderInterface.php create mode 100644 app/vendor/composer/composer/src/Composer/Repository/CanonicalPackagesTrait.php create mode 100644 app/vendor/composer/composer/src/Composer/Repository/RepositoryUtils.php create mode 100644 app/vendor/composer/composer/src/Composer/Util/PackageInfo.php delete mode 100644 app/vendor/composer/pcre/phpstan-baseline.neon create mode 100644 app/vendor/composer/pcre/src/MatchAllStrictGroupsResult.php create mode 100644 app/vendor/composer/pcre/src/MatchStrictGroupsResult.php create mode 100644 app/vendor/composer/pcre/src/UnexpectedNullMatchException.php create mode 100644 app/vendor/composer/spdx-licenses/.github/workflows/continuous-integration.yml create mode 100644 app/vendor/composer/spdx-licenses/.github/workflows/lint.yml create mode 100644 app/vendor/composer/spdx-licenses/.github/workflows/phpstan.yml create mode 100644 app/vendor/composer/spdx-licenses/phpstan.neon.dist delete mode 100644 app/vendor/dealerdirect/phpcodesniffer-composer-installer/.remarkrc delete mode 100644 app/vendor/dealerdirect/phpcodesniffer-composer-installer/.yamllint delete mode 100644 app/vendor/dealerdirect/phpcodesniffer-composer-installer/CODE_OF_CONDUCT.md create mode 100644 app/vendor/doctrine/dbal/src/ArrayParameterType.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/AbstractSQLiteDriver/Middleware/EnableForeignKeys.php delete mode 100644 app/vendor/doctrine/dbal/src/Driver/IBMDB2/Exception/CannotWriteToTemporaryFile.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PDO/PDOException.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PDO/ParameterTypeMap.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Connection.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/ConvertParameters.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Driver.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Exception.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnexpectedValue.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Exception/UnknownParameter.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Result.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/PgSQL/Statement.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/SQLite3/Connection.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/SQLite3/Driver.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/SQLite3/Exception.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/SQLite3/Result.php create mode 100644 app/vendor/doctrine/dbal/src/Driver/SQLite3/Statement.php create mode 100644 app/vendor/doctrine/dbal/src/Event/Listeners/SQLiteSessionInit.php create mode 100644 app/vendor/doctrine/dbal/src/Exception/DatabaseRequired.php create mode 100644 app/vendor/doctrine/dbal/src/Exception/MalformedDsnException.php create mode 100644 app/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php create mode 100644 app/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/CachingCollationMetadataProvider.php create mode 100644 app/vendor/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/ConnectionCollationMetadataProvider.php create mode 100644 app/vendor/doctrine/dbal/src/SQL/Builder/CreateSchemaObjectsSQLBuilder.php create mode 100644 app/vendor/doctrine/dbal/src/SQL/Builder/DropSchemaObjectsSQLBuilder.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/DefaultSchemaManagerFactory.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/ColumnAlreadyExists.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/ColumnDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/ForeignKeyDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/IndexAlreadyExists.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/IndexDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/IndexNameInvalid.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/NamedForeignKeyRequired.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/NamespaceAlreadyExists.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/SequenceAlreadyExists.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/SequenceDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/TableAlreadyExists.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/TableDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/Exception/UniqueConstraintDoesNotExist.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/LegacySchemaManagerFactory.php create mode 100644 app/vendor/doctrine/dbal/src/Schema/SchemaManagerFactory.php delete mode 100644 app/vendor/doctrine/dbal/src/Schema/Visitor/SchemaDiffVisitor.php create mode 100644 app/vendor/doctrine/dbal/src/Tools/DsnParser.php create mode 100644 app/vendor/doctrine/dbal/static-analysis/driver-manager-get-available-drivers-return-type.php create mode 100644 app/vendor/doctrine/deprecations/test_fixtures/vendor/doctrine/foo/Bar.php create mode 100644 app/vendor/doctrine/deprecations/test_fixtures/vendor/doctrine/foo/Baz.php delete mode 100644 app/vendor/doctrine/event-manager/.doctrine-project.json create mode 100644 app/vendor/doctrine/event-manager/UPGRADE.md create mode 100644 app/vendor/doctrine/event-manager/phpstan.neon.dist rename app/vendor/{sebastian/recursion-context/.psalm/config.xml => doctrine/event-manager/psalm.xml} (79%) rename app/vendor/doctrine/event-manager/{lib/Doctrine/Common => src}/EventArgs.php (75%) rename app/vendor/doctrine/event-manager/{lib/Doctrine/Common => src}/EventManager.php (57%) rename app/vendor/doctrine/event-manager/{lib/Doctrine/Common => src}/EventSubscriber.php (86%) create mode 100644 app/vendor/doctrine/instantiator/psalm.xml delete mode 100644 app/vendor/laminas/laminas-diactoros/.laminas-ci.json delete mode 100644 app/vendor/laminas/laminas-diactoros/composer.lock delete mode 100644 app/vendor/laminas/laminas-diactoros/psalm-baseline.xml delete mode 100644 app/vendor/laminas/laminas-diactoros/psalm.xml.dist create mode 100644 app/vendor/laminas/laminas-diactoros/src/Exception/InvalidForwardedHeaderNameException.php create mode 100644 app/vendor/laminas/laminas-diactoros/src/Exception/InvalidProxyAddressException.php create mode 100644 app/vendor/laminas/laminas-diactoros/src/ServerRequestFilter/DoNotFilter.php create mode 100644 app/vendor/laminas/laminas-diactoros/src/ServerRequestFilter/FilterServerRequestInterface.php create mode 100644 app/vendor/laminas/laminas-diactoros/src/ServerRequestFilter/FilterUsingXForwardedHeaders.php create mode 100644 app/vendor/laminas/laminas-diactoros/src/ServerRequestFilter/IPRange.php delete mode 100644 app/vendor/laminas/laminas-httphandlerrunner/CHANGELOG.md delete mode 100644 app/vendor/laminas/laminas-httphandlerrunner/psalm-baseline.xml delete mode 100644 app/vendor/laminas/laminas-httphandlerrunner/psalm.xml.dist create mode 100644 app/vendor/laminas/laminas-httphandlerrunner/src/RequestHandlerRunnerInterface.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/.github/FUNDING.yml delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/.github/workflows/continuous-integration.yml delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/.github/workflows/release-on-milestone-closed.yml delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/.laminas-ci.json delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/COPYRIGHT.md delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/LICENSE.md delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/README.md delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/composer.json delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/composer.lock delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/config/replacements.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/psalm-baseline.xml delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/psalm.xml.dist delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/Autoloader.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/ConfigPostProcessor.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/Module.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/Replacements.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/RewriteRules.php delete mode 100644 app/vendor/laminas/laminas-zendframework-bridge/src/autoload.php rename app/vendor/{phpdocumentor/reflection-common => mobiledetect/mobiledetectlib}/LICENSE (93%) create mode 100644 app/vendor/nikic/php-parser/lib/PhpParser/Builder/EnumCase.php create mode 100644 app/vendor/nikic/php-parser/lib/PhpParser/Builder/Enum_.php create mode 100644 app/vendor/nikic/php-parser/lib/PhpParser/Lexer/TokenEmulator/ReadonlyFunctionTokenEmulator.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/.github/dependabot.yml delete mode 100644 app/vendor/phpdocumentor/reflection-common/.github/workflows/push.yml delete mode 100644 app/vendor/phpdocumentor/reflection-common/README.md delete mode 100644 app/vendor/phpdocumentor/reflection-common/composer.json delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/Element.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/File.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/Fqsen.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/Location.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/Project.php delete mode 100644 app/vendor/phpdocumentor/reflection-common/src/ProjectFactory.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/README.md delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/composer.json delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Description.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/DescriptionFactory.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/ExampleFinder.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Serializer.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/StandardTagFactory.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tag.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/TagFactory.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Author.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/BaseTag.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Covers.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Deprecated.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Example.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Factory/StaticMethod.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/AlignFormatter.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Formatter/PassthroughFormatter.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Generic.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/InvalidTag.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Link.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Method.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Param.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Property.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyRead.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/PropertyWrite.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Fqsen.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Reference.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Reference/Url.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Return_.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/See.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Since.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Source.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/TagWithType.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Throws.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Uses.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Var_.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlock/Tags/Version.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactory.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/DocBlockFactoryInterface.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/Exception/PcreException.php delete mode 100644 app/vendor/phpdocumentor/reflection-docblock/src/Utils.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/README.md delete mode 100644 app/vendor/phpdocumentor/type-resolver/composer.json delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/FqsenResolver.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoType.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/CallableString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/False_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/HtmlEscapedString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/LiteralString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/LowercaseString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyLowercaseString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/NonEmptyString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/NumericString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/PositiveInteger.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/TraitString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/PseudoTypes/True_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Type.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/TypeResolver.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/AbstractList.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/AggregatedType.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/ArrayKey.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Array_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Boolean.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Callable_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/ClassString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Collection.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Compound.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Context.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/ContextFactory.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Expression.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Float_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Integer.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/InterfaceString.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Intersection.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Iterable_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Mixed_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Never_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Null_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Nullable.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Object_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Parent_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Resource_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Scalar.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Self_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Static_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/String_.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/This.php delete mode 100644 app/vendor/phpdocumentor/type-resolver/src/Types/Void_.php delete mode 100644 app/vendor/phpspec/prophecy/CHANGES.md delete mode 100644 app/vendor/phpspec/prophecy/LICENSE delete mode 100644 app/vendor/phpspec/prophecy/README.md delete mode 100644 app/vendor/phpspec/prophecy/composer.json delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/ArgumentsWildcard.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValueToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/AnyValuesToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ApproximateValueToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayCountToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEntryToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ArrayEveryEntryToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/CallbackToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ExactValueToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/IdenticalValueToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/InArrayToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalAndToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/LogicalNotToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/NotInArrayToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/ObjectStateToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/StringContainsToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TokenInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Argument/Token/TypeToken.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Call/Call.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Call/CallCenter.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Comparator/ClosureComparator.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Comparator/Factory.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Comparator/ProphecyComparator.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/CachedDoubler.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ClassPatchInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/DisableConstructorPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/HhvmExceptionPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/KeywordPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/MagicCallPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ProphecySubjectPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ReflectionClassNewInstancePatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/SplFileInfoPatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/ThrowablePatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/ClassPatch/TraversablePatch.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/DoubleInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Doubler.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCodeGenerator.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassCreator.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ClassMirror.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentNode.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ArgumentTypeNode.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ClassNode.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/MethodNode.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/ReturnTypeNode.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/Node/TypeNodeAbstract.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/ReflectionInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/Generator/TypeHintReference.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/LazyDouble.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Doubler/NameGenerator.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Call/UnexpectedCallException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassCreatorException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassMirrorException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ClassNotFoundException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoubleException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/DoublerException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/InterfaceNotFoundException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotExtendableException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/MethodNotFoundException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Doubler/ReturnByReferenceException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Exception.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/InvalidArgumentException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/AggregateException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/FailedPredictionException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/NoCallsException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/PredictionException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsCountException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prediction/UnexpectedCallsException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/MethodProphecyException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ObjectProphecyException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Exception/Prophecy/ProphecyException.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassAndInterfaceTagRetriever.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/ClassTagRetriever.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/LegacyClassTagRetriever.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/PhpDocumentor/MethodTagRetrieverInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallPrediction.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallTimesPrediction.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prediction/CallbackPrediction.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prediction/NoCallsPrediction.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prediction/PredictionInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Promise/CallbackPromise.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Promise/PromiseInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnArgumentPromise.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Promise/ReturnPromise.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Promise/ThrowPromise.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/MethodProphecy.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ObjectProphecy.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecyInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/ProphecySubjectInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/Revealer.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophecy/RevealerInterface.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Prophet.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Util/ExportUtil.php delete mode 100644 app/vendor/phpspec/prophecy/src/Prophecy/Util/StringUtil.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/NodeAttributes.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagMethodValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagPropertyValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/AssertTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/ParamOutTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/SelfOutTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasImportTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypeAliasTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/PhpDoc/TypelessParamTagValueNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeForParameterNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/Type/ConditionalTypeNode.php create mode 100644 app/vendor/phpstan/phpdoc-parser/src/Ast/Type/OffsetAccessTypeNode.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/Node/CrapIndex.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/StaticAnalysis/CachingFileAnalyser.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/StaticAnalysis/FileAnalyser.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/StaticAnalysis/ParsingFileAnalyser.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/Util/Filesystem.php create mode 100644 app/vendor/phpunit/php-code-coverage/src/Util/Percentage.php delete mode 100644 app/vendor/phpunit/phpunit/ChangeLog-9.5.md create mode 100644 app/vendor/phpunit/phpunit/ChangeLog-9.6.md create mode 100644 app/vendor/phpunit/phpunit/SECURITY.md create mode 100644 app/vendor/phpunit/phpunit/src/Framework/MockObject/Exception/ClassIsReadonlyException.php create mode 100644 app/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/intersection.tpl create mode 100644 app/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/mocked_method_never_or_void.tpl create mode 100644 app/vendor/phpunit/phpunit/src/Framework/MockObject/Generator/proxied_method_never_or_void.tpl create mode 100644 app/vendor/phpunit/phpunit/src/Util/Cloner.php create mode 100644 app/vendor/phpunit/phpunit/src/Util/Reflection.php delete mode 100644 app/vendor/psy/psysh/src/ConsoleColorFactory.php create mode 100644 app/vendor/psy/psysh/src/Output/Theme.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Autocompleter.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/AutocompleterAggregate.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/AutocompleterPath.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/AutocompleterWord.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Console.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleCursor.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleInput.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleOutput.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleProcessus.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleTput.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ConsoleWindow.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Event.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventBucket.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventListenable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventListener.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventListens.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/EventSource.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Exception.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ExceptionIdle.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/File.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileDirectory.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileDoesNotExistException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileFinder.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileGeneric.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileLink.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileLinkRead.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileLinkReadWrite.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileRead.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/FileReadWrite.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/IStream.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/IteratorFileSystem.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/IteratorRecursiveDirectory.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/IteratorSplFileInfo.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Protocol.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ProtocolException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ProtocolNode.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ProtocolNodeLibrary.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/ProtocolWrapper.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Readline.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Stream.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamBufferable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamContext.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamException.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamIn.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamLockable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamOut.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamPathable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamPointable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamStatable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/StreamTouchable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Terminfo/77/windows-ansi create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Terminfo/78/xterm create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Terminfo/78/xterm-256color create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Ustring.php create mode 100644 app/vendor/psy/psysh/src/Readline/Hoa/Xcallable.php create mode 100644 app/vendor/psy/psysh/src/Readline/Userland.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/Downloader.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/Downloader/CurlDownloader.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/Downloader/Factory.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/Downloader/FileDownloader.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/Installer.php create mode 100644 app/vendor/psy/psysh/src/VersionUpdater/SelfUpdate.php delete mode 100644 app/vendor/robmorgan/phinx/docs/es/commands.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/es/conf.py delete mode 100644 app/vendor/robmorgan/phinx/docs/es/contents.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/commands.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/conf.py delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/configuration.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/contents.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/index.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/migrations.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/fr/seeding.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/commands.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/conf.py delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/configuration.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/contents.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/index.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/migrations.rst delete mode 100644 app/vendor/robmorgan/phinx/docs/ja/seeding.rst create mode 100644 app/vendor/robmorgan/phinx/src/Phinx/Config/FeatureFlags.php rename app/vendor/robmorgan/phinx/src/Phinx/Migration/{Migration.template.php.dist => Migration.change.template.php.dist} (100%) create mode 100644 app/vendor/robmorgan/phinx/src/Phinx/Migration/Migration.up_down.template.php.dist delete mode 100644 app/vendor/sebastian/recursion-context/.psalm/baseline.xml create mode 100644 app/vendor/sebastian/type/src/Parameter.php create mode 100644 app/vendor/sebastian/type/src/type/CallableType.php create mode 100644 app/vendor/sebastian/type/src/type/FalseType.php create mode 100644 app/vendor/sebastian/type/src/type/GenericObjectType.php create mode 100644 app/vendor/sebastian/type/src/type/IntersectionType.php create mode 100644 app/vendor/sebastian/type/src/type/IterableType.php create mode 100644 app/vendor/sebastian/type/src/type/MixedType.php create mode 100644 app/vendor/sebastian/type/src/type/NeverType.php create mode 100644 app/vendor/sebastian/type/src/type/NullType.php create mode 100644 app/vendor/sebastian/type/src/type/ObjectType.php create mode 100644 app/vendor/sebastian/type/src/type/SimpleType.php create mode 100644 app/vendor/sebastian/type/src/type/StaticType.php create mode 100644 app/vendor/sebastian/type/src/type/TrueType.php create mode 100644 app/vendor/sebastian/type/src/type/Type.php create mode 100644 app/vendor/sebastian/type/src/type/UnionType.php create mode 100644 app/vendor/sebastian/type/src/type/UnknownType.php create mode 100644 app/vendor/sebastian/type/src/type/VoidType.php create mode 100644 app/vendor/seld/signal-handler/.github/workflows/continuous-integration.yml create mode 100644 app/vendor/seld/signal-handler/.github/workflows/lint.yml create mode 100644 app/vendor/seld/signal-handler/.github/workflows/phpstan.yml create mode 100644 app/vendor/seld/signal-handler/.php_cs create mode 100644 app/vendor/seld/signal-handler/CHANGELOG.mdown rename app/vendor/{phpdocumentor/reflection-docblock => seld/signal-handler}/LICENSE (83%) create mode 100644 app/vendor/seld/signal-handler/README.mdown create mode 100644 app/vendor/seld/signal-handler/composer.json create mode 100644 app/vendor/seld/signal-handler/phpstan-baseline.neon create mode 100644 app/vendor/seld/signal-handler/phpstan.neon.dist create mode 100644 app/vendor/seld/signal-handler/phpunit.xml.dist create mode 100644 app/vendor/seld/signal-handler/src/SignalHandler.php create mode 100644 app/vendor/seld/signal-handler/tests/SignalHandlerTest.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Annotation/AssertAnnotation.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Annotation/ParameterOutAnnotation.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Annotation/SelfOutAnnotation.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Annotation/TypeAliasAnnotation.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Annotation/TypeImportAnnotation.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/Attribute.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/AttributeHelper.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/TernaryOperatorHelper.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Helpers/TypeHint.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Attributes/AttributeAndTargetSpacingSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Attributes/AttributesOrderSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Attributes/DisallowAttributesJoiningSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Attributes/DisallowMultipleAttributesPerLineSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Attributes/RequireAttributeAfterDocCommentSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/BackedEnumTypeSpacingSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/ClassLengthSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/DisallowConstructorPropertyPromotionSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/ForbiddenPublicPropertySniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/PropertyDeclarationSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/RequireAbstractOrFinalSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Classes/RequireConstructorPropertyPromotionSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Complexity/CognitiveSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/ControlStructures/DisallowNullSafeObjectOperatorSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/ControlStructures/RequireNullSafeObjectOperatorSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/ControlStructures/UnsupportedKeywordException.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Exceptions/DisallowNonCapturingCatchSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Exceptions/RequireNonCapturingCatchSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Files/FileLengthSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Files/FunctionLengthSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/DisallowNamedArgumentsSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/DisallowTrailingCommaInCallSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/DisallowTrailingCommaInClosureUseSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/DisallowTrailingCommaInDeclarationSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/FunctionLengthSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/RequireTrailingCommaInCallSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/RequireTrailingCommaInClosureUseSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/Functions/RequireTrailingCommaInDeclarationSniff.php delete mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TypeHints/PropertyTypeHintSpacingSniff.php create mode 100644 app/vendor/slevomat/coding-standard/SlevomatCodingStandard/Sniffs/TypeHints/UnionTypeHintFormatSniff.php create mode 100644 app/vendor/slevomat/coding-standard/doc/arrays.md create mode 100644 app/vendor/slevomat/coding-standard/doc/attributes.md create mode 100644 app/vendor/slevomat/coding-standard/doc/classes.md create mode 100644 app/vendor/slevomat/coding-standard/doc/commenting.md create mode 100644 app/vendor/slevomat/coding-standard/doc/complexity.md create mode 100644 app/vendor/slevomat/coding-standard/doc/control-structures.md create mode 100644 app/vendor/slevomat/coding-standard/doc/exceptions.md create mode 100644 app/vendor/slevomat/coding-standard/doc/files.md create mode 100644 app/vendor/slevomat/coding-standard/doc/functions.md create mode 100644 app/vendor/slevomat/coding-standard/doc/namespaces.md create mode 100644 app/vendor/slevomat/coding-standard/doc/numbers.md create mode 100644 app/vendor/slevomat/coding-standard/doc/operators.md create mode 100644 app/vendor/slevomat/coding-standard/doc/php.md create mode 100644 app/vendor/slevomat/coding-standard/doc/type-hints.md create mode 100644 app/vendor/slevomat/coding-standard/doc/variables.md create mode 100644 app/vendor/slevomat/coding-standard/doc/whitespaces.md create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/NamingConventions/AbstractClassNamePrefixStandard.xml create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/NamingConventions/InterfaceNameSuffixStandard.xml create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Docs/NamingConventions/TraitNameSuffixStandard.xml create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/AbstractClassNamePrefixSniff.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/InterfaceNameSuffixSniff.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Sniffs/NamingConventions/TraitNameSuffixSniff.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNewlineUnitTest.6.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNewlineUnitTest.6.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNewlineUnitTest.7.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNewlineUnitTest.7.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNewlineUnitTest.8.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNoNewlineUnitTest.10.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNoNewlineUnitTest.8.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNoNewlineUnitTest.8.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNoNewlineUnitTest.9.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/EndFileNoNewlineUnitTest.9.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/ExecutableFileUnitTest.3.inc create mode 100755 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/ExecutableFileUnitTest.4.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LineEndingsUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LineEndingsUnitTest.1.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LineEndingsUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LineEndingsUnitTest.2.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LowercasedFilenameUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/Files/LowercasedFilenameUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/AbstractClassNamePrefixUnitTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/AbstractClassNamePrefixUnitTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/InterfaceNameSuffixUnitTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/InterfaceNameSuffixUnitTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/TraitNameSuffixUnitTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/NamingConventions/TraitNameSuffixUnitTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/PHP/ClosingPHPTagUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/PHP/ClosingPHPTagUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/PHP/SyntaxUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/PHP/SyntaxUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/VersionControl/GitMergeConflictUnitTest.7.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowSpaceIndentUnitTest.3.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowSpaceIndentUnitTest.3.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowTabIndentUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowTabIndentUnitTest.1.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowTabIndentUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Generic/Tests/WhiteSpace/DisallowTabIndentUnitTest.2.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PEAR/Tests/Commenting/FileCommentUnitTest.1.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PEAR/Tests/Commenting/FileCommentUnitTest.2.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PEAR/Tests/Commenting/FileCommentUnitTest.3.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR1/Tests/Classes/ClassDeclarationUnitTest.3.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR12/Sniffs/Classes/OpeningBraceSpaceSniff.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR12/Tests/Classes/OpeningBraceSpaceUnitTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR12/Tests/Classes/OpeningBraceSpaceUnitTest.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR12/Tests/Classes/OpeningBraceSpaceUnitTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR12/Tests/Files/FileHeaderUnitTest.17.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.11.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.11.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.12.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.12.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.13.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.13.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/PSR2/Tests/Files/EndFileNewlineUnitTest.14.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Tests/Commenting/FileCommentUnitTest.7.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Tests/Commenting/FileCommentUnitTest.8.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Tests/Commenting/FileCommentUnitTest.9.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed create mode 100644 app/vendor/squizlabs/php_codesniffer/src/Standards/Squiz/Tests/Files/FileExtensionUnitTest.5.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/File/FindStartOfStatementTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/File/FindStartOfStatementTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/ArrayKeywordTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/ArrayKeywordTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/AttributesTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/AttributesTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillEnumTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillEnumTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillExplicitOctalNotationTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillMatchTokenTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillMatchTokenTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillReadonlyTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BackfillReadonlyTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BitwiseOrTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/BitwiseOrTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/ContextSensitiveKeywordsTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/ContextSensitiveKeywordsTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DefaultKeywordTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DefaultKeywordTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DoubleArrowTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DoubleArrowTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DoubleQuotedStringTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/DoubleQuotedStringTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/EnumCaseTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/EnumCaseTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/FinallyTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/FinallyTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/GotoLabelTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/GotoLabelTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/NamedFunctionCallArgumentsTest.php create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/TypeIntersectionTest.inc create mode 100644 app/vendor/squizlabs/php_codesniffer/tests/Core/Tokenizer/TypeIntersectionTest.php create mode 100644 app/vendor/symfony/config/Definition/ConfigurableInterface.php create mode 100644 app/vendor/symfony/config/Definition/Configuration.php create mode 100644 app/vendor/symfony/config/Definition/Configurator/DefinitionConfigurator.php create mode 100644 app/vendor/symfony/config/Definition/Loader/DefinitionFileLoader.php create mode 100644 app/vendor/symfony/config/Loader/DirectoryAwareLoaderInterface.php create mode 100644 app/vendor/symfony/console/Command/CompleteCommand.php create mode 100644 app/vendor/symfony/console/Command/DumpCompletionCommand.php create mode 100644 app/vendor/symfony/console/Completion/CompletionInput.php create mode 100644 app/vendor/symfony/console/Completion/CompletionSuggestions.php create mode 100644 app/vendor/symfony/console/Completion/Output/BashCompletionOutput.php create mode 100644 app/vendor/symfony/console/Completion/Output/CompletionOutputInterface.php create mode 100644 app/vendor/symfony/console/Completion/Output/FishCompletionOutput.php create mode 100644 app/vendor/symfony/console/Completion/Output/ZshCompletionOutput.php create mode 100644 app/vendor/symfony/console/Completion/Suggestion.php create mode 100644 app/vendor/symfony/console/Helper/OutputWrapper.php create mode 100644 app/vendor/symfony/console/Output/AnsiColorMode.php create mode 100644 app/vendor/symfony/console/Resources/completion.bash create mode 100644 app/vendor/symfony/console/Resources/completion.fish create mode 100644 app/vendor/symfony/console/Resources/completion.zsh create mode 100644 app/vendor/symfony/console/Tester/CommandCompletionTester.php create mode 100644 app/vendor/symfony/console/Tester/Constraint/CommandIsSuccessful.php delete mode 100644 app/vendor/symfony/deprecation-contracts/.gitignore create mode 100644 app/vendor/symfony/filesystem/Exception/RuntimeException.php create mode 100644 app/vendor/symfony/filesystem/Path.php create mode 100644 app/vendor/symfony/finder/Iterator/VcsIgnoredFilterIterator.php create mode 100644 app/vendor/symfony/polyfill-php80/PhpToken.php create mode 100644 app/vendor/symfony/polyfill-php80/Resources/stubs/PhpToken.php delete mode 100644 app/vendor/symfony/service-contracts/.gitignore create mode 100644 app/vendor/symfony/service-contracts/Attribute/SubscribedService.php create mode 100644 app/vendor/symfony/var-dumper/Caster/FFICaster.php create mode 100644 app/vendor/symfony/var-dumper/Caster/FiberCaster.php create mode 100644 app/vendor/symfony/var-dumper/Caster/MysqliCaster.php delete mode 100644 app/vendor/twig/twig/.editorconfig delete mode 100644 app/vendor/twig/twig/.gitattributes delete mode 100644 app/vendor/twig/twig/.github/workflows/ci.yml delete mode 100644 app/vendor/twig/twig/.github/workflows/documentation.yml delete mode 100644 app/vendor/twig/twig/.gitignore delete mode 100644 app/vendor/twig/twig/.php-cs-fixer.dist.php create mode 100644 app/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php create mode 100644 app/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php delete mode 100644 app/vendor/webmozart/assert/.editorconfig delete mode 100644 app/vendor/webmozart/assert/.github/workflows/ci.yaml delete mode 100644 app/vendor/webmozart/assert/.php_cs delete mode 100644 app/vendor/webmozart/assert/CHANGELOG.md delete mode 100644 app/vendor/webmozart/assert/LICENSE delete mode 100644 app/vendor/webmozart/assert/README.md delete mode 100644 app/vendor/webmozart/assert/composer.json delete mode 100644 app/vendor/webmozart/assert/psalm.xml delete mode 100644 app/vendor/webmozart/assert/src/Assert.php delete mode 100644 app/vendor/webmozart/assert/src/InvalidArgumentException.php delete mode 100644 app/vendor/webmozart/assert/src/Mixin.php diff --git a/app/composer.json b/app/composer.json index 3bea99d9d..85310beb1 100644 --- a/app/composer.json +++ b/app/composer.json @@ -6,7 +6,7 @@ "license": "MIT", "require": { "php": ">=8.0", - "cakephp/cakephp": "4.3.9", + "cakephp/cakephp": "4.4.*", "cakephp/migrations": "^3.2", "cakephp/plugin-installer": "^1.3", "doctrine/dbal": "^3.3", diff --git a/app/composer.lock b/app/composer.lock index 64dc9760d..3ebb0d9ba 100644 --- a/app/composer.lock +++ b/app/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "b5b872b4fb7ca7b66353dd22890a8ee6", + "content-hash": "b8641c704e99c64fa4e1c3bfd3c27959", "packages": [ { "name": "cakephp/cakephp", - "version": "4.3.9", + "version": "4.4.11", "source": { "type": "git", "url": "https://github.com/cakephp/cakephp.git", - "reference": "6548d1141fc8311d0fd4d6acdd18446d4279fe32" + "reference": "7d9b6a639e5c1f52a813696f6b347726a74f9680" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/cakephp/zipball/6548d1141fc8311d0fd4d6acdd18446d4279fe32", - "reference": "6548d1141fc8311d0fd4d6acdd18446d4279fe32", + "url": "https://api.github.com/repos/cakephp/cakephp/zipball/7d9b6a639e5c1f52a813696f6b347726a74f9680", + "reference": "7d9b6a639e5c1f52a813696f6b347726a74f9680", "shasum": "" }, "require": { @@ -27,9 +27,9 @@ "ext-json": "*", "ext-mbstring": "*", "laminas/laminas-diactoros": "^2.2.2", - "laminas/laminas-httphandlerrunner": "^1.1", + "laminas/laminas-httphandlerrunner": "^1.1 || ^2.0", "league/container": "^4.2.0", - "php": ">=7.2.0", + "php": ">=7.4.0", "psr/container": "^1.1 || ^2.0", "psr/http-client": "^1.0", "psr/http-server-handler": "^1.0", @@ -108,20 +108,20 @@ "issues": "https://github.com/cakephp/cakephp/issues", "source": "https://github.com/cakephp/cakephp" }, - "time": "2022-05-14T01:25:15+00:00" + "time": "2023-02-11T01:01:55+00:00" }, { "name": "cakephp/chronos", - "version": "2.3.0", + "version": "2.3.2", "source": { "type": "git", "url": "https://github.com/cakephp/chronos.git", - "reference": "3ecd6e7ae191c676570cd1bed51fd561de4606dd" + "reference": "a21b7b633f483c4cf525d200219d200f551ee38b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/chronos/zipball/3ecd6e7ae191c676570cd1bed51fd561de4606dd", - "reference": "3ecd6e7ae191c676570cd1bed51fd561de4606dd", + "url": "https://api.github.com/repos/cakephp/chronos/zipball/a21b7b633f483c4cf525d200219d200f551ee38b", + "reference": "a21b7b633f483c4cf525d200219d200f551ee38b", "shasum": "" }, "require": { @@ -152,48 +152,47 @@ }, { "name": "The CakePHP Team", - "homepage": "http://cakephp.org" + "homepage": "https://cakephp.org" } ], "description": "A simple API extension for DateTime.", - "homepage": "http://cakephp.org", + "homepage": "https://cakephp.org", "keywords": [ "date", "datetime", "time" ], "support": { - "irc": "irc://irc.freenode.org/cakephp", "issues": "https://github.com/cakephp/chronos/issues", "source": "https://github.com/cakephp/chronos" }, - "time": "2021-10-17T02:44:05+00:00" + "time": "2022-11-08T02:17:04+00:00" }, { "name": "cakephp/migrations", - "version": "3.5.2", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/cakephp/migrations.git", - "reference": "e1b03bfef53ce41feabbf2120021ad5187e80289" + "reference": "97dfc6bdd0ac62f628ce51429a8737e1e5e86684" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/migrations/zipball/e1b03bfef53ce41feabbf2120021ad5187e80289", - "reference": "e1b03bfef53ce41feabbf2120021ad5187e80289", + "url": "https://api.github.com/repos/cakephp/migrations/zipball/97dfc6bdd0ac62f628ce51429a8737e1e5e86684", + "reference": "97dfc6bdd0ac62f628ce51429a8737e1e5e86684", "shasum": "" }, "require": { "cakephp/cache": "^4.3.0", "cakephp/orm": "^4.3.0", - "php": ">=7.2.0", - "robmorgan/phinx": "^0.12" + "php": ">=7.4.0", + "robmorgan/phinx": "^0.13.2" }, "require-dev": { "cakephp/bake": "^2.6.0", "cakephp/cakephp": "^4.3.0", "cakephp/cakephp-codesniffer": "^4.1", - "phpunit/phpunit": "^8.5.0 || ^9.5.0" + "phpunit/phpunit": "^9.5.0" }, "suggest": { "cakephp/bake": "If you want to generate migrations.", @@ -227,7 +226,7 @@ "issues": "https://github.com/cakephp/migrations/issues", "source": "https://github.com/cakephp/migrations" }, - "time": "2022-05-10T15:01:58+00:00" + "time": "2023-01-12T15:41:05+00:00" }, { "name": "cakephp/plugin-installer", @@ -280,16 +279,16 @@ }, { "name": "composer/ca-bundle", - "version": "1.3.1", + "version": "1.3.5", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b" + "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b", - "reference": "4c679186f2aca4ab6a0f1b0b9cf9252decb44d0b", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/74780ccf8c19d6acb8d65c5f39cd72110e132bbd", + "reference": "74780ccf8c19d6acb8d65c5f39cd72110e132bbd", "shasum": "" }, "require": { @@ -336,7 +335,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/ca-bundle/issues", - "source": "https://github.com/composer/ca-bundle/tree/1.3.1" + "source": "https://github.com/composer/ca-bundle/tree/1.3.5" }, "funding": [ { @@ -352,20 +351,20 @@ "type": "tidelift" } ], - "time": "2021-10-28T20:44:15+00:00" + "time": "2023-01-11T08:27:00+00:00" }, { "name": "doctrine/cache", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { @@ -375,18 +374,12 @@ "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^8.0", - "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "predis/predis": "~1.0", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", - "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, "type": "library", "autoload": { @@ -435,7 +428,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.1.1" + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { @@ -451,42 +444,43 @@ "type": "tidelift" } ], - "time": "2021-07-17T14:49:29+00:00" + "time": "2022-05-20T20:07:39+00:00" }, { "name": "doctrine/dbal", - "version": "3.3.7", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a" + "reference": "85b98cb23c8af471a67abfe14485da696bcabc2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a", - "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/85b98cb23c8af471a67abfe14485da696bcabc2e", + "reference": "85b98cb23c8af471a67abfe14485da696bcabc2e", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1.0", - "php": "^7.3 || ^8.0", + "doctrine/event-manager": "^1|^2", + "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2022.1", - "phpstan/phpstan": "1.7.13", - "phpstan/phpstan-strict-rules": "^1.2", - "phpunit/phpunit": "9.5.20", - "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.7.0", - "symfony/cache": "^5.2|^6.0", - "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.23.0" + "doctrine/coding-standard": "11.1.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2022.3", + "phpstan/phpstan": "1.9.14", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "9.6.3", + "psalm/plugin-phpunit": "0.18.4", + "squizlabs/php_codesniffer": "3.7.1", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.30.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -546,7 +540,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.3.7" + "source": "https://github.com/doctrine/dbal/tree/3.6.0" }, "funding": [ { @@ -562,7 +556,7 @@ "type": "tidelift" } ], - "time": "2022-06-13T21:43:03+00:00" + "time": "2023-02-07T22:52:03+00:00" }, { "name": "doctrine/deprecations", @@ -609,37 +603,34 @@ }, { "name": "doctrine/event-manager", - "version": "1.1.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "conflict": { - "doctrine/common": "<2.9@dev" + "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpunit/phpunit": "^7.0" + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.28" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -683,7 +674,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + "source": "https://github.com/doctrine/event-manager/tree/2.0.0" }, "funding": [ { @@ -699,29 +690,28 @@ "type": "tidelift" } ], - "time": "2020-05-29T18:28:51+00:00" + "time": "2022-10-12T20:59:15+00:00" }, { "name": "laminas/laminas-diactoros", - "version": "2.10.0", + "version": "2.24.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-diactoros.git", - "reference": "a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4" + "reference": "6028af6c3b5ced4d063a680d2483cce67578b902" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4", - "reference": "a3f03b3c158a3a7014c6ba553b0cb83bf7da19c4", + "url": "https://api.github.com/repos/laminas/laminas-diactoros/zipball/6028af6c3b5ced4d063a680d2483cce67578b902", + "reference": "6028af6c3b5ced4d063a680d2483cce67578b902", "shasum": "" }, "require": { - "php": "^7.3 || ~8.0.0 || ~8.1.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.0" }, "conflict": { - "phpspec/prophecy": "<1.9.0", "zendframework/zend-diactoros": "*" }, "provide": { @@ -733,13 +723,12 @@ "ext-dom": "*", "ext-gd": "*", "ext-libxml": "*", - "http-interop/http-factory-tests": "^0.8.0", - "laminas/laminas-coding-standard": "~1.0.0", - "php-http/psr7-integration-tests": "^1.1", - "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.1", - "psalm/plugin-phpunit": "^0.14.0", - "vimeo/psalm": "^4.3" + "http-interop/http-factory-tests": "^0.9.0", + "laminas/laminas-coding-standard": "^2.4.0", + "php-http/psr7-integration-tests": "^1.2", + "phpunit/phpunit": "^9.5.27", + "psalm/plugin-phpunit": "^0.18.4", + "vimeo/psalm": "^5.4" }, "type": "library", "extra": { @@ -798,38 +787,34 @@ "type": "community_bridge" } ], - "time": "2022-05-04T15:16:15+00:00" + "time": "2022-12-20T12:22:40+00:00" }, { "name": "laminas/laminas-httphandlerrunner", - "version": "1.5.0", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-httphandlerrunner.git", - "reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e" + "reference": "7a47834aaad7852816d2ec4fdbb0492163b039ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/5f94e55d93f756e8ad07b9049aeb3d6d84582d0e", - "reference": "5f94e55d93f756e8ad07b9049aeb3d6d84582d0e", + "url": "https://api.github.com/repos/laminas/laminas-httphandlerrunner/zipball/7a47834aaad7852816d2ec4fdbb0492163b039ae", + "reference": "7a47834aaad7852816d2ec4fdbb0492163b039ae", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^7.3 || ~8.0.0 || ~8.1.0", + "php": "~8.0.0 || ~8.1.0 || ~8.2.0", "psr/http-message": "^1.0", "psr/http-message-implementation": "^1.0", "psr/http-server-handler": "^1.0" }, - "replace": { - "zendframework/zend-httphandlerrunner": "^1.1.0" - }, "require-dev": { - "laminas/laminas-coding-standard": "~1.0.0", - "laminas/laminas-diactoros": "^2.8.0", - "phpunit/phpunit": "^9.5.9", - "psalm/plugin-phpunit": "^0.16.1", - "vimeo/psalm": "^4.10.0" + "laminas/laminas-coding-standard": "~2.4.0", + "laminas/laminas-diactoros": "^2.18", + "phpunit/phpunit": "^9.5.26", + "psalm/plugin-phpunit": "^0.18.0", + "vimeo/psalm": "^5.0.0" }, "type": "library", "extra": { @@ -869,69 +854,7 @@ "type": "community_bridge" } ], - "time": "2021-09-22T09:17:54+00:00" - }, - { - "name": "laminas/laminas-zendframework-bridge", - "version": "1.5.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "7f049390b756d34ba5940a8fb47634fbb51f79ab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/7f049390b756d34ba5940a8fb47634fbb51f79ab", - "reference": "7f049390b756d34ba5940a8fb47634fbb51f79ab", - "shasum": "" - }, - "require": { - "php": ">=7.4, <8.2" - }, - "require-dev": { - "phpunit/phpunit": "^9.5.14", - "psalm/plugin-phpunit": "^0.15.2", - "squizlabs/php_codesniffer": "^3.6.2", - "vimeo/psalm": "^4.21.0" - }, - "type": "library", - "extra": { - "laminas": { - "module": "Laminas\\ZendFrameworkBridge" - } - }, - "autoload": { - "files": [ - "src/autoload.php" - ], - "psr-4": { - "Laminas\\ZendFrameworkBridge\\": "src//" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Alias legacy ZF class names to Laminas Project equivalents.", - "keywords": [ - "ZendFramework", - "autoloading", - "laminas", - "zf" - ], - "support": { - "forum": "https://discourse.laminas.dev/", - "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", - "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", - "source": "https://github.com/laminas/laminas-zendframework-bridge" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2022-02-22T22:17:01+00:00" + "time": "2023-01-05T21:54:03+00:00" }, { "name": "league/container", @@ -1017,16 +940,16 @@ }, { "name": "mobiledetect/mobiledetectlib", - "version": "2.8.39", + "version": "2.8.41", "source": { "type": "git", "url": "https://github.com/serbanghita/Mobile-Detect.git", - "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45" + "reference": "fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/0fd6753003fc870f6e229bae869cc1337c99bc45", - "reference": "0fd6753003fc870f6e229bae869cc1337c99bc45", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1", + "reference": "fc9cccd4d3706d5a7537b562b59cc18f9e4c0cb1", "shasum": "" }, "require": { @@ -1067,9 +990,9 @@ ], "support": { "issues": "https://github.com/serbanghita/Mobile-Detect/issues", - "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.39" + "source": "https://github.com/serbanghita/Mobile-Detect/tree/2.8.41" }, - "time": "2022-02-17T19:24:25+00:00" + "time": "2022-11-08T18:31:26+00:00" }, { "name": "psr/cache", @@ -1550,16 +1473,16 @@ }, { "name": "robmorgan/phinx", - "version": "0.12.10", + "version": "0.13.4", "source": { "type": "git", "url": "https://github.com/cakephp/phinx.git", - "reference": "ad056cff354fc67fedf9bf96c441c2b428afad0c" + "reference": "18e06e4a2b18947663438afd2f467e17c62e867d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/phinx/zipball/ad056cff354fc67fedf9bf96c441c2b428afad0c", - "reference": "ad056cff354fc67fedf9bf96c441c2b428afad0c", + "url": "https://api.github.com/repos/cakephp/phinx/zipball/18e06e4a2b18947663438afd2f467e17c62e867d", + "reference": "18e06e4a2b18947663438afd2f467e17c62e867d", "shasum": "" }, "require": { @@ -1630,33 +1553,32 @@ ], "support": { "issues": "https://github.com/cakephp/phinx/issues", - "source": "https://github.com/cakephp/phinx/tree/0.12.10" + "source": "https://github.com/cakephp/phinx/tree/0.13.4" }, - "time": "2022-01-21T19:53:14+00:00" + "time": "2023-01-07T00:42:55+00:00" }, { "name": "symfony/config", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "6ac50d559aa64c8e7b5b17640c46241e4accb487" + "reference": "f31b3c78a3650157188a240695e688d6a182aa91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/6ac50d559aa64c8e7b5b17640c46241e4accb487", - "reference": "6ac50d559aa64c8e7b5b17640c46241e4accb487", + "url": "https://api.github.com/repos/symfony/config/zipball/f31b3c78a3650157188a240695e688d6a182aa91", + "reference": "f31b3c78a3650157188a240695e688d6a182aa91", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3", "symfony/filesystem": "^5.4|^6.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php81": "^1.22" + "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<4.4" + "symfony/finder": "<5.4" }, "require-dev": { "symfony/event-dispatcher": "^5.4|^6.0", @@ -1694,7 +1616,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.0.8" + "source": "https://github.com/symfony/config/tree/v6.2.5" }, "funding": [ { @@ -1710,24 +1632,25 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:11:42+00:00" + "time": "2023-01-09T04:38:22+00:00" }, { "name": "symfony/console", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0d00aa289215353aa8746a31d101f8e60826285c" + "reference": "3e294254f2191762c1d137aed4b94e966965e985" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0d00aa289215353aa8746a31d101f8e60826285c", - "reference": "0d00aa289215353aa8746a31d101f8e60826285c", + "url": "https://api.github.com/repos/symfony/console/zipball/3e294254f2191762c1d137aed4b94e966965e985", + "reference": "3e294254f2191762c1d137aed4b94e966965e985", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^1.1|^2|^3", "symfony/string": "^5.4|^6.0" @@ -1789,7 +1712,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.8" + "source": "https://github.com/symfony/console/tree/v6.2.5" }, "funding": [ { @@ -1805,29 +1728,29 @@ "type": "tidelift" } ], - "time": "2022-04-20T15:01:42+00:00" + "time": "2023-01-01T08:38:09+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1856,7 +1779,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" }, "funding": [ { @@ -1872,24 +1795,24 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/filesystem", - "version": "v6.0.7", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff" + "reference": "e59e8a4006afd7f5654786a83b4fcb8da98f4593" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", - "reference": "6c9e4c41f2c51dfde3db298594ed9cba55dbf5ff", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e59e8a4006afd7f5654786a83b4fcb8da98f4593", + "reference": "e59e8a4006afd7f5654786a83b4fcb8da98f4593", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, @@ -1919,7 +1842,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.7" + "source": "https://github.com/symfony/filesystem/tree/v6.2.5" }, "funding": [ { @@ -1935,20 +1858,20 @@ "type": "tidelift" } ], - "time": "2022-04-01T12:54:51+00:00" + "time": "2023-01-20T17:45:48+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "30885182c981ab175d4d034db0f6f469898070ab" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", - "reference": "30885182c981ab175d4d034db0f6f469898070ab", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -1963,7 +1886,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2001,7 +1924,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -2017,20 +1940,20 @@ "type": "tidelift" } ], - "time": "2021-10-20T20:35:02+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783" + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/81b86b50cf841a64252b439e738e97f4a34e2783", - "reference": "81b86b50cf841a64252b439e738e97f4a34e2783", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", "shasum": "" }, "require": { @@ -2042,7 +1965,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2082,7 +2005,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" }, "funding": [ { @@ -2098,20 +2021,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T21:10:46+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -2123,7 +2046,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2166,7 +2089,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -2182,20 +2105,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -2210,7 +2133,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2249,86 +2172,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.25.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-11-30T18:21:41+00:00" - }, - { - "name": "symfony/polyfill-php81", - "version": "v1.25.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "reference": "5de4ba2d41b15f9bd0e19b2ab9674135813ec98f", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "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 8.1+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -2344,24 +2188,24 @@ "type": "tidelift" } ], - "time": "2021-09-13T13:58:11+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/container": "^2.0" }, "conflict": { @@ -2373,7 +2217,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -2383,7 +2227,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2410,7 +2257,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" }, "funding": [ { @@ -2426,24 +2273,24 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/string", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "ac0aa5c2282e0de624c175b68d13f2c8f2e2649d" + "reference": "b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/ac0aa5c2282e0de624c175b68d13f2c8f2e2649d", - "reference": "ac0aa5c2282e0de624c175b68d13f2c8f2e2649d", + "url": "https://api.github.com/repos/symfony/string/zipball/b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0", + "reference": "b2dac0fa27b1ac0f9c0c0b23b43977f12308d0b0", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -2455,6 +2302,7 @@ "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", "symfony/translation-contracts": "^2.0|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, @@ -2495,7 +2343,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.8" + "source": "https://github.com/symfony/string/tree/v6.2.5" }, "funding": [ { @@ -2511,22 +2359,22 @@ "type": "tidelift" } ], - "time": "2022-04-22T08:18:02+00:00" + "time": "2023-01-01T08:38:09+00:00" } ], "packages-dev": [ { "name": "brick/varexporter", - "version": "0.3.5", + "version": "0.3.8", "source": { "type": "git", "url": "https://github.com/brick/varexporter.git", - "reference": "05241f28dfcba2b51b11e2d750e296316ebbe518" + "reference": "b5853edea6204ff8fa10633c3a4cccc4058410ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/brick/varexporter/zipball/05241f28dfcba2b51b11e2d750e296316ebbe518", - "reference": "05241f28dfcba2b51b11e2d750e296316ebbe518", + "url": "https://api.github.com/repos/brick/varexporter/zipball/b5853edea6204ff8fa10633c3a4cccc4058410ed", + "reference": "b5853edea6204ff8fa10633c3a4cccc4058410ed", "shasum": "" }, "require": { @@ -2536,7 +2384,7 @@ "require-dev": { "php-coveralls/php-coveralls": "^2.2", "phpunit/phpunit": "^8.5 || ^9.0", - "vimeo/psalm": "4.4.1" + "vimeo/psalm": "4.23.0" }, "type": "library", "autoload": { @@ -2554,28 +2402,35 @@ ], "support": { "issues": "https://github.com/brick/varexporter/issues", - "source": "https://github.com/brick/varexporter/tree/0.3.5" + "source": "https://github.com/brick/varexporter/tree/0.3.8" }, - "time": "2021-02-10T13:53:07+00:00" + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2023-01-21T23:05:38+00:00" }, { "name": "cakephp/bake", - "version": "2.7.0", + "version": "2.8.2", "source": { "type": "git", "url": "https://github.com/cakephp/bake.git", - "reference": "3933caa0941b2f75f3e53c5456efdbf588917584" + "reference": "ef021497ab517c33ecd97d2184200d8990ffc0ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/bake/zipball/3933caa0941b2f75f3e53c5456efdbf588917584", - "reference": "3933caa0941b2f75f3e53c5456efdbf588917584", + "url": "https://api.github.com/repos/cakephp/bake/zipball/ef021497ab517c33ecd97d2184200d8990ffc0ab", + "reference": "ef021497ab517c33ecd97d2184200d8990ffc0ab", "shasum": "" }, "require": { "brick/varexporter": "^0.3.5", "cakephp/cakephp": "^4.3.0", "cakephp/twig-view": "^1.0.2", + "nikic/php-parser": "^4.13.2", "php": ">=7.2" }, "require-dev": { @@ -2612,25 +2467,25 @@ "issues": "https://github.com/cakephp/bake/issues", "source": "https://github.com/cakephp/bake" }, - "time": "2022-04-14T08:50:07+00:00" + "time": "2022-10-05T18:45:20+00:00" }, { "name": "cakephp/cakephp-codesniffer", - "version": "4.5.1", + "version": "4.6.0", "source": { "type": "git", "url": "https://github.com/cakephp/cakephp-codesniffer.git", - "reference": "6b17905db024b8d7e64a15296688545c61ab6694" + "reference": "5a64e6e6434128f6a1549318de86c564737d5cda" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/6b17905db024b8d7e64a15296688545c61ab6694", - "reference": "6b17905db024b8d7e64a15296688545c61ab6694", + "url": "https://api.github.com/repos/cakephp/cakephp-codesniffer/zipball/5a64e6e6434128f6a1549318de86c564737d5cda", + "reference": "5a64e6e6434128f6a1549318de86c564737d5cda", "shasum": "" }, "require": { "php": ">=7.2.0", - "slevomat/coding-standard": "^6.3.6 || ^7.0", + "slevomat/coding-standard": "^6.3.6 || ^7.0 || ^8.0", "squizlabs/php_codesniffer": "^3.6" }, "require-dev": { @@ -2664,28 +2519,28 @@ "issues": "https://github.com/cakephp/cakephp-codesniffer/issues", "source": "https://github.com/cakephp/cakephp-codesniffer" }, - "time": "2021-07-11T04:47:47+00:00" + "time": "2022-07-04T03:29:58+00:00" }, { "name": "cakephp/debug_kit", - "version": "4.7.1", + "version": "4.9.3", "source": { "type": "git", "url": "https://github.com/cakephp/debug_kit.git", - "reference": "ce564bacca4ebf471c34a886741672b54328b382" + "reference": "db848e787bf53483069cba2feb449c2e8523f525" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/ce564bacca4ebf471c34a886741672b54328b382", - "reference": "ce564bacca4ebf471c34a886741672b54328b382", + "url": "https://api.github.com/repos/cakephp/debug_kit/zipball/db848e787bf53483069cba2feb449c2e8523f525", + "reference": "db848e787bf53483069cba2feb449c2e8523f525", "shasum": "" }, "require": { - "cakephp/cakephp": "^4.3.0", + "cakephp/cakephp": "^4.4.0", "cakephp/chronos": "^2.0", "composer/composer": "^1.3 | ^2.0", "jdorn/sql-formatter": "^1.2", - "php": ">=7.2" + "php": ">=7.4" }, "require-dev": { "cakephp/authorization": "^2.0", @@ -2730,7 +2585,7 @@ "issues": "https://github.com/cakephp/debug_kit/issues", "source": "https://github.com/cakephp/debug_kit" }, - "time": "2022-01-20T02:44:41+00:00" + "time": "2023-01-25T04:49:08+00:00" }, { "name": "cakephp/twig-view", @@ -2795,26 +2650,100 @@ }, "time": "2021-09-17T14:07:52+00:00" }, + { + "name": "composer/class-map-generator", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-06-19T11:31:27+00:00" + }, { "name": "composer/composer", - "version": "2.3.5", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "50c47b1f907cfcdb8f072b88164d22b527557ae1" + "reference": "607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/50c47b1f907cfcdb8f072b88164d22b527557ae1", - "reference": "50c47b1f907cfcdb8f072b88164d22b527557ae1", + "url": "https://api.github.com/repos/composer/composer/zipball/607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab", + "reference": "607a4c04006ce1d2b6fdfd5467bae3d7ad9ce5ab", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", + "composer/class-map-generator": "^1.0", "composer/metadata-minifier": "^1.0", - "composer/pcre": "^2 || ^3", + "composer/pcre": "^2.1 || ^3.1", "composer/semver": "^3.0", - "composer/spdx-licenses": "^1.2", + "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", "justinrainbow/json-schema": "^5.2.11", "php": "^7.2.5 || ^8.0", @@ -2822,19 +2751,21 @@ "react/promise": "^2.8", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", - "symfony/console": "^5.4.1 || ^6.0", + "seld/signal-handler": "^2.0", + "symfony/console": "^5.4.11 || ^6.0.11", "symfony/filesystem": "^5.4 || ^6.0", "symfony/finder": "^5.4 || ^6.0", "symfony/polyfill-php73": "^1.24", "symfony/polyfill-php80": "^1.24", + "symfony/polyfill-php81": "^1.24", "symfony/process": "^5.4 || ^6.0" }, "require-dev": { - "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan": "^1.9.3", "phpstan/phpstan-deprecation-rules": "^1", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-strict-rules": "^1", - "phpstan/phpstan-symfony": "^1.1", + "phpstan/phpstan-symfony": "^1.2.10", "symfony/phpunit-bridge": "^6.0" }, "suggest": { @@ -2848,7 +2779,12 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.5-dev" + }, + "phpstan": { + "includes": [ + "phpstan/rules.neon" + ] } }, "autoload": { @@ -2882,7 +2818,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.3.5" + "source": "https://github.com/composer/composer/tree/2.5.3" }, "funding": [ { @@ -2898,7 +2834,7 @@ "type": "tidelift" } ], - "time": "2022-04-13T14:43:00+00:00" + "time": "2023-02-10T12:23:52+00:00" }, { "name": "composer/metadata-minifier", @@ -2971,16 +2907,16 @@ }, { "name": "composer/pcre", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { @@ -3022,7 +2958,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -3038,7 +2974,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T20:21:48+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", @@ -3123,16 +3059,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.5.6", + "version": "1.5.7", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "a30d487169d799745ca7280bc90fdfa693536901" + "reference": "c848241796da2abf65837d51dce1fae55a960149" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/a30d487169d799745ca7280bc90fdfa693536901", - "reference": "a30d487169d799745ca7280bc90fdfa693536901", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/c848241796da2abf65837d51dce1fae55a960149", + "reference": "c848241796da2abf65837d51dce1fae55a960149", "shasum": "" }, "require": { @@ -3183,7 +3119,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/spdx-licenses/issues", - "source": "https://github.com/composer/spdx-licenses/tree/1.5.6" + "source": "https://github.com/composer/spdx-licenses/tree/1.5.7" }, "funding": [ { @@ -3199,7 +3135,7 @@ "type": "tidelift" } ], - "time": "2021-11-18T10:14:14+00:00" + "time": "2022-05-23T07:37:50+00:00" }, { "name": "composer/xdebug-handler", @@ -3269,35 +3205,38 @@ }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", + "version": "v1.0.0", "source": { "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + "url": "https://github.com/PHPCSStandards/composer-installer.git", + "reference": "4be43904336affa5c2f70744a348312336afd0da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", + "reference": "4be43904336affa5c2f70744a348312336afd0da", "shasum": "" }, "require": { "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", + "php": ">=5.4", "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { "composer/composer": "*", + "ext-json": "*", + "ext-zip": "*", "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" + "phpcompatibility/php-compatibility": "^9.0", + "yoast/phpunit-polyfills": "^1.0" }, "type": "composer-plugin", "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + "class": "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, "autoload": { "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + "PHPCSStandards\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -3313,7 +3252,7 @@ }, { "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + "homepage": "https://github.com/PHPCSStandards/composer-installer/graphs/contributors" } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", @@ -3337,37 +3276,37 @@ "tests" ], "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" }, - "time": "2022-02-04T12:51:07+00:00" + "time": "2023-01-05T11:28:13+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -3394,7 +3333,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -3410,7 +3349,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "jasny/twig-extensions", @@ -3780,16 +3719,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.15.3", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/570e980a201d8ed0236b0a62ddf2c9cbb2034039", + "reference": "570e980a201d8ed0236b0a62ddf2c9cbb2034039", "shasum": "" }, "require": { @@ -3830,9 +3769,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.3" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2023-01-16T22:05:37+00:00" }, { "name": "phar-io/manifest", @@ -3946,295 +3885,69 @@ "time": "2022-02-21T01:04:05+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", + "name": "phpstan/phpdoc-parser", + "version": "1.15.3", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "61800f71a5526081d1b5633766aa88341f1ade76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/61800f71a5526081d1b5633766aa88341f1ade76", + "reference": "61800f71a5526081d1b5633766aa88341f1ade76", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" }, + "type": "library", "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": "src/" + "PHPStan\\PhpDocParser\\": [ + "src/" + ] } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.15.3" }, - "time": "2020-06-27T09:03:43+00:00" + "time": "2022-12-20T20:56:55+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "name": "phpunit/php-code-coverage", + "version": "9.2.24", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, - { - "name": "phpstan/phpdoc-parser", - "version": "1.5.1", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "981cc368a216c988e862a75e526b6076987d1b50" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/981cc368a216c988e862a75e526b6076987d1b50", - "reference": "981cc368a216c988e862a75e526b6076987d1b50", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", - "symfony/process": "^5.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "PHPStan\\PhpDocParser\\": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "PHPDoc parser with support for nullable, intersection and generic types", - "support": { - "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.5.1" - }, - "time": "2022-05-05T11:32:40+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.2.15", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2cf940ebc6355a9d430462811b5aaa308b174bed", + "reference": "2cf940ebc6355a9d430462811b5aaa308b174bed", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.14", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4283,7 +3996,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.24" }, "funding": [ { @@ -4291,7 +4004,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2023-01-26T08:26:55+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4536,20 +4249,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.20", + "version": "9.6.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7b1615e3e887d6c719121c6d4a44b0ab9645555", + "reference": "e7b1615e3e887d6c719121c6d4a44b0ab9645555", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -4560,7 +4273,6 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", @@ -4568,20 +4280,16 @@ "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", + "sebastian/comparator": "^4.0.8", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", + "sebastian/exporter": "^4.0.5", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.2", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -4592,7 +4300,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -4623,7 +4331,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.3" }, "funding": [ { @@ -4633,22 +4341,26 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2022-04-01T12:37:26+00:00" + "time": "2023-02-04T13:37:15+00:00" }, { "name": "psy/psysh", - "version": "v0.11.4", + "version": "v0.11.12", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "05c544b339b112226ad14803e1e5b09a61957454" + "reference": "52cb7c47d403c31c0adc9bf7710fc355f93c20f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/05c544b339b112226ad14803e1e5b09a61957454", - "reference": "05c544b339b112226ad14803e1e5b09a61957454", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/52cb7c47d403c31c0adc9bf7710fc355f93c20f7", + "reference": "52cb7c47d403c31c0adc9bf7710fc355f93c20f7", "shasum": "" }, "require": { @@ -4709,9 +4421,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.4" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.12" }, - "time": "2022-05-06T12:49:14+00:00" + "time": "2023-01-29T21:24:40+00:00" }, { "name": "react/promise", @@ -4958,16 +4670,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -5020,7 +4732,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -5028,7 +4740,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -5155,16 +4867,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -5206,7 +4918,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -5214,20 +4926,20 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -5283,7 +4995,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -5291,7 +5003,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -5528,16 +5240,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -5576,10 +5288,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -5587,7 +5299,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -5646,16 +5358,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -5667,7 +5379,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -5690,7 +5402,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -5698,7 +5410,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -5819,16 +5531,16 @@ }, { "name": "seld/phar-utils", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "9f3452c93ff423469c0d56450431562ca423dcee" + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/9f3452c93ff423469c0d56450431562ca423dcee", - "reference": "9f3452c93ff423469c0d56450431562ca423dcee", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", "shasum": "" }, "require": { @@ -5861,43 +5573,104 @@ ], "support": { "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/1.2.0" + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" }, - "time": "2021-12-10T11:20:11+00:00" + "time": "2022-08-31T10:31:18+00:00" + }, + { + "name": "seld/signal-handler", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/signal-handler.git", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^7.5.20 || ^8.5.23", + "psr/log": "^1 || ^2 || ^3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\Signal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Simple unix signal handler that silently fails where signals are not supported for easy cross-platform development", + "keywords": [ + "posix", + "sigint", + "signal", + "sigterm", + "unix" + ], + "support": { + "issues": "https://github.com/Seldaek/signal-handler/issues", + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + }, + "time": "2022-07-20T18:31:45+00:00" }, { "name": "slevomat/coding-standard", - "version": "7.2.0", + "version": "8.8.0", "source": { "type": "git", "url": "https://github.com/slevomat/coding-standard.git", - "reference": "b4f96a8beea515d2d89141b7b9ad72f526d84071" + "reference": "59e25146a4ef0a7b194c5bc55b32dd414345db89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b4f96a8beea515d2d89141b7b9ad72f526d84071", - "reference": "b4f96a8beea515d2d89141b7b9ad72f526d84071", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/59e25146a4ef0a7b194c5bc55b32dd414345db89", + "reference": "59e25146a4ef0a7b194c5bc55b32dd414345db89", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7 || ^1.0", "php": "^7.2 || ^8.0", - "phpstan/phpdoc-parser": "^1.5.1", - "squizlabs/php_codesniffer": "^3.6.2" + "phpstan/phpdoc-parser": ">=1.15.2 <1.16.0", + "squizlabs/php_codesniffer": "^3.7.1" }, "require-dev": { - "phing/phing": "2.17.3", + "phing/phing": "2.17.4", "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpstan/phpstan": "1.4.10|1.6.7", - "phpstan/phpstan-deprecation-rules": "1.0.0", - "phpstan/phpstan-phpunit": "1.0.0|1.1.1", - "phpstan/phpstan-strict-rules": "1.2.3", - "phpunit/phpunit": "7.5.20|8.5.21|9.5.20" + "phpstan/phpstan": "1.4.10|1.9.6", + "phpstan/phpstan-deprecation-rules": "1.1.1", + "phpstan/phpstan-phpunit": "1.0.0|1.3.3", + "phpstan/phpstan-strict-rules": "1.4.4", + "phpunit/phpunit": "7.5.20|8.5.21|9.5.27" }, "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "7.x-dev" + "dev-master": "8.x-dev" } }, "autoload": { @@ -5910,9 +5683,13 @@ "MIT" ], "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], "support": { "issues": "https://github.com/slevomat/coding-standard/issues", - "source": "https://github.com/slevomat/coding-standard/tree/7.2.0" + "source": "https://github.com/slevomat/coding-standard/tree/8.8.0" }, "funding": [ { @@ -5924,20 +5701,20 @@ "type": "tidelift" } ], - "time": "2022-05-06T10:58:42+00:00" + "time": "2023-01-09T10:46:13+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.2", + "version": "3.7.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", - "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", "shasum": "" }, "require": { @@ -5980,24 +5757,27 @@ "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2021-12-12T21:44:58+00:00" + "time": "2022-06-18T07:21:10+00:00" }, { "name": "symfony/finder", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f" + "reference": "c90dc446976a612e3312a97a6ec0069ab0c2099c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/af7edab28d17caecd1f40a9219fc646ae751c21f", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f", + "url": "https://api.github.com/repos/symfony/finder/zipball/c90dc446976a612e3312a97a6ec0069ab0c2099c", + "reference": "c90dc446976a612e3312a97a6ec0069ab0c2099c", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" }, "type": "library", "autoload": { @@ -6025,7 +5805,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.8" + "source": "https://github.com/symfony/finder/tree/v6.2.5" }, "funding": [ { @@ -6041,20 +5821,20 @@ "type": "tidelift" } ], - "time": "2022-04-15T08:07:58+00:00" + "time": "2023-01-20T17:45:48+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5" + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/cc5db0e22b3cb4111010e48785a97f670b350ca5", - "reference": "cc5db0e22b3cb4111010e48785a97f670b350ca5", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/9e8ecb5f92152187c4799efd3c96b78ccab18ff9", + "reference": "9e8ecb5f92152187c4799efd3c96b78ccab18ff9", "shasum": "" }, "require": { @@ -6063,7 +5843,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6104,7 +5884,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.27.0" }, "funding": [ { @@ -6120,20 +5900,20 @@ "type": "tidelift" } ], - "time": "2021-06-05T21:20:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.25.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4407588e0d3f1f52efb65fbe92babe41f37fe50c", - "reference": "4407588e0d3f1f52efb65fbe92babe41f37fe50c", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -6142,7 +5922,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6187,7 +5967,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.25.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -6203,24 +5983,103 @@ "type": "tidelift" } ], - "time": "2022-03-04T08:16:47+00:00" + "time": "2022-11-03T14:55:06+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/process", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9" + "reference": "9ead139f63dfa38c4e4a9049cc64a8b2748c83b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d074154ea8b1443a96391f6e39f9e547b2dd01b9", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9", + "url": "https://api.github.com/repos/symfony/process/zipball/9ead139f63dfa38c4e4a9049cc64a8b2748c83b7", + "reference": "9ead139f63dfa38c4e4a9049cc64a8b2748c83b7", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -6248,7 +6107,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.8" + "source": "https://github.com/symfony/process/tree/v6.2.5" }, "funding": [ { @@ -6264,24 +6123,24 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:11:42+00:00" + "time": "2023-01-01T08:38:09+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.0.8", + "version": "v6.2.5", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "fa61dfb4bd3068df2492013dc65f3190e9f550c0" + "reference": "44b7b81749fd20c1bdf4946c041050e22bc8da27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/fa61dfb4bd3068df2492013dc65f3190e9f550c0", - "reference": "fa61dfb4bd3068df2492013dc65f3190e9f550c0", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/44b7b81749fd20c1bdf4946c041050e22bc8da27", + "reference": "44b7b81749fd20c1bdf4946c041050e22bc8da27", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -6336,7 +6195,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.8" + "source": "https://github.com/symfony/var-dumper/tree/v6.2.5" }, "funding": [ { @@ -6352,7 +6211,7 @@ "type": "tidelift" } ], - "time": "2022-04-26T13:22:23+00:00" + "time": "2023-01-20T17:45:48+00:00" }, { "name": "theseer/tokenizer", @@ -6406,16 +6265,16 @@ }, { "name": "twig/markdown-extra", - "version": "v3.4.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/twigphp/markdown-extra.git", - "reference": "25ed505b6ffd3b00f922ca682489dfbaf44eb1f7" + "reference": "9474c89fd2787187a3809e5e964dfce2395ae5f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/25ed505b6ffd3b00f922ca682489dfbaf44eb1f7", - "reference": "25ed505b6ffd3b00f922ca682489dfbaf44eb1f7", + "url": "https://api.github.com/repos/twigphp/markdown-extra/zipball/9474c89fd2787187a3809e5e964dfce2395ae5f0", + "reference": "9474c89fd2787187a3809e5e964dfce2395ae5f0", "shasum": "" }, "require": { @@ -6426,13 +6285,13 @@ "erusev/parsedown": "^1.7", "league/commonmark": "^1.0|^2.0", "league/html-to-markdown": "^4.8|^5.0", - "michelf/php-markdown": "^1.8", + "michelf/php-markdown": "^1.8|^2.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -6463,7 +6322,7 @@ "twig" ], "support": { - "source": "https://github.com/twigphp/markdown-extra/tree/v3.4.0" + "source": "https://github.com/twigphp/markdown-extra/tree/v3.5.1" }, "funding": [ { @@ -6475,20 +6334,20 @@ "type": "tidelift" } ], - "time": "2022-01-29T15:34:05+00:00" + "time": "2023-02-08T07:44:55+00:00" }, { "name": "twig/twig", - "version": "v3.4.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "ed19f4bf9d19c4ef920b5d8243910bd32e85b9ba" + "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/ed19f4bf9d19c4ef920b5d8243910bd32e85b9ba", - "reference": "ed19f4bf9d19c4ef920b5d8243910bd32e85b9ba", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a6e0510cc793912b451fd40ab983a1d28f611c15", + "reference": "a6e0510cc793912b451fd40ab983a1d28f611c15", "shasum": "" }, "require": { @@ -6503,7 +6362,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -6539,7 +6398,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.0" + "source": "https://github.com/twigphp/Twig/tree/v3.5.1" }, "funding": [ { @@ -6551,65 +6410,7 @@ "type": "tidelift" } ], - "time": "2022-05-15T06:25:28+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2023-02-08T07:49:20+00:00" } ], "aliases": [], @@ -6623,5 +6424,5 @@ "php": ">=8.0" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.1.0" } diff --git a/app/config/schema/schema.json b/app/config/schema/schema.json index a7144a176..3a5b7bb3b 100644 --- a/app/config/schema/schema.json +++ b/app/config/schema/schema.json @@ -110,6 +110,7 @@ "We don't really need an index, but DBAL will create one for all foreign keys if none exists", "typeIsDefault will make queries using these columns, but rarely and won't usually have enough rows to need the index" ], + "needed": false, "columns": [ "default_name_type_id" ] }, "co_settings_i3": { "columns": [ "default_email_address_type_id" ] }, @@ -166,9 +167,7 @@ "cous_i1": { "columns": [ "co_id" ] }, "cous_i2": { "columns": [ "name" ] }, "cous_i3": { "columns": [ "co_id", "name" ] }, - "cous_i4": { - "comment": "We don't really need an index, but DBAL will create one for all foreign keys if none exists", - "columns": [ "parent_id" ] + "cous_i4": { "needed": false, "columns": [ "parent_id" ] } } }, @@ -273,7 +272,7 @@ "groups_i2": { "columns": [ "co_id", "name" ] }, "groups_i3": { "columns": [ "co_id", "group_type" ] }, "groups_i4": { "columns": [ "cou_id", "group_type" ] }, - "groups_i5": { "columns": [ "cou_id" ], "comment": "Not really needed but DBAL autogenerates"} + "groups_i5": { "needed": false, "columns": [ "cou_id" ]} } }, @@ -476,6 +475,55 @@ "history_records_i6": { "columns": [ "group_id" ] }, "history_records_i7": { "columns": [ "actor_api_user_id" ] } } + }, + + "jobs": { + "columns": { + "id": {}, + "co_id": {}, + "plugin": {}, + "parameters": { "type": "text" }, + "requeue_interval": { "type": "integer" }, + "retry_interval": { "type": "integer" }, + "requeued_from_job_id": { "type": "integer", "foreignkey": { "table": "jobs", "column": "id" }}, + "status": {}, + "assigned_host": { "type": "string", "size": 64 }, + "assigned_pid": { "type": "integer" }, + "register_summary": { "type": "string", "size": 256 }, + "start_summary": { "type": "string", "size": 256 }, + "finish_summary": { "type": "string", "size": 256 }, + "register_time": { "type": "datetime" }, + "start_after_time": { "type": "datetime" }, + "start_time": { "type": "datetime" }, + "finish_time": { "type": "datetime" }, + "percent_complete": { "type": "integer" } + }, + "indexes": { + "jobs_i1": { "columns": [ "co_id" ] }, + "jobs_i3": { "columns": [ "assigned_host", "assigned_pid" ] }, + "jobs_i4": { "needed": false, "columns": [ "requeued_from_job_id" ] } + }, + "skip-indexes-for-now": { + "jobs_i2": { "columns": [ "co_id", "plugin", "parameters", "status" ] } + } + }, + + "job_history_records": { + "columns": { + "id": {}, + "job_id": { "type": "integer", "foreignkey": { "table": "jobs", "column": "id" }}, + "record_key": { "type": "string", "size": 64 }, + "person_id": {}, + "external_identity_id": {}, + "comment": {}, + "status": {} + }, + "indexes": { + "job_history_records_i1": { "columns": [ "job_id" ] }, + "job_history_records_i2": { "columns": [ "person_id" ] }, + "job_history_records_i3": { "columns": [ "external_identity_id" ] }, + "job_history_records_i4": { "columns": [ "job_id", "record_key" ] } + } } }, diff --git a/app/resources/locales/en_US/command.po b/app/resources/locales/en_US/command.po index 4abf825d2..5a3303979 100644 --- a/app/resources/locales/en_US/command.po +++ b/app/resources/locales/en_US/command.po @@ -39,6 +39,36 @@ msgstr "Loading database schema from active plugin {0}" msgid "db.schema.plugin.none" msgstr "No database schema found for active plugin {0}" +msgid "job.process" +msgstr "Processing job {0}" + +msgid "job.registered" +msgstr "Registered job {0}" + +msgid "job.run.child.done.empty" +msgstr "No jobs left in the queue, queue runner {0} exiting" + +msgid "job.run.child.done.max" +msgstr "Queue runner {0} reached maximum number of jobs ({1}), exiting" + +msgid "job.run.child.request" +msgstr "Queue runner {0} requesting assignment {1} for CO {2}" + +msgid "job.run.child.running" +msgstr "Queue runner {0} processing job ID {1}" + +msgid "job.run.max" +msgstr "Reached max queue runner count ({0}), waiting for one to exit" + +msgid "job.run.piddone" +msgstr "Queue runner PID {0} completed" + +msgid "job.run.start" +msgstr "Launching queue runner {0} (of {1}) for CO {2}" + +msgid "job.run.waiting" +msgstr "{0,plural,=1{Waiting for the last queue runner to complete} other{Waiting for # queue runners to complete}}" + msgid "opt.admin-family-name" msgstr "Family Name of initial platform administrator" @@ -51,6 +81,27 @@ msgstr "Username of initial platform administrator" msgid "opt.force" msgstr "Force a rerun of setup (only if you know what you are doing)" +msgid "opt.job.co_id" +msgstr "CO ID" + +msgid "opt.job.max" +msgstr "Maximum number of concurrent queue runners (use with -r)" + +msgid "opt.job.parallel" +msgstr "Number of parallel queue runners per CO (use with -r)" + +msgid "opt.job.parameters" +msgstr "Job (plugin) specific parameters" + +msgid "opt.job.plugin" +msgstr "Job (plugin) to run" + +msgid "opt.job.run" +msgstr "Run the Job queue for the specified CO" + +msgid "opt.job.synchronous" +msgstr "Run the requested job synchronously (use with -j)" + msgid "opt.not" msgstr "Calculate changes but do not apply" diff --git a/app/resources/locales/en_US/controller.po b/app/resources/locales/en_US/controller.po index 67753bd02..6df39e05b 100644 --- a/app/resources/locales/en_US/controller.po +++ b/app/resources/locales/en_US/controller.po @@ -75,6 +75,12 @@ msgstr "{0,plural,=1{History Record} other{History Records}}" msgid "Identifiers" msgstr "{0,plural,=1{Identifier} other{Identifiers}}" +msgid "JobHistoryRecords" +msgstr "{0,plural,=1{Job History Record} other{Job History Records}}" + +msgid "Jobs" +msgstr "{0,plural,=1{Job} other{Jobs}}" + msgid "Names" msgstr "{0,plural,=1{Name} other{Names}}" diff --git a/app/resources/locales/en_US/enumeration.po b/app/resources/locales/en_US/enumeration.po index e4eb276eb..fb01ca1b2 100644 --- a/app/resources/locales/en_US/enumeration.po +++ b/app/resources/locales/en_US/enumeration.po @@ -72,6 +72,27 @@ msgstr "All Members" msgid "GroupTypeEnum.S" msgstr "Standard" +msgid "JobStatusEnum.A" +msgstr "Assigned" + +msgid "JobStatusEnum.CX" +msgstr "Canceled" + +msgid "JobStatusEnum.GO" +msgstr "In Progress" + +msgid "JobStatusEnum.NT" +msgstr "Notice" + +msgid "JobStatusEnum.OK" +msgstr "Complete" + +msgid "JobStatusEnum.Q" +msgstr "Queued" + +msgid "JobStatusEnum.X" +msgstr "Failed" + msgid "LanguageEnum.af" msgstr "Afrikaans" diff --git a/app/resources/locales/en_US/error.po b/app/resources/locales/en_US/error.po index 6d49759e9..7fed7b33b 100644 --- a/app/resources/locales/en_US/error.po +++ b/app/resources/locales/en_US/error.po @@ -100,6 +100,9 @@ msgstr "Cannot read file {0}" msgid "flash" msgstr "{0}: {1}" +msgid "Cos.active" +msgstr "Requested CO {0} is not active" + msgid "GroupNestings.active" msgstr "Group {0} is not active and so cannot be nested" @@ -151,6 +154,30 @@ msgstr "{0} must be provided" msgid "invalid" msgstr "Invalid value \"{0}\"" +msgid "Jobs.failed.abnormal" +msgstr "The Job terminated unexpectedly" + +msgid "Jobs.plugin.parameter.int" +msgstr "Provided value is not an integer" + +msgid "Jobs.plugin.parameter.invalid" +msgstr "Invalid parameter" + +msgid "Jobs.plugin.parameter.required" +msgstr "Required parameter not provided" + +msgid "Jobs.plugin.parameter.type" +msgstr "Unknown parameter type {0}" + +msgid "Jobs.registered.already" +msgstr "A Job is already registered for this plugin ({0}) with these parameters" + +msgid "Jobs.status.invalid" +msgstr "Job {0} is not in {1} status and cannot be set to {2} (Job is {3})" + +msgid "Jobs.status.invalid.cancel" +msgstr "Job {0} is not in a cancelable status (Job is {1})" + msgid "Names.minimum" msgstr "At least one name is required" @@ -178,6 +205,9 @@ msgstr "Page number must be an integer" msgid "perm" msgstr "Permission Denied" +msgid "Plugins.inactive" +msgstr "The plugin {0} is not active" + msgid "Plugins.inuse" msgstr "{0,plural,=1{Plugin in use for {1} \"{2}\" in CO {3}} other{Plugin in use for {1} \"{2}\" in CO {3} and others}}" diff --git a/app/resources/locales/en_US/field.po b/app/resources/locales/en_US/field.po index 58cb5352a..9d688eb35 100644 --- a/app/resources/locales/en_US/field.po +++ b/app/resources/locales/en_US/field.po @@ -150,6 +150,9 @@ msgstr "Order" msgid "organization" msgstr "Organization" +msgid "parameters" +msgstr "Parameters" + msgid "parent_id" msgstr "Parent" @@ -342,6 +345,57 @@ msgstr "Open" msgid "Groups.open.desc" msgstr "Open groups may be self-joined by any Person in the CO" +msgid "JobHistoryRecords.record_key" +msgstr "Record Key" + +msgid "Jobs.assigned_host" +msgstr "Assigned Host" + +msgid "Jobs.assigned_pid" +msgstr "Assigned Process ID" + +msgid "Jobs.finish_summary" +msgstr "Finish Summary" + +msgid "Jobs.finish_time" +msgstr "Finished" + +msgid "Jobs.percent_complete" +msgstr "Percent Complete" + +msgid "Jobs.register_summary" +msgstr "Register Summary" + +msgid "Jobs.register_time" +msgstr "Registered" + +msgid "Jobs.requeue_interval" +msgstr "Requeue Interval" + +msgid "Jobs.requeue_interval.desc" +msgstr "After the job successfully completes, it will automatically be requeued to execute after this interval (in seconds). (To stop requeuing, cancel this job.)" + +msgid "Jobs.requeued_from_job_id" +msgstr "Requeued From Job" + +msgid "Jobs.retry_interval" +msgstr "Retry Interval" + +msgid "Jobs.retry_interval.desc" +msgstr "If the job fails, it will automatically be retried after this interval (in seconds). (To stop retrying, cancel this job.)" + +msgid "Jobs.start_after_time" +msgstr "Start After" + +msgid "Jobs.start_after_time.desc" +msgstr "The queued job will not be started until after this time" + +msgid "Jobs.start_summary" +msgstr "Start Summary" + +msgid "Jobs.start_time" +msgstr "Started" + msgid "Plugins.plugin" msgstr "Plugin" diff --git a/app/resources/locales/en_US/result.po b/app/resources/locales/en_US/result.po index e241c06c9..db9d5fbdc 100644 --- a/app/resources/locales/en_US/result.po +++ b/app/resources/locales/en_US/result.po @@ -84,6 +84,15 @@ msgstr "Removed {0} as an owner of group {1}" msgid "Names.primary_name" msgstr "Primary Name Updated" +msgid "Jobs.canceled" +msgstr "Job {0} canceled" + +msgid "Jobs.canceled.by" +msgstr "Job canceled by {0}" + +msgid "Jobs.registered" +msgstr "Started via JobCommand by {0} (uid {1})" + msgid "saved" msgstr "Saved" diff --git a/app/src/Command/JobCommand.php b/app/src/Command/JobCommand.php new file mode 100644 index 000000000..7be128bb5 --- /dev/null +++ b/app/src/Command/JobCommand.php @@ -0,0 +1,275 @@ +addOption( + 'co_id', + [ + 'required' => true, + 'short' => 'c', + 'help' => __d('command', 'opt.job.co_id') + ] + )->addOption( + 'job', + [ + 'required' => false, + 'short' => 'j', + 'help' => __d('command', 'opt.job.plugin') + ] + )->addOption( + 'parallel', + [ + 'required' => false, + 'short' => 'p', + 'default' => 1, + 'help' => __d('command', 'opt.job.parallel') + ] + )->addOption( + 'max', + [ + 'required' => false, + 'short' => 'm', + 'default' => 10, + 'help' => __d('command', 'opt.job.max') + ] + )->addOption( + 'run', + [ + 'short' => 'r', + 'boolean' => true, + 'help' => __d('command', 'opt.job.run') + ] + )->addOption( + 'synchronous', + [ + 'short' => 's', + 'boolean' => true, + 'help' => __d('command', 'opt.job.synchronous') + ] + ); + + return $parser; + } + + /** + * Execute the Job Command. + * + * @since COmanage Registry v5.0.0 + * @param Arguments $args Command Arguments + * @param ConsoleIo $io Console IO + */ + + public function execute(Arguments $args, ConsoleIo $io) + { + $CosTable = $this->getTableLocator()->get('Cos'); + $JobTable = $this->getTableLocator()->get('Jobs'); + + if($args->getOption('run')) { + // Run the Job queue + + $coIds = []; + + if($args->getOption('co_id') == 'all') { + $cos = $CosTable->find() + ->where(['status' => \App\Lib\Enum\SuspendableStatusEnum::Active]) + ->toArray(); + + $coIds = \Cake\Utility\Hash::extract($cos, '{n}.id'); + } else { + $coIds[] = (int)$args->getOption('co_id'); + + // Verify that the requested CO exists and is active + $co = $CosTable->get($coIds[0]); + + if(!$co->isActive()) { + throw new \InvalidArgumentException(__d('error', 'Cos.active', [$coIds[0]])); + } + } + + // The set of PIDs launched + $pids = []; + // The total number of actively running children + $pidcount = 0; + + // The maximum number of runners to run at any one time + $max = (int)$args->getOption('max'); + // The number of parallel runners for each CO + $parallel = (int)$args->getOption('parallel'); + + // The maximum number of jobs a queue runner will process before exiting + $maxjobs = 100; + + foreach($coIds as $coId) { + // We start counting from 1 rather than 0 to simplify console output + for($i = 1;$i <= $parallel;$i++) { + $io->out(__d('command', 'job.run.start', [$i, $parallel, $coId])); + + $newPid = pcntl_fork(); + + switch($newPid) { + case -1: + throw new \RuntimeException('fork failed'); + break; + case 0: + // We are the child, process jobs from the requested CO's queue. + // We'll run up to 100 jobs, the same behavior as v4, then exit. + // This could become configurable at some point. + + // We need to open a new database connection for the child after the fork + // so we don't run into problems with other processes (the parent or more + // likely the other children) closing the connection. We'll use the default + // configuration and create a new configuration on the fly so we don't have + // to pollute the database config file. + + ConnectionManager::setConfig('plugin', ConnectionManager::getConfig('default')); +// XXX this doesn't seem to work, so plugins must always access the 'plugin' database, at least for now (CFM-253) +// ConnectionManager::alias('plugin', 'default'); + $cxn = ConnectionManager::get('plugin'); + + $JobTable->setConnection($cxn); + + for($j = 1;$j <= $maxjobs;$j++) { + $io->verbose(__d('command', 'job.run.child.request', [$i, $j, $coId])); + + // Request a job to run + $job = $JobTable->assignNext($coId); + + if(!$job) { + // Nothing to do, exit + $io->verbose(__d('command', 'job.run.child.done.empty', [$newPid])); + exit; + } + + $io->verbose(__d('command', 'job.run.child.running', [$newPid, $job->id])); + + try { + $JobTable->process($job); + } + catch(\Exception $e) { + // The only Exception would be if the Job is in an invalid state, + // which shouldn't happen because we just ran assignNext() + $io->error($e->getMessage()); + } + } + + $io->verbose(__d('command', 'job.run.child.done.max', [$newPid, $maxjobs])); + exit; + break; + default: + // We are the parent, keep launching + $pids[$newPid] = $coId; + $pidcount++; + break; + } + + if($pidcount == $max) { + $io->out(__d('command', 'job.run.max', [$max])); + + $status = -1; + $pid = pcntl_waitpid(-1, $status); + + // Confirm the Job was properly finished. + $JobTable->confirmFinished($pid); + + $io->verbose(__d('command', 'job.run.piddone', [$pid])); + $pidcount--; + } + } + } + + // We are the parent, and we're done launching queue runners. wait() for them. + while($pidcount > 0) { + $io->out(__d('command', 'job.run.waiting', $pidcount)); + + $status = -1; + $pid = pcntl_waitpid(-1, $status); + + // Confirm the Job was properly finished. + $JobTable->confirmFinished($pid); + + $io->verbose(__d('command', 'job.run.piddone', [$pid])); + + $pidcount--; + } + } else { + // Run the requested job synchronously? + $synchronous = $args->getOption('synchronous'); + + // Pull current user info + $pwent = posix_getpwuid(posix_getuid()); + + // Parse any provided parameters + $params = []; + + foreach($args->getArguments() as $a) { + $p = explode('=', $a, 2); + + $params[ $p[0] ] = $p[1]; + } + + $job = $JobTable->register( + coId: (int)$args->getOption('co_id'), + plugin: $args->getOption('job'), + parameters: $params, + registerSummary: __d('result', 'Jobs.registered', [$pwent['name'], $pwent['uid']]), + synchronous: $synchronous + ); + + $io->out(__d('command', 'job.registered', [$job->id])); + + if($synchronous) { + $io->out(__d('command', 'job.process', [$job->id])); + + $JobTable->process($job); + } + } + } +} \ No newline at end of file diff --git a/app/src/Command/SetupCommand.php b/app/src/Command/SetupCommand.php index 6f61830f9..ee80da1ad 100644 --- a/app/src/Command/SetupCommand.php +++ b/app/src/Command/SetupCommand.php @@ -45,7 +45,7 @@ class SetupCommand extends Command * @param ConsoleOptionParser $parser Console Option Parser * * @return ConsoleOptionParser Console Option Parser - * @since COmanage Registry v6.0.0 + * @since COmanage Registry v5.0.0 */ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser diff --git a/app/src/Command/TransmogrifyCommand.php b/app/src/Command/TransmogrifyCommand.php index 8597b9d37..f2efead3f 100644 --- a/app/src/Command/TransmogrifyCommand.php +++ b/app/src/Command/TransmogrifyCommand.php @@ -315,6 +315,29 @@ class TransmogrifyCommand extends Command { 'co_email_list_id' => null, 'co_service_id' => null ] + ], + 'jobs' => [ + 'source' => 'cm_co_jobs', + 'displayField' => 'id', + 'fieldMap' => [ + 'job_type' => 'plugin', + 'job_mode' => null, + 'queue_time' => 'register_time', + 'complete_time' => 'finish_time', + 'job_type_fk' => null, + 'job_params' => 'parameters', + 'requeued_from_co_job_id' => 'requeued_from_job_id' + ], + 'preRow' => 'filterJobs' + ], + 'job_history_records' => [ + 'source' => 'cm_co_job_history_records', + 'displayField' => 'id', + 'fieldMap' => [ + 'co_job_id' => 'job_id', + 'co_person_id' => 'person_id', + 'org_identity_id' => 'external_identity_id' + ] ] ]; @@ -641,6 +664,28 @@ public function execute(Arguments $args, ConsoleIo $io) { } } + /** + * Filter Jobs. + * + * @since COmanage Registry v5.0.0 + * @param array $origRow Row of table data (original data) + * @param array $row Row of table data (post fixes) + * @throws InvalidArgumentException + */ + + protected function filterJobs(array $origRow, array $row) { + // We don't update any of the attributes, but for rows with unsupported data + // we throw an exception so they don't transmogrify. + + if($row['status'] == 'GO' || $row['status'] == 'Q') { + throw new \InvalidArgumentException("Job is Queued or In Progress"); + } + + if($row['job_type'] == 'EX' || $row['job_type'] == 'OS') { + throw new \InvalidArgumentException("Legacy Job types cannot be transmogrified"); + } + } + /** * Find the CO for a row of table data, based on a foreign key. * diff --git a/app/src/Controller/AppController.php b/app/src/Controller/AppController.php index d6c023593..1d67d1184 100644 --- a/app/src/Controller/AppController.php +++ b/app/src/Controller/AppController.php @@ -375,9 +375,9 @@ protected function populateAvailableCos() { $availableCos = []; - $userInfo = $this->viewBuilder()->getVar('vv_user'); + $username = $this->RegistryAuth->getAuthenticatedUser(); - if(!empty($userInfo['username'])) { + if(!empty($username)) { // There are two data sets to look at: the COs the current user is a member // of, and (if the current user is a Platform Admin) all other COs. We then // bubble the COmanage CO to the top (if present), followed by an alphabetical @@ -386,7 +386,7 @@ protected function populateAvailableCos() { $Cos = TableRegistry::getTableLocator()->get("Cos"); // Pull the set of COs this user is a member of, for rendering via menuMain - $memberCos = Hash::sort($Cos->getCosForIdentifier(loginIdentifier: $userInfo['username']), '{n}.name', 'asc'); + $memberCos = Hash::sort($Cos->getCosForIdentifier(loginIdentifier: $username), '{n}.name', 'asc'); $allCos = null; if($this->RegistryAuth->isPlatformAdmin()) { diff --git a/app/src/Controller/JobHistoryRecordsController.php b/app/src/Controller/JobHistoryRecordsController.php new file mode 100644 index 000000000..66948a95d --- /dev/null +++ b/app/src/Controller/JobHistoryRecordsController.php @@ -0,0 +1,62 @@ + [ + 'JobHistoryRecords.id' => 'desc' + ] + ]; + + /** + * Callback run prior to the request render. + * + * @since COmanage Registry v5.0.0 + * @param EventInterface $event Cake Event + */ + + public function beforeRender(\Cake\Event\EventInterface $event) { + // Pull the Group name for breadcrumb rendering + + $link = $this->getPrimaryLink(true); + + if(!empty($link->value)) { + $this->set('vv_bc_parent_obj', $this->JobHistoryRecords->Jobs->get($link->value)); + $this->set('vv_bc_parent_displayfield', $this->JobHistoryRecords->Jobs->getDisplayField()); + } + + return parent::beforeRender($event); + } +} \ No newline at end of file diff --git a/app/src/Controller/JobsController.php b/app/src/Controller/JobsController.php new file mode 100644 index 000000000..4d399ddc8 --- /dev/null +++ b/app/src/Controller/JobsController.php @@ -0,0 +1,61 @@ + [ + 'Jobs.id' => 'desc' + ] + ]; + + /** + * Cancel a Job. + * + * @since COmanage Registry v5.0.0 + * @param string $id Job ID + */ + + public function cancel(string $id) { + try { + $this->Jobs->cancel((int)$id, $this->RegistryAuth->getAuthenticatedUser()); + $this->Flash->success(__d('result', 'Jobs.canceled', [$id])); + } + catch(Exception $e) { + $this->Flash->error($e->getMessage()); + } + + return $this->generateRedirect(null); + } +} \ No newline at end of file diff --git a/app/src/Lib/Enum/JobStatusEnum.php b/app/src/Lib/Enum/JobStatusEnum.php new file mode 100644 index 000000000..12a60eb07 --- /dev/null +++ b/app/src/Lib/Enum/JobStatusEnum.php @@ -0,0 +1,40 @@ +find() - ->select('plugin') - ->distinct(['plugin']) - ->all(); - - foreach($models as $m) { - $this->hasMany($m->plugin) - ->setDependent(true) - ->setCascadeCallbacks(true); - } - - $this->setAllowLookupPrimaryLink(['configure']); + public function getPluggableModelType(): string { + return Inflector::underscore(StringUtilities::tableToEntityName($this)); } /** - * Determine the plugin type used by this Pluggable Model. This is the lowercased - * singular prefix of the Pluggable Model Table name. eg: For "ReportsTable" the - * plugin type is "report". + * Instantiate a plugin model that is NOT a Cake Table model. * * @since COmanage Registry v5.0.0 - * @return string Plugin model type + * @param string $pmodel Model, in Plugin.Model format + * @param string $path Path to model within Plugin, in namespace format (eg: \Lib\Jobs) + * @return object Newly instantiated object of Model class */ - public function getPluggableModelType(): string { - return Inflector::underscore(StringUtilities::tableToEntityName($this)); + protected function instantiatePluginModel(string $pmodel, string $path) { + $pluginName = StringUtilities::pluginPlugin($pmodel); + $pluginModel = StringUtilities::pluginModel($pmodel); + + // First check that the requested plugin is actually enabled. + // We can use Cake's check here since we would have loaded the plugin + // in Application.php already if it were enabled. + + if(!\Cake\Core\Plugin::isLoaded($pluginName)) { + throw new \InvalidArgumentException(__d('error', 'Plugins.inactive', [$pluginName])); + } + + // Next try to instantiate the model. Since instantiatePluginModel() is called for + // models that do not represent Cake Tables, we can't use the TableLocator here, + // we just use plain PHP "new". + + $pluginClassName = "\\" . $pluginName . "\\" . $path . "\\" . $pluginModel; + $pClass = new $pluginClassName(); + + return $pClass; } /** @@ -87,4 +93,31 @@ public function pluginInUse(string $plugin): ResultSet { ->where(['plugin LIKE' => $plugin . ".%"]) ->all(); } + + /** + * Set up hasMany relations for instantiated plugin models. + * + * @since COmanage Registry v5.0.0 + */ + + protected function setPluginRelations() { + // To determine which plugin models are instantiated, we'll query the configuration + // for this pluggable model. We only need to do this once per plugin model, not + // once per instantiation. + + $models = $this->find() + ->select('plugin') + ->distinct(['plugin']) + ->all(); + + foreach($models as $m) { + $this->hasMany($m->plugin) + ->setDependent(true) + ->setCascadeCallbacks(true); + } + + if($this->isConfigurationTable()) { + $this->setAllowLookupPrimaryLink(['configure']); + } + } } diff --git a/app/src/Lib/Traits/PrimaryLinkTrait.php b/app/src/Lib/Traits/PrimaryLinkTrait.php index ec52aa6ca..7412e4dce 100644 --- a/app/src/Lib/Traits/PrimaryLinkTrait.php +++ b/app/src/Lib/Traits/PrimaryLinkTrait.php @@ -48,8 +48,9 @@ trait PrimaryLinkTrait { // Actions where the primary link can be obtained by looking up the record ID private $lookupActions = ['delete', 'edit', 'view']; - // Where to redirect on add or edit, can be 'self', 'index', or 'primaryLink' - private $redirectGoal = 'index'; + // Where to redirect on add or edit, can be 'self', 'index', 'pluggableLink', or 'primaryLink' + // We use null to mean "index unless we're in a plugin context, in which case pluggableLink" + private $redirectGoal = null; // Accept the current CO ID? private $acceptCoId = false; @@ -236,7 +237,7 @@ public function getPrimaryLinkTableName(string $primaryLink): string { * @return string Redirect goal */ - public function getRedirectGoal(): string { + public function getRedirectGoal(): ?string { return $this->redirectGoal; } @@ -465,12 +466,12 @@ public function setPrimaryLink($fields) { * Set the redirect goal for this table. * * @since COmanage Registry v5.0.0 - * @param string $goal Redirect goal ('index', 'primaryLink', 'self') + * @param string $goal Redirect goal ('index', 'pluggableLink', 'primaryLink', 'self') * @throws InvalidArgumentException */ public function setRedirectGoal(string $goal) { - if(!in_array($goal, ['index', 'primaryLink', 'self'])) { + if(!in_array($goal, ['index', 'pluggableLink', 'primaryLink', 'self'])) { throw new \InvalidArgumentException(__d('error', 'invalid', [$goal])); } diff --git a/app/src/Lib/Traits/TableMetaTrait.php b/app/src/Lib/Traits/TableMetaTrait.php index 41e27b584..673de3046 100644 --- a/app/src/Lib/Traits/TableMetaTrait.php +++ b/app/src/Lib/Traits/TableMetaTrait.php @@ -30,33 +30,44 @@ namespace App\Lib\Traits; use Cake\Utility\Inflector; +use App\Lib\Enum\TableTypeEnum; trait TableMetaTrait { - // Does this Table represent Registry objects or configuration? - private $confTable = false; + // What type of Table is this? + private $tableType = null; /** - * Determine if this Table represents Registry configuration (vs objects). + * Determine if this Table represents Registry artifacts. * * @since COmanage Registry v5.0.0 - * @return bool True if this Table represents Configuration data, false otherwise + * @return bool True if this Table represents artifact data, false otherwise */ - public function getIsConfigurationTable() { - return $this->confTable; + public function isArtifactTable() { + return $this->tableType === TableTypeEnum::Artifact; } /** - * Set if this Table represents Registry configuration (vs objects). + * Determine if this Table represents Registry configuration. * * @since COmanage Registry v5.0.0 - * @param array $vars Array of auto view variables + * @return bool True if this Table represents Configuration data, false otherwise */ - public function setIsConfigurationTable(bool $confTable) { - $this->confTable = $confTable; + public function isConfigurationTable() { + return $this->tableType === TableTypeEnum::Configuration; } + + /** + * Set the type of this Table. + * + * @since COmanage Registry v5.0.0 + * @param TableTypeEnum $tableType Table Type + */ + public function setTableType(string $tableType) { + $this->tableType = $tableType; + } /** * Filter metadata fields. diff --git a/app/src/Model/Entity/Job.php b/app/src/Model/Entity/Job.php new file mode 100644 index 000000000..7441775ca --- /dev/null +++ b/app/src/Model/Entity/Job.php @@ -0,0 +1,67 @@ + true, + 'id' => false, + 'slug' => false, + ]; + + /** + * Determine if this entity can be canceled. + * + * @since COmanage Registry v5.0.0 + * @return bool true if the entity can be canceled, false otherwise + */ + + public function canCancel(): bool { + return in_array($this->status, [JobStatusEnum::Assigned, + JobStatusEnum::InProgress, + JobStatusEnum::Queued]); + } + + /** + * Determine if this entity is Read Only. + * + * @since COmanage Registry v5.0.0 + * @return bool true if the entity is read only, false otherwise + */ + + public function isReadOnly(): bool { + // As far as the UI is concerned, all Job records are read only + + return true; + } +} \ No newline at end of file diff --git a/app/src/Model/Entity/JobHistoryRecord.php b/app/src/Model/Entity/JobHistoryRecord.php new file mode 100644 index 000000000..5df5e3f2f --- /dev/null +++ b/app/src/Model/Entity/JobHistoryRecord.php @@ -0,0 +1,54 @@ + true, + 'id' => false, + 'slug' => false, + ]; + + /** + * Determine if this entity is Read Only. + * + * @since COmanage Registry v5.0.0 + * @param Entity $entity Cake Entity + * @return boolean true if the entity is read only, false otherwise + */ + + public function isReadOnly(): bool { + // History records can't be altered once created + + return true; + } +} \ No newline at end of file diff --git a/app/src/Model/Table/AdHocAttributesTable.php b/app/src/Model/Table/AdHocAttributesTable.php index 37e2ff713..b7857f8d2 100644 --- a/app/src/Model/Table/AdHocAttributesTable.php +++ b/app/src/Model/Table/AdHocAttributesTable.php @@ -55,8 +55,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Ad Hoc Attributes are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/AddressesTable.php b/app/src/Model/Table/AddressesTable.php index 293fb6d98..a149dd445 100644 --- a/app/src/Model/Table/AddressesTable.php +++ b/app/src/Model/Table/AddressesTable.php @@ -70,8 +70,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Addesses are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/ApiUsersTable.php b/app/src/Model/Table/ApiUsersTable.php index 28fd66fe1..169a5b17b 100644 --- a/app/src/Model/Table/ApiUsersTable.php +++ b/app/src/Model/Table/ApiUsersTable.php @@ -62,8 +62,7 @@ public function initialize(array $config): void { $this->addBehavior('Timestamp'); $this->addBehavior('Timezone'); - // ApiUsers are configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/AuthenticationEventsTable.php b/app/src/Model/Table/AuthenticationEventsTable.php index 5dbd5144b..f74a64cc6 100644 --- a/app/src/Model/Table/AuthenticationEventsTable.php +++ b/app/src/Model/Table/AuthenticationEventsTable.php @@ -60,8 +60,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Authentication Events are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Artifact); // Define associations // Technically, Authentication Events do not directly foreign key since diff --git a/app/src/Model/Table/CoSettingsTable.php b/app/src/Model/Table/CoSettingsTable.php index 81ed851ec..d66fea2f5 100644 --- a/app/src/Model/Table/CoSettingsTable.php +++ b/app/src/Model/Table/CoSettingsTable.php @@ -68,8 +68,7 @@ public function initialize(array $config): void { $this->addBehavior('Changelog'); $this->addBehavior('Timestamp'); - // CO Settings are (a special type of) configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/CosTable.php b/app/src/Model/Table/CosTable.php index 8fad3b625..56a16dc94 100644 --- a/app/src/Model/Table/CosTable.php +++ b/app/src/Model/Table/CosTable.php @@ -64,8 +64,7 @@ public function initialize(array $config): void { // Timestamp behavior handles created/modified updates $this->addBehavior('Timestamp'); - // COs are configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations @@ -81,6 +80,9 @@ public function initialize(array $config): void { $this->hasMany('Groups') ->setDependent(true) ->setCascadeCallbacks(true); + $this->hasMany('Jobs') + ->setDependent(true) + ->setCascadeCallbacks(true); $this->hasMany('People') ->setDependent(true) ->setCascadeCallbacks(true); diff --git a/app/src/Model/Table/CousTable.php b/app/src/Model/Table/CousTable.php index 70f8cdc55..f3ef2f1df 100644 --- a/app/src/Model/Table/CousTable.php +++ b/app/src/Model/Table/CousTable.php @@ -59,8 +59,7 @@ public function initialize(array $config): void { $this->addBehavior('Timestamp'); $this->addBehavior('Tree'); - // COUs are configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/DashboardsTable.php b/app/src/Model/Table/DashboardsTable.php index a6eaa2abd..c6f164438 100644 --- a/app/src/Model/Table/DashboardsTable.php +++ b/app/src/Model/Table/DashboardsTable.php @@ -50,8 +50,7 @@ public function initialize(array $config): void { $this->addBehavior('Timestamp'); $this->addBehavior('Timezone'); - // Dashboards are configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/EmailAddressesTable.php b/app/src/Model/Table/EmailAddressesTable.php index bd296ff18..7d48c5218 100644 --- a/app/src/Model/Table/EmailAddressesTable.php +++ b/app/src/Model/Table/EmailAddressesTable.php @@ -71,8 +71,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Email Addresses are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/ExternalIdentitiesTable.php b/app/src/Model/Table/ExternalIdentitiesTable.php index d96180634..1694fd076 100644 --- a/app/src/Model/Table/ExternalIdentitiesTable.php +++ b/app/src/Model/Table/ExternalIdentitiesTable.php @@ -59,8 +59,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // External Identities are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); @@ -89,6 +88,9 @@ public function initialize(array $config): void { $this->hasMany('Identifiers') ->setDependent(true) ->setCascadeCallbacks(true); + $this->hasMany('JobHistoryRecords') + ->setDependent(true) + ->setCascadeCallbacks(true); $this->hasMany('Pronouns') ->setDependent(true) ->setCascadeCallbacks(true); diff --git a/app/src/Model/Table/ExternalIdentityRolesTable.php b/app/src/Model/Table/ExternalIdentityRolesTable.php index 42b7d68d8..fb9f5275d 100644 --- a/app/src/Model/Table/ExternalIdentityRolesTable.php +++ b/app/src/Model/Table/ExternalIdentityRolesTable.php @@ -59,8 +59,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // External Identity Roles are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('ExternalIdentities'); diff --git a/app/src/Model/Table/GroupMembersTable.php b/app/src/Model/Table/GroupMembersTable.php index 16cedbf10..9fd0a85c4 100644 --- a/app/src/Model/Table/GroupMembersTable.php +++ b/app/src/Model/Table/GroupMembersTable.php @@ -63,8 +63,7 @@ public function initialize(array $config): void { $this->addBehavior('Timestamp'); $this->addBehavior('Timezone'); - // Group Members are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('GroupNestings'); diff --git a/app/src/Model/Table/GroupNestingsTable.php b/app/src/Model/Table/GroupNestingsTable.php index d3a36e791..806584b67 100644 --- a/app/src/Model/Table/GroupNestingsTable.php +++ b/app/src/Model/Table/GroupNestingsTable.php @@ -59,8 +59,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Group Nestings are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('Groups'); diff --git a/app/src/Model/Table/GroupOwnersTable.php b/app/src/Model/Table/GroupOwnersTable.php index fcd14362d..4f258206f 100644 --- a/app/src/Model/Table/GroupOwnersTable.php +++ b/app/src/Model/Table/GroupOwnersTable.php @@ -60,8 +60,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Group Owners are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('Groups'); diff --git a/app/src/Model/Table/GroupsTable.php b/app/src/Model/Table/GroupsTable.php index e4e7b0d27..f12c98e2a 100644 --- a/app/src/Model/Table/GroupsTable.php +++ b/app/src/Model/Table/GroupsTable.php @@ -65,8 +65,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Groups are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Primary); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/HistoryRecordsTable.php b/app/src/Model/Table/HistoryRecordsTable.php index f5e0345c6..c10585b81 100644 --- a/app/src/Model/Table/HistoryRecordsTable.php +++ b/app/src/Model/Table/HistoryRecordsTable.php @@ -54,8 +54,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // History Records are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Artifact); // Define associations $this->belongsTo('ApiUser') diff --git a/app/src/Model/Table/IdentifiersTable.php b/app/src/Model/Table/IdentifiersTable.php index a788d3556..241eef6cb 100644 --- a/app/src/Model/Table/IdentifiersTable.php +++ b/app/src/Model/Table/IdentifiersTable.php @@ -83,8 +83,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Identifiers are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('ExternalIdentities'); diff --git a/app/src/Model/Table/JobHistoryRecordsTable.php b/app/src/Model/Table/JobHistoryRecordsTable.php new file mode 100644 index 000000000..11743f374 --- /dev/null +++ b/app/src/Model/Table/JobHistoryRecordsTable.php @@ -0,0 +1,200 @@ +addBehavior('Changelog'); + $this->addBehavior('Log'); + $this->addBehavior('Timestamp'); + + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Artifact); + + // Define associations + $this->belongsTo('Jobs'); + $this->belongsTo('People'); + $this->belongsTo('ExternalIdentities'); + + $this->setDisplayField('comment'); + + $this->setPrimaryLink(['job_id']); + $this->setAllowLookupPrimaryLink(['primary']); + $this->setRequiresCO(true); + + $this->setAutoViewVars([ + 'statuses' => [ + 'type' => 'enum', + 'class' => 'JobStatusEnum' + ] + ]); + + $this->setViewContains([ + 'People' => ['PrimaryName'], + 'ExternalIdentities' => ['PrimaryName'] + ]); + + $this->setPermissions([ + // Actions that operate over an entity (ie: require an $id) + 'entity' => [ + 'delete' => false, + 'edit' => false, + 'view' => ['platformAdmin', 'coAdmin'] + ], + // Actions that operate over a table (ie: do not require an $id) + 'table' => [ + 'add' => false, //['platformAdmin', 'coAdmin'], + 'index' => ['platformAdmin', 'coAdmin'] + ] + ]); + } + + /** + * Table specific logic to generate a display field. + * + * @since COmanage Registry v5.0.0 + * @param JobHistoryRecord $entity Entity to generate display field for + * @return string Display field + */ + + public function generateDisplayField(\App\Model\Entity\JobHistoryRecord $entity): string { + // Comments may be too long to render, so we just use the model name + // (which will get appended with the record ID) + + return __d('controller', 'JobHistoryRecords', [1]); + } + + /** + * Record a Job History Record. + * + * @since COmanage Registry v5.0.0 + * @param int $jobId Job ID + * @param string $recordKey A Job specific record identifier + * @param string $comment Comment + * @param int $personId Person ID + * @param int $externalIdentityId External Identity ID + * @return int Job History Record ID + */ + + public function record(int $jobId, + string $recordKey, + string $comment, + string $status=JobStatusEnum::Notice, + ?int $personId=null, + ?int $externalIdentityId=null, + ?int $externalIdentityRoleId=null): int { + $obj = $this->newEntity([ + 'job_id' => $jobId, + 'record_key' => $recordKey, + 'comment' => $comment, + 'person_id' => $personId, + 'external_identity_id' => $externalIdentityId, + 'status' => $status + ]); + + $this->saveOrFail($obj); + + // For now, always trace log Job History. We might do something more complicated later. + // eg: Make it configurable whether we create Job History, log, or both? + // This is documented at https://spaces.at.internet2.edu/display/COmanage/Registry+PE+Jobs#RegistryPEJobs-RegistryJobHistory + $this->llog('trace', $comment, "{$jobId}:{$recordKey}"); + + return $obj->id; + } + + /** + * Set validation rules. + * + * @since COmanage Registry v5.0.0 + * @param Validator $validator Validator + * @return Validator Validator + * @throws InvalidArgumentException + * @throws RecordNotFoundException + */ + + public function validationDefault(Validator $validator): Validator { + $schema = $this->getSchema(); + + $validator->add('job_id', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->notEmptyString('job_id'); + + $validator->add('record_key', [ + 'length' => ['rule' => ['validateMaxLength', ['column' => $schema->getColumn('record_key')]], + 'provider' => 'table'], + ]); + $validator->allowEmptyString('record_key'); + + $validator->add('comment', [ + 'length' => ['rule' => ['validateMaxLength', ['column' => $schema->getColumn('comment')]], + 'provider' => 'table'], + ]); + $validator->notEmptyString('comment'); + + $validator->add('status', [ + 'content' => ['rule' => ['inList', JobStatusEnum::getConstValues()]] + ]); + $validator->notEmptyString('status'); + + $validator->add('person_id', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('person_id'); + + $validator->add('external_identity_id', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('external_identity_id'); + + return $validator; + } +} \ No newline at end of file diff --git a/app/src/Model/Table/JobsTable.php b/app/src/Model/Table/JobsTable.php new file mode 100644 index 000000000..601fec6c8 --- /dev/null +++ b/app/src/Model/Table/JobsTable.php @@ -0,0 +1,730 @@ +addBehavior('Changelog'); + $this->addBehavior('Log'); + $this->addBehavior('Timestamp'); + + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Artifact); + + // Define associations + $this->belongsTo('Cos'); + $this->belongsTo('RequeuedFromJobs') + ->setClassName('Jobs') + ->setForeignKey('requeued_from_job_id') + // Property is set so ruleValidateCO can find it. We don't use the + // _id suffix to match Cake's default pattern. + ->setProperty('requeued_from_job'); + + $this->hasMany('JobHistoryRecords') + ->setDependent(true) + ->setCascadeCallbacks(true);; + + $this->setPluginRelations(); + + $this->setDisplayField('id'); + + $this->setPrimaryLink('co_id'); + $this->setRequiresCO(true); + $this->setAllowLookupPrimaryLink(['cancel']); + + $this->setAutoViewVars([ + 'statuses' => [ + 'type' => 'enum', + 'class' => 'JobStatusEnum' + ] + ]); + + $this->setViewContains([ + 'RequeuedFromJobs' + ]); + + $this->setPermissions([ + // Actions that operate over an entity (ie: require an $id) + 'entity' => [ + 'cancel' => ['platformAdmin', 'coAdmin'], + 'delete' => false,// ['platformAdmin', 'coAdmin'], + 'edit' => false,// ['platformAdmin', 'coAdmin'], + 'view' => ['platformAdmin', 'coAdmin'] + ], + // Actions that operate over a table (ie: do not require an $id) + 'table' => [ + 'add' => false, // ['platformAdmin', 'coAdmin'], + 'index' => ['platformAdmin', 'coAdmin'] + ], + 'readOnly' => ['cancel'], + // Related models whose permissions we'll need, typically for table views + 'related' => [ + 'JobHistoryRecords' + ] + ]); + } + + /** + * Assign a Job to a worker. This function should be called by the process + * that will be processing the specified job. + * + * @since COmanage Registry v5.0.0 + * @param Job $job Job to assign + * @throws InvalidArgumentException + */ + + public function assign(Job $job) { + // The Job must be Queued to be Assigned + if($job->status != JobStatusEnum::Queued) { + throw new \InvalidArgumentException( + __d('error', + 'Jobs.status.invalid', + [ + $jobs->id, + __d('enumeration', 'JobStatusEnum.Queued'), + __d('enumeration', 'JobStatusEnum.Assigned'), + __d('enumeration', 'JobStatusEnum.'.$job->status) + ] + ) + ); + } + + $job->status = JobStatusEnum::Assigned; + $job->assigned_host = gethostname() ?: "unknown"; + $job->assigned_pid = getmypid() ?: -1; + + $this->saveOrFail($job); + } + + /** + * Assign the next Job in the queue to the current worker. This function is + * intended to be called by JobShell. + * + * @since COmanage Registry v5.0.0 + * @param int $coId CO ID to assign job from + * @return Job Job to process, or null if there are no more jobs in the queue + */ + + public function assignNext(int $coId): ?Job { + // Start a new transaction. When we select from the Job queue, we need a read lock + // to ensure another worker doesn't grab the same process. + $cxn = $this->getConnection(); + $cxn->begin(); + + $job = $this->find() + ->where([ + 'status' => JobStatusEnum::Queued, + 'co_id' => $coId, + 'OR' => [ + 'start_after_time IS NULL', + 'start_after_time <' => date('Y-m-d H:i:s', time()) + ] + ]) + // We sort by id to pull the oldest job first + ->order(['id' => 'ASC']) + ->epilog('FOR UPDATE') + ->first(); + + if($job) { + // Assign the Job while we're still in the transaction + $this->assign($job); + } + + $cxn->commit(); + + return $job; + } + + /** + * Define business rules. + * + * @since COmanage Registry v5.0.0 + * @param RulesChecker $rules RulesChecker object + * @return RulesChecker + */ + + public function buildRules(RulesChecker $rules): RulesChecker { + // AR-Job-1 A Job may not be registered if an existing Job with the same plugin + // and parameters is registered in either Queued or In Progress status + $rules->addCreate([$this, 'ruleAlreadyRegistered'], + 'alreadyRegistered', + ['errorField' => 'parameters']); + + // If another rule is added here, register() will need to be updated with a more + // sophisticated mechanism to disable AR-Job-1 whene passed $concurrent=true. + + return $rules; + } + + /** + * Cancel a Job. The Job must be in a cancelable state. + * + * @since COmanage Registry v5.0.0 + * @param int $id Job ID + * @param string $actor Login Identifier of actor who requested cancelation + * @throws InvalidArgumentException + * @throws RecordNotFoundException + */ + + public function cancel(int $id, string $actor) { + $job = $this->get($id); + + if(!$job->canCancel()) { + throw new \InvalidArgumentException(__d('error', + 'Jobs.status.invalid.cancel', + [ + $job->id, + __d('enumeration', 'JobStatusEnum.'.$job->status) + ])); + } + + $this->finish( + job: $job, + summary: __d('result', 'Jobs.canceled.by', [$actor]), + result: JobStatusEnum::Canceled + ); + } + + /** + * Confirm a Job was properly finished. + * + * @since COmanage Registry v5.0.0 + * @param int $pid Process ID (on the current host) + */ + + public function confirmFinished(int $pid) { + // Ordinarily we want the plugin to mark the Job as finished so it can update the + // finish summary, but if the process exits abnormally we want to capture that + // and clean up the Job. Note under extremely rare circumstances it's possible for + // the PID we're looking for to be reassigned before we can run this check, but + // that probably implies a host with runaway processes (since the PID count must cycle). + + $job = $this->find() + ->where([ + 'status' => JobStatusEnum::InProgress, + 'assigned_pid' => $pid, + 'assigned_host' => gethostname() ?: "unknown" + ]) + ->first(); + + if(!empty($job)) { + // Terminate the job + $this->finish( + job: $job, + summary: __d('error', 'Jobs.failed.abnormal'), + result: JobStatusEnum::Failed + ); + } + } + + /** + * Mark a job as completed. + * + * @since COmanage Registry v2.0.0 + * @param Job $job Job to update + * @param string $summary Summary + * @param JobStatusEnum $result Result + * @throws InvalidArgumentException + */ + + public function finish(Job $job, string $summary="", string $result=JobStatusEnum::Complete) { + // The Job must be InProgress to be finished, unless we're canceling it + if($job->status != JobStatusEnum::InProgress + && !($result == JobStatusEnum::Canceled && $job->canCancel())) { + throw new \InvalidArgumentException( + __d('error', + 'Jobs.status.invalid', + [ + $job->id, + __d('enumeration', 'JobStatusEnum.InProgress'), + __d('enumeration', 'JobStatusEnum.'.$result), + __d('enumeration', 'JobStatusEnum.'.$job->status) + ] + ) + ); + } + + $job->status = $result; + $job->finish_summary = $summary; + $job->finish_time = date('Y-m-d H:i:s', time()); + + $this->saveOrFail($job); + + // On success, if a requeue_interval is specified then register a new job + // with the same parameters, but with a delayed start time. Do the same thing + // on failure if a retry_interval is specified. We need to do this after we + // update the status of $id to avoid issues with concurrent jobs. + + if($result == JobStatusEnum::Complete + && !empty($job->requeue_interval) + && $job->requeue_interval > 0) { + // The new job will be substantially the same as the last one... + + $this->register($job->co_id, + $job->plugin, + json_decode($job->parameters, true), + $job->register_summary, + false, + // we only support serialized jobs, not concurrent + false, + $job->requeue_interval, + $job->requeue_interval, + $job->retry_interval, + $job->id); + } elseif($result == JobStatusEnum::Failed + && !empty($job->retry_interval) + && $job->retry_interval > 0) { + // The new job will be substantially the same as the last one... + + $this->register(job->co_id, + $job->plugin, + json_decode($job->parameters, true), + $job->register_summary, + false, + // we only support serialized jobs, not concurrent + false, + $job->retry_interval, + $job->requeue_interval, + $job->retry_interval, + $job->id); + } + } + + /** + * Determine if a Job has been canceled. + * + * @since COmanage Registry v5.0.0 + * @param int $id Job ID + * @return bool True if the Job has been canceled, false otherwise + */ + + public function isCanceled(int $id): bool { + // Make sure to skip any cached records, since a Job InProgress needs up to + // date status to determine if it should stop. + + $job = $this->get($id, ['cache' => false]); + + return $job->status == JobStatusEnum::Canceled; + } + + /** + * Process a Job. Jobs must be in Ready status (ie: assigned) in order to be processed. + * + * @since COmanage Registry v5.0.0 + * @param Job $job Job to process + * @throws InvalidArgumentException + */ + + public function process(Job $job) { + // The Job must be Assigned to be processed + if($job->status != JobStatusEnum::Assigned) { + throw new \InvalidArgumentException( + __d('error', + 'Jobs.status.invalid', + [ + $jobs->id, + __d('enumeration', 'JobStatusEnum.Assigned'), + __d('enumeration', 'JobStatusEnum.InProgress'), + __d('enumeration', 'JobStatusEnum.'.$job->status) + ] + ) + ); + } + + try { + // First create an instance of the Entry Point Model + $pClass = $this->instantiatePluginModel($job->plugin, '\Lib\Jobs'); + + $JobHistoryRecords = TableRegistry::getTableLocator()->get('JobHistoryRecords'); + + // Maybe set the connection on the JobHistoryTable (if we were run via + // the queue runner). + $cxn = ConnectionManager::get('plugin'); + + if(!empty($cxn)) { + $JobHistoryRecords->setConnection($cxn); + } + + $pClass->run( + $this, + $JobHistoryRecords, + $job, + json_decode(json: $job->parameters, associative: true) + ); + } + catch(\Exception $e) { + $this->finish($job, $e->getMessage(), JobStatusEnum::Failed); + } + } + + /** + * Register a new Job. + * + * @since COmanage Registry v5.0.0 + * @param int $coId CO ID + * @param string $plugin Plugin Entry Point Model, in Plugin.Model format + * @param array $parameters Plugin parameters + * @param string $registerSummary Summary + * @param bool $synchronous Whether the Job is started (true) or queued (false) + * @param bool $concurrent Whether multiple instances of this Job with the same parameters are permitted to run concurrently + * @param int $delay Minimum number of seconds to delay the start of this Job + * @param int $requeueInterval If non-zero, number of seconds after successful completion to requeue the same Job + * @param int $retryInterval If non-zero, number of seconds after failed completion to requeue the same Job + * @param int $requeuedFrom If requeued, the ID of the Job that created this Job + * @return Job Job entity + * @throws InvalidArgumentException + */ + + public function register( + int $coId, + string $plugin, + array $parameters=[], + string $registerSummary="", + bool $synchronous=false, + bool $concurrent=false, + int $delay=0, + ?int $requeueInterval=null, + ?int $retryInterval=null, + ?int $requeuedFrom=null + ): Job { + // Start a transaction. In addition to ruleAlreadyRegistered needing a read lock, + // if we're synchronous we need to make sure the current caller gets assigned the Job. + + $cxn = ConnectionManager::get('default'); + $cxn->begin(); + + // Insert a new Job into the job table. A synchronous job is queued with status + // "In Progress" on the assumption that the caller will immediately begin + // processing it. Otherwise, the job is given status "Queued". + + $errors = $this->validateJobParameters($plugin, $coId, $parameters); + + if(!empty($errors)) { + // Convert the error array to a string + $err = ""; + + foreach($errors as $p => $e) { + $err .= "$p: $e,"; + } + + $cxn->rollback(); + throw new \InvalidArgumentException(rtrim($err, ",")); + } + + $entity = $this->newEntity([ + 'co_id' => $coId, + 'plugin' => $plugin, + 'parameters' => json_encode($parameters), + 'register_summary' => $registerSummary, + 'register_time' => date('Y-m-d H:i:s', time()), + 'status' => JobStatusEnum::Queued, + 'requeue_interval' => $requeueInterval, + 'retry_interval' => $retryInterval, + 'requeued_from_job_id' => $requeuedFrom, + 'start_after_time' => date('Y-m-d H:i:s', time()+$delay) + // We don't set percent_complete here since not all jobs might use that field, + // and then a null vs 0 can be used to distinguish. + ]); + + // If $concurrent is true, we want to disable AR-Job-1. Right now, since this + // is the only application rule we can simply disable rule checking, but if + // another rule is added this won't work. + $this->saveOrFail($entity, ['checkRules' => !$concurrent]); + + if($synchronous) { + // Assign the job within the transaction to make sure it doesn't get + // picked up by a queue runner + $this->assign($entity); + } + + $cxn->commit(); + + return $entity; + } + + /** + * Application Rule to determine if the Job is already registered. + * + * @since COmanage Registyr v5.0.0 + * @param Entity $entity Entity to be validated + * @param array $options Application rule options + * @return boolean true if the Rule check passes, false otherwise + */ + + public function ruleAlreadyRegistered($entity, $options) { + // We can't SELECT COUNT ... FOR UPDATE, so we select first which is good enough + $count = $this->find() + ->where([ + 'plugin' => $entity->plugin, + 'parameters' => $entity->parameters, + 'status IN' => [JobStatusEnum::InProgress, JobStatusEnum::Queued] + ]) + ->epilog('FOR UPDATE') + ->first(); + + if(!empty($count)) { + $this->llog( + level: 'error', + msg: "AR-Job-1 A Job matching the requested plugin (" . $entity->plugin . ") and parameters is already registered", + id: $entity->id + ); + return __d('error', 'Jobs.registered.already', [$entity->plugin]); + } + + return true; + } + + /** + * Set the percent complete for a job. + * + * @since COmanage Registry v5.0.0 + * @param Job $job Job to update + * @param int $percent Percent (between 0 and 100 inclusive) + */ + + public function setPercentComplete(Job $job, int $percent) { + $job->percent_complete = $percent; + + $this->saveOrFail($job); + } + + /** + * Mark a job as in progress. + * + * @since COmanage Registry v2.0.0 + * @param Job $job Job to update + * @param string $summary Summary + * @throws InvalidArgumentException + */ + + public function start(Job $job, string $summary="") { + // The Job must be Assigned to be started + if($job->status != JobStatusEnum::Assigned) { + throw new \InvalidArgumentException( + __d('error', + 'Jobs.status.invalid', + [ + $jobs->id, + __d('enumeration', 'JobStatusEnum.Assigned'), + __d('enumeration', 'JobStatusEnum.InProgress'), + __d('enumeration', 'JobStatusEnum.'.$job->status) + ] + ) + ); + } + + $job->status = JobStatusEnum::InProgress; + $job->start_summary = $summary; + $job->start_time = date('Y-m-d H:i:s', time()); + + $this->saveOrFail($job); + } + + /** + * Validate Job parameters. + * + * @since COmanage Registry v5.0.0 + * @param string $plugin Plugin Entry Point Model, in Plugin.Model form + * @param int $coId CO ID + * @param array $params Parameters to validate + * @return array An array of validation errors, keyed on parameter name + * @throws InvalidArgumentException + */ + + protected function validateJobParameters(string $plugin, int $coId, array $params): array { + $ret = []; + + $pClass = $this->instantiatePluginModel($plugin, '\Lib\Jobs'); + + // Validate each provided parameter + + $pluginParameters = $pClass->parameterFormat(); + + foreach($params as $p => $val) { + if(!empty($pluginParameters[$p])) { + switch($pluginParameters[$p]['type']) { + case 'bool': + case 'boolean': + throw new \RuntimeException('not implemented'); +// XXX implement + break; + case 'int': + case 'integer': + if(!preg_match('/^[0-9.+-]*$/', $val)) { + $ret[$p] = __d('error', 'Jobs.plugin.parameter.int'); + } + break; + case 'select': + throw new \RuntimeException('not implemented'); +// XXX implement + break; + case 'string': + // For now, anything can pass as a string + break; + default: + $ret[$p] = __d('error', 'Jobs.plugin.parameter.type', [$pluginParameters[$p]['type']]); + break; + } + } else { + // Requested parameter is not defined + $ret[$p] = __d('error', 'Jobs.plugin.parameter.invalid'); + } + } + + // Check that required parameters were provided + + foreach(array_keys($pluginParameters) as $p) { + if(isset($pluginParameters[$p]['required']) + && $pluginParameters[$p]['required'] + && empty($params[$p])) { + $ret[$p] = __d('error', 'Jobs.plugin.parameter.required'); + } + } + + return $ret; + } + + /** + * Set validation rules. + * + * @since COmanage Registry v5.0.0 + * @param Validator $validator Validator + * @return Validator Validator + */ + + public function validationDefault(Validator $validator): Validator { + $schema = $this->getSchema(); + + $validator->add('co_id', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->notEmptyString('co_id'); + + $this->registerStringValidation($validator, $schema, 'plugin', true); +/* + $validator->add('parameters', [ + 'content' => ['rule' => 'isArray'] + ]); + $validator->allowEmptyArray('parameters');*/ +// This doesn't work because parameters is passed as an array but stored as a string +// $this->registerStringValidation($validator, $schema, 'parameters', false); + + $validator->add('requeue_interval', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('requeue_interval'); + + $validator->add('retry_interval', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('retry_interval'); + + $validator->add('requeued_from_job_id', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('requeued_from_job_id'); + + $validator->add('status', [ + 'content' => ['rule' => ['inList', JobStatusEnum::getConstValues()]] + ]); + $validator->notEmptyString('status'); + + $this->registerStringValidation($validator, $schema, 'assigned_host', false); + + $validator->add('assigned_pid', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->allowEmptyString('assigned_pid'); + + $this->registerStringValidation($validator, $schema, 'register_summary', false); + + $this->registerStringValidation($validator, $schema, 'start_summary', false); + + $this->registerStringValidation($validator, $schema, 'finish_summary', false); + + $validator->add('register_time', [ + 'content' => ['rule' => 'dateTime'] + ]); + $validator->allowEmptyString('register_time'); + + $validator->add('start_after_time', [ + 'content' => ['rule' => 'dateTime'] + ]); + $validator->allowEmptyString('start_after_time'); + + $validator->add('start_time', [ + 'content' => ['rule' => 'dateTime'] + ]); + $validator->allowEmptyString('start_time'); + + $validator->add('finish_time', [ + 'content' => ['rule' => 'dateTime'] + ]); + $validator->allowEmptyString('finish_time'); + + $validator->add('percent_complete', [ + 'content' => ['rule' => 'isInteger'] + ]); + $validator->add('percent_complete', [ + 'range' => ['rule' => 'range', 0, 100] + ]); + $validator->allowEmptyString('percent_complete'); + + return $validator; + } +} \ No newline at end of file diff --git a/app/src/Model/Table/MetaTable.php b/app/src/Model/Table/MetaTable.php index 72c873f92..bc77e08cc 100644 --- a/app/src/Model/Table/MetaTable.php +++ b/app/src/Model/Table/MetaTable.php @@ -43,8 +43,7 @@ class MetaTable extends Table { */ public function initialize(array $config): void { - // Dashboards are configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Metadata); $this->setDisplayField('upgrade_version'); } diff --git a/app/src/Model/Table/NamesTable.php b/app/src/Model/Table/NamesTable.php index 1671ae9d6..a09777c64 100644 --- a/app/src/Model/Table/NamesTable.php +++ b/app/src/Model/Table/NamesTable.php @@ -75,8 +75,7 @@ public function initialize(array $config): void { // Timestamp behavior handles created/modified updates $this->addBehavior('Timestamp'); - // Names are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php index f495b9ce0..6766ad8b2 100644 --- a/app/src/Model/Table/PeopleTable.php +++ b/app/src/Model/Table/PeopleTable.php @@ -63,8 +63,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // CO People are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Primary); // Define associations $this->belongsTo('Cos'); @@ -99,6 +98,9 @@ public function initialize(array $config): void { $this->hasMany('Identifiers') ->setDependent(true) ->setCascadeCallbacks(true); + $this->hasMany('JobHistoryRecords') + ->setDependent(true) + ->setCascadeCallbacks(true); $this->hasMany('PersonRoles') ->setDependent(true) ->setCascadeCallbacks(true); diff --git a/app/src/Model/Table/PersonRolesTable.php b/app/src/Model/Table/PersonRolesTable.php index d66192061..0278a59b7 100644 --- a/app/src/Model/Table/PersonRolesTable.php +++ b/app/src/Model/Table/PersonRolesTable.php @@ -80,8 +80,7 @@ public function initialize(array $config): void { $this->addBehavior('Timestamp'); $this->addBehavior('Timezone'); - // Person Roles are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('Cous'); diff --git a/app/src/Model/Table/PluginsTable.php b/app/src/Model/Table/PluginsTable.php index 93bd55130..edc3296ff 100644 --- a/app/src/Model/Table/PluginsTable.php +++ b/app/src/Model/Table/PluginsTable.php @@ -76,8 +76,7 @@ public function initialize(array $config): void { // Timestamp behavior handles created/modified updates $this->addBehavior('Timestamp'); - // Plugins are configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Metadata); $this->setDisplayField('plugin'); @@ -366,16 +365,22 @@ public function ruleInUse($entity, array $options): string|bool { $tableName = Inflector::pluralize(Inflector::classify($type)); $table = TableRegistry::getTableLocator()->get($tableName); - // We don't actually need $entryPoints here, we just wanted to make sure - // the plugin implements at least one Entry Point for this $type. - $r = $table->pluginInUse($entity->plugin); - - if(!empty($r) && count($r) > 0) { - // There could be other plugin types in use, but that's probably the - // exception and anyway just returning a single error will be sufficient - // for now - - return __d('error', 'Plugins.inuse', [count($r), $type, $r->first()->name, $r->first()->co_id]); + // This rule only applies to _configuration_ objects, so (eg) Jobs + // (which are artifacts) can continue to reference a Plugin after + // it has been suspended. Note that if a Plugin is polymorphic, this + // rule still applies to the Configuration based Entry Point Models. + if($table->isConfigurationTable()) { + // We don't actually need $entryPoints here, we just wanted to make sure + // the plugin implements at least one Entry Point for this $type. + $r = $table->pluginInUse($entity->plugin); + + if(!empty($r) && count($r) > 0) { + // There could be other plugin types in use, but that's probably the + // exception and anyway just returning a single error will be sufficient + // for now + + return __d('error', 'Plugins.inuse', [count($r), $type, $r->first()->name, $r->first()->co_id]); + } } } } diff --git a/app/src/Model/Table/PronounsTable.php b/app/src/Model/Table/PronounsTable.php index 9b7c86f38..b7b1bc702 100644 --- a/app/src/Model/Table/PronounsTable.php +++ b/app/src/Model/Table/PronounsTable.php @@ -66,8 +66,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Pronouns are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/TelephoneNumbersTable.php b/app/src/Model/Table/TelephoneNumbersTable.php index 73e7ac8dd..3044435ed 100644 --- a/app/src/Model/Table/TelephoneNumbersTable.php +++ b/app/src/Model/Table/TelephoneNumbersTable.php @@ -70,8 +70,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Telephone Numbers are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/Model/Table/TypesTable.php b/app/src/Model/Table/TypesTable.php index a0a3368c4..b62b4c5fa 100644 --- a/app/src/Model/Table/TypesTable.php +++ b/app/src/Model/Table/TypesTable.php @@ -79,8 +79,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // Types are configuration - $this->setIsConfigurationTable(true); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Configuration); // Define associations $this->belongsTo('Cos'); diff --git a/app/src/Model/Table/UrlsTable.php b/app/src/Model/Table/UrlsTable.php index 2fdbbcdd3..914d051ee 100644 --- a/app/src/Model/Table/UrlsTable.php +++ b/app/src/Model/Table/UrlsTable.php @@ -66,8 +66,7 @@ public function initialize(array $config): void { $this->addBehavior('Log'); $this->addBehavior('Timestamp'); - // URLs are not configuration - $this->setIsConfigurationTable(false); + $this->setTableType(\App\Lib\Enum\TableTypeEnum::Secondary); // Define associations $this->belongsTo('People'); diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php index b28d6f24f..02f014cdb 100644 --- a/app/src/View/Helper/FieldHelper.php +++ b/app/src/View/Helper/FieldHelper.php @@ -123,7 +123,7 @@ public function control(string $fieldName, $vv_obj = $this->getView()->get('vv_obj'); - if($fieldName == 'plugin') { + if($fieldName == 'plugin' && $this->action == 'edit') { return $this->statusControl($fieldName, $vv_obj->$fieldName, [ diff --git a/app/templates/JobHistoryRecords/columns.inc b/app/templates/JobHistoryRecords/columns.inc new file mode 100644 index 000000000..c305c37a2 --- /dev/null +++ b/app/templates/JobHistoryRecords/columns.inc @@ -0,0 +1,50 @@ + [ + 'type' => 'link', + 'sortable' => true + ], + 'record_key' => [ + 'type' => 'echo', + 'sortable' => true + ], + 'comment' => [ + 'type' => 'echo', + 'sortable' => true + ], + 'status' => [ + 'type' => 'enum', + 'class' => 'JobStatusEnum', + 'sortable' => true + ], + 'created' => [ + 'type' => 'datetime', + 'sortable' => true + ] +]; diff --git a/app/templates/JobHistoryRecords/fields.inc b/app/templates/JobHistoryRecords/fields.inc new file mode 100644 index 000000000..ea26401a1 --- /dev/null +++ b/app/templates/JobHistoryRecords/fields.inc @@ -0,0 +1,70 @@ +Field->control('record_key'); + + print $this->Field->control('comment'); + + print $this->Field->control('status'); + +// Rewrite these to always emit the column even if the field is blank + if(!empty($vv_obj->person->primary_name)) { + $viewLink = [ + 'url' => [ + 'controller' => 'people', + 'action' => 'edit', + $vv_obj->person->id + ], + ]; + + print $this->Field->statusControl( + 'person_id', + $vv_obj->person->primary_name->full_name, + $viewLink + ); + } + + if(!empty($vv_obj->external_identity->primary_name)) { + $viewLink = [ + 'url' => [ + 'controller' => 'external_identities', + 'action' => 'edit', + $vv_obj->external_identity->id + ], + ]; + + print $this->Field->statusControl( + 'external_identity_id', + $vv_obj->external_identity->primary_name->full_name, + $viewLink + ); + } + + print $this->Field->control('created'); +} diff --git a/app/templates/Jobs/columns.inc b/app/templates/Jobs/columns.inc new file mode 100644 index 000000000..0497f9739 --- /dev/null +++ b/app/templates/Jobs/columns.inc @@ -0,0 +1,50 @@ + [ + 'type' => 'link', + 'sortable' => true + ], + 'plugin' => [ + 'type' => 'echo', + 'label' => __d('controller', 'Jobs', [1]), + 'sortable' => true + ], + 'status' => [ + 'type' => 'enum', + 'class' => 'JobStatusEnum', + 'sortable' => true + ], + 'register_summary' => [ + 'type' => 'echo' + ], + 'created' => [ + 'type' => 'datetime', + 'sortable' => true + ] +]; diff --git a/app/templates/Jobs/fields-links.inc b/app/templates/Jobs/fields-links.inc new file mode 100644 index 000000000..bf2a70bd9 --- /dev/null +++ b/app/templates/Jobs/fields-links.inc @@ -0,0 +1,51 @@ + 'history', + 'order' => 'Default', + 'label' => __d('controller', 'JobHistoryRecords', [99]), + 'link' => [ + 'controller' => 'job_history_records', + 'action' => 'index', + 'job_id' => $vv_obj->id + ], + 'class' => '' +]; + +if(!empty($vv_obj) && $vv_obj->canCancel()) { + $topLinks[] = [ + 'icon' => 'cancel', + 'order' => 'Default', + 'label' => __d('operation', 'cancel'), + 'link' => [ + 'action' => 'cancel', + $vv_obj->id + ], + 'class' => '' + ]; +} \ No newline at end of file diff --git a/app/templates/Jobs/fields.inc b/app/templates/Jobs/fields.inc new file mode 100644 index 000000000..c646f41f8 --- /dev/null +++ b/app/templates/Jobs/fields.inc @@ -0,0 +1,78 @@ +Field->control('plugin', labelText: __d('controller', 'Jobs', [1])); + + print $this->Field->control('status'); + + if($vv_obj->status == \App\Lib\Enum\JobStatusEnum::InProgress) { + print $this->Field->statusControl( + fieldName: 'percent_complete', + status: (string)$vv_obj->percent_complete + ); + } + + print $this->Field->control('parameters'); + + print $this->Field->control('register_time'); + + print $this->Field->control('register_summary'); + + print $this->Field->control('assigned_host'); + + print $this->Field->control('assigned_pid'); + + print $this->Field->control('start_after_time'); + + print $this->Field->control('start_time'); + + print $this->Field->control('start_summary'); + + print $this->Field->control('finish_time'); + + print $this->Field->control('finish_summary'); + + print $this->Field->control('requeue_interval'); + + print $this->Field->control('retry_interval'); + + if(!empty($vv_obj->requeued_from_job->id)) { + print $this->Field->statusControl( + fieldName: 'requeued_from_job_id', + status: (string)$vv_obj->requeued_from_job->id, + link: [ + 'url' => [ + 'controller' => 'jobs', + 'action' => 'view', + $vv_obj->requeued_from_job->id + ] + ] + ); + } +} diff --git a/app/templates/Standard/add-edit-view.php b/app/templates/Standard/add-edit-view.php index 16800f0c2..18cece2b3 100644 --- a/app/templates/Standard/add-edit-view.php +++ b/app/templates/Standard/add-edit-view.php @@ -46,6 +46,10 @@ } } +if(file_exists(ROOT . DS . "templates" . DS . $modelsName . DS . "fields-links.inc")) { + include(ROOT . DS . "templates" . DS . $modelsName . DS . "fields-links.inc"); +} + // $linkFilter is used for models that belong to a specific parent model (eg: co_id) $linkFilter = []; @@ -107,14 +111,31 @@ $action_args['vv_attr_id'] = $vv_obj->id; foreach(($topLinks ?? []) as $t) { - if($vv_permissions[ $t['link']['action'] ]) { + $perm = false; + + if(!empty($t['link']['controller'])) { + // We're linking into a related model + + $linkModel = \Cake\Utility\Inflector::camelize($t['link']['controller']); + + if(isset($vv_permissions[$linkModel][ $t['link']['action'] ])) { + $perm = $vv_permissions[$linkModel][ $t['link']['action'] ]; + } + + // Inject a link to the current object ID + $t['link']['?'][\App\Lib\Util\StringUtilities::entityToForeignKey($vv_obj)] = $vv_obj->id; + } else { + $perm = $vv_permissions[ $t['link']['action'] ]; + // We need to inject $linkFilter, but not overwrite any existing query params if(!empty($t['link']['?'])) { $t['link']['?'] = array_merge($t['link']['?'], $linkFilter); } else { $t['link']['?'] = $linkFilter; } - + } + + if($perm) { $action_args['vv_actions'][] = [ 'order' => $this->Menu->getMenuOrder($t['order']), 'icon' => $this->Menu->getMenuIcon($t['icon']), diff --git a/app/templates/element/breadcrumbs.php b/app/templates/element/breadcrumbs.php index 83bcdac47..5dbc9b4c1 100644 --- a/app/templates/element/breadcrumbs.php +++ b/app/templates/element/breadcrumbs.php @@ -70,7 +70,11 @@ ); } - if(!empty($vv_primary_link_obj->plugin)) { + if(!empty($vv_primary_link_obj->plugin) + // JobHistoryRecords have Jobs as their primary link, which define a plugin + // but aren't standard Pluggable Models, so we exempt them here. If this + // becomes a pattern we should annotate something instead. + && $modelsName != 'JobHistoryRecords') { // We're in a plugin. Insert a link back to the pluggable object. $plModelsName = \App\Lib\Util\StringUtilities::entityToClassName($vv_primary_link_obj); @@ -118,7 +122,7 @@ $vv_bc_parent_obj->$vv_bc_parent_displayfield, ['plugin' => null, 'controller' => $parentController, - 'action' => 'edit', + 'action' => $vv_bc_parent_obj->isReadOnly() ? 'view' : 'edit', $vv_bc_parent_obj->id] ); } @@ -196,8 +200,8 @@ if($vv_action != 'index' && !($modelsName == 'Dashboards' && $vv_action == 'configuration') - // Plugin breadcrumbs are handled above - && empty($vv_primary_link_obj->plugin)) { + // Plugin breadcrumbs are handled above, but see above note re JobHistoryRecords + && (empty($vv_primary_link_obj->plugin) || $modelsName == 'JobHistoryRecords')) { // Default parent is index, to which we might need to append the Primary Link ID $target = [ diff --git a/app/vendor/autoload.php b/app/vendor/autoload.php index b8de0f7f6..3e8e561ee 100644 --- a/app/vendor/autoload.php +++ b/app/vendor/autoload.php @@ -2,11 +2,6 @@ // 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); -} - require_once __DIR__ . '/composer/autoload_real.php'; return ComposerAutoloaderInitb25f76eec921984aa94dcf4015a4846e::getLoader(); diff --git a/app/vendor/bin/composer b/app/vendor/bin/composer deleted file mode 100755 index b48a11b33..000000000 --- a/app/vendor/bin/composer +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/composer/composer/bin/composer'); - exit(0); - } -} - -include __DIR__ . '/..'.'/composer/composer/bin/composer'; diff --git a/app/vendor/bin/composer b/app/vendor/bin/composer new file mode 120000 index 000000000..f43551575 --- /dev/null +++ b/app/vendor/bin/composer @@ -0,0 +1 @@ +../composer/composer/bin/composer \ No newline at end of file diff --git a/app/vendor/bin/doctrine-dbal b/app/vendor/bin/doctrine-dbal deleted file mode 100755 index 374a92a09..000000000 --- a/app/vendor/bin/doctrine-dbal +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal'); - exit(0); - } -} - -include __DIR__ . '/..'.'/doctrine/dbal/bin/doctrine-dbal'; diff --git a/app/vendor/bin/doctrine-dbal b/app/vendor/bin/doctrine-dbal new file mode 120000 index 000000000..58a8a89c2 --- /dev/null +++ b/app/vendor/bin/doctrine-dbal @@ -0,0 +1 @@ +../doctrine/dbal/bin/doctrine-dbal \ No newline at end of file diff --git a/app/vendor/bin/phinx b/app/vendor/bin/phinx deleted file mode 100755 index 6734d67f2..000000000 --- a/app/vendor/bin/phinx +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/robmorgan/phinx/bin/phinx'); - exit(0); - } -} - -include __DIR__ . '/..'.'/robmorgan/phinx/bin/phinx'; diff --git a/app/vendor/bin/phinx b/app/vendor/bin/phinx new file mode 120000 index 000000000..8b2b0f455 --- /dev/null +++ b/app/vendor/bin/phinx @@ -0,0 +1 @@ +../robmorgan/phinx/bin/phinx \ No newline at end of file diff --git a/app/vendor/bin/php-parse b/app/vendor/bin/php-parse deleted file mode 100755 index 80f0e486d..000000000 --- a/app/vendor/bin/php-parse +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse'); - exit(0); - } -} - -include __DIR__ . '/..'.'/nikic/php-parser/bin/php-parse'; diff --git a/app/vendor/bin/php-parse b/app/vendor/bin/php-parse new file mode 120000 index 000000000..062d66a3e --- /dev/null +++ b/app/vendor/bin/php-parse @@ -0,0 +1 @@ +../nikic/php-parser/bin/php-parse \ No newline at end of file diff --git a/app/vendor/bin/phpcbf b/app/vendor/bin/phpcbf deleted file mode 100755 index dd5f763df..000000000 --- a/app/vendor/bin/phpcbf +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/squizlabs/php_codesniffer/bin/phpcbf'); - exit(0); - } -} - -include __DIR__ . '/..'.'/squizlabs/php_codesniffer/bin/phpcbf'; diff --git a/app/vendor/bin/phpcbf b/app/vendor/bin/phpcbf new file mode 120000 index 000000000..bdf04fbca --- /dev/null +++ b/app/vendor/bin/phpcbf @@ -0,0 +1 @@ +../squizlabs/php_codesniffer/bin/phpcbf \ No newline at end of file diff --git a/app/vendor/bin/phpcs b/app/vendor/bin/phpcs deleted file mode 100755 index 5123b7d63..000000000 --- a/app/vendor/bin/phpcs +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/squizlabs/php_codesniffer/bin/phpcs'); - exit(0); - } -} - -include __DIR__ . '/..'.'/squizlabs/php_codesniffer/bin/phpcs'; diff --git a/app/vendor/bin/phpcs b/app/vendor/bin/phpcs new file mode 120000 index 000000000..9481d68a4 --- /dev/null +++ b/app/vendor/bin/phpcs @@ -0,0 +1 @@ +../squizlabs/php_codesniffer/bin/phpcs \ No newline at end of file diff --git a/app/vendor/bin/phpunit b/app/vendor/bin/phpunit deleted file mode 100755 index c52ed8c3b..000000000 --- a/app/vendor/bin/phpunit +++ /dev/null @@ -1,120 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = 'phpvfscomposer://'.$this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - $data = str_replace('__DIR__', var_export(dirname($this->realpath), true), $data); - $data = str_replace('__FILE__', var_export($this->realpath, true), $data); - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/phpunit/phpunit/phpunit'); - exit(0); - } -} - -include __DIR__ . '/..'.'/phpunit/phpunit/phpunit'; diff --git a/app/vendor/bin/phpunit b/app/vendor/bin/phpunit new file mode 120000 index 000000000..2c4893031 --- /dev/null +++ b/app/vendor/bin/phpunit @@ -0,0 +1 @@ +../phpunit/phpunit/phpunit \ No newline at end of file diff --git a/app/vendor/bin/psysh b/app/vendor/bin/psysh deleted file mode 100755 index c10304ba4..000000000 --- a/app/vendor/bin/psysh +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/psy/psysh/bin/psysh'); - exit(0); - } -} - -include __DIR__ . '/..'.'/psy/psysh/bin/psysh'; diff --git a/app/vendor/bin/psysh b/app/vendor/bin/psysh new file mode 120000 index 000000000..3c06b1ae9 --- /dev/null +++ b/app/vendor/bin/psysh @@ -0,0 +1 @@ +../psy/psysh/bin/psysh \ No newline at end of file diff --git a/app/vendor/bin/var-dump-server b/app/vendor/bin/var-dump-server deleted file mode 100755 index 527f3ed42..000000000 --- a/app/vendor/bin/var-dump-server +++ /dev/null @@ -1,117 +0,0 @@ -#!/usr/bin/env php -realpath = realpath($opened_path) ?: $opened_path; - $opened_path = $this->realpath; - $this->handle = fopen($this->realpath, $mode); - $this->position = 0; - - return (bool) $this->handle; - } - - public function stream_read($count) - { - $data = fread($this->handle, $count); - - if ($this->position === 0) { - $data = preg_replace('{^#!.*\r?\n}', '', $data); - } - - $this->position += strlen($data); - - return $data; - } - - public function stream_cast($castAs) - { - return $this->handle; - } - - public function stream_close() - { - fclose($this->handle); - } - - public function stream_lock($operation) - { - return $operation ? flock($this->handle, $operation) : true; - } - - public function stream_seek($offset, $whence) - { - if (0 === fseek($this->handle, $offset, $whence)) { - $this->position = ftell($this->handle); - return true; - } - - return false; - } - - public function stream_tell() - { - return $this->position; - } - - public function stream_eof() - { - return feof($this->handle); - } - - public function stream_stat() - { - return array(); - } - - public function stream_set_option($option, $arg1, $arg2) - { - return true; - } - - public function url_stat($path, $flags) - { - $path = substr($path, 17); - if (file_exists($path)) { - return stat($path); - } - - return false; - } - } - } - - if (function_exists('stream_wrapper_register') && stream_wrapper_register('phpvfscomposer', 'Composer\BinProxyWrapper')) { - include("phpvfscomposer://" . __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server'); - exit(0); - } -} - -include __DIR__ . '/..'.'/symfony/var-dumper/Resources/bin/var-dump-server'; diff --git a/app/vendor/bin/var-dump-server b/app/vendor/bin/var-dump-server new file mode 120000 index 000000000..6bd4e93db --- /dev/null +++ b/app/vendor/bin/var-dump-server @@ -0,0 +1 @@ +../symfony/var-dumper/Resources/bin/var-dump-server \ No newline at end of file diff --git a/app/vendor/brick/varexporter/CHANGELOG.md b/app/vendor/brick/varexporter/CHANGELOG.md new file mode 100644 index 000000000..f636ce3fa --- /dev/null +++ b/app/vendor/brick/varexporter/CHANGELOG.md @@ -0,0 +1,120 @@ +# Changelog + +## [0.3.8](https://github.com/brick/varexporter/releases/tag/0.3.8) - 2023-01-22 + +✨ **New feature** + +- Support for PHP 8.1 `readonly` properties (#27, #28) + +Thanks @AnnaDamm! + +## [0.3.7](https://github.com/brick/varexporter/releases/tag/0.3.7) - 2022-06-30 + +✨ **New feature** + +- New option: `VarExporter::INLINE_ARRAY` + +🗑️ **Deprecated** + +- The `VarExporter::INLINE_NUMERIC_SCALAR_ARRAY` is deprecated, please use `INLINE_SCALAR_LIST` instead + +## [0.3.6](https://github.com/brick/varexporter/releases/tag/0.3.6) - 2022-06-15 + +✨ **New feature** + +Support for PHP 8.1 enums (#23). + +Thanks @Jacobs63! + +## [0.3.5](https://github.com/brick/varexporter/releases/tag/0.3.5) - 2021-02-10 + +✨ **New feature** + +Support for controlling the base indentation level (#17). + +Thanks @ADmad! + +## [0.3.4](https://github.com/brick/varexporter/releases/tag/0.3.4) - 2021-02-07 + +✨ **New feature** + +Support for trailing comma in non-inline arrays, with the `TRAILING_COMMA_IN_ARRAY` flag (#16). + +Thanks @ADmad! + +## [0.3.3](https://github.com/brick/varexporter/releases/tag/0.3.3) - 2020-12-24 + +🐛 **Bug fix** + +- Exporting an object with numeric dynamic properties would lead to a `TypeError` + +## [0.3.2](https://github.com/brick/varexporter/releases/tag/0.3.2) - 2020-03-13 + +✨ **New feature** + +Support for exporting internal classes implementing `__set_state()`: + +- `DateTime` +- `DateTimeImmutable` +- `DateTimeZone` +- `DateInterval` +- `DatePeriod` + +Thanks @GameplayJDK! + +## [0.3.1](https://github.com/brick/varexporter/releases/tag/0.3.1) - 2020-01-23 + +✨ **New features** + +- Support for closures with `use()` using the `CLOSURE_SNAPSHOT_USE` option (#7) +- Support for arrow functions in PHP 7.4 (#8) + +Thanks to @jasny for his awesome work! + +## [0.3.0](https://github.com/brick/varexporter/releases/tag/0.3.0) - 2019-12-24 + +Minimum PHP version is now `7.2`. No breaking changes. + +## [0.2.1](https://github.com/brick/varexporter/releases/tag/0.2.1) - 2019-04-16 + +✨ **New option**: `VarExporter::INLINE_NUMERIC_SCALAR_ARRAY` (#3) + +Formats numeric arrays containing only scalar values on a single line. + +## [0.2.0](https://github.com/brick/varexporter/releases/tag/0.2.0) - 2019-04-09 + +✨ **New feature** + +- Experimental support for closures 🎉 + +💥 **Minor BC break** + +- `export()` does not throw an exception anymore when encountering a `Closure`. + To get the old behaviour back, use the `NO_CLOSURES` option. + +## [0.1.2](https://github.com/brick/varexporter/releases/tag/0.1.2) - 2019-04-08 + +🐛 **Bug fixes** + +- Static properties in custom classes were wrongly included—`unset()`—in the output + +✨ **Improvements** + +- Circular references are now detected, and throw an `ExportException` instead of erroring. + +## [0.1.1](https://github.com/brick/varexporter/releases/tag/0.1.1) - 2019-04-08 + +🐛 **Bug fixes** + +- Single-letter properties were wrongly exported using `->{'x'}` notation. + +✨ **Improvements** + +- Exception messages now contain the path (array keys / object properties) to the failure: + + > `[foo][bar][0]` Type "resource" is not supported. + +## [0.1.0](https://github.com/brick/varexporter/releases/tag/0.1.0) - 2019-04-07 + +First release. + diff --git a/app/vendor/brick/varexporter/composer.json b/app/vendor/brick/varexporter/composer.json index f627551c0..916985d8c 100644 --- a/app/vendor/brick/varexporter/composer.json +++ b/app/vendor/brick/varexporter/composer.json @@ -13,7 +13,7 @@ "require-dev": { "phpunit/phpunit": "^8.5 || ^9.0", "php-coveralls/php-coveralls": "^2.2", - "vimeo/psalm": "4.4.1" + "vimeo/psalm": "4.23.0" }, "autoload": { "psr-4": { diff --git a/app/vendor/brick/varexporter/src/Internal/GenericExporter.php b/app/vendor/brick/varexporter/src/Internal/GenericExporter.php index e665fd280..6b520a231 100644 --- a/app/vendor/brick/varexporter/src/Internal/GenericExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/GenericExporter.php @@ -51,7 +51,14 @@ final class GenericExporter * * @var bool */ - public $inlineNumericScalarArray; + public $inlineArray; + + /** + * @psalm-readonly + * + * @var bool + */ + public $inlineScalarList; /** * @psalm-readonly @@ -74,10 +81,6 @@ final class GenericExporter */ public $indentLevel; - /** - * @param int $options - * @param int Indentation level - */ public function __construct(int $options, int $indentLevel = 0) { $this->objectExporters[] = new ObjectExporter\StdClassExporter($this); @@ -96,13 +99,18 @@ public function __construct(int $options, int $indentLevel = 0) $this->objectExporters[] = new ObjectExporter\SerializeExporter($this); } + if (! ($options & VarExporter::NO_ENUMS)) { + $this->objectExporters[] = new ObjectExporter\EnumExporter($this); + } + if (! ($options & VarExporter::NOT_ANY_OBJECT)) { $this->objectExporters[] = new ObjectExporter\AnyObjectExporter($this); } $this->addTypeHints = (bool) ($options & VarExporter::ADD_TYPE_HINTS); $this->skipDynamicProperties = (bool) ($options & VarExporter::SKIP_DYNAMIC_PROPERTIES); - $this->inlineNumericScalarArray = (bool) ($options & VarExporter::INLINE_NUMERIC_SCALAR_ARRAY); + $this->inlineArray = (bool) ($options & VarExporter::INLINE_ARRAY); + $this->inlineScalarList = (bool) ($options & VarExporter::INLINE_SCALAR_LIST); $this->closureSnapshotUses = (bool) ($options & VarExporter::CLOSURE_SNAPSHOT_USES); $this->trailingCommaInArray = (bool) ($options & VarExporter::TRAILING_COMMA_IN_ARRAY); @@ -165,11 +173,11 @@ public function exportArray(array $array, array $path, array $parentIds) : array $result = []; $count = count($array); - $isNumeric = array_keys($array) === range(0, $count - 1); + $isList = array_keys($array) === range(0, $count - 1); $current = 0; - $inline = ($this->inlineNumericScalarArray && $isNumeric && $this->isScalarArray($array)); + $inline = $this->inlineArray || ($this->inlineScalarList && $isList && $this->isScalarList($array)); foreach ($array as $key => $value) { $isLast = (++$current === $count); @@ -180,12 +188,16 @@ public function exportArray(array $array, array $path, array $parentIds) : array $exported = $this->export($value, $newPath, $parentIds); if ($inline) { - $result[] = $exported[0]; + if ($isList) { + $result[] = $exported[0]; + } else { + $result[] = var_export($key, true) . ' => ' . $exported[0]; + } } else { $prepend = ''; $append = ''; - if (! $isNumeric) { + if (! $isList) { $prepend = var_export($key, true) . ' => '; } @@ -220,7 +232,7 @@ public function exportArray(array $array, array $path, array $parentIds) : array * * @return bool */ - private function isScalarArray(array $array) : bool + private function isScalarList(array $array) : bool { foreach ($array as $value) { if ($value !== null && ! is_scalar($value)) { diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/AnyObjectExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/AnyObjectExporter.php index 5449e71ab..7cb3b6292 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/AnyObjectExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/AnyObjectExporter.php @@ -29,7 +29,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool * * @psalm-suppress MixedAssignment */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { $lines = $this->getCreateObjectCode($reflectionObject); @@ -44,10 +44,10 @@ public function export($object, \ReflectionObject $reflectionObject, array $path $returnNewObject = ($reflectionObject->getConstructor() === null); while ($current) { - $publicProperties = []; - $nonPublicProperties = []; - $unsetPublicProperties = []; - $unsetNonPublicProperties = []; + $publicNonReadonlyProperties = []; + $nonPublicOrPublicReadonlyProperties = []; + $unsetPublicNonReadonlyProperties = []; + $unsetNonPublicOrPublicReadonlyProperties = []; foreach ($current->getProperties() as $property) { if ($property->isStatic()) { @@ -70,26 +70,26 @@ public function export($object, \ReflectionObject $reflectionObject, array $path if (array_key_exists($key, $objectAsArray)) { $value = $objectAsArray[$key]; - if ($property->isPublic()) { - $publicProperties[$name] = $value; + if ($property->isPublic() && !(method_exists($property, 'isReadOnly') && $property->isReadOnly())) { + $publicNonReadonlyProperties[$name] = $value; } else { - $nonPublicProperties[$name] = $value; + $nonPublicOrPublicReadonlyProperties[$name] = $value; } } else { - if ($property->isPublic()) { - $unsetPublicProperties[] = $name; + if ($property->isPublic() && !(method_exists($property, 'isReadOnly') && $property->isReadOnly())) { + $unsetPublicNonReadonlyProperties[] = $name; } else { - $unsetNonPublicProperties[] = $name; + $unsetNonPublicOrPublicReadonlyProperties[] = $name; } } $returnNewObject = false; } - if ($publicProperties || $unsetPublicProperties) { + if ($publicNonReadonlyProperties || $unsetPublicNonReadonlyProperties) { $lines[] = ''; - foreach ($publicProperties as $name => $value) { + foreach ($publicNonReadonlyProperties as $name => $value) { /** @psalm-suppress RedundantCast See: https://github.com/vimeo/psalm/issues/4891 */ $name = (string) $name; @@ -104,19 +104,19 @@ public function export($object, \ReflectionObject $reflectionObject, array $path $lines = array_merge($lines, $exportedValue); } - foreach ($unsetPublicProperties as $name) { + foreach ($unsetPublicNonReadonlyProperties as $name) { $lines[] = 'unset($object->' . $this->escapePropName($name) . ');'; } } - if ($nonPublicProperties || $unsetNonPublicProperties) { + if ($nonPublicOrPublicReadonlyProperties || $unsetNonPublicOrPublicReadonlyProperties) { $closureLines = []; if ($this->exporter->addTypeHints) { $closureLines[] = '/** @var \\' . $current->getName() . ' $this */'; } - foreach ($nonPublicProperties as $name => $value) { + foreach ($nonPublicOrPublicReadonlyProperties as $name => $value) { $newPath = $path; $newPath[] = $name; @@ -128,7 +128,7 @@ public function export($object, \ReflectionObject $reflectionObject, array $path $closureLines = array_merge($closureLines, $exportedValue); } - foreach ($unsetNonPublicProperties as $name) { + foreach ($unsetNonPublicOrPublicReadonlyProperties as $name) { $closureLines[] = 'unset($this->' . $this->escapePropName($name) . ');'; } diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/ClosureExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/ClosureExporter.php index 6cfb9f57f..ea98891cc 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/ClosureExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/ClosureExporter.php @@ -39,7 +39,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool /** * {@inheritDoc} */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { assert($object instanceof Closure); diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/EnumExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/EnumExporter.php new file mode 100644 index 000000000..dfec28f42 --- /dev/null +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/EnumExporter.php @@ -0,0 +1,39 @@ +isEnum(); + } + + /** + * {@inheritDoc} + */ + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + { + assert($object instanceof UnitEnum); + + return [ + get_class($object) . '::' . $object->name + ]; + } +} diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/InternalClassExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/InternalClassExporter.php index 1deb23e61..e0adbd111 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/InternalClassExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/InternalClassExporter.php @@ -25,7 +25,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool /** * {@inheritDoc} */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { $className = $reflectionObject->getName(); diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SerializeExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SerializeExporter.php index 7c826c3ac..604a104ea 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SerializeExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SerializeExporter.php @@ -25,7 +25,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool /** * {@inheritDoc} */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { $lines = $this->getCreateObjectCode($reflectionObject); diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SetStateExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SetStateExporter.php index 4963dd260..a464b992a 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SetStateExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/SetStateExporter.php @@ -31,7 +31,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool /** * {@inheritDoc} */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { $className = $reflectionObject->getName(); diff --git a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/StdClassExporter.php b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/StdClassExporter.php index 52fc0a97c..ac958f18f 100644 --- a/app/vendor/brick/varexporter/src/Internal/ObjectExporter/StdClassExporter.php +++ b/app/vendor/brick/varexporter/src/Internal/ObjectExporter/StdClassExporter.php @@ -24,7 +24,7 @@ public function supports(\ReflectionObject $reflectionObject) : bool /** * {@inheritDoc} */ - public function export($object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array + public function export(object $object, \ReflectionObject $reflectionObject, array $path, array $parentIds) : array { $exported = $this->exporter->exportArray((array) $object, $path, $parentIds); diff --git a/app/vendor/brick/varexporter/src/VarExporter.php b/app/vendor/brick/varexporter/src/VarExporter.php index c2717683f..21d6e4fcd 100644 --- a/app/vendor/brick/varexporter/src/VarExporter.php +++ b/app/vendor/brick/varexporter/src/VarExporter.php @@ -48,10 +48,16 @@ final class VarExporter public const NO_CLOSURES = 1 << 6; /** - * Formats numeric arrays containing only scalar values on a single line. + * Formats lists (0-based numeric arrays) containing only scalar values on a single line. * Types considered scalar here are int, bool, float, string and null. + * This option is a subset of INLINE_ARRAY, and has no effect when INLINE_ARRAY is used. */ - public const INLINE_NUMERIC_SCALAR_ARRAY = 1 << 7; + public const INLINE_SCALAR_LIST = 1 << 7; + + /** + * @deprecated Please use INLINE_SCALAR_LIST instead. + */ + public const INLINE_NUMERIC_SCALAR_ARRAY = self::INLINE_SCALAR_LIST; /** * Export static vars defined via `use` as variables. @@ -63,6 +69,16 @@ final class VarExporter */ public const TRAILING_COMMA_IN_ARRAY = 1 << 9; + /** + * Disallows exporting enums. + */ + public const NO_ENUMS = 1 << 10; + + /** + * Formats all arrays on a single line. + */ + public const INLINE_ARRAY = 1 << 11; + /** * @param mixed $var The variable to export. * @param int $options A bitmask of options. Possible values are `VarExporter::*` constants. diff --git a/app/vendor/cakephp-plugins.php b/app/vendor/cakephp-plugins.php index 114fb5eea..8f0549d56 100644 --- a/app/vendor/cakephp-plugins.php +++ b/app/vendor/cakephp-plugins.php @@ -7,5 +7,6 @@ 'Cake/TwigView' => $baseDir . '/vendor/cakephp/twig-view/', 'DebugKit' => $baseDir . '/vendor/cakephp/debug_kit/', 'Migrations' => $baseDir . '/vendor/cakephp/migrations/', + 'TestWidget' => $baseDir . '/plugins/TestWidget/', ], ]; diff --git a/app/vendor/cakephp/bake/composer.json b/app/vendor/cakephp/bake/composer.json index 96daca727..58ad76d07 100644 --- a/app/vendor/cakephp/bake/composer.json +++ b/app/vendor/cakephp/bake/composer.json @@ -21,7 +21,8 @@ "php": ">=7.2", "cakephp/cakephp": "^4.3.0", "cakephp/twig-view": "^1.0.2", - "brick/varexporter": "^0.3.5" + "brick/varexporter": "^0.3.5", + "nikic/php-parser": "^4.13.2" }, "require-dev": { "cakephp/cakephp-codesniffer": "^4.0", @@ -52,7 +53,7 @@ "cs-check": "phpcs --parallel=16 -p src/ tests/", "cs-fix": "phpcbf --parallel=16 -p src/ tests/", "stan": "phpstan analyse src/ && psalm.phar", - "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^1.5 psalm/phar:~4.22.0 && mv composer.backup composer.json", + "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^1.7 psalm/phar:~4.27.0 && mv composer.backup composer.json", "test": "phpunit", "test-coverage": "phpunit --coverage-clover=clover.xml" }, diff --git a/app/vendor/cakephp/bake/src/CodeGen/ClassBuilder.php b/app/vendor/cakephp/bake/src/CodeGen/ClassBuilder.php new file mode 100644 index 000000000..de9482835 --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/ClassBuilder.php @@ -0,0 +1,89 @@ +parsedClass = $parsedClass; + } + + /** + * Returns the list of implements to add to class. + * + * @param array $generated Implements that are generated + * @return array + */ + public function getImplements(array $generated = []): array + { + return array_unique(array_merge($generated, $this->parsedClass->implements ?? [])); + } + + /** + * Returns the user functions from existing file. + * + * @param array $generated Constants that are generated + * @return array + */ + public function getUserConstants(array $generated = []): array + { + if ($this->parsedClass === null) { + return []; + } + + return array_diff_key($this->parsedClass->constants, array_flip($generated)); + } + + /** + * Returns the user functions from existing file. + * + * @param array $generated Proeprties that are generated + * @return array + */ + public function getUserProperties(array $generated = []): array + { + if ($this->parsedClass === null) { + return []; + } + + return array_diff_key($this->parsedClass->properties, array_flip($generated)); + } + + /** + * Returns the user functions from existing file. + * + * @param array $generated Methods that are generated + * @return array + */ + public function getUserFunctions(array $generated = []): array + { + if ($this->parsedClass === null) { + return []; + } + + return array_diff_key($this->parsedClass->methods, array_flip($generated)); + } +} diff --git a/app/vendor/cakephp/bake/src/CodeGen/CodeParser.php b/app/vendor/cakephp/bake/src/CodeGen/CodeParser.php new file mode 100644 index 000000000..6944c1b1d --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/CodeParser.php @@ -0,0 +1,255 @@ +parser = (new ParserFactory())->create( + ParserFactory::PREFER_PHP7, + new Emulative([ + 'usedAttributes' => ['comments', 'startLine', 'endLine', 'startFilePos', 'endFilePos'], + ]) + ); + $this->traverser = new NodeTraverser(); + $this->traverser->addVisitor($this); + } + + /** + * @param string $code Code to parse + * @return \Bake\CodeGen\ParsedFile|null + * @throws \Bake\CodeGen\ParseException + */ + public function parseFile(string $code): ?ParsedFile + { + $this->fileText = $code; + try { + $this->traverser->traverse($this->parser->parse($code)); + } catch (Error $e) { + throw new ParseException($e->getMessage(), null, $e); + } + + if (!isset($this->parsed['namespace'], $this->parsed['class'])) { + return null; + } + + return new ParsedFile( + $this->parsed['namespace'], + $this->parsed['imports']['class'], + $this->parsed['imports']['function'], + $this->parsed['imports']['const'], + $this->parsed['class'] + ); + } + + /** + * @inheritDoc + */ + public function beforeTraverse(array $nodes) + { + $this->parsed = [ + 'imports' => [ + 'class' => [], + 'function' => [], + 'const' => [], + ], + ]; + + return null; + } + + /** + * @inheritDoc + */ + public function enterNode(Node $node) + { + if ($node instanceof Namespace_) { + if (isset($this->parsed['namespace'])) { + throw new ParseException('Multiple namespaces are not not supported, update your file'); + } + $this->parsed['namespace'] = (string)$node->name; + + return null; + } + + if ($node instanceof Use_) { + if (count($node->uses) > 1) { + throw new ParseException('Multiple use statements per line are not supported, update your file'); + } + + [$alias, $target] = $this->normalizeUse(current($node->uses)); + switch ($node->type) { + case Use_::TYPE_NORMAL: + $this->parsed['imports']['class'][$alias] = $target; + break; + case Use_::TYPE_FUNCTION: + $this->parsed['imports']['function'][$alias] = $target; + break; + case Use_::TYPE_CONSTANT: + $this->parsed['imports']['const'][$alias] = $target; + break; + } + + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } + + if ($node instanceof GroupUse) { + throw new ParseException('Group use statements are not supported, update your file'); + } + + if ($node instanceof Class_) { + if (!isset($this->parsed['namespace'])) { + throw new ParseException('Classes defined in the global namespace is not supported, update your file'); + } + if (isset($this->parsed['class'])) { + throw new ParseException('Multiple classes are not supported, update your file'); + } + + $constants = []; + foreach ($node->getConstants() as $constant) { + if (count($constant->consts) > 1) { + throw new ParseException('Multiple constants per line are not supported, update your file'); + } + + $name = (string)current($constant->consts)->name; + $constants[$name] = $this->getNodeCode($constant); + } + + $properties = []; + foreach ($node->getProperties() as $property) { + if (count($property->props) > 1) { + throw new ParseException('Multiple properties per line are not supported, update your file'); + } + + $name = (string)current($property->props)->name; + $properties[$name] = $this->getNodeCode($property); + } + + $methods = []; + foreach ($node->getMethods() as $method) { + $name = (string)$method->name; + $methods[$name] = $this->getNodeCode($method); + } + + $implements = array_map(function ($name) { + return (string)$name; + }, $node->implements); + + $this->parsed['class'] = new ParsedClass( + (string)$node->name, + $implements, + $constants, + $properties, + $methods + ); + + return NodeTraverser::DONT_TRAVERSE_CHILDREN; + } + + return null; + } + + /** + * @param \PhpParser\NodeAbstract $node Parser node + * @return string + */ + protected function getNodeCode(NodeAbstract $node): string + { + $code = ''; + + $doc = $node->getDocComment() ? $node->getDocComment()->getText() : ''; + if ($doc) { + $code = static::INDENT . $doc . "\n"; + } + + $startPos = $node->getStartFilePos(); + $endPos = $node->getEndFilePos(); + $code .= static::INDENT . substr($this->fileText, $startPos, $endPos - $startPos + 1); + + return $code; + } + + /** + * @param \PhpParser\Node\Stmt\UseUse $use Use node + * @param string|null $prefix Group use prefix + * @return array{string, string} + */ + protected function normalizeUse(UseUse $use, ?string $prefix = null): array + { + $name = (string)$use->name; + if ($prefix) { + $name = $prefix . '\\' . $name; + } + + $alias = $use->alias; + if (!$alias) { + $last = strrpos($name, '\\', -1); + if ($last !== false) { + $alias = substr($name, strrpos($name, '\\', -1) + 1); + } else { + $alias = $name; + } + } + + return [(string)$alias, $name]; + } +} diff --git a/app/vendor/cakephp/bake/src/CodeGen/FileBuilder.php b/app/vendor/cakephp/bake/src/CodeGen/FileBuilder.php new file mode 100644 index 000000000..d3cffa2ce --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/FileBuilder.php @@ -0,0 +1,114 @@ +namespace !== $namespace) { + throw new ParseException(sprintf( + 'Existing namespace `%s` does not match expected namespace `%s`, cannot update existing file', + $parsedFile->namespace, + $namespace + )); + } + + $this->io = $io; + $this->namespace = $namespace; + $this->parsedFile = $parsedFile; + $this->classBuilder = new ClassBuilder($parsedFile->class ?? null); + } + + /** + * Returns the file namespace. + * + * @return string + */ + public function getNamespace(): string + { + return $this->namespace; + } + + /** + * @return \Bake\CodeGen\ClassBuilder + */ + public function classBuilder(): ClassBuilder + { + return $this->classBuilder; + } + + /** + * Returns class imports merged with user imports from file. + * + * @param array $imports Class imports to merge with file imports + * @return array + */ + public function getClassImports(array $imports = []): array + { + return ImportHelper::merge($imports, $this->parsedFile->classImports ?? [], $this->io); + } + + /** + * Returns function imports merged with user imports from file. + * + * @param array $imports Function imports to merge with file imports + * @return array + */ + public function getFunctionImports(array $imports = []): array + { + return ImportHelper::merge($imports, $this->parsedFile->functionImports ?? [], $this->io); + } + + /** + * Returns const imports merged with user imports from file. + * + * @param array $imports Const imports to merge with file imports + * @return array + */ + public function getConstImports(array $imports = []): array + { + return ImportHelper::merge($imports, $this->parsedFile->constImports ?? [], $this->io); + } +} diff --git a/app/vendor/cakephp/bake/src/CodeGen/ImportHelper.php b/app/vendor/cakephp/bake/src/CodeGen/ImportHelper.php new file mode 100644 index 000000000..01b60d349 --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/ImportHelper.php @@ -0,0 +1,88 @@ + name] format. + * + * @param array $imports Imports + * @return array + */ + public static function normalize(array $imports): array + { + $normalized = []; + foreach ($imports as $alias => $class) { + if (is_int($alias)) { + $last = strrpos($class, '\\', -1); + if ($last !== false) { + $alias = substr($class, strrpos($class, '\\', -1) + 1); + } else { + $alias = $class; + } + } + + $normalized[$alias] = $class; + } + + return $normalized; + } + + /** + * Merges imports allowing for duplicates and collisions. + * + * @param array $existing Existing imports to merge into + * @param array $imports Imports to merge into existing + * @param \Cake\Console\ConsoleIo|null $io Used to output warnings on collisions + * @return array + */ + public static function merge(array $existing, array $imports, ?ConsoleIo $io = null): array + { + $existing = static::normalize($existing); + foreach (static::normalize($imports) as $alias => $class) { + if (isset($existing[$alias]) && $existing[$alias] !== $class) { + if ($io) { + $io->warning(sprintf( + 'Import `%s` conflicts with existing import, discarding.', + $class + )); + } + continue; + } + + $existingAlias = array_search($class, $existing, true); + if ($existingAlias !== false && $existingAlias != $alias) { + if ($io) { + $io->warning(sprintf( + 'Import `%s` conflicts with existing import, discarding.', + $class + )); + } + continue; + } + + $existing[$alias] = $class; + } + + asort($existing, SORT_STRING | SORT_FLAG_CASE); + + return $existing; + } +} diff --git a/app/vendor/cakephp/bake/src/CodeGen/ParseException.php b/app/vendor/cakephp/bake/src/CodeGen/ParseException.php new file mode 100644 index 000000000..b910faae1 --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/ParseException.php @@ -0,0 +1,23 @@ + + */ + public $implements; + + /** + * @var array + */ + public $constants; + + /** + * @var array + */ + public $properties; + + /** + * @var array + */ + public $methods; + + /** + * @param string $name Class name + * @param array $implements List of implements + * @param array $constants Class constants + * @param array $properties Class properties + * @param array $methods Class methods + */ + public function __construct(string $name, array $implements, array $constants, array $properties, array $methods) + { + $this->name = $name; + $this->implements = $implements; + $this->constants = $constants; + $this->properties = $properties; + $this->methods = $methods; + } +} diff --git a/app/vendor/cakephp/bake/src/CodeGen/ParsedFile.php b/app/vendor/cakephp/bake/src/CodeGen/ParsedFile.php new file mode 100644 index 000000000..9a096f27e --- /dev/null +++ b/app/vendor/cakephp/bake/src/CodeGen/ParsedFile.php @@ -0,0 +1,69 @@ + + */ + public $classImports; + + /** + * @var array + */ + public $functionImports; + + /** + * @var array + */ + public $constImports; + + /** + * @var \Bake\CodeGen\ParsedClass + */ + public $class; + + /** + * @param string $namespace Namespace + * @param array $classImports Class imports + * @param array $functionImports Function imports + * @param array $constImports Const imports + * @param \Bake\CodeGen\ParsedClass $class Parsed class + */ + public function __construct( + string $namespace, + array $classImports, + array $functionImports, + array $constImports, + ParsedClass $class + ) { + $this->namespace = $namespace; + $this->classImports = $classImports; + $this->functionImports = $functionImports; + $this->constImports = $constImports; + $this->class = $class; + } +} diff --git a/app/vendor/cakephp/bake/src/Command/BakeCommand.php b/app/vendor/cakephp/bake/src/Command/BakeCommand.php index 6ca98b700..903192c0e 100644 --- a/app/vendor/cakephp/bake/src/Command/BakeCommand.php +++ b/app/vendor/cakephp/bake/src/Command/BakeCommand.php @@ -16,12 +16,17 @@ */ namespace Bake\Command; +use Bake\CodeGen\CodeParser; +use Bake\CodeGen\ParsedFile; use Bake\Utility\CommonOptionsTrait; +use Bake\Utility\TemplateRenderer; use Cake\Command\Command; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Core\Configure; use Cake\Core\ConventionsTrait; +use Cake\Event\Event; +use Cake\Event\EventManager; use InvalidArgumentException; /** @@ -150,6 +155,19 @@ public function getTemplatePath(Arguments $args, ?string $container = null): str return str_replace('/', DIRECTORY_SEPARATOR, $path); } + /** + * Creates a new instance of TemplateRenderer with theme set. + * + * @return \Bake\Utility\TemplateRenderer + */ + public function createTemplateRenderer(): TemplateRenderer + { + $renderer = new TemplateRenderer($this->theme); + EventManager::instance()->dispatch(new Event('Bake.renderer', $renderer)); + + return $renderer; + } + /** * Delete empty file in a given path * @@ -179,4 +197,47 @@ protected function isValidColumnName(string $name): bool { return (bool)preg_match('/^[a-zA-Z_][a-zA-Z0-9_]*$/', $name); } + + /** + * Parses a file if it exists. + * + * @param string $path File path + * @return \Bake\CodeGen\ParsedFile|null + */ + protected function parseFile(string $path): ?ParsedFile + { + if (file_exists($path)) { + return (new CodeParser())->parseFile(file_get_contents($path)); + } + + return null; + } + + /** + * Write file contents out to path and prompt user with options with file exists. + * + * @param \Cake\Console\ConsoleIo $io Console io + * @param string $path The path to create the file at + * @param string $contents The contents to put into the file + * @param bool $forceOverwrite Whether the file should be overwritten without prompting the user + * @param bool $skipIfUnchnged Skip writing output if the contents match existing file + * @return bool True if successful, false otherwise + * @throws \Cake\Console\Exception\StopException When `q` is given as an answer + * to whether a file should be overwritten. + */ + protected function writeFile( + ConsoleIo $io, + string $path, + string $contents, + bool $forceOverwrite = false, + bool $skipIfUnchnged = true + ): bool { + if ($skipIfUnchnged && file_exists($path) && file_get_contents($path) === $contents) { + $io->info("Skipping update to `{$path}`. It already exists and would not change."); + + return true; + } + + return $io->createFile($path, $contents, $forceOverwrite); + } } diff --git a/app/vendor/cakephp/bake/src/Command/CellCommand.php b/app/vendor/cakephp/bake/src/Command/CellCommand.php index 962f6dbd4..989a7ddb7 100644 --- a/app/vendor/cakephp/bake/src/Command/CellCommand.php +++ b/app/vendor/cakephp/bake/src/Command/CellCommand.php @@ -107,7 +107,7 @@ protected function bakeTemplate(string $name, Arguments $args, ConsoleIo $io): v $path = $this->getTemplatePath($args, 'cell'); $path .= implode(DS, [$name, 'display.php']); - $io->createFile($path, '', $args->getOption('force')); + $io->createFile($path, '', $this->force); } /** diff --git a/app/vendor/cakephp/bake/src/Command/ControllerCommand.php b/app/vendor/cakephp/bake/src/Command/ControllerCommand.php index d83e43969..954fd3a73 100644 --- a/app/vendor/cakephp/bake/src/Command/ControllerCommand.php +++ b/app/vendor/cakephp/bake/src/Command/ControllerCommand.php @@ -17,7 +17,6 @@ namespace Bake\Command; use Bake\Utility\TableScanner; -use Bake\Utility\TemplateRenderer; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; @@ -177,14 +176,13 @@ public function bakeController(string $controllerName, array $data, Arguments $a 'pluginPath' => null, ]; - $renderer = new TemplateRenderer($this->theme); - $renderer->set($data); - - $contents = $renderer->generate('Bake.Controller/controller'); + $contents = $this->createTemplateRenderer() + ->set($data) + ->generate('Bake.Controller/controller'); $path = $this->getPath($args); $filename = $path . $controllerName . 'Controller.php'; - $io->createFile($filename, $contents, $args->getOption('force')); + $io->createFile($filename, $contents, $this->force); } /** diff --git a/app/vendor/cakephp/bake/src/Command/FixtureCommand.php b/app/vendor/cakephp/bake/src/Command/FixtureCommand.php index 69855d217..5353e0c52 100644 --- a/app/vendor/cakephp/bake/src/Command/FixtureCommand.php +++ b/app/vendor/cakephp/bake/src/Command/FixtureCommand.php @@ -17,13 +17,12 @@ namespace Bake\Command; use Bake\Utility\TableScanner; -use Bake\Utility\TemplateRenderer; use Brick\VarExporter\VarExporter; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Core\Configure; -use Cake\Database\Exception; +use Cake\Database\Exception\DatabaseException; use Cake\Database\Schema\TableSchemaInterface; use Cake\Datasource\ConnectionManager; use Cake\Utility\Inflector; @@ -160,7 +159,7 @@ protected function bake(string $model, string $useTable, Arguments $args, Consol try { $data = $this->readSchema($model, $useTable); - } catch (Exception $e) { + } catch (DatabaseException $e) { $this->getTableLocator()->remove($model); $useTable = Inflector::underscore($model); $table = $useTable; @@ -261,13 +260,13 @@ public function generateFixtureFile(Arguments $args, ConsoleIo $io, string $mode $path = $this->getPath($args); $filename = $vars['name'] . 'Fixture.php'; - $renderer = new TemplateRenderer($args->getOption('theme')); - $renderer->set('model', $model); - $renderer->set($vars); - $content = $renderer->generate('Bake.tests/fixture'); + $contents = $this->createTemplateRenderer() + ->set('model', $model) + ->set($vars) + ->generate('Bake.tests/fixture'); $io->out("\n" . sprintf('Baking test fixture for %s...', $model), 1, ConsoleIo::NORMAL); - $io->createFile($path . $filename, $content, $args->getOption('force')); + $io->createFile($path . $filename, $contents, $this->force); $emptyFile = $path . '.gitkeep'; $this->deleteEmptyFile($emptyFile, $io); } diff --git a/app/vendor/cakephp/bake/src/Command/ModelCommand.php b/app/vendor/cakephp/bake/src/Command/ModelCommand.php index d6a19b7d0..0e7c38603 100644 --- a/app/vendor/cakephp/bake/src/Command/ModelCommand.php +++ b/app/vendor/cakephp/bake/src/Command/ModelCommand.php @@ -16,15 +16,15 @@ */ namespace Bake\Command; +use Bake\CodeGen\FileBuilder; use Bake\Utility\TableScanner; -use Bake\Utility\TemplateRenderer; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Core\Configure; use Cake\Database\Connection; use Cake\Database\Driver\Sqlserver; -use Cake\Database\Exception; +use Cake\Database\Exception\DatabaseException; use Cake\Database\Schema\CachedCollection; use Cake\Database\Schema\TableSchema; use Cake\Database\Schema\TableSchemaInterface; @@ -227,6 +227,7 @@ public function getAssociations(Table $table, Arguments $args, ConsoleIo $io): a $associations = [ 'belongsTo' => [], + 'hasOne' => [], 'hasMany' => [], 'belongsToMany' => [], ]; @@ -242,6 +243,7 @@ public function getAssociations(Table $table, Arguments $args, ConsoleIo $io): a return $associations; } + $associations = $this->findHasOne($table, $associations); $associations = $this->findHasMany($table, $associations); $associations = $this->findBelongsToMany($table, $associations); @@ -346,11 +348,25 @@ public function findBelongsTo(Table $model, array $associations): array ]; } else { $tmpModelName = $this->_modelNameFromKey($fieldName); - if (!in_array(Inflector::tableize($tmpModelName), $this->_tables, true)) { + if (!$this->getTableLocator()->exists($tmpModelName)) { + $this->getTableLocator()->get( + $tmpModelName, + ['connection' => ConnectionManager::get($this->connection)] + ); + } + $associationTable = $this->getTableLocator()->get($tmpModelName); + $this->getTableLocator()->remove($tmpModelName); + $tables = $this->listAll(); + // Check if association model could not be instantiated as a subclass but a generic Table instance instead + if ( + get_class($associationTable) === Table::class && + !in_array(Inflector::tableize($tmpModelName), $tables, true) + ) { $found = $this->findTableReferencedBy($schema, $fieldName); - if ($found) { - $tmpModelName = Inflector::camelize($found); + if (!$found) { + continue; } + $tmpModelName = Inflector::camelize($found); } $assoc = [ 'alias' => $tmpModelName, @@ -406,13 +422,65 @@ public function findTableReferencedBy(TableSchemaInterface $schema, string $keyF } /** - * Find the hasMany relations and add them to associations list + * Checks whether the given source and target table names are sides + * of a possible many-to-many relation. + * + * @param string $sourceTable The source table name. + * @param string $targetTable The target table name. + * @return bool + */ + public function isPossibleBelongsToManyRelation(string $sourceTable, string $targetTable): bool + { + $tables = $this->listAll(); + + $pregTableName = preg_quote($sourceTable, '/'); + $pregPattern = "/^{$pregTableName}_|_{$pregTableName}$/"; + + if (preg_match($pregPattern, $targetTable) === 1) { + $possibleBTMTargetTable = preg_replace($pregPattern, '', $targetTable); + if (in_array($possibleBTMTargetTable, $tables, true)) { + return true; + } + } + + return false; + } + + /** + * Checks whether the given table schema has a unique constraint for + * the given field. + * + * The check is only going to be satisfied if the constraint has + * only this one specific field. Multi-column constraints will not + * match, as they cannot guarantee uniqueness on the given field. + * + * @param \Cake\Database\Schema\TableSchemaInterface $schema The schema to check for the constraint. + * @param string $keyField The field of the constraint. + * @return bool + */ + public function hasUniqueConstraintFor(TableSchemaInterface $schema, string $keyField): bool + { + foreach ($schema->constraints() as $constraint) { + $constraintInfo = $schema->getConstraint($constraint); + if ( + $constraintInfo['type'] === TableSchema::CONSTRAINT_UNIQUE && + $constraintInfo['columns'] === [$keyField] + ) { + return true; + } + } + + return false; + } + + /** + * Find the hasOne relations and add them to associations list * * @param \Cake\ORM\Table $model Model instance being generated * @param array $associations Array of in progress associations - * @return array Associations with hasMany added in. + * @return array Associations with hasOne added in. */ - public function findHasMany(Table $model, array $associations): array + public function findHasOne(Table $model, array $associations): array { $schema = $model->getSchema(); $primaryKey = $schema->getPrimaryKey(); @@ -421,21 +489,67 @@ public function findHasMany(Table $model, array $associations): array $tables = $this->listAll(); foreach ($tables as $otherTableName) { + if ($this->isPossibleBelongsToManyRelation($tableName, $otherTableName)) { + continue; + } + $otherModel = $this->getTableObject($this->_camelize($otherTableName), $otherTableName); $otherSchema = $otherModel->getSchema(); - $pregTableName = preg_quote($tableName, '/'); - $pregPattern = "/^{$pregTableName}_|_{$pregTableName}$/"; - if (preg_match($pregPattern, $otherTableName) === 1) { - $possibleHABTMTargetTable = preg_replace($pregPattern, '', $otherTableName); - if (in_array($possibleHABTMTargetTable, $tables)) { + foreach ($otherSchema->columns() as $fieldName) { + if (!$this->hasUniqueConstraintFor($otherSchema, $fieldName)) { continue; } + + $assoc = false; + if (!in_array($fieldName, $primaryKey) && $fieldName === $foreignKey) { + $assoc = [ + 'alias' => $otherModel->getAlias(), + 'foreignKey' => $fieldName, + ]; + } + if ($assoc && $this->plugin) { + $assoc['className'] = $this->plugin . '.' . $assoc['alias']; + } + if ($assoc) { + $associations['hasOne'][] = $assoc; + } + } + } + + return $associations; + } + + /** + * Find the hasMany relations and add them to associations list + * + * @param \Cake\ORM\Table $model Model instance being generated + * @param array $associations Array of in progress associations + * @return array Associations with hasMany added in. + */ + public function findHasMany(Table $model, array $associations): array + { + $schema = $model->getSchema(); + $primaryKey = $schema->getPrimaryKey(); + $tableName = $schema->name(); + $foreignKey = $this->_modelKey($tableName); + + $tables = $this->listAll(); + foreach ($tables as $otherTableName) { + if ($this->isPossibleBelongsToManyRelation($tableName, $otherTableName)) { + continue; } + $otherModel = $this->getTableObject($this->_camelize($otherTableName), $otherTableName); + $otherSchema = $otherModel->getSchema(); + foreach ($otherSchema->columns() as $fieldName) { $assoc = false; - if (!in_array($fieldName, $primaryKey) && $fieldName === $foreignKey) { + if ( + !in_array($fieldName, $primaryKey) && + $fieldName === $foreignKey && + !$this->hasUniqueConstraintFor($otherSchema, $fieldName) + ) { $assoc = [ 'alias' => $otherModel->getAlias(), 'foreignKey' => $fieldName, @@ -683,12 +797,19 @@ public function getValidation(Table $model, array $associations, Arguments $args $validate = []; $primaryKey = $schema->getPrimaryKey(); + $foreignKeys = []; + if (isset($associations['belongsTo'])) { + foreach ($associations['belongsTo'] as $assoc) { + $foreignKeys[] = $assoc['foreignKey']; + } + } foreach ($fields as $fieldName) { // Skip primary key if (in_array($fieldName, $primaryKey, true)) { continue; } $field = $schema->getColumn($fieldName); + $field['isForeignKey'] = in_array($fieldName, $foreignKeys, true); $validation = $this->fieldValidation($schema, $fieldName, $field, $primaryKey); if ($validation) { $validate[$fieldName] = $validation; @@ -776,7 +897,8 @@ public function fieldValidation( 'args' => [], ]; } else { - if ($metaData['default'] === null || $metaData['default'] === false) { + // FKs shouldn't be required on create to allow e.g. save calls with hasMany associations to create entities + if (($metaData['default'] === null || $metaData['default'] === false) && !$metaData['isForeignKey']) { $validation['requirePresence'] = [ 'rule' => 'requirePresence', 'args' => ['create'], @@ -956,7 +1078,7 @@ public function getCounterCache(Table $model): array try { $otherSchema = $otherModel->getSchema(); - } catch (Exception $e) { + } catch (DatabaseException $e) { continue; } @@ -985,7 +1107,9 @@ public function bakeEntity(Table $model, array $data, Arguments $args, ConsoleIo if ($args->getOption('no-entity')) { return; } + $name = $this->_entityName($model->getAlias()); + $io->out("\n" . sprintf('Baking entity class for %s...', $name), 1, ConsoleIo::NORMAL); $namespace = Configure::read('App.namespace'); $pluginPath = ''; @@ -994,22 +1118,28 @@ public function bakeEntity(Table $model, array $data, Arguments $args, ConsoleIo $pluginPath = $this->plugin . '.'; } + $path = $this->getPath($args); + $filename = $path . 'Entity' . DS . $name . '.php'; + + $parsedFile = null; + if ($args->getOption('update')) { + $parsedFile = $this->parseFile($filename); + } + $data += [ 'name' => $name, 'namespace' => $namespace, 'plugin' => $this->plugin, 'pluginPath' => $pluginPath, 'primaryKey' => [], + 'fileBuilder' => new FileBuilder($io, "{$namespace}\Model\Entity", $parsedFile), ]; - $renderer = new TemplateRenderer($this->theme); - $renderer->set($data); - $out = $renderer->generate('Bake.Model/entity'); + $contents = $this->createTemplateRenderer() + ->set($data) + ->generate('Bake.Model/entity'); - $path = $this->getPath($args); - $filename = $path . 'Entity' . DS . $name . '.php'; - $io->out("\n" . sprintf('Baking entity class for %s...', $name), 1, ConsoleIo::NORMAL); - $io->createFile($filename, $out, $args->getOption('force')); + $this->writeFile($io, $filename, $contents, $this->force); $emptyFile = $path . 'Entity' . DS . '.gitkeep'; $this->deleteEmptyFile($emptyFile, $io); @@ -1030,13 +1160,23 @@ public function bakeTable(Table $model, array $data, Arguments $args, ConsoleIo return; } + $name = $model->getAlias(); + $io->out("\n" . sprintf('Baking table class for %s...', $name), 1, ConsoleIo::NORMAL); + $namespace = Configure::read('App.namespace'); $pluginPath = ''; if ($this->plugin) { $namespace = $this->_pluginNamespace($this->plugin); } - $name = $model->getAlias(); + $path = $this->getPath($args); + $filename = $path . 'Table' . DS . $name . 'Table.php'; + + $parsedFile = null; + if ($args->getOption('update')) { + $parsedFile = $this->parseFile($filename); + } + $entity = $this->_entityName($model->getAlias()); $data += [ 'plugin' => $this->plugin, @@ -1052,16 +1192,14 @@ public function bakeTable(Table $model, array $data, Arguments $args, ConsoleIo 'rulesChecker' => [], 'behaviors' => [], 'connection' => $this->connection, + 'fileBuilder' => new FileBuilder($io, "{$namespace}\Model\Table", $parsedFile), ]; - $renderer = new TemplateRenderer($this->theme); - $renderer->set($data); - $out = $renderer->generate('Bake.Model/table'); + $contents = $this->createTemplateRenderer() + ->set($data) + ->generate('Bake.Model/table'); - $path = $this->getPath($args); - $filename = $path . 'Table' . DS . $name . 'Table.php'; - $io->out("\n" . sprintf('Baking table class for %s...', $name), 1, ConsoleIo::NORMAL); - $io->createFile($filename, $out, $args->getOption('force')); + $this->writefile($io, $filename, $contents, $this->force); // Work around composer caching that classes/files do not exist. // Check for the file as it might not exist in tests. @@ -1140,6 +1278,9 @@ public function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionPar )->addArgument('name', [ 'help' => 'Name of the model to bake (without the Table suffix). ' . 'You can use Plugin.name to bake plugin models.', + ])->addOption('update', [ + 'boolean' => true, + 'help' => 'Update generated methods in existing files. If the file doesn\'t exist it will be created.', ])->addOption('table', [ 'help' => 'The table name to use if you have non-conventional table names.', ])->addOption('no-entity', [ diff --git a/app/vendor/cakephp/bake/src/Command/PluginCommand.php b/app/vendor/cakephp/bake/src/Command/PluginCommand.php index 2479e1068..aa9f8103e 100644 --- a/app/vendor/cakephp/bake/src/Command/PluginCommand.php +++ b/app/vendor/cakephp/bake/src/Command/PluginCommand.php @@ -174,17 +174,18 @@ protected function _generateFiles( true ); - $renderer = new TemplateRenderer($args->getOption('theme')); - $renderer->set([ - 'package' => $package, - 'namespace' => $namespace, - 'baseNamespace' => $baseNamespace, - 'plugin' => $pluginName, - 'routePath' => Inflector::dasherize($pluginName), - 'path' => $path, - 'root' => ROOT, - 'cakeVersion' => $composerConfig['require']['cakephp/cakephp'], - ]); + $renderer = $this->createTemplateRenderer() + ->set([ + 'name' => $name, + 'package' => $package, + 'namespace' => $namespace, + 'baseNamespace' => $baseNamespace, + 'plugin' => $pluginName, + 'routePath' => Inflector::dasherize($pluginName), + 'path' => $path, + 'root' => ROOT, + 'cakeVersion' => $composerConfig['require']['cakephp/cakephp'], + ]); $root = $path . $pluginName . DS; @@ -202,7 +203,7 @@ protected function _generateFiles( $templatesPath = array_shift($paths) . BakeView::BAKE_TEMPLATE_FOLDER . '/Plugin'; if (is_dir($templatesPath)) { $templates = array_keys(iterator_to_array( - $fs->findRecursive($templatesPath, '/.*\.(twig|php)/') + $fs->findRecursive($templatesPath, '/\.twig$/') )); } } while (!$templates); @@ -211,7 +212,11 @@ protected function _generateFiles( foreach ($templates as $template) { $template = substr($template, strrpos($template, 'Plugin' . DIRECTORY_SEPARATOR) + 7, -4); $template = rtrim($template, '.'); - $this->_generateFile($renderer, $template, $root, $io); + $filename = $template; + if ($filename === 'src/Plugin.php') { + $filename = 'src/' . $name . 'Plugin.php'; + } + $this->_generateFile($renderer, $template, $root, $filename, $io); } } @@ -221,6 +226,7 @@ protected function _generateFiles( * @param \Bake\Utility\TemplateRenderer $renderer The renderer to use. * @param string $template The template to render * @param string $root The path to the plugin's root + * @param string $filename Filename to generate. * @param \Cake\Console\ConsoleIo $io The io instance. * @return void */ @@ -228,11 +234,12 @@ protected function _generateFile( TemplateRenderer $renderer, string $template, string $root, + string $filename, ConsoleIo $io ): void { $io->out(sprintf('Generating %s file...', $template)); $out = $renderer->generate('Bake.Plugin/' . $template); - $io->createFile($root . $template, $out); + $io->createFile($root . $filename, $out); } /** @@ -270,7 +277,7 @@ protected function _modifyAutoloader( $io->out('Modifying composer autoloader'); $out = json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . "\n"; - $io->createFile($file, $out, (bool)$args->getOption('force')); + $io->createFile($file, $out, $this->force); $composer = $this->findComposer($args, $io); diff --git a/app/vendor/cakephp/bake/src/Command/SimpleBakeCommand.php b/app/vendor/cakephp/bake/src/Command/SimpleBakeCommand.php index b48aa4a3a..8e114c149 100644 --- a/app/vendor/cakephp/bake/src/Command/SimpleBakeCommand.php +++ b/app/vendor/cakephp/bake/src/Command/SimpleBakeCommand.php @@ -16,7 +16,6 @@ */ namespace Bake\Command; -use Bake\Utility\TemplateRenderer; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; @@ -100,13 +99,13 @@ public function execute(Arguments $args, ConsoleIo $io): ?int */ protected function bake(string $name, Arguments $args, ConsoleIo $io): void { - $renderer = new TemplateRenderer($args->getOption('theme')); - $renderer->set('name', $name); - $renderer->set($this->templateData($args)); - $contents = $renderer->generate($this->template()); + $contents = $this->createTemplateRenderer() + ->set('name', $name) + ->set($this->templateData($args)) + ->generate($this->template()); $filename = $this->getPath($args) . $this->fileName($name); - $io->createFile($filename, $contents, (bool)$args->getOption('force')); + $io->createFile($filename, $contents, $this->force); $emptyFile = $this->getPath($args) . '.gitkeep'; $this->deleteEmptyFile($emptyFile, $io); diff --git a/app/vendor/cakephp/bake/src/Command/TemplateCommand.php b/app/vendor/cakephp/bake/src/Command/TemplateCommand.php index 4b8ea3629..8a4e3de0c 100644 --- a/app/vendor/cakephp/bake/src/Command/TemplateCommand.php +++ b/app/vendor/cakephp/bake/src/Command/TemplateCommand.php @@ -18,7 +18,6 @@ use Bake\Utility\Model\AssociationFilter; use Bake\Utility\TableScanner; -use Bake\Utility\TemplateRenderer; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; @@ -85,6 +84,13 @@ class TemplateCommand extends BakeCommand */ public $path; + /** + * Output extension + * + * @var string + */ + public $ext = 'php'; + /** * Override initialize * @@ -351,15 +357,16 @@ public function bake( $content = $this->getContent($args, $io, $template); } if (empty($content)) { - $io->err("No generated content for '{$template}.php', not generating template."); + // phpcs:ignore Generic.Files.LineLength + $io->err("No generated content for '{$template}.{$this->ext}', not generating template."); return; } $path = $this->getTemplatePath($args); - $filename = $path . Inflector::underscore($outputFile) . '.php'; + $filename = $path . Inflector::underscore($outputFile) . '.' . $this->ext; $io->out("\n" . sprintf('Baking `%s` view template file...', $outputFile), 1, ConsoleIo::NORMAL); - $io->createFile($filename, $content, $args->getOption('force')); + $io->createFile($filename, $content, $this->force); } /** @@ -386,10 +393,10 @@ public function getContent(Arguments $args, ConsoleIo $io, string $action, ?arra $vars['fields'] = array_diff($vars['fields'], $vars['hidden']); } - $renderer = new TemplateRenderer($args->getOption('theme')); - $renderer->set('action', $action); - $renderer->set('plugin', $this->plugin); - $renderer->set($vars); + $renderer = $this->createTemplateRenderer() + ->set('action', $action) + ->set('plugin', $this->plugin) + ->set($vars); $indexColumns = 0; if ($action === 'index' && $args->getOption('index-columns') !== null) { diff --git a/app/vendor/cakephp/bake/src/Command/TestCommand.php b/app/vendor/cakephp/bake/src/Command/TestCommand.php index 6158ec9b7..7df61a610 100644 --- a/app/vendor/cakephp/bake/src/Command/TestCommand.php +++ b/app/vendor/cakephp/bake/src/Command/TestCommand.php @@ -16,14 +16,13 @@ */ namespace Bake\Command; -use Bake\Utility\TemplateRenderer; use Cake\Console\Arguments; use Cake\Console\ConsoleIo; use Cake\Console\ConsoleOptionParser; use Cake\Console\Shell; use Cake\Controller\Controller; use Cake\Core\Configure; -use Cake\Core\Exception\Exception; +use Cake\Core\Exception\CakeException; use Cake\Core\Plugin; use Cake\Filesystem\Filesystem; use Cake\Http\Response; @@ -279,32 +278,32 @@ public function bake(string $type, string $className, Arguments $args, ConsoleIo $io->out("\n" . sprintf('Baking test case for %s ...', $fullClassName), 1, Shell::QUIET); - $renderer = new TemplateRenderer($this->theme); - $renderer->set('fixtures', $this->_fixtures); - $renderer->set('plugin', $this->plugin); - $renderer->set(compact( - 'subject', - 'className', - 'properties', - 'methods', - 'type', - 'fullClassName', - 'mock', - 'preConstruct', - 'postConstruct', - 'construction', - 'uses', - 'baseNamespace', - 'subNamespace', - 'namespace' - )); - $out = $renderer->generate('Bake.tests/test_case'); + $contents = $this->createTemplateRenderer() + ->set('fixtures', $this->_fixtures) + ->set('plugin', $this->plugin) + ->set(compact( + 'subject', + 'className', + 'properties', + 'methods', + 'type', + 'fullClassName', + 'mock', + 'preConstruct', + 'postConstruct', + 'construction', + 'uses', + 'baseNamespace', + 'subNamespace', + 'namespace' + )) + ->generate('Bake.tests/test_case'); $filename = $this->testCaseFileName($type, $fullClassName); $emptyFile = dirname($filename) . DS . '.gitkeep'; $this->deleteEmptyFile($emptyFile, $io); - if ($io->createFile($filename, $out, $args->getOption('force'))) { - return $out; + if ($io->createFile($filename, $contents, $this->force)) { + return $contents; } return false; @@ -399,12 +398,12 @@ public function getSubspacePath(string $type): string * * @param string $type The type of thing having a test generated. * @return string - * @throws \Cake\Core\Exception\Exception When invalid object types are requested. + * @throws \Cake\Core\Exception\CakeException When invalid object types are requested. */ public function mapType(string $type): string { if (empty($this->classTypes[$type])) { - throw new Exception('Invalid object type: ' . $type); + throw new CakeException('Invalid object type: ' . $type); } return $this->classTypes[$type]; diff --git a/app/vendor/cakephp/bake/src/Utility/CommonOptionsTrait.php b/app/vendor/cakephp/bake/src/Utility/CommonOptionsTrait.php index 2ec2d448d..4d4b080ad 100644 --- a/app/vendor/cakephp/bake/src/Utility/CommonOptionsTrait.php +++ b/app/vendor/cakephp/bake/src/Utility/CommonOptionsTrait.php @@ -31,7 +31,7 @@ trait CommonOptionsTrait { /** - * @var string|null + * @var string */ public $plugin; @@ -45,6 +45,11 @@ trait CommonOptionsTrait */ public $connection; + /** + * @var bool + */ + public $force = false; + /** * Pull common/frequently used arguments & options into properties * so that method signatures can be simpler. @@ -70,6 +75,7 @@ protected function extractCommonProperties(Arguments $args): void $this->theme = $args->getOption('theme'); $this->connection = $args->getOption('connection'); + $this->force = $args->getOption('force'); } /** @@ -105,6 +111,7 @@ protected function _setCommonOptions(ConsoleOptionParser $parser): ConsoleOption ])->addOption('force', [ 'short' => 'f', 'boolean' => true, + 'default' => 'false', 'help' => 'Force overwriting existing files without prompting.', ])->addOption('connection', [ 'short' => 'c', diff --git a/app/vendor/cakephp/bake/src/Utility/TemplateRenderer.php b/app/vendor/cakephp/bake/src/Utility/TemplateRenderer.php index bffec7ae2..10abc01ef 100644 --- a/app/vendor/cakephp/bake/src/Utility/TemplateRenderer.php +++ b/app/vendor/cakephp/bake/src/Utility/TemplateRenderer.php @@ -42,7 +42,7 @@ class TemplateRenderer /** * Template theme * - * @var string + * @var string|null */ protected $theme; @@ -51,9 +51,9 @@ class TemplateRenderer * * @param ?string $theme The template theme/plugin to use. */ - public function __construct(?string $theme = '') + public function __construct(?string $theme = null) { - $this->theme = $theme ?? ''; + $this->theme = $theme; } /** diff --git a/app/vendor/cakephp/bake/src/View/BakeView.php b/app/vendor/cakephp/bake/src/View/BakeView.php index b359c5e14..2700cb679 100644 --- a/app/vendor/cakephp/bake/src/View/BakeView.php +++ b/app/vendor/cakephp/bake/src/View/BakeView.php @@ -45,8 +45,9 @@ class BakeView extends TwigView public function initialize(): void { $this->setConfig('environment', [ - 'cache' => false, - 'strict_variables' => Configure::read('Bake.twigStrictVariables', false), + 'autoescape' => false, + 'cache' => false, + 'strict_variables' => Configure::read('Bake.twigStrictVariables', false), ]); parent::initialize(); @@ -69,7 +70,7 @@ public function initialize(): void * * @param string|null $template Name of view file to use, or a template string to render * @param string|false|null $layout Layout to use. Not used, for consistency with other views only - * @throws \Cake\Core\Exception\Exception If there is an error in the view. + * @throws \Cake\Core\Exception\CakeException If there is an error in the view. * @return string Rendered content. */ public function render(?string $template = null, $layout = null): string diff --git a/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php b/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php index 07ab0965a..8dc0d899f 100644 --- a/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php +++ b/app/vendor/cakephp/bake/src/View/Helper/BakeHelper.php @@ -3,6 +3,7 @@ namespace Bake\View\Helper; +use Bake\CodeGen\ImportHelper; use Bake\Utility\Model\AssociationFilter; use Brick\VarExporter\VarExporter; use Cake\Core\Configure; @@ -456,6 +457,115 @@ public function escapeArguments(array $args): array }, $args); } + /** + * Generates block of use statements from imports. + * + * @param array $imports Class imports + * @return string + */ + public function getClassUses(array $imports): string + { + $uses = []; + + $imports = ImportHelper::normalize($imports); + asort($imports, SORT_STRING | SORT_FLAG_CASE); + foreach ($imports as $alias => $type) { + $uses[] = 'use ' . $this->getUseType($alias, $type) . ';'; + } + + return implode("\n", $uses); + } + + /** + * Generates block of suse statements from function imports. + * + * @param array $imports Function imports + * @return string + */ + public function getFunctionUses(array $imports): string + { + $uses = []; + + $imports = ImportHelper::normalize($imports); + asort($imports, SORT_STRING | SORT_FLAG_CASE); + foreach ($imports as $alias => $type) { + $uses[] = 'use function ' . $this->getUseType($alias, $type) . ';'; + } + + return implode("\n", $uses); + } + + /** + * Generates block of use statements from const imports. + * + * @param array $imports constImports + * @return string + */ + public function getConstUses(array $imports): string + { + $uses = []; + + $imports = ImportHelper::normalize($imports); + asort($imports, SORT_STRING | SORT_FLAG_CASE); + foreach ($imports as $alias => $type) { + $uses[] = 'use const ' . $this->getUseType($alias, $type) . ';'; + } + + return implode("\n", $uses); + } + + /** + * Gets use type string from name and alias. + * + * @param string $alias Import alias + * @param string $name Import name + * @return string + */ + protected function getUseType(string $alias, string $name): string + { + if ($name == $alias || substr($name, -strlen("\\{$alias}")) === "\\{$alias}") { + return $name; + } + + return "{$name} as {$alias}"; + } + + /** + * Concats strings together. + * + * @param string $delimiter Delimiter to separate strings + * @param array|string> $strings Strings to concatenate + * @param string $prefix Code to prepend if final output is not empty + * @param string $suffix Code to append if final output is not empty + * @return string + */ + public function concat( + string $delimiter, + array $strings, + string $prefix = '', + string $suffix = '' + ): string { + $output = implode( + $delimiter, + array_map(function ($string) use ($delimiter) { + if (is_string($string)) { + return $string; + } + + return implode($delimiter, array_filter($string)); + }, array_filter($strings)) + ); + + if ($prefix && !empty($output)) { + $output = $prefix . $output; + } + if ($suffix && !empty($output)) { + $output .= $suffix; + } + + return $output; + } + /** * To be mocked elsewhere... * diff --git a/app/vendor/cakephp/bake/templates/bake/Command/command.twig b/app/vendor/cakephp/bake/templates/bake/Command/command.twig index e1c7c91e5..9eeafa29e 100644 --- a/app/vendor/cakephp/bake/templates/bake/Command/command.twig +++ b/app/vendor/cakephp/bake/templates/bake/Command/command.twig @@ -13,15 +13,15 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ #} - - + diff --git a/app/vendor/cakephp/bake/templates/bake/Plugin/src/Controller/AppController.php.twig b/app/vendor/cakephp/bake/templates/bake/Plugin/src/Controller/AppController.php.twig index dcdc78cde..c03c62bb0 100644 --- a/app/vendor/cakephp/bake/templates/bake/Plugin/src/Controller/AppController.php.twig +++ b/app/vendor/cakephp/bake/templates/bake/Plugin/src/Controller/AppController.php.twig @@ -13,12 +13,12 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ #} -loadSqlFiles('tests/schema.sql', 'test'); diff --git a/app/vendor/cakephp/bake/templates/bake/Shell/helper.twig b/app/vendor/cakephp/bake/templates/bake/Shell/helper.twig index 171b4cfa8..d52832442 100644 --- a/app/vendor/cakephp/bake/templates/bake/Shell/helper.twig +++ b/app/vendor/cakephp/bake/templates/bake/Shell/helper.twig @@ -13,12 +13,12 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ #} - ${{ pluralVar }} */ ?>
diff --git a/app/vendor/cakephp/bake/templates/bake/View/cell.twig b/app/vendor/cakephp/bake/templates/bake/View/cell.twig index 6ba66be8c..8f0a8acd4 100644 --- a/app/vendor/cakephp/bake/templates/bake/View/cell.twig +++ b/app/vendor/cakephp/bake/templates/bake/View/cell.twig @@ -13,12 +13,12 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ #} - ['primary' => ['type' => 'primary', 'columns' => ['id']]], ], + [ + 'table' => 'todo_reminders', + 'columns' => [ + 'id' => ['type' => 'integer', 'null' => false], + 'todo_item_id' => ['type' => 'integer', 'null' => false], + 'triggered_at' => ['type' => 'datetime'], + ], + 'constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + 'unique_todo_item' => ['type' => 'unique', 'columns' => ['todo_item_id']], + ], + ], [ 'table' => 'todo_labels', 'columns' => [ @@ -511,4 +523,15 @@ ], ], ], + [ + 'table' => 'self_referencing_unique_keys', + 'columns' => [ + 'id' => ['type' => 'integer'], + 'parent_id' => ['type' => 'integer'], + ], + 'constraints' => [ + 'primary' => ['type' => 'primary', 'columns' => ['id']], + 'unique_self_referencing_parent' => ['type' => 'unique', 'columns' => ['parent_id']], + ], + ], ]; diff --git a/app/vendor/cakephp/cakephp-codesniffer/.github/workflows/ci.yml b/app/vendor/cakephp/cakephp-codesniffer/.github/workflows/ci.yml index f3149de54..a9c5b62b7 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/.github/workflows/ci.yml +++ b/app/vendor/cakephp/cakephp-codesniffer/.github/workflows/ci.yml @@ -54,9 +54,9 @@ jobs: composer install fi - - name: Configure PHPUnit matcher + - name: Setup problem matchers for PHPUnit if: matrix.php-version == '7.4' - uses: mheap/phpunit-matcher-action@master + run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - name: Run PHPUnit run: | diff --git a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/ruleset.xml b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/ruleset.xml index b85444eba..543481aa8 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/CakePHP/ruleset.xml +++ b/app/vendor/cakephp/cakephp-codesniffer/CakePHP/ruleset.xml @@ -23,6 +23,7 @@ */config/Migrations/* + */config/Seeds/* */config/* diff --git a/app/vendor/cakephp/cakephp-codesniffer/composer.json b/app/vendor/cakephp/cakephp-codesniffer/composer.json index 2fd121bee..bb1e9380f 100644 --- a/app/vendor/cakephp/cakephp-codesniffer/composer.json +++ b/app/vendor/cakephp/cakephp-codesniffer/composer.json @@ -19,7 +19,7 @@ }, "require": { "php": ">=7.2.0", - "slevomat/coding-standard": "^6.3.6 || ^7.0", + "slevomat/coding-standard": "^6.3.6 || ^7.0 || ^8.0", "squizlabs/php_codesniffer": "^3.6" }, "require-dev": { @@ -30,6 +30,11 @@ "CakePHP\\": "CakePHP/" } }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + }, "scripts": { "add-standard" : "phpcs --config-set installed_paths $(pwd)", "test": [ diff --git a/app/vendor/cakephp/cakephp/README.md b/app/vendor/cakephp/cakephp/README.md index 9cb846bb1..97ddeb14b 100644 --- a/app/vendor/cakephp/cakephp/README.md +++ b/app/vendor/cakephp/cakephp/README.md @@ -7,9 +7,6 @@ Software License - - Build Status - Coverage Status @@ -69,7 +66,7 @@ tests for CakePHP by doing the following: ## Get Support! -* [Slack](https://cakesf.herokuapp.com/) - Join us on Slack. +* [Slack](https://slack-invite.cakephp.org/) - Join us on Slack. * [Discord](https://discord.gg/k4trEMPebj) - Join us on Discord. * [#cakephp](https://webchat.freenode.net/?channels=#cakephp) on irc.freenode.net - Come chat with us, we have cake. * [Forum](https://discourse.cakephp.org/) - Official CakePHP forum. diff --git a/app/vendor/cakephp/cakephp/VERSION.txt b/app/vendor/cakephp/cakephp/VERSION.txt index 43155def3..320e64024 100644 --- a/app/vendor/cakephp/cakephp/VERSION.txt +++ b/app/vendor/cakephp/cakephp/VERSION.txt @@ -16,4 +16,4 @@ // @license https://opensource.org/licenses/mit-license.php MIT License // +--------------------------------------------------------------------------------------------+ // //////////////////////////////////////////////////////////////////////////////////////////////////// -4.3.9 +4.4.11 diff --git a/app/vendor/cakephp/cakephp/composer.json b/app/vendor/cakephp/cakephp/composer.json index ba3abe71e..39f7d6672 100644 --- a/app/vendor/cakephp/cakephp/composer.json +++ b/app/vendor/cakephp/cakephp/composer.json @@ -22,14 +22,14 @@ } ], "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "ext-intl": "*", "ext-json": "*", "ext-mbstring": "*", "cakephp/chronos": "^2.2", "composer/ca-bundle": "^1.2", "laminas/laminas-diactoros": "^2.2.2", - "laminas/laminas-httphandlerrunner": "^1.1", + "laminas/laminas-httphandlerrunner": "^1.1 || ^2.0", "league/container": "^4.2.0", "psr/container": "^1.1 || ^2.0", "psr/http-client": "^1.0", @@ -97,7 +97,7 @@ "TestPluginTwo\\": "tests/test_app/Plugin/TestPluginTwo/src/", "Company\\TestPluginThree\\": "tests/test_app/Plugin/Company/TestPluginThree/src/", "Company\\TestPluginThree\\Test\\": "tests/test_app/Plugin/Company/TestPluginThree/tests/", - "ParentPlugin\\": "tests/test_app/Plugin/ParentPlugin/src/" + "Named\\": "tests/test_app/Plugin/Named/src/" } }, "scripts": { @@ -107,15 +107,15 @@ ], "cs-check": "phpcs --colors --parallel=16 -p src/ tests/", "cs-fix": "phpcbf --colors --parallel=16 -p src/ tests/", - "phpstan": "phpstan.phar analyse", - "psalm": "psalm.phar --show-info=false", + "phpstan": "tools/phpstan analyse", + "psalm": "tools/psalm --show-info=false", "stan": [ "@phpstan", "@psalm" ], "stan-tests": "phpstan.phar analyze -c tests/phpstan.neon", "stan-baseline": "phpstan.phar --generate-baseline", - "stan-setup": "cp composer.json composer.backup && composer require --dev symfony/polyfill-php81 phpstan/phpstan:~1.6.0 psalm/phar:~4.22.0 && mv composer.backup composer.json", + "stan-setup": "phive install", "lowest": "validate-prefer-lowest", "lowest-setup": "composer update --prefer-lowest --prefer-stable --prefer-dist --no-interaction && cp composer.json composer.backup && composer require --dev dereuromark/composer-prefer-lowest && mv composer.backup composer.json", "test": "phpunit", diff --git a/app/vendor/cakephp/cakephp/config/bootstrap.php b/app/vendor/cakephp/cakephp/config/bootstrap.php index 47b2d402d..da48e6bff 100644 --- a/app/vendor/cakephp/cakephp/config/bootstrap.php +++ b/app/vendor/cakephp/cakephp/config/bootstrap.php @@ -18,7 +18,7 @@ /** * @var float */ -define('TIME_START', (float)microtime(true)); +define('TIME_START', microtime(true)); require CAKE . 'basics.php'; diff --git a/app/vendor/cakephp/cakephp/src/Cache/CacheEngine.php b/app/vendor/cakephp/cakephp/src/Cache/CacheEngine.php index ed01098e3..da5bcc719 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/CacheEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/CacheEngine.php @@ -18,6 +18,7 @@ use Cake\Core\InstanceConfigTrait; use DateInterval; +use DateTime; use Psr\SimpleCache\CacheInterface; /** @@ -383,7 +384,9 @@ protected function duration($ttl): int return $ttl; } if ($ttl instanceof DateInterval) { - return (int)$ttl->format('%s'); + return (int)DateTime::createFromFormat('U', '0') + ->add($ttl) + ->format('U'); } throw new InvalidArgumentException('TTL values must be one of null, int, \DateInterval'); diff --git a/app/vendor/cakephp/cakephp/src/Cache/Engine/ArrayEngine.php b/app/vendor/cakephp/cakephp/src/Cache/Engine/ArrayEngine.php index 9050537eb..4693c0242 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/Engine/ArrayEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/Engine/ArrayEngine.php @@ -35,7 +35,7 @@ class ArrayEngine extends CacheEngine * * Structured as [key => [exp => expiration, val => value]] * - * @var array + * @var array */ protected $data = []; diff --git a/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php b/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php index 46a7f187a..35252b98e 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/Engine/FileEngine.php @@ -17,7 +17,6 @@ namespace Cake\Cache\Engine; use Cake\Cache\CacheEngine; -use Cake\Cache\InvalidArgumentException; use CallbackFilterIterator; use Exception; use FilesystemIterator; @@ -173,6 +172,7 @@ public function get($key, $default = null) /** @psalm-suppress PossiblyNullReference */ $this->_File->rewind(); $time = time(); + /** @psalm-suppress RiskyCast */ $cachetime = (int)$this->_File->current(); if ($cachetime < $time) { @@ -441,14 +441,7 @@ protected function _key($key): string { $key = parent::_key($key); - if (preg_match('/[\/\\<>?:|*"]/', $key)) { - throw new InvalidArgumentException( - "Cache key `{$key}` contains invalid characters. " . - 'You cannot use /, \\, <, >, ?, :, |, *, or " in cache keys.' - ); - } - - return $key; + return rawurlencode($key); } /** diff --git a/app/vendor/cakephp/cakephp/src/Cache/Engine/RedisEngine.php b/app/vendor/cakephp/cakephp/src/Cache/Engine/RedisEngine.php index b7f0fec4b..dc90ef72f 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/Engine/RedisEngine.php +++ b/app/vendor/cakephp/cakephp/src/Cache/Engine/RedisEngine.php @@ -47,6 +47,7 @@ class RedisEngine extends CacheEngine * - `port` port number to the Redis server. * - `prefix` Prefix appended to all entries. Good for when you need to share a keyspace * with either another cache config or another application. + * - `scanCount` Number of keys to ask for each scan (default: 10) * - `server` URL or IP to the Redis server host. * - `timeout` timeout in seconds (float). * - `unix_socket` Path to the unix socket file (default: false) @@ -65,6 +66,7 @@ class RedisEngine extends CacheEngine 'server' => '127.0.0.1', 'timeout' => 0, 'unix_socket' => false, + 'scanCount' => 10, ]; /** @@ -227,6 +229,21 @@ public function delete($key): bool return $this->_Redis->del($key) > 0; } + /** + * Delete a key from the cache asynchronously + * + * Just unlink a key from the cache. The actual removal will happen later asynchronously. + * + * @param string $key Identifier for the data + * @return bool True if the value was successfully deleted, false if it didn't exist or couldn't be removed + */ + public function deleteAsync(string $key): bool + { + $key = $this->_key($key); + + return $this->_Redis->unlink($key) > 0; + } + /** * Delete all keys from the cache * @@ -241,7 +258,7 @@ public function clear(): bool $pattern = $this->_config['prefix'] . '*'; while (true) { - $keys = $this->_Redis->scan($iterator, $pattern); + $keys = $this->_Redis->scan($iterator, $pattern, (int)$this->_config['scanCount']); if ($keys === false) { break; @@ -256,6 +273,37 @@ public function clear(): bool return $isAllDeleted; } + /** + * Delete all keys from the cache by a blocking operation + * + * Faster than clear() using unlink method. + * + * @return bool True if the cache was successfully cleared, false otherwise + */ + public function clearBlocking(): bool + { + $this->_Redis->setOption(Redis::OPT_SCAN, (string)Redis::SCAN_RETRY); + + $isAllDeleted = true; + $iterator = null; + $pattern = $this->_config['prefix'] . '*'; + + while (true) { + $keys = $this->_Redis->scan($iterator, $pattern, (int)$this->_config['scanCount']); + + if ($keys === false) { + break; + } + + foreach ($keys as $key) { + $isDeleted = ($this->_Redis->unlink($key) > 0); + $isAllDeleted = $isAllDeleted && $isDeleted; + } + } + + return $isAllDeleted; + } + /** * Write data for key into cache if it doesn't exist already. * If it already exists, it fails and returns false. diff --git a/app/vendor/cakephp/cakephp/src/Cache/composer.json b/app/vendor/cakephp/cakephp/src/Cache/composer.json index 001a8a9dc..96aec1982 100644 --- a/app/vendor/cakephp/cakephp/src/Cache/composer.json +++ b/app/vendor/cakephp/cakephp/src/Cache/composer.json @@ -22,7 +22,7 @@ "source": "https://github.com/cakephp/cache" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "psr/simple-cache": "^1.0 || ^2.0" }, diff --git a/app/vendor/cakephp/cakephp/src/Collection/Collection.php b/app/vendor/cakephp/cakephp/src/Collection/Collection.php index d3af8c0f0..147d41302 100644 --- a/app/vendor/cakephp/cakephp/src/Collection/Collection.php +++ b/app/vendor/cakephp/cakephp/src/Collection/Collection.php @@ -17,6 +17,7 @@ namespace Cake\Collection; use ArrayIterator; +use Exception; use IteratorIterator; use Serializable; @@ -120,8 +121,14 @@ public function countKeys(): int */ public function __debugInfo(): array { + try { + $count = $this->count(); + } catch (Exception $e) { + $count = 'An exception occurred while getting count'; + } + return [ - 'count' => $this->count(), + 'count' => $count, ]; } } diff --git a/app/vendor/cakephp/cakephp/src/Collection/composer.json b/app/vendor/cakephp/cakephp/src/Collection/composer.json index 87c05665e..16ec80218 100644 --- a/app/vendor/cakephp/cakephp/src/Collection/composer.json +++ b/app/vendor/cakephp/cakephp/src/Collection/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/collection" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "autoload": { "psr-4": { diff --git a/app/vendor/cakephp/cakephp/src/Command/Command.php b/app/vendor/cakephp/cakephp/src/Command/Command.php index 5c6afc026..1ab0c3c49 100644 --- a/app/vendor/cakephp/cakephp/src/Command/Command.php +++ b/app/vendor/cakephp/cakephp/src/Command/Command.php @@ -30,6 +30,7 @@ * Includes traits that integrate logging * and ORM models to console commands. */ +#[\AllowDynamicProperties] class Command extends BaseCommand { use LocatorAwareTrait; @@ -67,3 +68,10 @@ public function execute(Arguments $args, ConsoleIo $io) { } } + +// phpcs:disable +class_alias( + 'Cake\Command\Command', + 'Cake\Console\Command' +); +// phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Command/I18nExtractCommand.php b/app/vendor/cakephp/cakephp/src/Command/I18nExtractCommand.php index 891f6d8e8..724783bcf 100644 --- a/app/vendor/cakephp/cakephp/src/Command/I18nExtractCommand.php +++ b/app/vendor/cakephp/cakephp/src/Command/I18nExtractCommand.php @@ -147,8 +147,6 @@ protected function _getPaths(ConsoleIo $io): void if (strtoupper($response) === 'Q') { $io->err('Extract Aborted'); $this->abort(); - - return; } if (strtoupper($response) === 'D' && count($this->_paths)) { $io->out(); @@ -832,7 +830,11 @@ protected function _searchFiles(): void } foreach ($this->_paths as $path) { - $path = realpath($path) . DIRECTORY_SEPARATOR; + $path = realpath($path); + if ($path === false) { + continue; + } + $path .= DIRECTORY_SEPARATOR; $fs = new Filesystem(); $files = $fs->findRecursive($path, '/\.php$/'); $files = array_keys(iterator_to_array($files)); diff --git a/app/vendor/cakephp/cakephp/src/Command/RoutesCheckCommand.php b/app/vendor/cakephp/cakephp/src/Command/RoutesCheckCommand.php index b660e4d68..86245a5c7 100644 --- a/app/vendor/cakephp/cakephp/src/Command/RoutesCheckCommand.php +++ b/app/vendor/cakephp/cakephp/src/Command/RoutesCheckCommand.php @@ -58,7 +58,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int } } - unset($route['_matchedRoute']); + unset($route['_route'], $route['_matchedRoute']); ksort($route); $output = [ diff --git a/app/vendor/cakephp/cakephp/src/Command/RoutesCommand.php b/app/vendor/cakephp/cakephp/src/Command/RoutesCommand.php index e3a20b9f1..66d9814de 100644 --- a/app/vendor/cakephp/cakephp/src/Command/RoutesCommand.php +++ b/app/vendor/cakephp/cakephp/src/Command/RoutesCommand.php @@ -40,10 +40,11 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $header[] = 'Defaults'; } - $output = []; + $availableRoutes = Router::routes(); + $output = $duplicateRoutesCounter = []; - foreach (Router::routes() as $route) { - $methods = $route->defaults['_method'] ?? ''; + foreach ($availableRoutes as $route) { + $methods = isset($route->defaults['_method']) ? (array)$route->defaults['_method'] : ['']; $item = [ $route->options['_name'] ?? $route->getName(), @@ -52,7 +53,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $route->defaults['prefix'] ?? '', $route->defaults['controller'] ?? '', $route->defaults['action'] ?? '', - is_string($methods) ? $methods : implode(', ', $route->defaults['_method']), + implode(', ', $methods), ]; if ($args->getOption('verbose')) { @@ -61,6 +62,14 @@ public function execute(Arguments $args, ConsoleIo $io): ?int } $output[] = $item; + + foreach ($methods as $method) { + if (!isset($duplicateRoutesCounter[$route->template][$method])) { + $duplicateRoutesCounter[$route->template][$method] = 0; + } + + $duplicateRoutesCounter[$route->template][$method]++; + } } if ($args->getOption('sort')) { @@ -74,6 +83,39 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $io->helper('table')->output($output); $io->out(); + $duplicateRoutes = []; + + foreach ($availableRoutes as $route) { + $methods = isset($route->defaults['_method']) ? (array)$route->defaults['_method'] : ['']; + + foreach ($methods as $method) { + if ( + $duplicateRoutesCounter[$route->template][$method] > 1 || + ($method === '' && count($duplicateRoutesCounter[$route->template]) > 1) || + ($method !== '' && isset($duplicateRoutesCounter[$route->template][''])) + ) { + $duplicateRoutes[] = [ + $route->options['_name'] ?? $route->getName(), + $route->template, + $route->defaults['plugin'] ?? '', + $route->defaults['prefix'] ?? '', + $route->defaults['controller'] ?? '', + $route->defaults['action'] ?? '', + implode(', ', $methods), + ]; + + break; + } + } + } + + if ($duplicateRoutes) { + array_unshift($duplicateRoutes, $header); + $io->warning('The following possible route collisions were detected.'); + $io->helper('table')->output($duplicateRoutes); + $io->out(); + } + return static::CODE_SUCCESS; } diff --git a/app/vendor/cakephp/cakephp/src/Console/BaseCommand.php b/app/vendor/cakephp/cakephp/src/Console/BaseCommand.php index ad4866bfe..c927ccf80 100644 --- a/app/vendor/cakephp/cakephp/src/Console/BaseCommand.php +++ b/app/vendor/cakephp/cakephp/src/Console/BaseCommand.php @@ -65,6 +65,16 @@ public function getName(): string return $this->name; } + /** + * Get the command description. + * + * @return string + */ + public static function getDescription(): string + { + return ''; + } + /** * Get the root command name. * @@ -91,9 +101,8 @@ public static function defaultName(): string $pos = strrpos(static::class, '\\'); /** @psalm-suppress PossiblyFalseOperand */ $name = substr(static::class, $pos + 1, -7); - $name = Inflector::underscore($name); - return $name; + return Inflector::underscore($name); } /** @@ -109,6 +118,7 @@ public function getOptionParser(): ConsoleOptionParser [$root, $name] = explode(' ', $this->name, 2); $parser = new ConsoleOptionParser($name); $parser->setRootName($root); + $parser->setDescription(static::getDescription()); $parser = $this->buildOptionParser($parser); if ($parser->subcommands()) { @@ -153,7 +163,7 @@ public function run(array $argv, ConsoleIo $io): ?int $parser = $this->getOptionParser(); try { - [$options, $arguments] = $parser->parse($argv); + [$options, $arguments] = $parser->parse($argv, $io); $args = new Arguments( $arguments, $options, @@ -233,6 +243,7 @@ abstract public function execute(Arguments $args, ConsoleIo $io); * @param int $code The exit code to use. * @throws \Cake\Console\Exception\StopException * @return void + * @psalm-return never-return */ public function abort(int $code = self::CODE_ERROR): void { diff --git a/app/vendor/cakephp/cakephp/src/Console/Command.php b/app/vendor/cakephp/cakephp/src/Console/Command.php index f593ff9bc..9494b024a 100644 --- a/app/vendor/cakephp/cakephp/src/Console/Command.php +++ b/app/vendor/cakephp/cakephp/src/Console/Command.php @@ -4,8 +4,4 @@ /** * @deprecated 4.0.0 Use {@link \Cake\Command\Command} instead. */ - -class_alias( - 'Cake\Command\Command', - 'Cake\Console\Command' -); +class_exists('Cake\Command\Command'); diff --git a/app/vendor/cakephp/cakephp/src/Console/Command/HelpCommand.php b/app/vendor/cakephp/cakephp/src/Console/Command/HelpCommand.php index 9999518f7..8f96f1a86 100644 --- a/app/vendor/cakephp/cakephp/src/Console/Command/HelpCommand.php +++ b/app/vendor/cakephp/cakephp/src/Console/Command/HelpCommand.php @@ -112,7 +112,10 @@ protected function asText(ConsoleIo $io, iterable $commands): void [, $shortestName] = explode('.', $shortestName, 2); } - $grouped[$prefix][] = $shortestName; + $grouped[$prefix][] = [ + 'name' => $shortestName, + 'description' => is_subclass_of($class, BaseCommand::class) ? $class::getDescription() : '', + ]; } ksort($grouped); @@ -122,8 +125,11 @@ protected function asText(ConsoleIo $io, iterable $commands): void foreach ($grouped as $prefix => $names) { $io->out("{$prefix}:"); sort($names); - foreach ($names as $name) { - $io->out(' - ' . $name); + foreach ($names as $data) { + $io->out(' - ' . $data['name']); + if ($data['description']) { + $io->info(str_pad(" \u{2514}", 13, "\u{2500}") . ' ' . $data['description']); + } } $io->out(''); } diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandCollection.php b/app/vendor/cakephp/cakephp/src/Console/CommandCollection.php index a3ac801c5..47aa17db2 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandCollection.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandCollection.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandCollectionAwareInterface.php b/app/vendor/cakephp/cakephp/src/Console/CommandCollectionAwareInterface.php index 7892bc677..5c2e457c4 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandCollectionAwareInterface.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandCollectionAwareInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandFactory.php b/app/vendor/cakephp/cakephp/src/Console/CommandFactory.php index 20c8367a2..364bb4b16 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandFactory.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandFactory.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandFactoryInterface.php b/app/vendor/cakephp/cakephp/src/Console/CommandFactoryInterface.php index 7be77a84f..67284a416 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandFactoryInterface.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandFactoryInterface.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php b/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php index 4d6fdfd43..8e84e7ea0 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandRunner.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/CommandScanner.php b/app/vendor/cakephp/cakephp/src/Console/CommandScanner.php index a704e4112..d086679af 100644 --- a/app/vendor/cakephp/cakephp/src/Console/CommandScanner.php +++ b/app/vendor/cakephp/cakephp/src/Console/CommandScanner.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Console; diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleErrorHandler.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleErrorHandler.php index 977aa7071..cac0d22f5 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleErrorHandler.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleErrorHandler.php @@ -1,10 +1,7 @@ usage() === $argument->usage(); + return $this->name() === $argument->name() && + $this->usage() === $argument->usage(); } /** diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php index 21a253dd8..b6853726c 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleInputOption.php @@ -76,6 +76,13 @@ class ConsoleInputOption */ protected $_choices; + /** + * The prompt string + * + * @var string|null + */ + protected $prompt; + /** * Is the option required. * @@ -94,6 +101,7 @@ class ConsoleInputOption * @param array $choices Valid choices for this option. * @param bool $multiple Whether this option can accept multiple value definition. * @param bool $required Whether this option is required or not. + * @param string|null $prompt The prompt string. * @throws \Cake\Console\Exception\ConsoleException */ public function __construct( @@ -104,7 +112,8 @@ public function __construct( $default = null, array $choices = [], bool $multiple = false, - bool $required = false + bool $required = false, + ?string $prompt = null ) { $this->_name = $name; $this->_short = $short; @@ -113,6 +122,7 @@ public function __construct( $this->_choices = $choices; $this->_multiple = $multiple; $this->required = $required; + $this->prompt = $prompt; if ($isBoolean) { $this->_default = (bool)$default; @@ -125,6 +135,12 @@ public function __construct( sprintf('Short option "%s" is invalid, short options must be one letter.', $this->_short) ); } + if (isset($this->_default) && $this->prompt) { + throw new ConsoleException( + 'You cannot set both `prompt` and `default` options. ' . + 'Use either a static `default` or interactive `prompt`' + ); + } } /** @@ -266,6 +282,26 @@ public function validChoice($value): bool return true; } + /** + * Get the list of choices this option has. + * + * @return array + */ + public function choices(): array + { + return $this->_choices; + } + + /** + * Get the prompt string + * + * @return string + */ + public function prompt(): string + { + return (string)$this->prompt; + } + /** * Append the option's XML into the parent. * diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php index 704f7951a..583873800 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleIo.php @@ -298,6 +298,7 @@ public function success($message, int $newlines = 1, int $level = self::NORMAL): * @param string $message Error message. * @param int $code Error code. * @return void + * @psalm-return never-return * @throws \Cake\Console\Exception\StopException */ public function abort($message, $code = CommandInterface::CODE_ERROR): void diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php index 77044ffce..b20775a1d 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleOptionParser.php @@ -245,7 +245,7 @@ public static function buildFromArray(array $spec, bool $defaultOptions = true) */ public function toArray(): array { - $result = [ + return [ 'command' => $this->_command, 'arguments' => $this->_args, 'options' => $this->_options, @@ -253,8 +253,6 @@ public function toArray(): array 'description' => $this->_description, 'epilog' => $this->_epilog, ]; - - return $result; } /** @@ -426,6 +424,7 @@ public function addOption($name, array $options = []) 'multiple' => false, 'choices' => [], 'required' => false, + 'prompt' => null, ]; $options += $defaults; $option = new ConsoleInputOption( @@ -436,7 +435,8 @@ public function addOption($name, array $options = []) $options['default'], $options['choices'], $options['multiple'], - $options['required'] + $options['required'], + $options['prompt'] ); } $this->_options[$name] = $option; @@ -677,10 +677,11 @@ public function subcommands() * to parse the $argv * * @param array $argv Array of args (argv) to parse. + * @param \Cake\Console\ConsoleIo|null $io A ConsoleIo instance or null. If null prompt options will error. * @return array [$params, $args] * @throws \Cake\Console\Exception\ConsoleException When an invalid parameter is encountered. */ - public function parse(array $argv): array + public function parse(array $argv, ?ConsoleIo $io = null): array { $command = isset($argv[0]) ? Inflector::underscore($argv[0]) : null; if (isset($this->_subcommands[$command])) { @@ -688,7 +689,7 @@ public function parse(array $argv): array } if (isset($this->_subcommands[$command]) && $this->_subcommands[$command]->parser()) { /** @psalm-suppress PossiblyNullReference */ - return $this->_subcommands[$command]->parser()->parse($argv); + return $this->_subcommands[$command]->parser()->parse($argv, $io); } $params = $args = []; $this->_tokens = $argv; @@ -722,12 +723,29 @@ public function parse(array $argv): array $isBoolean = $option->isBoolean(); $default = $option->defaultValue(); - if ($default !== null && !isset($params[$name]) && !$isBoolean) { + $useDefault = !isset($params[$name]); + if ($default !== null && $useDefault && !$isBoolean) { $params[$name] = $default; } - if ($isBoolean && !isset($params[$name])) { + if ($isBoolean && $useDefault) { $params[$name] = false; } + $prompt = $option->prompt(); + if (!isset($params[$name]) && $prompt) { + if (!$io) { + throw new ConsoleException( + 'Cannot use interactive option prompts without a ConsoleIo instance. ' . + 'Please provide a `$io` parameter to `parse()`.' + ); + } + $choices = $option->choices(); + if ($choices) { + $value = $io->askChoice($prompt, $choices); + } else { + $value = $io->ask($prompt); + } + $params[$name] = $value; + } if ($option->isRequired() && !isset($params[$name])) { throw new ConsoleException( sprintf('Missing required option. The `%s` option is required and has no default value.', $name) diff --git a/app/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php b/app/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php index d87fbb390..c11101875 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php +++ b/app/vendor/cakephp/cakephp/src/Console/ConsoleOutput.php @@ -214,17 +214,25 @@ public function styleText(string $text): string if ($this->_outputAs === static::RAW) { return $text; } - if ($this->_outputAs === static::PLAIN) { - $tags = implode('|', array_keys(static::$_styles)); + if ($this->_outputAs !== static::PLAIN) { + $output = preg_replace_callback( + '/<(?P[a-z0-9-_]+)>(?P.*?)<\/(\1)>/ims', + [$this, '_replaceTags'], + $text + ); + if ($output !== null) { + return $output; + } + } - return preg_replace('##', '', $text); + $tags = implode('|', array_keys(static::$_styles)); + $output = preg_replace('##', '', $text); + + if ($output === null) { + return $text; } - return preg_replace_callback( - '/<(?P[a-z0-9-_]+)>(?P.*?)<\/(\1)>/ims', - [$this, '_replaceTags'], - $text - ); + return $output; } /** diff --git a/app/vendor/cakephp/cakephp/src/Console/Shell.php b/app/vendor/cakephp/cakephp/src/Console/Shell.php index 0fae3a508..636216766 100644 --- a/app/vendor/cakephp/cakephp/src/Console/Shell.php +++ b/app/vendor/cakephp/cakephp/src/Console/Shell.php @@ -40,6 +40,7 @@ * @deprecated 3.6.0 ShellDispatcher and Shell will be removed in 5.0 * @method int|bool|null|void main(...$args) Main entry method for the shell. */ +#[\AllowDynamicProperties] class Shell { use LocatorAwareTrait; @@ -136,7 +137,7 @@ class Shell * Contains tasks to load and instantiate * * @var array|bool - * @link https://book.cakephp.org/4/en/console-and-shells.html#Shell::$tasks + * @link https://book.cakephp.org/4/en/console-commands/shells.html#shell-tasks */ public $tasks = []; @@ -180,7 +181,7 @@ class Shell * * @param \Cake\Console\ConsoleIo|null $io An io instance. * @param \Cake\ORM\Locator\LocatorInterface|null $locator Table locator instance. - * @link https://book.cakephp.org/4/en/console-and-shells.html#Shell + * @link https://book.cakephp.org/4/en/console-commands/shells.html */ public function __construct(?ConsoleIo $io = null, ?LocatorInterface $locator = null) { @@ -468,7 +469,7 @@ public function runCommand(array $argv, bool $autoMethod = false, array $extra = $command = isset($argv[0]) ? Inflector::underscore($argv[0]) : null; $this->OptionParser = $this->getOptionParser(); try { - [$this->params, $this->args] = $this->OptionParser->parse($argv); + [$this->params, $this->args] = $this->OptionParser->parse($argv, $this->_io); } catch (ConsoleException $e) { $this->err('Error: ' . $e->getMessage()); diff --git a/app/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php b/app/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php index 79f4fcedf..2075784b0 100644 --- a/app/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php +++ b/app/vendor/cakephp/cakephp/src/Console/ShellDispatcher.php @@ -179,9 +179,7 @@ public function dispatch(array $extra = []): int try { $result = $this->_dispatch($extra); } catch (StopException $e) { - $code = $e->getCode(); - - return $code; + return $e->getCode(); } if ($result === null || $result === true) { /** @psalm-suppress DeprecatedClass */ diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/ConsoleIntegrationTestTrait.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/ConsoleIntegrationTestTrait.php new file mode 100644 index 000000000..f5f756fc7 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/ConsoleIntegrationTestTrait.php @@ -0,0 +1,345 @@ +makeRunner(); + + if ($this->_out === null) { + $this->_out = new StubConsoleOutput(); + } + if ($this->_err === null) { + $this->_err = new StubConsoleOutput(); + } + if ($this->_in === null) { + $this->_in = new StubConsoleInput($input); + } elseif ($input) { + throw new RuntimeException('You can use `$input` only if `$_in` property is null and will be reset.'); + } + + $args = $this->commandStringToArgs("cake $command"); + $io = new ConsoleIo($this->_out, $this->_err, $this->_in); + + try { + $this->_exitCode = $runner->run($args, $io); + } catch (MissingConsoleInputException $e) { + $messages = $this->_out->messages(); + if (count($messages)) { + $e->setQuestion($messages[count($messages) - 1]); + } + throw $e; + } catch (StopException $exception) { + $this->_exitCode = $exception->getCode(); + } + } + + /** + * Cleans state to get ready for the next test + * + * @after + * @return void + * @psalm-suppress PossiblyNullPropertyAssignmentValue + */ + public function cleanupConsoleTrait(): void + { + $this->_exitCode = null; + $this->_out = null; + $this->_err = null; + $this->_in = null; + $this->_useCommandRunner = false; + } + + /** + * Set this test case to use the CommandRunner rather than the legacy + * ShellDispatcher + * + * @return void + */ + public function useCommandRunner(): void + { + $this->_useCommandRunner = true; + } + + /** + * Asserts shell exited with the expected code + * + * @param int $expected Expected exit code + * @param string $message Failure message + * @return void + */ + public function assertExitCode(int $expected, string $message = ''): void + { + $this->assertThat($expected, new ExitCode($this->_exitCode), $message); + } + + /** + * Asserts shell exited with the Command::CODE_SUCCESS + * + * @param string $message Failure message + * @return void + */ + public function assertExitSuccess($message = '') + { + $this->assertThat(Command::CODE_SUCCESS, new ExitCode($this->_exitCode), $message); + } + + /** + * Asserts shell exited with Command::CODE_ERROR + * + * @param string $message Failure message + * @return void + */ + public function assertExitError($message = '') + { + $this->assertThat(Command::CODE_ERROR, new ExitCode($this->_exitCode), $message); + } + + /** + * Asserts that `stdout` is empty + * + * @param string $message The message to output when the assertion fails. + * @return void + */ + public function assertOutputEmpty(string $message = ''): void + { + $this->assertThat(null, new ContentsEmpty($this->_out->messages(), 'output'), $message); + } + + /** + * Asserts `stdout` contains expected output + * + * @param string $expected Expected output + * @param string $message Failure message + * @return void + */ + public function assertOutputContains(string $expected, string $message = ''): void + { + $this->assertThat($expected, new ContentsContain($this->_out->messages(), 'output'), $message); + } + + /** + * Asserts `stdout` does not contain expected output + * + * @param string $expected Expected output + * @param string $message Failure message + * @return void + */ + public function assertOutputNotContains(string $expected, string $message = ''): void + { + $this->assertThat($expected, new ContentsNotContain($this->_out->messages(), 'output'), $message); + } + + /** + * Asserts `stdout` contains expected regexp + * + * @param string $pattern Expected pattern + * @param string $message Failure message + * @return void + */ + public function assertOutputRegExp(string $pattern, string $message = ''): void + { + $this->assertThat($pattern, new ContentsRegExp($this->_out->messages(), 'output'), $message); + } + + /** + * Check that a row of cells exists in the output. + * + * @param array $row Row of cells to ensure exist in the output. + * @param string $message Failure message. + * @return void + */ + protected function assertOutputContainsRow(array $row, string $message = ''): void + { + $this->assertThat($row, new ContentsContainRow($this->_out->messages(), 'output'), $message); + } + + /** + * Asserts `stderr` contains expected output + * + * @param string $expected Expected output + * @param string $message Failure message + * @return void + */ + public function assertErrorContains(string $expected, string $message = ''): void + { + $this->assertThat($expected, new ContentsContain($this->_err->messages(), 'error output'), $message); + } + + /** + * Asserts `stderr` contains expected regexp + * + * @param string $pattern Expected pattern + * @param string $message Failure message + * @return void + */ + public function assertErrorRegExp(string $pattern, string $message = ''): void + { + $this->assertThat($pattern, new ContentsRegExp($this->_err->messages(), 'error output'), $message); + } + + /** + * Asserts that `stderr` is empty + * + * @param string $message The message to output when the assertion fails. + * @return void + */ + public function assertErrorEmpty(string $message = ''): void + { + $this->assertThat(null, new ContentsEmpty($this->_err->messages(), 'error output'), $message); + } + + /** + * Builds the appropriate command dispatcher + * + * @return \Cake\Console\CommandRunner|\Cake\Console\TestSuite\LegacyCommandRunner + */ + protected function makeRunner() + { + if ($this->_useCommandRunner) { + /** @var \Cake\Core\ConsoleApplicationInterface $app */ + $app = $this->createApp(); + + return new CommandRunner($app); + } + + return new LegacyCommandRunner(); + } + + /** + * Creates an $argv array from a command string + * + * @param string $command Command string + * @return array + */ + protected function commandStringToArgs(string $command): array + { + $charCount = strlen($command); + $argv = []; + $arg = ''; + $inDQuote = false; + $inSQuote = false; + for ($i = 0; $i < $charCount; $i++) { + $char = substr($command, $i, 1); + + // end of argument + if ($char === ' ' && !$inDQuote && !$inSQuote) { + if ($arg !== '') { + $argv[] = $arg; + } + $arg = ''; + continue; + } + + // exiting single quote + if ($inSQuote && $char === "'") { + $inSQuote = false; + continue; + } + + // exiting double quote + if ($inDQuote && $char === '"') { + $inDQuote = false; + continue; + } + + // entering double quote + if ($char === '"' && !$inSQuote) { + $inDQuote = true; + continue; + } + + // entering single quote + if ($char === "'" && !$inDQuote) { + $inSQuote = true; + continue; + } + + $arg .= $char; + } + $argv[] = $arg; + + return $argv; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsBase.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsBase.php new file mode 100644 index 000000000..8ea9d2619 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsBase.php @@ -0,0 +1,48 @@ + $contents Contents + * @param string $output Output type + */ + public function __construct(array $contents, string $output) + { + $this->contents = implode(PHP_EOL, $contents); + $this->output = $output; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContain.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContain.php new file mode 100644 index 000000000..5dc3942e4 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContain.php @@ -0,0 +1,45 @@ +contents, $other) !== false; + } + + /** + * Assertion message + * + * @return string + */ + public function toString(): string + { + return sprintf('is in %s,' . PHP_EOL . 'actual result:' . PHP_EOL, $this->output) . $this->contents; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContainRow.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContainRow.php new file mode 100644 index 000000000..a1b9edd08 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsContainRow.php @@ -0,0 +1,61 @@ +contents) > 0; + } + + /** + * Assertion message + * + * @return string + */ + public function toString(): string + { + return sprintf('row was in %s', $this->output); + } + + /** + * @param mixed $other Expected content + * @return string + */ + public function failureDescription($other): string + { + return '`' . $this->exporter()->shortenedExport($other) . '` ' . $this->toString(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsEmpty.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsEmpty.php new file mode 100644 index 000000000..015d68bbc --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsEmpty.php @@ -0,0 +1,56 @@ +contents === ''; + } + + /** + * Assertion message + * + * @return string + */ + public function toString(): string + { + return sprintf('%s is empty', $this->output); + } + + /** + * Overwrites the descriptions so we can remove the automatic "expected" message + * + * @param mixed $other Value + * @return string + */ + protected function failureDescription($other): string + { + return $this->toString(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsNotContain.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsNotContain.php new file mode 100644 index 000000000..47855c520 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsNotContain.php @@ -0,0 +1,45 @@ +contents, $other) === false; + } + + /** + * Assertion message + * + * @return string + */ + public function toString(): string + { + return sprintf('is not in %s', $this->output); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsRegExp.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsRegExp.php new file mode 100644 index 000000000..e3a3fb6c7 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ContentsRegExp.php @@ -0,0 +1,54 @@ +contents) > 0; + } + + /** + * Assertion message + * + * @return string + */ + public function toString(): string + { + return sprintf('PCRE pattern found in %s', $this->output); + } + + /** + * @param mixed $other Expected + * @return string + */ + public function failureDescription($other): string + { + return '`' . $other . '` ' . $this->toString(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ExitCode.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ExitCode.php new file mode 100644 index 000000000..4e7f01edb --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/Constraint/ExitCode.php @@ -0,0 +1,62 @@ +exitCode = $exitCode; + } + + /** + * Checks if event is in fired array + * + * @param mixed $other Constraint check + * @return bool + */ + public function matches($other): bool + { + return $other === $this->exitCode; + } + + /** + * Assertion message string + * + * @return string + */ + public function toString(): string + { + return sprintf('matches exit code %s', $this->exitCode ?? 'null'); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyCommandRunner.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyCommandRunner.php new file mode 100644 index 000000000..8cbb5542a --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyCommandRunner.php @@ -0,0 +1,39 @@ +dispatch(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyShellDispatcher.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyShellDispatcher.php new file mode 100644 index 000000000..59caba325 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/LegacyShellDispatcher.php @@ -0,0 +1,64 @@ +_io = $io; + parent::__construct($args, $bootstrap); + } + + /** + * Injects mock and stub io components into the shell + * + * @param string $className Class name + * @param string $shortName Short name + * @return \Cake\Console\Shell + */ + protected function _createShell(string $className, string $shortName): Shell + { + [$plugin] = pluginSplit($shortName); + /** @var \Cake\Console\Shell $instance */ + $instance = new $className($this->_io); + if ($plugin) { + $instance->plugin = trim($plugin, '.'); + } + + return $instance; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/MissingConsoleInputException.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/MissingConsoleInputException.php new file mode 100644 index 000000000..a76d36f63 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/MissingConsoleInputException.php @@ -0,0 +1,39 @@ +message .= "\nThe question asked was: " . $question; + } +} + +// phpcs:disable +class_alias(MissingConsoleInputException::class, 'Cake\TestSuite\Stub\MissingConsoleInputException'); +// phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleInput.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleInput.php new file mode 100644 index 000000000..96a83198f --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleInput.php @@ -0,0 +1,88 @@ + + */ + protected $replies = []; + + /** + * Current message index + * + * @var int + */ + protected $currentIndex = -1; + + /** + * Constructor + * + * @param array $replies A list of replies for read() + */ + public function __construct(array $replies) + { + parent::__construct(); + + $this->replies = $replies; + } + + /** + * Read a reply + * + * @return string The value of the reply + */ + public function read(): string + { + $this->currentIndex += 1; + + if (!isset($this->replies[$this->currentIndex])) { + $total = count($this->replies); + $formatter = new NumberFormatter('en', NumberFormatter::ORDINAL); + $nth = $formatter->format($this->currentIndex + 1); + + $replies = implode(', ', $this->replies); + $message = "There are no more input replies available. This is the {$nth} read operation, " . + "only {$total} replies were set.\nThe provided replies are: {$replies}"; + throw new MissingConsoleInputException($message); + } + + return $this->replies[$this->currentIndex]; + } + + /** + * Check if data is available on stdin + * + * @param int $timeout An optional time to wait for data + * @return bool True for data available, false otherwise + */ + public function dataAvailable($timeout = 0): bool + { + return true; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleOutput.php b/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleOutput.php new file mode 100644 index 000000000..280ea3e7d --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Console/TestSuite/StubConsoleOutput.php @@ -0,0 +1,84 @@ + + */ + protected $_out = []; + + /** + * Write output to the buffer. + * + * @param array|string $message A string or an array of strings to output + * @param int $newlines Number of newlines to append + * @return int + */ + public function write($message, int $newlines = 1): int + { + foreach ((array)$message as $line) { + $this->_out[] = $line; + } + + $newlines--; + while ($newlines > 0) { + $this->_out[] = ''; + $newlines--; + } + + return 0; + } + + /** + * Get the buffered output. + * + * @return array + */ + public function messages(): array + { + return $this->_out; + } + + /** + * Get the output as a string + * + * @return string + */ + public function output(): string + { + return implode("\n", $this->_out); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Console/composer.json b/app/vendor/cakephp/cakephp/src/Console/composer.json index 971d9a610..d7d392b50 100644 --- a/app/vendor/cakephp/cakephp/src/Console/composer.json +++ b/app/vendor/cakephp/cakephp/src/Console/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/console" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "cakephp/event": "^4.0", "cakephp/filesystem": "^4.0", diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component.php b/app/vendor/cakephp/cakephp/src/Controller/Component.php index 52540c039..1ebafbd59 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Component.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Component.php @@ -58,6 +58,7 @@ * @link https://book.cakephp.org/4/en/controllers/components.html * @see \Cake\Controller\Controller::$components */ +#[\AllowDynamicProperties] class Component implements EventListenerInterface { use InstanceConfigTrait; diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component/CheckHttpCacheComponent.php b/app/vendor/cakephp/cakephp/src/Controller/Component/CheckHttpCacheComponent.php new file mode 100644 index 000000000..e546b6e7c --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Controller/Component/CheckHttpCacheComponent.php @@ -0,0 +1,54 @@ +getController(); + $response = $controller->getResponse(); + $request = $controller->getRequest(); + if (!$response->isNotModified($request)) { + return; + } + + $controller->setResponse($response->withNotModified()); + $event->stopPropagation(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php b/app/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php index 715ed486a..85e27729a 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Component/PaginatorComponent.php @@ -18,8 +18,8 @@ use Cake\Controller\Component; use Cake\Controller\ComponentRegistry; -use Cake\Datasource\Exception\PageOutOfBoundsException; -use Cake\Datasource\Paginator; +use Cake\Datasource\Paging\Exception\PageOutOfBoundsException; +use Cake\Datasource\Paging\NumericPaginator; use Cake\Datasource\ResultSetInterface; use Cake\Http\Exception\NotFoundException; use InvalidArgumentException; @@ -34,14 +34,15 @@ * You configure pagination when calling paginate(). See that method for more details. * * @link https://book.cakephp.org/4/en/controllers/components/pagination.html - * @mixin \Cake\Datasource\Paginator + * @mixin \Cake\Datasource\Paging\NumericPaginator + * @deprecated 4.4.0 Use Cake\Datasource\Paging\Paginator directly. */ class PaginatorComponent extends Component { /** * Datasource paginator instance. * - * @var \Cake\Datasource\Paginator + * @var \Cake\Datasource\Paging\NumericPaginator */ protected $_paginator; @@ -50,18 +51,30 @@ class PaginatorComponent extends Component */ public function __construct(ComponentRegistry $registry, array $config = []) { + deprecationWarning( + 'PaginatorComponent is deprecated, use a Cake\Datasource\Pagination\NumericPaginator instance directly.' + ); + if (!empty($this->_defaultConfig)) { throw new UnexpectedValueException('Default configuration must be set using a custom Paginator class.'); } if (isset($config['paginator'])) { - if (!$config['paginator'] instanceof Paginator) { - throw new InvalidArgumentException('Paginator must be an instance of ' . Paginator::class); + $config['className'] = $config['paginator']; + deprecationWarning( + '`paginator` option is deprecated,' + . ' use `className` instead a specify a paginator name/FQCN.' + ); + } + + if (isset($config['className'])) { + if (!$config['className'] instanceof NumericPaginator) { + throw new InvalidArgumentException('Paginator must be an instance of ' . NumericPaginator::class); } - $this->_paginator = $config['paginator']; - unset($config['paginator']); + $this->_paginator = $config['className']; + unset($config['className']); } else { - $this->_paginator = new Paginator(); + $this->_paginator = new NumericPaginator(); } parent::__construct($registry, $config); @@ -86,7 +99,7 @@ public function implementedEvents(): array * These settings are used to build the queries made and control other pagination settings. * * If your settings contain a key with the current table's alias. The data inside that key will be used. - * Otherwise the top level configuration will be used. + * Otherwise, the top level configuration will be used. * * ``` * $settings = [ @@ -225,10 +238,10 @@ public function mergeOptions(string $alias, array $settings): array /** * Set paginator instance. * - * @param \Cake\Datasource\Paginator $paginator Paginator instance. + * @param \Cake\Datasource\Paging\NumericPaginator $paginator Paginator instance. * @return $this */ - public function setPaginator(Paginator $paginator) + public function setPaginator(NumericPaginator $paginator) { $this->_paginator = $paginator; @@ -238,9 +251,9 @@ public function setPaginator(Paginator $paginator) /** * Get paginator instance. * - * @return \Cake\Datasource\Paginator + * @return \Cake\Datasource\Paging\NumericPaginator */ - public function getPaginator(): Paginator + public function getPaginator(): NumericPaginator { return $this->_paginator; } diff --git a/app/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php b/app/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php index f18c3cc64..84c5a26ab 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Component/RequestHandlerComponent.php @@ -22,6 +22,7 @@ use Cake\Core\App; use Cake\Core\Configure; use Cake\Event\EventInterface; +use Cake\Http\ContentTypeNegotiation; use Cake\Http\Exception\NotFoundException; use Cake\Http\Response; use Cake\Http\ServerRequest; @@ -38,6 +39,8 @@ * etc. and return a response accordingly. * * @link https://book.cakephp.org/4/en/controllers/components/request-handling.html + * @deprecated 4.4.0 See the 4.4 migration guide for how to upgrade. + * https://book.cakephp.org/4/en/appendices/4-4-migration-guide.html#requesthandlercomponent */ class RequestHandlerComponent extends Component { @@ -121,7 +124,9 @@ public function implementedEvents(): array */ protected function _setExtension(ServerRequest $request, Response $response): void { - $accept = $request->parseAccept(); + $content = new ContentTypeNegotiation(); + $accept = $content->parseAccept($request); + if (empty($accept) || current($accept)[0] === 'text/html') { return; } @@ -214,14 +219,10 @@ public function beforeRender(EventInterface $event): void $response = $response->withCharset(Configure::read('App.encoding')); } - if ( - $this->_config['checkHttpCache'] && - $response->checkNotModified($controller->getRequest()) - ) { - $controller->setResponse($response); + $request = $controller->getRequest(); + if ($this->_config['checkHttpCache'] && $response->isNotModified($request)) { + $response = $response->withNotModified(); $event->stopPropagation(); - - return; } $controller->setResponse($response); @@ -252,6 +253,7 @@ public function beforeRender(EventInterface $event): void * types the client accepts. If a string is passed, returns true * if the client accepts it. If an array is passed, returns true * if the client accepts one or more elements in the array. + * @deprecated 4.4.0 Use ContentTypeNegotiation::prefersChoice() or Controller::getViewClasses() instead. */ public function accepts($type = null) { @@ -339,12 +341,15 @@ public function requestedWith($type = null) * a boolean will be returned if that type is preferred. * If an array of types are provided then the first preferred type is returned. * If no type is provided the first preferred type is returned. + * @deprecated 4.4.0 Use Controller::getViewClasses() instead. */ public function prefers($type = null) { $controller = $this->getController(); + $request = $controller->getRequest(); + $content = new ContentTypeNegotiation(); - $acceptRaw = $controller->getRequest()->parseAccept(); + $acceptRaw = $content->parseAccept($request); if (empty($acceptRaw)) { return $type ? $type === $this->ext : $this->ext; } @@ -470,12 +475,7 @@ public function respondAs($type, array $options = []): bool } if (is_array($cType)) { $cType = $cType[$options['index']] ?? $cType; - - if ($this->prefers($cType)) { - $cType = $this->prefers($cType); - } else { - $cType = $cType[0]; - } + $cType = $this->prefers($cType) ?: $cType[0]; } if (!$cType) { diff --git a/app/vendor/cakephp/cakephp/src/Controller/Controller.php b/app/vendor/cakephp/cakephp/src/Controller/Controller.php index a3300fbde..623214fd6 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/Controller.php +++ b/app/vendor/cakephp/cakephp/src/Controller/Controller.php @@ -19,18 +19,25 @@ use Cake\Controller\Exception\MissingActionException; use Cake\Core\App; use Cake\Datasource\ModelAwareTrait; +use Cake\Datasource\Paging\Exception\PageOutOfBoundsException; +use Cake\Datasource\Paging\NumericPaginator; +use Cake\Datasource\Paging\PaginatorInterface; use Cake\Event\EventDispatcherInterface; use Cake\Event\EventDispatcherTrait; use Cake\Event\EventInterface; use Cake\Event\EventListenerInterface; use Cake\Event\EventManagerInterface; +use Cake\Http\ContentTypeNegotiation; +use Cake\Http\Exception\NotFoundException; use Cake\Http\Response; use Cake\Http\ServerRequest; use Cake\Log\LogTrait; use Cake\ORM\Locator\LocatorAwareTrait; use Cake\Routing\Router; +use Cake\View\View; use Cake\View\ViewVarsTrait; use Closure; +use InvalidArgumentException; use Psr\Http\Message\ResponseInterface; use ReflectionClass; use ReflectionException; @@ -86,6 +93,7 @@ * @property \Cake\Controller\Component\AuthComponent $Auth * @link https://book.cakephp.org/4/en/controllers.html */ +#[\AllowDynamicProperties] class Controller implements EventListenerInterface, EventDispatcherInterface { use EventDispatcherTrait; @@ -128,7 +136,7 @@ class Controller implements EventListenerInterface, EventDispatcherInterface * tables your controller will be paginating. * * @var array - * @see \Cake\Controller\Component\PaginatorComponent + * @see \Cake\Datasource\Paging\NumericPaginator */ public $paginate = []; @@ -759,12 +767,78 @@ public function render(?string $template = null, ?string $layout = null): Respon if ($builder->getTemplate() === null) { $builder->setTemplate($this->request->getParam('action')); } + $viewClass = $this->chooseViewClass(); + $view = $this->createView($viewClass); - $view = $this->createView(); $contents = $view->render(); - $this->setResponse($view->getResponse()->withStringBody($contents)); + $response = $view->getResponse()->withStringBody($contents); - return $this->response; + return $this->setResponse($response)->response; + } + + /** + * Get the View classes this controller can perform content negotiation with. + * + * Each view class must implement the `getContentType()` hook method + * to participate in negotiation. + * + * @see Cake\Http\ContentTypeNegotiation + * @return array + */ + public function viewClasses(): array + { + return []; + } + + /** + * Use the view classes defined on this controller to view + * selection based on content-type negotiation. + * + * @return string|null The chosen view class or null for no decision. + */ + protected function chooseViewClass(): ?string + { + $possibleViewClasses = $this->viewClasses(); + if (empty($possibleViewClasses)) { + return null; + } + // Controller or component has already made a view class decision. + // That decision should overwrite the framework behavior. + if ($this->viewBuilder()->getClassName() !== null) { + return null; + } + + $typeMap = []; + foreach ($possibleViewClasses as $class) { + $viewContentType = $class::contentType(); + if ($viewContentType && !isset($typeMap[$viewContentType])) { + $typeMap[$viewContentType] = $class; + } + } + $request = $this->getRequest(); + + // Prefer the _ext route parameter if it is defined. + $ext = $request->getParam('_ext'); + if ($ext) { + $extTypes = (array)($this->response->getMimeType($ext) ?: []); + foreach ($extTypes as $extType) { + if (isset($typeMap[$extType])) { + return $typeMap[$extType]; + } + } + + throw new NotFoundException(); + } + + // Use accept header based negotiation. + $contentType = new ContentTypeNegotiation(); + $preferredType = $contentType->preferredType($request, array_keys($typeMap)); + if ($preferredType) { + return $typeMap[$preferredType]; + } + + // Use the match-all view if available or null for no decision. + return $typeMap[View::TYPE_MATCH_ALL] ?? null; } /** @@ -818,7 +892,7 @@ public function referer($default = '/', bool $local = true): string /** * Handles pagination of records in Table objects. * - * Will load the referenced Table object, and have the PaginatorComponent + * Will load the referenced Table object, and have the paginator * paginate the query using the request date and settings defined in `$this->paginate`. * * This method will also make the PaginatorHelper available in the view. @@ -847,13 +921,57 @@ public function paginate($object = null, array $settings = []) } } - $this->loadComponent('Paginator'); if (empty($table)) { throw new RuntimeException('Unable to locate an object compatible with paginate.'); } + $settings += $this->paginate; - return $this->Paginator->paginate($table, $settings); + if (isset($this->Paginator)) { + return $this->Paginator->paginate($table, $settings); + } + + if (isset($settings['paginator'])) { + $settings['className'] = $settings['paginator']; + deprecationWarning( + '`paginator` option is deprecated,' + . ' use `className` instead a specify a paginator name/FQCN.' + ); + } + + $paginator = $settings['className'] ?? NumericPaginator::class; + unset($settings['className']); + if (is_string($paginator)) { + $className = App::className($paginator, 'Datasource/Paging', 'Paginator'); + if ($className === null) { + throw new InvalidArgumentException('Invalid paginator: ' . $paginator); + } + $paginator = new $className(); + } + if (!$paginator instanceof PaginatorInterface) { + throw new InvalidArgumentException('Paginator must be an instance of ' . PaginatorInterface::class); + } + + $results = null; + try { + $results = $paginator->paginate( + $table, + $this->request->getQueryParams(), + $settings + ); + } catch (PageOutOfBoundsException $e) { + // Exception thrown below + } finally { + $paging = $paginator->getPagingParams() + (array)$this->request->getAttribute('paging', []); + $this->request = $this->request->withAttribute('paging', $paging); + } + + if (isset($e)) { + throw new NotFoundException(null, null, $e); + } + + /** @psalm-suppress NullableReturnStatement */ + return $results; } /** diff --git a/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php b/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php index 65a09ca99..3ebf99fa4 100644 --- a/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php +++ b/app/vendor/cakephp/cakephp/src/Controller/ControllerFactory.php @@ -79,10 +79,9 @@ public function create(ServerRequestInterface $request): Controller throw $this->missingController($request); } - // If the controller has a container definition - // add the request as a service. + // Get the controller from the container if defined. + // The request is in the container by default. if ($this->container->has($className)) { - $this->container->add(ServerRequest::class, $request); $controller = $this->container->get($className); } else { $controller = $reflection->newInstance($request); @@ -269,7 +268,7 @@ protected function coerceStringToType(string $argument, ReflectionNamedType $typ case 'float': return is_numeric($argument) ? (float)$argument : null; case 'int': - return ctype_digit($argument) ? (int)$argument : null; + return filter_var($argument, FILTER_VALIDATE_INT, FILTER_NULL_ON_FAILURE); case 'bool': return $argument === '0' ? false : ($argument === '1' ? true : null); case 'array': @@ -347,7 +346,7 @@ function ($val) { protected function missingController(ServerRequest $request) { return new MissingControllerException([ - 'class' => $request->getParam('controller'), + 'controller' => $request->getParam('controller'), 'plugin' => $request->getParam('plugin'), 'prefix' => $request->getParam('prefix'), '_ext' => $request->getParam('_ext'), diff --git a/app/vendor/cakephp/cakephp/src/Core/Configure.php b/app/vendor/cakephp/cakephp/src/Core/Configure.php index e4e8f10d8..99e82592a 100644 --- a/app/vendor/cakephp/cakephp/src/Core/Configure.php +++ b/app/vendor/cakephp/cakephp/src/Core/Configure.php @@ -37,7 +37,7 @@ class Configure /** * Array of values currently stored in Configure. * - * @var array + * @var array */ protected static $_values = [ 'debug' => false, @@ -78,7 +78,7 @@ class Configure * * @param array|string $config The key to write, can be a dot notation value. * Alternatively can be an array containing key(s) and value(s). - * @param mixed $value Value to set for var + * @param mixed $value Value to set for the given key. * @return void * @link https://book.cakephp.org/4/en/development/configuration.html#writing-configuration-data */ @@ -88,8 +88,8 @@ public static function write($config, $value = null): void $config = [$config => $value]; } - foreach ($config as $name => $value) { - static::$_values = Hash::insert(static::$_values, $name, $value); + foreach ($config as $name => $valueToInsert) { + static::$_values = Hash::insert(static::$_values, $name, $valueToInsert); } if (isset($config['debug'])) { diff --git a/app/vendor/cakephp/cakephp/src/Core/Container.php b/app/vendor/cakephp/cakephp/src/Core/Container.php index 27ccafbb5..b5b56f2b0 100644 --- a/app/vendor/cakephp/cakephp/src/Core/Container.php +++ b/app/vendor/cakephp/cakephp/src/Core/Container.php @@ -22,9 +22,6 @@ * Dependency Injection container * * Based on the container out of League\Container - * - * @experimental This class' interface is not stable and may change - * in future minor releases. */ class Container extends LeagueContainer implements ContainerInterface { diff --git a/app/vendor/cakephp/cakephp/src/Core/ContainerApplicationInterface.php b/app/vendor/cakephp/cakephp/src/Core/ContainerApplicationInterface.php index 3caff77cb..bd5f31dc6 100644 --- a/app/vendor/cakephp/cakephp/src/Core/ContainerApplicationInterface.php +++ b/app/vendor/cakephp/cakephp/src/Core/ContainerApplicationInterface.php @@ -18,9 +18,6 @@ /** * Interface for applications that configure and use a dependency injection container. - * - * @experimental This interface is not final and can have additional - * methods and parameters added in future minor releases. */ interface ContainerApplicationInterface { diff --git a/app/vendor/cakephp/cakephp/src/Core/ContainerInterface.php b/app/vendor/cakephp/cakephp/src/Core/ContainerInterface.php index 244e45f7e..d8d39e1bc 100644 --- a/app/vendor/cakephp/cakephp/src/Core/ContainerInterface.php +++ b/app/vendor/cakephp/cakephp/src/Core/ContainerInterface.php @@ -26,9 +26,6 @@ * * The methods defined in this interface use the conventions provided * by league/container as that is the library that CakePHP uses. - * - * @experimental This interface is not final and can have additional - * methods and parameters added in future minor releases. */ interface ContainerInterface extends DefinitionContainerInterface { diff --git a/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php b/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php index 4c85e326c..1862d6e43 100644 --- a/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php +++ b/app/vendor/cakephp/cakephp/src/Core/PluginCollection.php @@ -238,15 +238,28 @@ public function create(string $name, array $config = []): PluginInterface } $config += ['name' => $name]; - /** @var class-string<\Cake\Core\PluginInterface> $className */ - $className = str_replace('/', '\\', $name) . '\\' . 'Plugin'; + $namespace = str_replace('/', '\\', $name); + + $className = $namespace . '\\' . 'Plugin'; + // Check for [Vendor/]Foo/Plugin class if (!class_exists($className)) { - $className = BasePlugin::class; - if (empty($config['path'])) { - $config['path'] = $this->findPath($name); + $pos = strpos($name, '/'); + if ($pos === false) { + $className = $namespace . '\\' . $name . 'Plugin'; + } else { + $className = $namespace . '\\' . substr($name, $pos + 1) . 'Plugin'; + } + + // Check for [Vendor/]Foo/FooPlugin + if (!class_exists($className)) { + $className = BasePlugin::class; + if (empty($config['path'])) { + $config['path'] = $this->findPath($name); + } } } + /** @var class-string<\Cake\Core\PluginInterface> $className */ return new $className($config); } diff --git a/app/vendor/cakephp/cakephp/src/Core/ServiceProvider.php b/app/vendor/cakephp/cakephp/src/Core/ServiceProvider.php index b2ed8add9..8ff9b9cae 100644 --- a/app/vendor/cakephp/cakephp/src/Core/ServiceProvider.php +++ b/app/vendor/cakephp/cakephp/src/Core/ServiceProvider.php @@ -28,9 +28,6 @@ * to organize your application's dependencies. They also help * improve performance of applications with many services by * allowing service registration to be deferred until services are needed. - * - * @experimental This class' interface is not stable and may change - * in future minor releases. */ abstract class ServiceProvider extends AbstractServiceProvider implements BootableServiceProviderInterface { diff --git a/app/vendor/cakephp/cakephp/src/Core/TestSuite/ContainerStubTrait.php b/app/vendor/cakephp/cakephp/src/Core/TestSuite/ContainerStubTrait.php new file mode 100644 index 000000000..909ade79f --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Core/TestSuite/ContainerStubTrait.php @@ -0,0 +1,174 @@ +|class-string<\Cake\Core\ConsoleApplicationInterface>|null + * @var string|null + */ + protected $_appClass; + + /** + * The customized application constructor arguments. + * + * @var array|null + */ + protected $_appArgs; + + /** + * The collection of container services. + * + * @var array + */ + private $containerServices = []; + + /** + * Configure the application class to use in integration tests. + * + * @param string $class The application class name. + * @param array|null $constructorArgs The constructor arguments for your application class. + * @return void + * @psalm-param class-string<\Cake\Core\HttpApplicationInterface>|class-string<\Cake\Core\ConsoleApplicationInterface> $class + */ + public function configApplication(string $class, ?array $constructorArgs): void + { + $this->_appClass = $class; + $this->_appArgs = $constructorArgs; + } + + /** + * Create an application instance. + * + * Uses the configuration set in `configApplication()`. + * + * @return \Cake\Core\HttpApplicationInterface|\Cake\Core\ConsoleApplicationInterface + */ + protected function createApp() + { + if ($this->_appClass) { + $appClass = $this->_appClass; + } else { + /** @psalm-var class-string<\Cake\Http\BaseApplication> */ + $appClass = Configure::read('App.namespace') . '\Application'; + } + if (!class_exists($appClass)) { + throw new LogicException("Cannot load `{$appClass}` for use in integration testing."); + } + $appArgs = $this->_appArgs ?: [CONFIG]; + + $app = new $appClass(...$appArgs); + if (!empty($this->containerServices) && method_exists($app, 'getEventManager')) { + $app->getEventManager()->on('Application.buildContainer', [$this, 'modifyContainer']); + } + + return $app; + } + + /** + * Add a mocked service to the container. + * + * When the container is created the provided classname + * will be mapped to the factory function. The factory + * function will be used to create mocked services. + * + * @param string $class The class or interface you want to define. + * @param \Closure $factory The factory function for mocked services. + * @return $this + */ + public function mockService(string $class, Closure $factory) + { + $this->containerServices[$class] = $factory; + + return $this; + } + + /** + * Remove a mocked service to the container. + * + * @param string $class The class or interface you want to remove. + * @return $this + */ + public function removeMockService(string $class) + { + unset($this->containerServices[$class]); + + return $this; + } + + /** + * Wrap the application's container with one containing mocks. + * + * If any mocked services are defined, the application's container + * will be replaced with one containing mocks. The original + * container will be set as a delegate to the mock container. + * + * @param \Cake\Event\EventInterface $event The event + * @param \Cake\Core\ContainerInterface $container The container to wrap. + * @return \Cake\Core\ContainerInterface|null + */ + public function modifyContainer(EventInterface $event, ContainerInterface $container): ?ContainerInterface + { + if (empty($this->containerServices)) { + return null; + } + foreach ($this->containerServices as $key => $factory) { + if ($container->has($key)) { + try { + $container->extend($key)->setConcrete($factory); + } catch (NotFoundException $e) { + $container->add($key, $factory); + } + } else { + $container->add($key, $factory); + } + } + + return $container; + } + + /** + * Clears any mocks that were defined and cleans + * up application class configuration. + * + * @after + * @return void + */ + public function cleanupContainer(): void + { + $this->_appArgs = null; + $this->_appClass = null; + $this->containerServices = []; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Core/composer.json b/app/vendor/cakephp/cakephp/src/Core/composer.json index ffd17ba7a..2a62b03ec 100644 --- a/app/vendor/cakephp/cakephp/src/Core/composer.json +++ b/app/vendor/cakephp/cakephp/src/Core/composer.json @@ -22,7 +22,7 @@ "source": "https://github.com/cakephp/core" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/utility": "^4.0" }, "suggest": { diff --git a/app/vendor/cakephp/cakephp/src/Core/functions.php b/app/vendor/cakephp/cakephp/src/Core/functions.php index 2ca8619e8..e74ac1736 100644 --- a/app/vendor/cakephp/cakephp/src/Core/functions.php +++ b/app/vendor/cakephp/cakephp/src/Core/functions.php @@ -30,7 +30,7 @@ * * @param mixed $text Text to wrap through htmlspecialchars. Also works with arrays, and objects. * Arrays will be mapped and have all their elements escaped. Objects will be string cast if they - * implement a `__toString` method. Otherwise the class name will be used. + * implement a `__toString` method. Otherwise, the class name will be used. * Other scalar types will be returned unchanged. * @param bool $double Encode existing html entities. * @param string|null $charset Character set to use when escaping. @@ -206,8 +206,10 @@ function env(string $key, $default = null) $key = 'SCRIPT_URL'; } + /** @var string|null $val */ $val = $_SERVER[$key] ?? $_ENV[$key] ?? null; if ($val == null && getenv($key) !== false) { + /** @var string|false $val */ $val = getenv($key); } diff --git a/app/vendor/cakephp/cakephp/src/Database/Connection.php b/app/vendor/cakephp/cakephp/src/Database/Connection.php index 5153d0e81..92a54ae8d 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Connection.php +++ b/app/vendor/cakephp/cakephp/src/Database/Connection.php @@ -31,6 +31,7 @@ use Cake\Database\Schema\Collection as SchemaCollection; use Cake\Database\Schema\CollectionInterface as SchemaCollectionInterface; use Cake\Datasource\ConnectionInterface; +use Cake\Log\Engine\BaseLog; use Cake\Log\Log; use Psr\Log\LoggerInterface; use Psr\SimpleCache\CacheInterface; @@ -135,11 +136,14 @@ public function __construct(array $config) { $this->_config = $config; - $driver = ''; - if (!empty($config['driver'])) { - $driver = $config['driver']; - } - $this->setDriver($driver, $config); + $driverConfig = array_diff_key($config, array_flip([ + 'name', + 'driver', + 'log', + 'cacheMetaData', + 'cacheKeyPrefix', + ])); + $this->_driver = $this->createDriver($config['driver'] ?? '', $driverConfig); if (!empty($config['log'])) { $this->enableQueryLogging((bool)$config['log']); @@ -183,24 +187,43 @@ public function configName(): string * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing. * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing. * @return $this + * @deprecated 4.4.0 Setting the driver is deprecated. Use the connection config instead. */ public function setDriver($driver, $config = []) { + deprecationWarning('Setting the driver is deprecated. Use the connection config instead.'); + + $this->_driver = $this->createDriver($driver, $config); + + return $this; + } + + /** + * Creates driver from name, class name or instance. + * + * @param \Cake\Database\DriverInterface|string $name Driver name, class name or instance. + * @param array $config Driver config if $name is not an instance. + * @return \Cake\Database\DriverInterface + * @throws \Cake\Database\Exception\MissingDriverException When a driver class is missing. + * @throws \Cake\Database\Exception\MissingExtensionException When a driver's PHP extension is missing. + */ + protected function createDriver($name, array $config): DriverInterface + { + $driver = $name; if (is_string($driver)) { /** @psalm-var class-string<\Cake\Database\DriverInterface>|null $className */ $className = App::className($driver, 'Database/Driver'); if ($className === null) { - throw new MissingDriverException(['driver' => $driver]); + throw new MissingDriverException(['driver' => $driver, 'connection' => $this->configName()]); } $driver = new $className($config); } + if (!$driver->enabled()) { - throw new MissingExtensionException(['driver' => get_class($driver), 'name' => $config['name']]); + throw new MissingExtensionException(['driver' => get_class($driver), 'name' => $this->configName()]); } - $this->_driver = $driver; - - return $this; + return $driver; } /** @@ -406,7 +429,7 @@ public function getSchemaCollection(): SchemaCollectionInterface * * @param string $table the table to insert values in * @param array $values values to be inserted - * @param array $types list of associative array containing the types to be used for casting + * @param array $types Array containing the types to be used for casting * @return \Cake\Database\StatementInterface */ public function insert(string $table, array $values, array $types = []): StatementInterface @@ -427,7 +450,7 @@ public function insert(string $table, array $values, array $types = []): Stateme * @param string $table the table to update rows from * @param array $values values to be updated * @param array $conditions conditions to be set for update statement - * @param array $types list of associative array containing the types to be used for casting + * @param array $types list of associative array containing the types to be used for casting * @return \Cake\Database\StatementInterface */ public function update(string $table, array $values, array $conditions = [], array $types = []): StatementInterface @@ -445,7 +468,7 @@ public function update(string $table, array $values, array $conditions = [], arr * * @param string $table the table to delete rows from * @param array $conditions conditions to be set for delete statement - * @param array $types list of associative array containing the types to be used for casting + * @param array $types list of associative array containing the types to be used for casting * @return \Cake\Database\StatementInterface */ public function delete(string $table, array $conditions = [], array $types = []): StatementInterface @@ -897,7 +920,7 @@ public function getLogger(): LoggerInterface return $this->_logger; } - if (!class_exists(QueryLogger::class)) { + if (!class_exists(BaseLog::class)) { throw new RuntimeException( 'For logging you must either set a logger using Connection::setLogger()' . ' or require the cakephp/log package in your composer config.' diff --git a/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php b/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php index 0b2cdb0c5..6ca955856 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php +++ b/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlite.php @@ -29,6 +29,7 @@ use Cake\Database\StatementInterface; use InvalidArgumentException; use PDO; +use RuntimeException; /** * Class Sqlite @@ -52,6 +53,8 @@ class Sqlite extends Driver 'database' => ':memory:', 'encoding' => 'utf8', 'mask' => 0644, + 'cache' => null, + 'mode' => null, 'flags' => [], 'init' => [], ]; @@ -132,12 +135,30 @@ public function connect(): bool ); } - $databaseExists = file_exists($config['database']); + $chmodFile = false; + if ($config['database'] !== ':memory:' && $config['mode'] !== 'memory') { + $chmodFile = !file_exists($config['database']); + } - $dsn = "sqlite:{$config['database']}"; - $this->_connect($dsn, $config); + $params = []; + if ($config['cache']) { + $params[] = 'cache=' . $config['cache']; + } + if ($config['mode']) { + $params[] = 'mode=' . $config['mode']; + } - if (!$databaseExists && $config['database'] !== ':memory:') { + if ($params) { + if (PHP_VERSION_ID < 80100) { + throw new RuntimeException('SQLite URI support requires PHP 8.1.'); + } + $dsn = 'sqlite:file:' . $config['database'] . '?' . implode('&', $params); + } else { + $dsn = 'sqlite:' . $config['database']; + } + + $this->_connect($dsn, $config); + if ($chmodFile) { // phpcs:disable @chmod($config['database'], $config['mask']); // phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php b/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php index 23e23dd2e..a0dc2ec58 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php +++ b/app/vendor/cakephp/cakephp/src/Database/Driver/Sqlserver.php @@ -75,6 +75,8 @@ class Sqlserver extends Driver 'failoverPartner' => null, 'loginTimeout' => null, 'multiSubnetFailover' => null, + 'encrypt' => null, + 'trustServerCertificate' => null, ]; /** @@ -151,6 +153,12 @@ public function connect(): bool if ($config['multiSubnetFailover'] !== null) { $dsn .= ";MultiSubnetFailover={$config['multiSubnetFailover']}"; } + if ($config['encrypt'] !== null) { + $dsn .= ";Encrypt={$config['encrypt']}"; + } + if ($config['trustServerCertificate'] !== null) { + $dsn .= ";TrustServerCertificate={$config['trustServerCertificate']}"; + } $this->_connect($dsn, $config); $connection = $this->getConnection(); diff --git a/app/vendor/cakephp/cakephp/src/Database/Exception/MissingDriverException.php b/app/vendor/cakephp/cakephp/src/Database/Exception/MissingDriverException.php index d9f142264..77532a16c 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Exception/MissingDriverException.php +++ b/app/vendor/cakephp/cakephp/src/Database/Exception/MissingDriverException.php @@ -26,5 +26,5 @@ class MissingDriverException extends CakeException /** * @inheritDoc */ - protected $_messageTemplate = 'Database driver %s could not be found.'; + protected $_messageTemplate = 'Could not find driver `%s` for connection `%s`.'; } diff --git a/app/vendor/cakephp/cakephp/src/Database/Expression/CaseExpressionTrait.php b/app/vendor/cakephp/cakephp/src/Database/Expression/CaseExpressionTrait.php index e486a193f..8d1728b9e 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Expression/CaseExpressionTrait.php +++ b/app/vendor/cakephp/cakephp/src/Database/Expression/CaseExpressionTrait.php @@ -20,6 +20,7 @@ use Cake\Chronos\MutableDate; use Cake\Database\ExpressionInterface; use Cake\Database\Query; +use Cake\Database\TypedResultInterface; use Cake\Database\ValueBinder; use DateTimeInterface; @@ -67,6 +68,8 @@ protected function inferType($value): ?string $value instanceof IdentifierExpression ) { $type = $this->_typeMap->type($value->getIdentifier()); + } elseif ($value instanceof TypedResultInterface) { + $type = $value->getReturnType(); } return $type; diff --git a/app/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php b/app/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php index 2ab13d219..edb67399e 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php +++ b/app/vendor/cakephp/cakephp/src/Database/Expression/QueryExpression.php @@ -51,7 +51,7 @@ class QueryExpression implements ExpressionInterface, Countable /** * Constructor. A new expression object can be created without any params and - * be built dynamically. Otherwise it is possible to pass an array of conditions + * be built dynamically. Otherwise, it is possible to pass an array of conditions * containing either a tree-like array structure to be parsed and/or other * expression objects. Optionally, you can set the conjunction keyword to be used * for joining each part of this level of the expression tree. @@ -111,7 +111,7 @@ public function getConjunction(): string * be added. When using an array and the key is 'OR' or 'AND' a new expression * object will be created with that conjunction and internal array value passed * as conditions. - * @param array $types Associative array of fields pointing to the type of the + * @param array $types Associative array of fields pointing to the type of the * values that are being passed. Used for correctly binding values to statements. * @see \Cake\Database\Query::where() for examples on conditions * @return $this @@ -702,7 +702,7 @@ public function hasNestedExpression(): bool * representation is wrapped around an adequate instance or of this class. * * @param array $conditions list of conditions to be stored in this object - * @param array $types list of types associated on fields referenced in $conditions + * @param array $types list of types associated on fields referenced in $conditions * @return void */ protected function _addConditions(array $conditions, array $types): void diff --git a/app/vendor/cakephp/cakephp/src/Database/Expression/WhenThenExpression.php b/app/vendor/cakephp/cakephp/src/Database/Expression/WhenThenExpression.php index bf51eaf19..e4bbc0878 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Expression/WhenThenExpression.php +++ b/app/vendor/cakephp/cakephp/src/Database/Expression/WhenThenExpression.php @@ -134,7 +134,7 @@ public function when($when, $type = null) 'The `$when` argument must be either a non-empty array, a scalar value, an object, ' . 'or an instance of `\%s`, `%s` given.', ExpressionInterface::class, - is_array($when) ? '[]' : getTypeName($when) + is_array($when) ? '[]' : getTypeName($when) // @phpstan-ignore-line )); } diff --git a/app/vendor/cakephp/cakephp/src/Database/Expression/WindowExpression.php b/app/vendor/cakephp/cakephp/src/Database/Expression/WindowExpression.php index 3604be4b0..383e652cf 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Expression/WindowExpression.php +++ b/app/vendor/cakephp/cakephp/src/Database/Expression/WindowExpression.php @@ -310,13 +310,11 @@ protected function buildOffsetSql(ValueBinder $binder, $offset, string $directio $offset = $offset->sql($binder); } - $sql = sprintf( + return sprintf( '%s %s', $offset ?? 'UNBOUNDED', $direction ); - - return $sql; } /** diff --git a/app/vendor/cakephp/cakephp/src/Database/FieldTypeConverter.php b/app/vendor/cakephp/cakephp/src/Database/FieldTypeConverter.php index ff7f39f67..3448aa1ef 100644 --- a/app/vendor/cakephp/cakephp/src/Database/FieldTypeConverter.php +++ b/app/vendor/cakephp/cakephp/src/Database/FieldTypeConverter.php @@ -118,7 +118,7 @@ public function __construct(TypeMap $typeMap, DriverInterface $driver) * using the corresponding Type class. * * @param array $row The array with the fields to be casted - * @return array + * @return array */ public function __invoke(array $row): array { diff --git a/app/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php b/app/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php index 6b21a5ad6..b3a93e262 100644 --- a/app/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php +++ b/app/vendor/cakephp/cakephp/src/Database/IdentifierQuoter.php @@ -128,8 +128,8 @@ protected function _quoteParts(Query $query): void /** * A generic identifier quoting function used for various parts of the query * - * @param array $part the part of the query to quote - * @return array + * @param array $part the part of the query to quote + * @return array */ protected function _basicQuoter(array $part): array { @@ -148,7 +148,7 @@ protected function _basicQuoter(array $part): array * object * * @param array $joins The joins to quote. - * @return array + * @return array */ protected function _quoteJoins(array $joins): array { diff --git a/app/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php b/app/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php index 22814e394..47e529a55 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php +++ b/app/vendor/cakephp/cakephp/src/Database/Log/LoggingStatement.php @@ -75,8 +75,14 @@ public function execute(?array $params = null): bool $result = parent::execute($params); $this->loggedQuery->took = (int)round((microtime(true) - $this->startTime) * 1000, 0); } catch (Exception $e) { - /** @psalm-suppress UndefinedPropertyAssignment */ - $e->queryString = $this->queryString; + if (version_compare(PHP_VERSION, '8.2.0', '<')) { + deprecationWarning( + '4.4.12 - Having queryString set on exceptions is deprecated.' . + 'If you are not using this attribute there is no action to take.' + ); + /** @psalm-suppress UndefinedPropertyAssignment */ + $e->queryString = $this->queryString; + } $this->loggedQuery->error = $e; $this->_log(); throw $e; diff --git a/app/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php b/app/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php index b6957d1a5..a7f27b489 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php +++ b/app/vendor/cakephp/cakephp/src/Database/Log/QueryLogger.php @@ -52,6 +52,6 @@ public function log($level, $message, array $context = []) $context = $context['query']->getContext() + $context; $message = 'connection={connection} duration={took} rows={numRows} ' . $message; } - Log::write('debug', $message, $context); + Log::write('debug', (string)$message, $context); } } diff --git a/app/vendor/cakephp/cakephp/src/Database/Query.php b/app/vendor/cakephp/cakephp/src/Database/Query.php index 3df66cd51..fc66f6e80 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Query.php +++ b/app/vendor/cakephp/cakephp/src/Database/Query.php @@ -101,6 +101,7 @@ class Query implements ExpressionInterface, IteratorAggregate * The list of query clauses to traverse for generating a SELECT statement * * @var array + * @deprecated 4.4.3 This property is unused. */ protected $_selectParts = [ 'with', 'select', 'from', 'join', 'where', 'group', 'having', 'order', 'limit', @@ -111,6 +112,7 @@ class Query implements ExpressionInterface, IteratorAggregate * The list of query clauses to traverse for generating an UPDATE statement * * @var array + * @deprecated 4.4.3 This property is unused. */ protected $_updateParts = ['with', 'update', 'set', 'where', 'epilog']; @@ -118,6 +120,7 @@ class Query implements ExpressionInterface, IteratorAggregate * The list of query clauses to traverse for generating a DELETE statement * * @var array + * @deprecated 4.4.3 This property is unused. */ protected $_deleteParts = ['with', 'delete', 'modifier', 'from', 'where', 'epilog']; @@ -125,6 +128,7 @@ class Query implements ExpressionInterface, IteratorAggregate * The list of query clauses to traverse for generating an INSERT statement * * @var array + * @deprecated 4.4.3 This property is unused. */ protected $_insertParts = ['with', 'insert', 'values', 'epilog']; @@ -996,6 +1000,19 @@ protected function _makeJoin($table, $conditions, $type): array * If you use string conditions make sure that your values are correctly quoted. * The safest thing you can do is to never use string conditions. * + * ### Using null-able values + * + * When using values that can be null you can use the 'IS' keyword to let the ORM generate the correct SQL based on the value's type + * + * ``` + * $query->where([ + * 'posted >=' => new DateTime('3 days ago'), + * 'category_id IS' => $category, + * ]); + * ``` + * + * If $category is `null` - it will actually convert that into `category_id IS NULL` - if it's `4` it will convert it into `category_id = 4` + * * @param \Cake\Database\ExpressionInterface|\Closure|array|string|null $conditions The conditions to filter on. * @param array $types Associative array of type names used to bind values to query * @param bool $overwrite whether to reset conditions with passed list or not @@ -1530,6 +1547,9 @@ public function page(int $num, ?int $limit = null) */ public function limit($limit) { + if (is_string($limit) && !is_numeric($limit)) { + throw new InvalidArgumentException('Invalid value for `limit()`'); + } $this->_dirty(); $this->_parts['limit'] = $limit; @@ -1556,6 +1576,9 @@ public function limit($limit) */ public function offset($offset) { + if (is_string($offset) && !is_numeric($offset)) { + throw new InvalidArgumentException('Invalid value for `offset()`'); + } $this->_dirty(); $this->_parts['offset'] = $offset; @@ -1642,7 +1665,7 @@ public function unionAll($query, $overwrite = false) * with Query::values(). * * @param array $columns The columns to insert into. - * @param array $types A map between columns & their datatypes. + * @param array $types A map between columns & their datatypes. * @return $this * @throws \RuntimeException When there are 0 columns. */ @@ -1886,14 +1909,36 @@ public function type(): string * any format accepted by \Cake\Database\Expression\QueryExpression: * * ``` - * $expression = $query->newExpr(); // Returns an empty expression object - * $expression = $query->newExpr('Table.column = Table2.column'); // Return a raw SQL expression + * $expression = $query->expr(); // Returns an empty expression object + * $expression = $query->expr('Table.column = Table2.column'); // Return a raw SQL expression * ``` * * @param \Cake\Database\ExpressionInterface|array|string|null $rawExpression A string, array or anything you want wrapped in an expression object * @return \Cake\Database\Expression\QueryExpression */ public function newExpr($rawExpression = null): QueryExpression + { + return $this->expr($rawExpression); + } + + /** + * Returns a new QueryExpression object. This is a handy function when + * building complex queries using a fluent interface. You can also override + * this function in subclasses to use a more specialized QueryExpression class + * if required. + * + * You can optionally pass a single raw SQL string or an array or expressions in + * any format accepted by \Cake\Database\Expression\QueryExpression: + * + * ``` + * $expression = $query->expr(); // Returns an empty expression object + * $expression = $query->expr('Table.column = Table2.column'); // Return a raw SQL expression + * ``` + * + * @param \Cake\Database\ExpressionInterface|array|string|null $rawExpression A string, array or anything you want wrapped in an expression object + * @return \Cake\Database\Expression\QueryExpression + */ + public function expr($rawExpression = null): QueryExpression { $expression = new QueryExpression([], $this->getTypeMap()); diff --git a/app/vendor/cakephp/cakephp/src/Database/README.md b/app/vendor/cakephp/cakephp/src/Database/README.md index 877c7b68d..d7bbe8eb1 100644 --- a/app/vendor/cakephp/cakephp/src/Database/README.md +++ b/app/vendor/cakephp/cakephp/src/Database/README.md @@ -35,35 +35,29 @@ to use: ```php use Cake\Database\Connection; use Cake\Database\Driver\Mysql; +use Cake\Database\Driver\Sqlite; -$driver = new Mysql([ +$connection = new Connection([ + 'driver' => Mysql::class, 'database' => 'test', 'username' => 'root', - 'password' => 'secret' -]); -$connection = new Connection([ - 'driver' => $driver + 'password' => 'secret', ]); -``` - -Drivers are classes responsible for actually executing the commands to the database and -correctly building the SQL according to the database specific dialect. Drivers can also -be specified by passing a class name. In that case, include all the connection details -directly in the options array: -```php -use Cake\Database\Connection; - -$connection = new Connection([ - 'driver' => Cake\Database\Driver\Sqlite::class, +$connection2 = new Connection([ + 'driver' => Sqlite::class, 'database' => '/path/to/file.db' ]); ``` +Drivers are classes responsible for actually executing the commands to the database and +correctly building the SQL according to the database specific dialect. + ### Connection options This is a list of possible options that can be passed when creating a connection: +* `driver`: Driver class name * `persistent`: Creates a persistent connection * `host`: The server host * `database`: The database name diff --git a/app/vendor/cakephp/cakephp/src/Database/Retry/ReconnectStrategy.php b/app/vendor/cakephp/cakephp/src/Database/Retry/ReconnectStrategy.php index 2cdd0980e..7d76cc01e 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Retry/ReconnectStrategy.php +++ b/app/vendor/cakephp/cakephp/src/Database/Retry/ReconnectStrategy.php @@ -110,7 +110,9 @@ protected function reconnect(): bool try { $this->connection->connect(); - $this->connection->log('[RECONNECT]'); + if ($this->connection->isQueryLoggingEnabled()) { + $this->connection->log('[RECONNECT]'); + } return true; } catch (Exception $e) { diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php b/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php index d8dddef82..6142eb800 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/MysqlSchemaDialect.php @@ -238,7 +238,9 @@ public function convertIndexDescription(TableSchema $schema, array $row): void $name = $type = TableSchema::CONSTRAINT_PRIMARY; } - $columns[] = $row['Column_name']; + if (!empty($row['Column_name'])) { + $columns[] = $row['Column_name']; + } if ($row['Index_type'] === 'FULLTEXT') { $type = TableSchema::INDEX_FULLTEXT; diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/SqlGeneratorInterface.php b/app/vendor/cakephp/cakephp/src/Database/Schema/SqlGeneratorInterface.php index 3acaf27b9..9fbd5919f 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/SqlGeneratorInterface.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/SqlGeneratorInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Database\Schema; diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchema.php b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchema.php index f9ad3dcb0..3dac32330 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchema.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchema.php @@ -71,7 +71,7 @@ class TableSchema implements TableSchemaInterface, SqlGeneratorInterface /** * Options for the table. * - * @var array + * @var array */ protected $_options = []; diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaAwareInterface.php b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaAwareInterface.php index f08e363ba..d4045f9d2 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaAwareInterface.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaAwareInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Database\Schema; diff --git a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaInterface.php b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaInterface.php index 19e942de6..c3ec9d183 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaInterface.php +++ b/app/vendor/cakephp/cakephp/src/Database/Schema/TableSchemaInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Database\Schema; diff --git a/app/vendor/cakephp/cakephp/src/Database/Type/BatchCastingInterface.php b/app/vendor/cakephp/cakephp/src/Database/Type/BatchCastingInterface.php index 35f046bcb..8761f1c88 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Type/BatchCastingInterface.php +++ b/app/vendor/cakephp/cakephp/src/Database/Type/BatchCastingInterface.php @@ -31,7 +31,7 @@ interface BatchCastingInterface * @param array $values The original array of values containing the fields to be casted * @param array $fields The field keys to cast * @param \Cake\Database\DriverInterface $driver Object from which database preferences and configuration will be extracted. - * @return array + * @return array */ public function manyToPHP(array $values, array $fields, DriverInterface $driver): array; } diff --git a/app/vendor/cakephp/cakephp/src/Database/Type/BoolType.php b/app/vendor/cakephp/cakephp/src/Database/Type/BoolType.php index eeb1c8854..7bfa769bf 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Type/BoolType.php +++ b/app/vendor/cakephp/cakephp/src/Database/Type/BoolType.php @@ -59,7 +59,7 @@ public function toDatabase($value, DriverInterface $driver): ?bool */ public function toPHP($value, DriverInterface $driver): ?bool { - if ($value === null || $value === true || $value === false) { + if ($value === null || is_bool($value)) { return $value; } @@ -76,21 +76,11 @@ public function toPHP($value, DriverInterface $driver): ?bool public function manyToPHP(array $values, array $fields, DriverInterface $driver): array { foreach ($fields as $field) { - if (!isset($values[$field]) || $values[$field] === true || $values[$field] === false) { + $value = $values[$field] ?? null; + if ($value === null || is_bool($value)) { continue; } - if ($values[$field] === '1') { - $values[$field] = true; - continue; - } - - if ($values[$field] === '0') { - $values[$field] = false; - continue; - } - - $value = $values[$field]; if (!is_numeric($value)) { $values[$field] = strtolower($value) === 'true'; continue; diff --git a/app/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php b/app/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php index e87fdeaf8..655c78f3c 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php +++ b/app/vendor/cakephp/cakephp/src/Database/Type/DateTimeType.php @@ -328,7 +328,7 @@ public function marshal($value): ?DateTimeInterface return $value->setTimezone($this->defaultTimezone); } - /** @var class-string<\DatetimeInterface> $class */ + /** @var class-string<\DateTimeInterface> $class */ $class = $this->_className; try { if ($value === '' || $value === null || is_bool($value)) { @@ -336,7 +336,7 @@ public function marshal($value): ?DateTimeInterface } if (is_int($value) || (is_string($value) && ctype_digit($value))) { - /** @var \Datetime|\DateTimeImmutable $dateTime */ + /** @var \DateTime|\DateTimeImmutable $dateTime */ $dateTime = new $class('@' . $value); return $dateTime->setTimezone($this->defaultTimezone); @@ -349,7 +349,7 @@ public function marshal($value): ?DateTimeInterface $dateTime = $this->_parseValue($value); } - /** @var \Datetime|\DateTimeImmutable $dateTime */ + /** @var \DateTime|\DateTimeImmutable $dateTime */ if ($dateTime !== null) { $dateTime = $dateTime->setTimezone($this->defaultTimezone); } @@ -392,7 +392,7 @@ public function marshal($value): ?DateTimeInterface $value['microsecond'] ); - /** @var \Datetime|\DateTimeImmutable $dateTime */ + /** @var \DateTime|\DateTimeImmutable $dateTime */ $dateTime = new $class($format, $value['timezone'] ?? $this->userTimezone); return $dateTime->setTimezone($this->defaultTimezone); diff --git a/app/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php b/app/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php index 212b1aaba..4a84c59e3 100644 --- a/app/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php +++ b/app/vendor/cakephp/cakephp/src/Database/Type/IntegerType.php @@ -109,7 +109,7 @@ public function toStatement($value, DriverInterface $driver): int } /** - * Marshals request data into PHP floats. + * Marshals request data into PHP integers. * * @param mixed $value The value to convert. * @return int|null Converted value. diff --git a/app/vendor/cakephp/cakephp/src/Database/TypeMap.php b/app/vendor/cakephp/cakephp/src/Database/TypeMap.php index ad3482cb8..ac3f8eb8b 100644 --- a/app/vendor/cakephp/cakephp/src/Database/TypeMap.php +++ b/app/vendor/cakephp/cakephp/src/Database/TypeMap.php @@ -22,29 +22,29 @@ class TypeMap { /** - * Associative array with the default fields and the related types this query might contain. + * Array with the default fields and the related types this query might contain. * * Used to avoid repetition when calling multiple functions inside this class that * may require a custom type for a specific field. * - * @var array + * @var array */ protected $_defaults = []; /** - * Associative array with the fields and the related types that override defaults this query might contain + * Array with the fields and the related types that override defaults this query might contain * * Used to avoid repetition when calling multiple functions inside this class that * may require a custom type for a specific field. * - * @var array + * @var array */ protected $_types = []; /** * Creates an instance with the given defaults * - * @param array $defaults The defaults to use. + * @param array $defaults The defaults to use. */ public function __construct(array $defaults = []) { @@ -69,7 +69,7 @@ public function __construct(array $defaults = []) * This method will replace all the existing default mappings with the ones provided. * To add into the mappings use `addDefaults()`. * - * @param array $defaults Associative array where keys are field names and values + * @param array $defaults Array where keys are field names / positions and values * are the correspondent type. * @return $this */ @@ -83,7 +83,7 @@ public function setDefaults(array $defaults) /** * Returns the currently configured types. * - * @return array + * @return array */ public function getDefaults(): array { @@ -95,7 +95,7 @@ public function getDefaults(): array * * If a key already exists it will not be overwritten. * - * @param array $types The additional types to add. + * @param array $types The additional types to add. * @return void */ public function addDefaults(array $types): void @@ -114,7 +114,7 @@ public function addDefaults(array $types): void * * This method will replace all the existing type maps with the ones provided. * - * @param array $types Associative array where keys are field names and values + * @param array $types Array where keys are field names / positions and values * are the correspondent type. * @return $this */ @@ -128,7 +128,7 @@ public function setTypes(array $types) /** * Gets a map of fields and their associated types for single-use. * - * @return array + * @return array */ public function getTypes(): array { @@ -151,7 +151,7 @@ public function type($column): ?string /** * Returns an array of all types mapped types * - * @return array + * @return array */ public function toArray(): array { diff --git a/app/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php b/app/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php index d33070937..402a9b5fe 100644 --- a/app/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php +++ b/app/vendor/cakephp/cakephp/src/Database/TypeMapTrait.php @@ -66,7 +66,7 @@ public function getTypeMap(): TypeMap * To add a default without overwriting existing ones * use `getTypeMap()->addDefaults()` * - * @param array $types The array of types to set. + * @param array $types The array of types to set. * @return $this * @see \Cake\Database\TypeMap::setDefaults() */ @@ -80,7 +80,7 @@ public function setDefaultTypes(array $types) /** * Gets default types of current type map. * - * @return array + * @return array */ public function getDefaultTypes(): array { diff --git a/app/vendor/cakephp/cakephp/src/Database/composer.json b/app/vendor/cakephp/cakephp/src/Database/composer.json index 93251172c..64c22e80b 100644 --- a/app/vendor/cakephp/cakephp/src/Database/composer.json +++ b/app/vendor/cakephp/cakephp/src/Database/composer.json @@ -24,12 +24,13 @@ "source": "https://github.com/cakephp/database" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "cakephp/datasource": "^4.0" }, "suggest": { - "cakephp/i18n": "If you are using locale-aware datetime formats or Chronos types." + "cakephp/i18n": "If you are using locale-aware datetime formats or Chronos types.", + "cakephp/log": "If you want to use query logging without providing a logger yourself." }, "autoload": { "psr-4": { diff --git a/app/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php b/app/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php index fcf96b65d..01a7d5330 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/ConnectionInterface.php @@ -74,7 +74,7 @@ public function configName(): string; /** * Get the configuration data used to create the connection. * - * @return array + * @return array */ public function config(): array; @@ -82,7 +82,7 @@ public function config(): array; * Executes a callable function inside a transaction, if any exception occurs * while executing the passed callable, the transaction will be rolled back * If the result of the callable function is `false`, the transaction will - * also be rolled back. Otherwise the transaction is committed after executing + * also be rolled back. Otherwise, the transaction is committed after executing * the callback. * * The callback will receive the connection instance as its first argument. diff --git a/app/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php b/app/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php index a18b4cdea..b8ef4a9dd 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/EntityTrait.php @@ -107,7 +107,7 @@ trait EntityTrait * not defined in the map will take its value. For example, `'*' => true` * means that any field not defined in the map will be accessible by default * - * @var array + * @var array */ protected $_accessible = ['*' => true]; @@ -279,12 +279,12 @@ public function &get(string $field) } $value = null; - $method = static::_accessor($field, 'get'); if (isset($this->_fields[$field])) { $value = &$this->_fields[$field]; } + $method = static::_accessor($field, 'get'); if ($method) { $result = $this->{$method}($value); @@ -1071,7 +1071,7 @@ protected function _readError($object, $path = null): array /** * Get a list of invalid fields and their data for errors upon validation/patching * - * @return array + * @return array */ public function getInvalid(): array { @@ -1096,7 +1096,7 @@ public function getInvalidField(string $field) * This value could not be patched into the entity and is simply copied into the _invalid property for debugging * purposes or to be able to log it away. * - * @param array $fields The values to set. + * @param array $fields The values to set. * @param bool $overwrite Whether to overwrite pre-existing values for $field. * @return $this */ diff --git a/app/vendor/cakephp/cakephp/src/Datasource/Exception/PageOutOfBoundsException.php b/app/vendor/cakephp/cakephp/src/Datasource/Exception/PageOutOfBoundsException.php index 787365b14..be75b2d76 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/Exception/PageOutOfBoundsException.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/Exception/PageOutOfBoundsException.php @@ -1,28 +1,7 @@ $fields The values to set. * @param bool $overwrite Whether to overwrite pre-existing values for $field. * @return $this */ diff --git a/app/vendor/cakephp/cakephp/src/Datasource/Locator/AbstractLocator.php b/app/vendor/cakephp/cakephp/src/Datasource/Locator/AbstractLocator.php index 4bf00a814..1d925c09d 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/Locator/AbstractLocator.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/Locator/AbstractLocator.php @@ -53,7 +53,7 @@ public function get(string $alias, array $options = []) unset($storeOptions['allowFallbackClass']); if (isset($this->instances[$alias])) { - if (!empty($storeOptions) && $this->options[$alias] !== $storeOptions) { + if (!empty($storeOptions) && isset($this->options[$alias]) && $this->options[$alias] !== $storeOptions) { throw new RuntimeException(sprintf( 'You cannot configure "%s", it already exists in the registry.', $alias diff --git a/app/vendor/cakephp/cakephp/src/Datasource/Paginator.php b/app/vendor/cakephp/cakephp/src/Datasource/Paginator.php index d842cd90a..a87c8ea62 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/Paginator.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/Paginator.php @@ -1,679 +1,7 @@ - */ - protected $_defaultConfig = [ - 'page' => 1, - 'limit' => 20, - 'maxLimit' => 100, - 'allowedParameters' => ['limit', 'sort', 'page', 'direction'], - ]; - - /** - * Paging params after pagination operation is done. - * - * @var array - */ - protected $_pagingParams = []; - - /** - * Handles automatic pagination of model records. - * - * ### Configuring pagination - * - * When calling `paginate()` you can use the $settings parameter to pass in - * pagination settings. These settings are used to build the queries made - * and control other pagination settings. - * - * If your settings contain a key with the current table's alias. The data - * inside that key will be used. Otherwise the top level configuration will - * be used. - * - * ``` - * $settings = [ - * 'limit' => 20, - * 'maxLimit' => 100 - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * The above settings will be used to paginate any repository. You can configure - * repository specific settings by keying the settings with the repository alias. - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'limit' => 20, - * 'maxLimit' => 100 - * ], - * 'Comments' => [ ... ] - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * This would allow you to have different pagination settings for - * `Articles` and `Comments` repositories. - * - * ### Controlling sort fields - * - * By default CakePHP will automatically allow sorting on any column on the - * repository object being paginated. Often times you will want to allow - * sorting on either associated columns or calculated fields. In these cases - * you will need to define an allowed list of all the columns you wish to allow - * sorting on. You can define the allowed sort fields in the `$settings` parameter: - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'finder' => 'custom', - * 'sortableFields' => ['title', 'author_id', 'comment_count'], - * ] - * ]; - * ``` - * - * Passing an empty array as sortableFields disallows sorting altogether. - * - * ### Paginating with custom finders - * - * You can paginate with any find type defined on your table using the - * `finder` option. - * - * ``` - * $settings = [ - * 'Articles' => [ - * 'finder' => 'popular' - * ] - * ]; - * $results = $paginator->paginate($table, $settings); - * ``` - * - * Would paginate using the `find('popular')` method. - * - * You can also pass an already created instance of a query to this method: - * - * ``` - * $query = $this->Articles->find('popular')->matching('Tags', function ($q) { - * return $q->where(['name' => 'CakePHP']) - * }); - * $results = $paginator->paginate($query); - * ``` - * - * ### Scoping Request parameters - * - * By using request parameter scopes you can paginate multiple queries in - * the same controller action: - * - * ``` - * $articles = $paginator->paginate($articlesQuery, ['scope' => 'articles']); - * $tags = $paginator->paginate($tagsQuery, ['scope' => 'tags']); - * ``` - * - * Each of the above queries will use different query string parameter sets - * for pagination data. An example URL paginating both results would be: - * - * ``` - * /dashboard?articles[page]=1&tags[page]=2 - * ``` - * - * @param \Cake\Datasource\RepositoryInterface|\Cake\Datasource\QueryInterface $object The repository or query - * to paginate. - * @param array $params Request params - * @param array $settings The settings/configuration used for pagination. - * @return \Cake\Datasource\ResultSetInterface Query results - * @throws \Cake\Datasource\Exception\PageOutOfBoundsException - */ - public function paginate(object $object, array $params = [], array $settings = []): ResultSetInterface - { - $query = null; - if ($object instanceof QueryInterface) { - $query = $object; - $object = $query->getRepository(); - if ($object === null) { - throw new CakeException('No repository set for query.'); - } - } - - $data = $this->extractData($object, $params, $settings); - $query = $this->getQuery($object, $query, $data); - - $cleanQuery = clone $query; - $results = $query->all(); - $data['numResults'] = count($results); - $data['count'] = $this->getCount($cleanQuery, $data); - - $pagingParams = $this->buildParams($data); - $alias = $object->getAlias(); - $this->_pagingParams = [$alias => $pagingParams]; - if ($pagingParams['requestedPage'] > $pagingParams['page']) { - throw new PageOutOfBoundsException([ - 'requestedPage' => $pagingParams['requestedPage'], - 'pagingParams' => $this->_pagingParams, - ]); - } - - return $results; - } - - /** - * Get query for fetching paginated results. - * - * @param \Cake\Datasource\RepositoryInterface $object Repository instance. - * @param \Cake\Datasource\QueryInterface|null $query Query Instance. - * @param array $data Pagination data. - * @return \Cake\Datasource\QueryInterface - */ - protected function getQuery(RepositoryInterface $object, ?QueryInterface $query, array $data): QueryInterface - { - if ($query === null) { - $query = $object->find($data['finder'], $data['options']); - } else { - $query->applyOptions($data['options']); - } - - return $query; - } - - /** - * Get total count of records. - * - * @param \Cake\Datasource\QueryInterface $query Query instance. - * @param array $data Pagination data. - * @return int|null - */ - protected function getCount(QueryInterface $query, array $data): ?int - { - return $query->count(); - } - - /** - * Extract pagination data needed - * - * @param \Cake\Datasource\RepositoryInterface $object The repository object. - * @param array $params Request params - * @param array $settings The settings/configuration used for pagination. - * @return array Array with keys 'defaults', 'options' and 'finder' - */ - protected function extractData(RepositoryInterface $object, array $params, array $settings): array - { - $alias = $object->getAlias(); - $defaults = $this->getDefaults($alias, $settings); - $options = $this->mergeOptions($params, $defaults); - $options = $this->validateSort($object, $options); - $options = $this->checkLimit($options); - - $options += ['page' => 1, 'scope' => null]; - $options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page']; - [$finder, $options] = $this->_extractFinder($options); - - return compact('defaults', 'options', 'finder'); - } - - /** - * Build pagination params. - * - * @param array $data Paginator data containing keys 'options', - * 'count', 'defaults', 'finder', 'numResults'. - * @return array Paging params. - */ - protected function buildParams(array $data): array - { - $limit = $data['options']['limit']; - - $paging = [ - 'count' => $data['count'], - 'current' => $data['numResults'], - 'perPage' => $limit, - 'page' => $data['options']['page'], - 'requestedPage' => $data['options']['page'], - ]; - - $paging = $this->addPageCountParams($paging, $data); - $paging = $this->addStartEndParams($paging, $data); - $paging = $this->addPrevNextParams($paging, $data); - $paging = $this->addSortingParams($paging, $data); - - $paging += [ - 'limit' => $data['defaults']['limit'] != $limit ? $limit : null, - 'scope' => $data['options']['scope'], - 'finder' => $data['finder'], - ]; - - return $paging; - } - - /** - * Add "page" and "pageCount" params. - * - * @param array $params Paging params. - * @param array $data Paginator data. - * @return array Updated params. - */ - protected function addPageCountParams(array $params, array $data): array - { - $page = $params['page']; - $pageCount = 0; - - if ($params['count'] !== null) { - $pageCount = max((int)ceil($params['count'] / $params['perPage']), 1); - $page = min($page, $pageCount); - } elseif ($params['current'] === 0 && $params['requestedPage'] > 1) { - $page = 1; - } - - $params['page'] = $page; - $params['pageCount'] = $pageCount; - - return $params; - } - - /** - * Add "start" and "end" params. - * - * @param array $params Paging params. - * @param array $data Paginator data. - * @return array Updated params. - */ - protected function addStartEndParams(array $params, array $data): array - { - $start = $end = 0; - - if ($params['current'] > 0) { - $start = (($params['page'] - 1) * $params['perPage']) + 1; - $end = $start + $params['current'] - 1; - } - - $params['start'] = $start; - $params['end'] = $end; - - return $params; - } - - /** - * Add "prevPage" and "nextPage" params. - * - * @param array $params Paginator params. - * @param array $data Paging data. - * @return array Updated params. - */ - protected function addPrevNextParams(array $params, array $data): array - { - $params['prevPage'] = $params['page'] > 1; - if ($params['count'] === null) { - $params['nextPage'] = true; - } else { - $params['nextPage'] = $params['count'] > $params['page'] * $params['perPage']; - } - - return $params; - } - - /** - * Add sorting / ordering params. - * - * @param array $params Paginator params. - * @param array $data Paging data. - * @return array Updated params. - */ - protected function addSortingParams(array $params, array $data): array - { - $defaults = $data['defaults']; - $order = (array)$data['options']['order']; - $sortDefault = $directionDefault = false; - - if (!empty($defaults['order']) && count($defaults['order']) === 1) { - $sortDefault = key($defaults['order']); - $directionDefault = current($defaults['order']); - } - - $params += [ - 'sort' => $data['options']['sort'], - 'direction' => isset($data['options']['sort']) && count($order) ? current($order) : null, - 'sortDefault' => $sortDefault, - 'directionDefault' => $directionDefault, - 'completeSort' => $order, - ]; - - return $params; - } - - /** - * Extracts the finder name and options out of the provided pagination options. - * - * @param array $options the pagination options. - * @return array An array containing in the first position the finder name - * and in the second the options to be passed to it. - */ - protected function _extractFinder(array $options): array - { - $type = !empty($options['finder']) ? $options['finder'] : 'all'; - unset($options['finder'], $options['maxLimit']); - - if (is_array($type)) { - $options = (array)current($type) + $options; - $type = key($type); - } - - return [$type, $options]; - } - - /** - * Get paging params after pagination operation. - * - * @return array - */ - public function getPagingParams(): array - { - return $this->_pagingParams; - } - - /** - * Shim method for reading the deprecated whitelist or allowedParameters options - * - * @return array - */ - protected function getAllowedParameters(): array - { - $allowed = $this->getConfig('allowedParameters'); - if (!$allowed) { - $allowed = []; - } - $whitelist = $this->getConfig('whitelist'); - if ($whitelist) { - deprecationWarning('The `whitelist` option is deprecated. Use the `allowedParameters` option instead.'); - - return array_merge($allowed, $whitelist); - } - - return $allowed; - } - - /** - * Shim method for reading the deprecated sortWhitelist or sortableFields options. - * - * @param array $config The configuration data to coalesce and emit warnings on. - * @return array|null - */ - protected function getSortableFields(array $config): ?array - { - $allowed = $config['sortableFields'] ?? null; - if ($allowed !== null) { - return $allowed; - } - $deprecated = $config['sortWhitelist'] ?? null; - if ($deprecated !== null) { - deprecationWarning('The `sortWhitelist` option is deprecated. Use `sortableFields` instead.'); - } - - return $deprecated; - } - - /** - * Merges the various options that Paginator uses. - * Pulls settings together from the following places: - * - * - General pagination settings - * - Model specific settings. - * - Request parameters - * - * The result of this method is the aggregate of all the option sets - * combined together. You can change config value `allowedParameters` to modify - * which options/values can be set using request parameters. - * - * @param array $params Request params. - * @param array $settings The settings to merge with the request data. - * @return array Array of merged options. - */ - public function mergeOptions(array $params, array $settings): array - { - if (!empty($settings['scope'])) { - $scope = $settings['scope']; - $params = !empty($params[$scope]) ? (array)$params[$scope] : []; - } - - $allowed = $this->getAllowedParameters(); - $params = array_intersect_key($params, array_flip($allowed)); - - return array_merge($settings, $params); - } - - /** - * Get the settings for a $model. If there are no settings for a specific - * repository, the general settings will be used. - * - * @param string $alias Model name to get settings for. - * @param array $settings The settings which is used for combining. - * @return array An array of pagination settings for a model, - * or the general settings. - */ - public function getDefaults(string $alias, array $settings): array - { - if (isset($settings[$alias])) { - $settings = $settings[$alias]; - } - - $defaults = $this->getConfig(); - $defaults['whitelist'] = $defaults['allowedParameters'] = $this->getAllowedParameters(); - - $maxLimit = $settings['maxLimit'] ?? $defaults['maxLimit']; - $limit = $settings['limit'] ?? $defaults['limit']; - - if ($limit > $maxLimit) { - $limit = $maxLimit; - } - - $settings['maxLimit'] = $maxLimit; - $settings['limit'] = $limit; - - return $settings + $defaults; - } - - /** - * Validate that the desired sorting can be performed on the $object. - * - * Only fields or virtualFields can be sorted on. The direction param will - * also be sanitized. Lastly sort + direction keys will be converted into - * the model friendly order key. - * - * You can use the allowedParameters option to control which columns/fields are - * available for sorting via URL parameters. This helps prevent users from ordering large - * result sets on un-indexed values. - * - * If you need to sort on associated columns or synthetic properties you - * will need to use the `sortableFields` option. - * - * Any columns listed in the allowed sort fields will be implicitly trusted. - * You can use this to sort on synthetic columns, or columns added in custom - * find operations that may not exist in the schema. - * - * The default order options provided to paginate() will be merged with the user's - * requested sorting field/direction. - * - * @param \Cake\Datasource\RepositoryInterface $object Repository object. - * @param array $options The pagination options being used for this request. - * @return array An array of options with sort + direction removed and - * replaced with order if possible. - */ - public function validateSort(RepositoryInterface $object, array $options): array - { - if (isset($options['sort'])) { - $direction = null; - if (isset($options['direction'])) { - $direction = strtolower($options['direction']); - } - if (!in_array($direction, ['asc', 'desc'], true)) { - $direction = 'asc'; - } - - $order = isset($options['order']) && is_array($options['order']) ? $options['order'] : []; - if ($order && $options['sort'] && strpos($options['sort'], '.') === false) { - $order = $this->_removeAliases($order, $object->getAlias()); - } - - $options['order'] = [$options['sort'] => $direction] + $order; - } else { - $options['sort'] = null; - } - unset($options['direction']); - - if (empty($options['order'])) { - $options['order'] = []; - } - if (!is_array($options['order'])) { - return $options; - } - - $sortAllowed = false; - $allowed = $this->getSortableFields($options); - if ($allowed !== null) { - $options['sortableFields'] = $options['sortWhitelist'] = $allowed; - - $field = key($options['order']); - $sortAllowed = in_array($field, $allowed, true); - if (!$sortAllowed) { - $options['order'] = []; - $options['sort'] = null; - - return $options; - } - } - - if ( - $options['sort'] === null - && count($options['order']) === 1 - && !is_numeric(key($options['order'])) - ) { - $options['sort'] = key($options['order']); - } - - $options['order'] = $this->_prefix($object, $options['order'], $sortAllowed); - - return $options; - } - - /** - * Remove alias if needed. - * - * @param array $fields Current fields - * @param string $model Current model alias - * @return array $fields Unaliased fields where applicable - */ - protected function _removeAliases(array $fields, string $model): array - { - $result = []; - foreach ($fields as $field => $sort) { - if (strpos($field, '.') === false) { - $result[$field] = $sort; - continue; - } - - [$alias, $currentField] = explode('.', $field); - - if ($alias === $model) { - $result[$currentField] = $sort; - continue; - } - - $result[$field] = $sort; - } - - return $result; - } - - /** - * Prefixes the field with the table alias if possible. - * - * @param \Cake\Datasource\RepositoryInterface $object Repository object. - * @param array $order Order array. - * @param bool $allowed Whether the field was allowed. - * @return array Final order array. - */ - protected function _prefix(RepositoryInterface $object, array $order, bool $allowed = false): array - { - $tableAlias = $object->getAlias(); - $tableOrder = []; - foreach ($order as $key => $value) { - if (is_numeric($key)) { - $tableOrder[] = $value; - continue; - } - $field = $key; - $alias = $tableAlias; - - if (strpos($key, '.') !== false) { - [$alias, $field] = explode('.', $key); - } - $correctAlias = ($tableAlias === $alias); - - if ($correctAlias && $allowed) { - // Disambiguate fields in schema. As id is quite common. - if ($object->hasField($field)) { - $field = $alias . '.' . $field; - } - $tableOrder[$field] = $value; - } elseif ($correctAlias && $object->hasField($field)) { - $tableOrder[$tableAlias . '.' . $field] = $value; - } elseif (!$correctAlias && $allowed) { - $tableOrder[$alias . '.' . $field] = $value; - } - } - - return $tableOrder; - } - - /** - * Check the limit parameter and ensure it's within the maxLimit bounds. - * - * @param array $options An array of options with a limit key to be checked. - * @return array An array of options for pagination. - */ - public function checkLimit(array $options): array - { - $options['limit'] = (int)$options['limit']; - if ($options['limit'] < 1) { - $options['limit'] = 1; - } - $options['limit'] = max(min($options['limit'], $options['maxLimit']), 1); - - return $options; - } -} +class_exists('Cake\Datasource\Paging\NumericPaginator'); +deprecationWarning( + 'Use Cake\Datasource\Paging\NumericPaginator instead of Cake\Datasource\Paginator.' +); diff --git a/app/vendor/cakephp/cakephp/src/Datasource/PaginatorInterface.php b/app/vendor/cakephp/cakephp/src/Datasource/PaginatorInterface.php index c2bff1a17..eb8b3b79f 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/PaginatorInterface.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/PaginatorInterface.php @@ -1,41 +1,7 @@ + */ + protected $_defaultConfig = [ + 'page' => 1, + 'limit' => 20, + 'maxLimit' => 100, + 'allowedParameters' => ['limit', 'sort', 'page', 'direction'], + ]; + + /** + * Paging params after pagination operation is done. + * + * @var array + */ + protected $_pagingParams = []; + + /** + * Handles automatic pagination of model records. + * + * ### Configuring pagination + * + * When calling `paginate()` you can use the $settings parameter to pass in + * pagination settings. These settings are used to build the queries made + * and control other pagination settings. + * + * If your settings contain a key with the current table's alias. The data + * inside that key will be used. Otherwise, the top level configuration will + * be used. + * + * ``` + * $settings = [ + * 'limit' => 20, + * 'maxLimit' => 100 + * ]; + * $results = $paginator->paginate($table, $settings); + * ``` + * + * The above settings will be used to paginate any repository. You can configure + * repository specific settings by keying the settings with the repository alias. + * + * ``` + * $settings = [ + * 'Articles' => [ + * 'limit' => 20, + * 'maxLimit' => 100 + * ], + * 'Comments' => [ ... ] + * ]; + * $results = $paginator->paginate($table, $settings); + * ``` + * + * This would allow you to have different pagination settings for + * `Articles` and `Comments` repositories. + * + * ### Controlling sort fields + * + * By default CakePHP will automatically allow sorting on any column on the + * repository object being paginated. Often times you will want to allow + * sorting on either associated columns or calculated fields. In these cases + * you will need to define an allowed list of all the columns you wish to allow + * sorting on. You can define the allowed sort fields in the `$settings` parameter: + * + * ``` + * $settings = [ + * 'Articles' => [ + * 'finder' => 'custom', + * 'sortableFields' => ['title', 'author_id', 'comment_count'], + * ] + * ]; + * ``` + * + * Passing an empty array as sortableFields disallows sorting altogether. + * + * ### Paginating with custom finders + * + * You can paginate with any find type defined on your table using the + * `finder` option. + * + * ``` + * $settings = [ + * 'Articles' => [ + * 'finder' => 'popular' + * ] + * ]; + * $results = $paginator->paginate($table, $settings); + * ``` + * + * Would paginate using the `find('popular')` method. + * + * You can also pass an already created instance of a query to this method: + * + * ``` + * $query = $this->Articles->find('popular')->matching('Tags', function ($q) { + * return $q->where(['name' => 'CakePHP']) + * }); + * $results = $paginator->paginate($query); + * ``` + * + * ### Scoping Request parameters + * + * By using request parameter scopes you can paginate multiple queries in + * the same controller action: + * + * ``` + * $articles = $paginator->paginate($articlesQuery, ['scope' => 'articles']); + * $tags = $paginator->paginate($tagsQuery, ['scope' => 'tags']); + * ``` + * + * Each of the above queries will use different query string parameter sets + * for pagination data. An example URL paginating both results would be: + * + * ``` + * /dashboard?articles[page]=1&tags[page]=2 + * ``` + * + * @param \Cake\Datasource\RepositoryInterface|\Cake\Datasource\QueryInterface $object The repository or query + * to paginate. + * @param array $params Request params + * @param array $settings The settings/configuration used for pagination. + * @return \Cake\Datasource\ResultSetInterface Query results + * @throws \Cake\Datasource\Paging\Exception\PageOutOfBoundsException + */ + public function paginate(object $object, array $params = [], array $settings = []): ResultSetInterface + { + $query = null; + if ($object instanceof QueryInterface) { + $query = $object; + $object = $query->getRepository(); + if ($object === null) { + throw new CakeException('No repository set for query.'); + } + } + + $data = $this->extractData($object, $params, $settings); + $query = $this->getQuery($object, $query, $data); + + $cleanQuery = clone $query; + $results = $query->all(); + $data['numResults'] = count($results); + $data['count'] = $this->getCount($cleanQuery, $data); + + $pagingParams = $this->buildParams($data); + $alias = $object->getAlias(); + $this->_pagingParams = [$alias => $pagingParams]; + if ($pagingParams['requestedPage'] > $pagingParams['page']) { + throw new PageOutOfBoundsException([ + 'requestedPage' => $pagingParams['requestedPage'], + 'pagingParams' => $this->_pagingParams, + ]); + } + + return $results; + } + + /** + * Get query for fetching paginated results. + * + * @param \Cake\Datasource\RepositoryInterface $object Repository instance. + * @param \Cake\Datasource\QueryInterface|null $query Query Instance. + * @param array $data Pagination data. + * @return \Cake\Datasource\QueryInterface + */ + protected function getQuery(RepositoryInterface $object, ?QueryInterface $query, array $data): QueryInterface + { + if ($query === null) { + $query = $object->find($data['finder'], $data['options']); + } else { + $query->applyOptions($data['options']); + } + + return $query; + } + + /** + * Get total count of records. + * + * @param \Cake\Datasource\QueryInterface $query Query instance. + * @param array $data Pagination data. + * @return int|null + */ + protected function getCount(QueryInterface $query, array $data): ?int + { + return $query->count(); + } + + /** + * Extract pagination data needed + * + * @param \Cake\Datasource\RepositoryInterface $object The repository object. + * @param array $params Request params + * @param array $settings The settings/configuration used for pagination. + * @return array Array with keys 'defaults', 'options' and 'finder' + */ + protected function extractData(RepositoryInterface $object, array $params, array $settings): array + { + $alias = $object->getAlias(); + $defaults = $this->getDefaults($alias, $settings); + $options = $this->mergeOptions($params, $defaults); + $options = $this->validateSort($object, $options); + $options = $this->checkLimit($options); + + $options += ['page' => 1, 'scope' => null]; + $options['page'] = (int)$options['page'] < 1 ? 1 : (int)$options['page']; + [$finder, $options] = $this->_extractFinder($options); + + return compact('defaults', 'options', 'finder'); + } + + /** + * Build pagination params. + * + * @param array $data Paginator data containing keys 'options', + * 'count', 'defaults', 'finder', 'numResults'. + * @return array Paging params. + */ + protected function buildParams(array $data): array + { + $limit = $data['options']['limit']; + + $paging = [ + 'count' => $data['count'], + 'current' => $data['numResults'], + 'perPage' => $limit, + 'page' => $data['options']['page'], + 'requestedPage' => $data['options']['page'], + ]; + + $paging = $this->addPageCountParams($paging, $data); + $paging = $this->addStartEndParams($paging, $data); + $paging = $this->addPrevNextParams($paging, $data); + $paging = $this->addSortingParams($paging, $data); + + $paging += [ + 'limit' => $data['defaults']['limit'] != $limit ? $limit : null, + 'scope' => $data['options']['scope'], + 'finder' => $data['finder'], + ]; + + return $paging; + } + + /** + * Add "page" and "pageCount" params. + * + * @param array $params Paging params. + * @param array $data Paginator data. + * @return array Updated params. + */ + protected function addPageCountParams(array $params, array $data): array + { + $page = $params['page']; + $pageCount = 0; + + if ($params['count'] !== null) { + $pageCount = max((int)ceil($params['count'] / $params['perPage']), 1); + $page = min($page, $pageCount); + } elseif ($params['current'] === 0 && $params['requestedPage'] > 1) { + $page = 1; + } + + $params['page'] = $page; + $params['pageCount'] = $pageCount; + + return $params; + } + + /** + * Add "start" and "end" params. + * + * @param array $params Paging params. + * @param array $data Paginator data. + * @return array Updated params. + */ + protected function addStartEndParams(array $params, array $data): array + { + $start = $end = 0; + + if ($params['current'] > 0) { + $start = (($params['page'] - 1) * $params['perPage']) + 1; + $end = $start + $params['current'] - 1; + } + + $params['start'] = $start; + $params['end'] = $end; + + return $params; + } + + /** + * Add "prevPage" and "nextPage" params. + * + * @param array $params Paginator params. + * @param array $data Paging data. + * @return array Updated params. + */ + protected function addPrevNextParams(array $params, array $data): array + { + $params['prevPage'] = $params['page'] > 1; + if ($params['count'] === null) { + $params['nextPage'] = true; + } else { + $params['nextPage'] = $params['count'] > $params['page'] * $params['perPage']; + } + + return $params; + } + + /** + * Add sorting / ordering params. + * + * @param array $params Paginator params. + * @param array $data Paging data. + * @return array Updated params. + */ + protected function addSortingParams(array $params, array $data): array + { + $defaults = $data['defaults']; + $order = (array)$data['options']['order']; + $sortDefault = $directionDefault = false; + + if (!empty($defaults['order']) && count($defaults['order']) >= 1) { + $sortDefault = key($defaults['order']); + $directionDefault = current($defaults['order']); + } + + $params += [ + 'sort' => $data['options']['sort'], + 'direction' => isset($data['options']['sort']) && count($order) ? current($order) : null, + 'sortDefault' => $sortDefault, + 'directionDefault' => $directionDefault, + 'completeSort' => $order, + ]; + + return $params; + } + + /** + * Extracts the finder name and options out of the provided pagination options. + * + * @param array $options the pagination options. + * @return array An array containing in the first position the finder name + * and in the second the options to be passed to it. + */ + protected function _extractFinder(array $options): array + { + $type = !empty($options['finder']) ? $options['finder'] : 'all'; + unset($options['finder'], $options['maxLimit']); + + if (is_array($type)) { + $options = (array)current($type) + $options; + $type = key($type); + } + + return [$type, $options]; + } + + /** + * Get paging params after pagination operation. + * + * @return array + */ + public function getPagingParams(): array + { + return $this->_pagingParams; + } + + /** + * Shim method for reading the deprecated whitelist or allowedParameters options + * + * @return array + */ + protected function getAllowedParameters(): array + { + $allowed = $this->getConfig('allowedParameters'); + if (!$allowed) { + $allowed = []; + } + $whitelist = $this->getConfig('whitelist'); + if ($whitelist) { + deprecationWarning('The `whitelist` option is deprecated. Use the `allowedParameters` option instead.'); + + return array_merge($allowed, $whitelist); + } + + return $allowed; + } + + /** + * Shim method for reading the deprecated sortWhitelist or sortableFields options. + * + * @param array $config The configuration data to coalesce and emit warnings on. + * @return array|null + */ + protected function getSortableFields(array $config): ?array + { + $allowed = $config['sortableFields'] ?? null; + if ($allowed !== null) { + return $allowed; + } + $deprecated = $config['sortWhitelist'] ?? null; + if ($deprecated !== null) { + deprecationWarning('The `sortWhitelist` option is deprecated. Use `sortableFields` instead.'); + } + + return $deprecated; + } + + /** + * Merges the various options that Paginator uses. + * Pulls settings together from the following places: + * + * - General pagination settings + * - Model specific settings. + * - Request parameters + * + * The result of this method is the aggregate of all the option sets + * combined together. You can change config value `allowedParameters` to modify + * which options/values can be set using request parameters. + * + * @param array $params Request params. + * @param array $settings The settings to merge with the request data. + * @return array Array of merged options. + */ + public function mergeOptions(array $params, array $settings): array + { + if (!empty($settings['scope'])) { + $scope = $settings['scope']; + $params = !empty($params[$scope]) ? (array)$params[$scope] : []; + } + + $allowed = $this->getAllowedParameters(); + $params = array_intersect_key($params, array_flip($allowed)); + + return array_merge($settings, $params); + } + + /** + * Get the settings for a $model. If there are no settings for a specific + * repository, the general settings will be used. + * + * @param string $alias Model name to get settings for. + * @param array $settings The settings which is used for combining. + * @return array An array of pagination settings for a model, + * or the general settings. + */ + public function getDefaults(string $alias, array $settings): array + { + if (isset($settings[$alias])) { + $settings = $settings[$alias]; + } + + $defaults = $this->getConfig(); + $defaults['whitelist'] = $defaults['allowedParameters'] = $this->getAllowedParameters(); + + $maxLimit = $settings['maxLimit'] ?? $defaults['maxLimit']; + $limit = $settings['limit'] ?? $defaults['limit']; + + if ($limit > $maxLimit) { + $limit = $maxLimit; + } + + $settings['maxLimit'] = $maxLimit; + $settings['limit'] = $limit; + + return $settings + $defaults; + } + + /** + * Validate that the desired sorting can be performed on the $object. + * + * Only fields or virtualFields can be sorted on. The direction param will + * also be sanitized. Lastly sort + direction keys will be converted into + * the model friendly order key. + * + * You can use the allowedParameters option to control which columns/fields are + * available for sorting via URL parameters. This helps prevent users from ordering large + * result sets on un-indexed values. + * + * If you need to sort on associated columns or synthetic properties you + * will need to use the `sortableFields` option. + * + * Any columns listed in the allowed sort fields will be implicitly trusted. + * You can use this to sort on synthetic columns, or columns added in custom + * find operations that may not exist in the schema. + * + * The default order options provided to paginate() will be merged with the user's + * requested sorting field/direction. + * + * @param \Cake\Datasource\RepositoryInterface $object Repository object. + * @param array $options The pagination options being used for this request. + * @return array An array of options with sort + direction removed and + * replaced with order if possible. + */ + public function validateSort(RepositoryInterface $object, array $options): array + { + if (isset($options['sort'])) { + $direction = null; + if (isset($options['direction'])) { + $direction = strtolower($options['direction']); + } + if (!in_array($direction, ['asc', 'desc'], true)) { + $direction = 'asc'; + } + + $order = isset($options['order']) && is_array($options['order']) ? $options['order'] : []; + if ($order && $options['sort'] && strpos($options['sort'], '.') === false) { + $order = $this->_removeAliases($order, $object->getAlias()); + } + + $options['order'] = [$options['sort'] => $direction] + $order; + } else { + $options['sort'] = null; + } + unset($options['direction']); + + if (empty($options['order'])) { + $options['order'] = []; + } + if (!is_array($options['order'])) { + return $options; + } + + $sortAllowed = false; + $allowed = $this->getSortableFields($options); + if ($allowed !== null) { + $options['sortableFields'] = $options['sortWhitelist'] = $allowed; + + $field = key($options['order']); + $sortAllowed = in_array($field, $allowed, true); + if (!$sortAllowed) { + $options['order'] = []; + $options['sort'] = null; + + return $options; + } + } + + if ( + $options['sort'] === null + && count($options['order']) >= 1 + && !is_numeric(key($options['order'])) + ) { + $options['sort'] = key($options['order']); + } + + $options['order'] = $this->_prefix($object, $options['order'], $sortAllowed); + + return $options; + } + + /** + * Remove alias if needed. + * + * @param array $fields Current fields + * @param string $model Current model alias + * @return array $fields Unaliased fields where applicable + */ + protected function _removeAliases(array $fields, string $model): array + { + $result = []; + foreach ($fields as $field => $sort) { + if (strpos($field, '.') === false) { + $result[$field] = $sort; + continue; + } + + [$alias, $currentField] = explode('.', $field); + + if ($alias === $model) { + $result[$currentField] = $sort; + continue; + } + + $result[$field] = $sort; + } + + return $result; + } + + /** + * Prefixes the field with the table alias if possible. + * + * @param \Cake\Datasource\RepositoryInterface $object Repository object. + * @param array $order Order array. + * @param bool $allowed Whether the field was allowed. + * @return array Final order array. + */ + protected function _prefix(RepositoryInterface $object, array $order, bool $allowed = false): array + { + $tableAlias = $object->getAlias(); + $tableOrder = []; + foreach ($order as $key => $value) { + if (is_numeric($key)) { + $tableOrder[] = $value; + continue; + } + $field = $key; + $alias = $tableAlias; + + if (strpos($key, '.') !== false) { + [$alias, $field] = explode('.', $key); + } + $correctAlias = ($tableAlias === $alias); + + if ($correctAlias && $allowed) { + // Disambiguate fields in schema. As id is quite common. + if ($object->hasField($field)) { + $field = $alias . '.' . $field; + } + $tableOrder[$field] = $value; + } elseif ($correctAlias && $object->hasField($field)) { + $tableOrder[$tableAlias . '.' . $field] = $value; + } elseif (!$correctAlias && $allowed) { + $tableOrder[$alias . '.' . $field] = $value; + } + } + + return $tableOrder; + } + + /** + * Check the limit parameter and ensure it's within the maxLimit bounds. + * + * @param array $options An array of options with a limit key to be checked. + * @return array An array of options for pagination. + */ + public function checkLimit(array $options): array + { + $options['limit'] = (int)$options['limit']; + if ($options['limit'] < 1) { + $options['limit'] = 1; + } + $options['limit'] = max(min($options['limit'], $options['maxLimit']), 1); + + return $options; + } +} + +// phpcs:disable +class_alias( + 'Cake\Datasource\Paging\NumericPaginator', + 'Cake\Datasource\Paginator' +); +// phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Datasource/Paging/PaginatorInterface.php b/app/vendor/cakephp/cakephp/src/Datasource/Paging/PaginatorInterface.php new file mode 100644 index 000000000..4d30597b2 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Datasource/Paging/PaginatorInterface.php @@ -0,0 +1,50 @@ + */ public function aliasField(string $field, ?string $alias = null): array; @@ -62,7 +62,7 @@ public function aliasField(string $field, ?string $alias = null): array; * * @param array $fields The fields to alias * @param string|null $defaultAlias The default alias - * @return array + * @return array */ public function aliasFields(array $fields, ?string $defaultAlias = null): array; diff --git a/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php b/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php index dd950dd74..6d70a77b5 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/QueryTrait.php @@ -224,7 +224,7 @@ public function eagerLoaded(bool $value) * * @param string $field The field to alias * @param string|null $alias the alias used to prefix the field - * @return array + * @return array */ public function aliasField(string $field, ?string $alias = null): array { @@ -247,7 +247,7 @@ public function aliasField(string $field, ?string $alias = null): array * * @param array $fields The fields to alias * @param string|null $defaultAlias The default alias - * @return array + * @return array */ public function aliasFields(array $fields, ?string $defaultAlias = null): array { @@ -549,9 +549,11 @@ public function __call(string $method, array $arguments) $resultSetClass = $this->_decoratorClass(); if (in_array($method, get_class_methods($resultSetClass), true)) { deprecationWarning(sprintf( - 'Calling result set method `%s()` directly on query instance is deprecated. ' . - 'You must call `all()` to retrieve the results first.', - $method + 'Calling `%s` methods, such as `%s()`, on queries is deprecated. ' . + 'You must call `all()` first (for example, `all()->%s()`).', + ResultSetInterface::class, + $method, + $method, ), 2); $results = $this->all(); diff --git a/app/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php b/app/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php index df4ed7d6c..93a00416c 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/RepositoryInterface.php @@ -242,7 +242,7 @@ public function patchEntity(EntityInterface $entity, array $data, array $options * $article = $this->Articles->patchEntities($articles, $this->request->getData()); * ``` * - * @param \Traversable|array<\Cake\Datasource\EntityInterface> $entities the entities that will get the + * @param iterable<\Cake\Datasource\EntityInterface> $entities the entities that will get the * data merged in * @param array $data list of arrays to be merged into the entities * @param array $options A list of options for the objects hydration. diff --git a/app/vendor/cakephp/cakephp/src/Datasource/RuleInvoker.php b/app/vendor/cakephp/cakephp/src/Datasource/RuleInvoker.php index 3f9fe54a6..8a80efc8e 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/RuleInvoker.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/RuleInvoker.php @@ -37,7 +37,7 @@ class RuleInvoker /** * Rule options * - * @var array + * @var array */ protected $options = []; diff --git a/app/vendor/cakephp/cakephp/src/Datasource/SchemaInterface.php b/app/vendor/cakephp/cakephp/src/Datasource/SchemaInterface.php index eef98d1bb..08ab8be25 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/SchemaInterface.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/SchemaInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Datasource; diff --git a/app/vendor/cakephp/cakephp/src/Datasource/SimplePaginator.php b/app/vendor/cakephp/cakephp/src/Datasource/SimplePaginator.php index 705be9a2a..95499fb6d 100644 --- a/app/vendor/cakephp/cakephp/src/Datasource/SimplePaginator.php +++ b/app/vendor/cakephp/cakephp/src/Datasource/SimplePaginator.php @@ -1,40 +1,7 @@ =7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "psr/log": "^1.0 || ^2.0", "psr/simple-cache": "^1.0 || ^2.0" diff --git a/app/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php b/app/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php index c4b3f1d14..74963b2ab 100644 --- a/app/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php +++ b/app/vendor/cakephp/cakephp/src/Error/BaseErrorHandler.php @@ -88,6 +88,12 @@ abstract protected function _displayException(Throwable $exception): void; */ public function register(): void { + deprecationWarning( + 'Use of `BaseErrorHandler` and subclasses are deprecated. ' . + 'Upgrade to the new `ErrorTrap` and `ExceptionTrap` subsystem. ' . + 'See https://book.cakephp.org/4/en/appendices/4-4-migration-guide.html' + ); + $level = $this->_config['errorLevel'] ?? -1; error_reporting($level); set_error_handler([$this, 'handleError'], $level); @@ -330,6 +336,11 @@ public function logException(Throwable $exception, ?ServerRequestInterface $requ if (empty($this->_config['log'])) { return false; } + foreach ($this->_config['skipLog'] as $class) { + if ($exception instanceof $class) { + return false; + } + } return $this->getLogger()->log($exception, $request ?? Router::getRequest()); } diff --git a/app/vendor/cakephp/cakephp/src/Error/ConsoleErrorHandler.php b/app/vendor/cakephp/cakephp/src/Error/ConsoleErrorHandler.php index fa12c763c..78353d0ca 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ConsoleErrorHandler.php +++ b/app/vendor/cakephp/cakephp/src/Error/ConsoleErrorHandler.php @@ -130,3 +130,10 @@ protected function _stop(int $code): void exit($code); } } + +// phpcs:disable +class_alias( + 'Cake\Error\ConsoleErrorHandler', + 'Cake\Console\ConsoleErrorHandler' +); +// phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Error/Debugger.php b/app/vendor/cakephp/cakephp/src/Error/Debugger.php index ad4395dae..e8465bb1c 100644 --- a/app/vendor/cakephp/cakephp/src/Error/Debugger.php +++ b/app/vendor/cakephp/cakephp/src/Error/Debugger.php @@ -31,6 +31,8 @@ use Cake\Error\Debug\ScalarNode; use Cake\Error\Debug\SpecialNode; use Cake\Error\Debug\TextFormatter; +use Cake\Error\Renderer\HtmlErrorRenderer; +use Cake\Error\Renderer\TextErrorRenderer; use Cake\Log\Log; use Cake\Utility\Hash; use Cake\Utility\Security; @@ -81,6 +83,7 @@ class Debugger */ protected $_templates = [ 'log' => [ + // These templates are not actually used, as Debugger::log() is called instead. 'trace' => '{:reference} - {:path}, line {:line}', 'error' => '{:error} ({:code}): {:description} in [{:file}, line {:line}]', ], @@ -110,6 +113,21 @@ class Debugger ], ]; + /** + * Mapping for error renderers. + * + * Error renderers are replacing output formatting with + * an object based system. Having Debugger handle and render errors + * will be deprecated and the new ErrorTrap system should be used instead. + * + * @var array + */ + protected $renderers = [ + 'txt' => TextErrorRenderer::class, + // The html alias currently uses no JS and will be deprecated. + 'js' => HtmlErrorRenderer::class, + ]; + /** * A map of editors to their link templates. * @@ -442,9 +460,12 @@ public static function formatTrace($backtrace, array $options = []) if (in_array($signature, $options['exclude'], true)) { continue; } - if ($options['format'] === 'points' && $trace['file'] !== '[internal]') { - $back[] = ['file' => $trace['file'], 'line' => $trace['line']]; + if ($options['format'] === 'points') { + $back[] = ['file' => $trace['file'], 'line' => $trace['line'], 'reference' => $reference]; } elseif ($options['format'] === 'array') { + if (!$options['args']) { + unset($trace['args']); + } $back[] = $trace; } else { if (isset($self->_templates[$options['format']]['traceLine'])) { @@ -463,7 +484,10 @@ public static function formatTrace($backtrace, array $options = []) return $back; } - /** @psalm-suppress InvalidArgument */ + /** + * @psalm-suppress InvalidArgument + * @phpstan-ignore-next-line + */ return implode("\n", $back); } @@ -758,7 +782,7 @@ protected static function exportObject(object $var, DebugContext $context): Node if ($remaining > 0) { if (method_exists($var, '__debugInfo')) { try { - foreach ($var->__debugInfo() as $key => $val) { + foreach ((array)$var->__debugInfo() as $key => $val) { $node->addProperty(new PropertyNode("'{$key}'", null, static::export($val, $context))); } @@ -817,9 +841,12 @@ protected static function exportObject(object $var, DebugContext $context): Node * Get the output format for Debugger error rendering. * * @return string Returns the current format when getting. + * @deprecated 4.4.0 Update your application so use ErrorTrap instead. */ public static function getOutputFormat(): string { + deprecationWarning('Debugger::getOutputFormat() is deprecated.'); + return Debugger::getInstance()->_outputFormat; } @@ -829,9 +856,11 @@ public static function getOutputFormat(): string * @param string $format The format you want errors to be output as. * @return void * @throws \InvalidArgumentException When choosing a format that doesn't exist. + * @deprecated 4.4.0 Update your application so use ErrorTrap instead. */ public static function setOutputFormat(string $format): void { + deprecationWarning('Debugger::setOutputFormat() is deprecated.'); $self = Debugger::getInstance(); if (!isset($self->_templates[$format])) { @@ -882,9 +911,11 @@ public static function setOutputFormat(string $format): void * straight HTML output, or 'txt' for unformatted text. * @param array $strings Template strings, or a callback to be used for the output format. * @return array The resulting format string set. + * @deprecated 4.4.0 Update your application so use ErrorTrap instead. */ public static function addFormat(string $format, array $strings): array { + deprecationWarning('Debugger::addFormat() is deprecated.'); $self = Debugger::getInstance(); if (isset($self->_templates[$format])) { if (isset($strings['links'])) { @@ -898,15 +929,37 @@ public static function addFormat(string $format, array $strings): array } else { $self->_templates[$format] = $strings; } + unset($self->renderers[$format]); return $self->_templates[$format]; } + /** + * Add a renderer to the current instance. + * + * @param string $name The alias for the the renderer. + * @param class-string<\Cake\Error\ErrorRendererInterface> $class The classname of the renderer to use. + * @return void + * @deprecated 4.4.0 Update your application so use ErrorTrap instead. + */ + public static function addRenderer(string $name, string $class): void + { + deprecationWarning('Debugger::addRenderer() is deprecated.'); + if (!in_array(ErrorRendererInterface::class, class_implements($class))) { + throw new InvalidArgumentException( + 'Invalid renderer class. $class must implement ' . ErrorRendererInterface::class + ); + } + $self = Debugger::getInstance(); + $self->renderers[$name] = $class; + } + /** * Takes a processed array of data from an error and displays it in the chosen format. * * @param array $data Data to output. * @return void + * @deprecated 4.4.0 Update your application so use ErrorTrap instead. */ public function outputError(array $data): void { @@ -922,6 +975,17 @@ public function outputError(array $data): void ]; $data += $defaults; + $outputFormat = $this->_outputFormat; + if (isset($this->renderers[$outputFormat])) { + /** @var array $trace */ + $trace = static::trace(['start' => $data['start'], 'format' => 'points']); + $error = new PhpError($data['code'], $data['description'], $data['file'], $data['line'], $trace); + $renderer = new $this->renderers[$outputFormat](); + echo $renderer->render($error, Configure::read('debug')); + + return; + } + $files = static::trace(['start' => $data['start'], 'format' => 'points']); $code = ''; $file = null; @@ -956,7 +1020,7 @@ public function outputError(array $data): void $data['trace'] = $trace; $data['id'] = 'cakeErr' . uniqid(); - $tpl = $this->_templates[$this->_outputFormat] + $this->_templates['base']; + $tpl = $this->_templates[$outputFormat] + $this->_templates['base']; if (isset($tpl['links'])) { foreach ($tpl['links'] as $key => $val) { @@ -1064,9 +1128,8 @@ public static function formatHtmlMessage(string $message): string { $message = h($message); $message = preg_replace('/`([^`]+)`/', '$1', $message); - $message = nl2br($message); - return $message; + return nl2br($message); } /** diff --git a/app/vendor/cakephp/cakephp/src/Error/ErrorHandler.php b/app/vendor/cakephp/cakephp/src/Error/ErrorHandler.php index 540f02a87..f69193f3f 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ErrorHandler.php +++ b/app/vendor/cakephp/cakephp/src/Error/ErrorHandler.php @@ -199,7 +199,7 @@ protected function _logInternalError(Throwable $exception): void /** * Method that can be easily stubbed in testing. * - * @param \Cake\Http\Response|string $response Either the message or response object. + * @param \Psr\Http\Message\ResponseInterface|string $response Either the message or response object. * @return void */ protected function _sendResponse($response): void diff --git a/app/vendor/cakephp/cakephp/src/Error/ErrorLogger.php b/app/vendor/cakephp/cakephp/src/Error/ErrorLogger.php index 91b81db0a..4e91d8b90 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ErrorLogger.php +++ b/app/vendor/cakephp/cakephp/src/Error/ErrorLogger.php @@ -33,14 +33,11 @@ class ErrorLogger implements ErrorLoggerInterface /** * Default configuration values. * - * - `skipLog` List of exceptions to skip logging. Exceptions that - * extend one of the listed exceptions will also not be logged. * - `trace` Should error logs include stack traces? * * @var array */ protected $_defaultConfig = [ - 'skipLog' => [], 'trace' => false, ]; @@ -55,7 +52,59 @@ public function __construct(array $config = []) } /** - * @inheritDoc + * Log an error to Cake's Log subsystem + * + * @param \Cake\Error\PhpError $error The error to log + * @param ?\Psr\Http\Message\ServerRequestInterface $request The request if in an HTTP context. + * @param bool $includeTrace Should the log message include a stacktrace + * @return void + */ + public function logError(PhpError $error, ?ServerRequestInterface $request = null, bool $includeTrace = false): void + { + $message = $error->getMessage(); + if ($request) { + $message .= $this->getRequestContext($request); + } + if ($includeTrace) { + $message .= "\nTrace:\n" . $error->getTraceAsString() . "\n"; + } + $logMap = [ + 'strict' => LOG_NOTICE, + 'deprecated' => LOG_NOTICE, + ]; + $level = $error->getLabel(); + $level = $logMap[$level] ?? $level; + + Log::write($level, $message); + } + + /** + * Log an exception to Cake's Log subsystem + * + * @param \Throwable $exception The exception to log a message for. + * @param \Psr\Http\Message\ServerRequestInterface|null $request The current request if available. + * @param bool $includeTrace Whether or not a stack trace should be logged. + * @return void + */ + public function logException( + Throwable $exception, + ?ServerRequestInterface $request = null, + bool $includeTrace = false + ): void { + $message = $this->getMessage($exception, false, $includeTrace); + + if ($request !== null) { + $message .= $this->getRequestContext($request); + } + Log::error($message); + } + + /** + * @param string|int $level The logging level + * @param string $message The message to be logged. + * @param array $context Context. + * @return bool + * @deprecated 4.4.0 Use logError instead. */ public function logMessage($level, string $message, array $context = []): bool { @@ -65,22 +114,24 @@ public function logMessage($level, string $message, array $context = []): bool if (!empty($context['trace'])) { $message .= "\nTrace:\n" . $context['trace'] . "\n"; } + $logMap = [ + 'strict' => LOG_NOTICE, + 'deprecated' => LOG_NOTICE, + ]; + $level = $logMap[$level] ?? $level; return Log::write($level, $message); } /** - * @inheritDoc + * @param \Throwable $exception The exception to log a message for. + * @param \Psr\Http\Message\ServerRequestInterface|null $request The current request if available. + * @return bool + * @deprecated 4.4.0 Use logException instead. */ public function log(Throwable $exception, ?ServerRequestInterface $request = null): bool { - foreach ($this->getConfig('skipLog') as $class) { - if ($exception instanceof $class) { - return false; - } - } - - $message = $this->getMessage($exception); + $message = $this->getMessage($exception, false, $this->getConfig('trace')); if ($request !== null) { $message .= $this->getRequestContext($request); @@ -96,9 +147,10 @@ public function log(Throwable $exception, ?ServerRequestInterface $request = nul * * @param \Throwable $exception The exception to log a message for. * @param bool $isPrevious False for original exception, true for previous + * @param bool $includeTrace Whether or not to include a stack trace. * @return string Error message */ - protected function getMessage(Throwable $exception, bool $isPrevious = false): string + protected function getMessage(Throwable $exception, bool $isPrevious = false, bool $includeTrace = false): string { $message = sprintf( '%s[%s] %s in %s on line %s', @@ -117,7 +169,7 @@ protected function getMessage(Throwable $exception, bool $isPrevious = false): s } } - if ($this->getConfig('trace')) { + if ($includeTrace) { /** @var array $trace */ $trace = Debugger::formatTrace($exception, ['format' => 'points']); $message .= "\nStack Trace:\n"; @@ -132,7 +184,7 @@ protected function getMessage(Throwable $exception, bool $isPrevious = false): s $previous = $exception->getPrevious(); if ($previous) { - $message .= $this->getMessage($previous, true); + $message .= $this->getMessage($previous, true, $includeTrace); } return $message; diff --git a/app/vendor/cakephp/cakephp/src/Error/ErrorLoggerInterface.php b/app/vendor/cakephp/cakephp/src/Error/ErrorLoggerInterface.php index b8ee57c23..5a2626b24 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ErrorLoggerInterface.php +++ b/app/vendor/cakephp/cakephp/src/Error/ErrorLoggerInterface.php @@ -24,6 +24,11 @@ * * Used by the ErrorHandlerMiddleware and global * error handlers to log exceptions and errors. + * + * @method void logException(\Throwable $exception, ?\Psr\Http\Message\ServerRequestInterface $request = null, bool $includeTrace = false) + * Log an exception with an optional HTTP request. + * @method void logError(\Cake\Error\PhpError $error, ?\Psr\Http\Message\ServerRequestInterface $request = null, bool $includeTrace = false) + * Log an error with an optional HTTP request. */ interface ErrorLoggerInterface { @@ -33,6 +38,7 @@ interface ErrorLoggerInterface * @param \Throwable $exception The exception to log a message for. * @param \Psr\Http\Message\ServerRequestInterface|null $request The current request if available. * @return bool + * @deprecated 4.4.0 Implement `logException` instead. */ public function log( Throwable $exception, @@ -46,6 +52,7 @@ public function log( * @param string $message The message to be logged. * @param array $context Context. * @return bool + * @deprecated 4.4.0 Implement `logError` instead. */ public function logMessage($level, string $message, array $context = []): bool; } diff --git a/app/vendor/cakephp/cakephp/src/Error/ErrorRendererInterface.php b/app/vendor/cakephp/cakephp/src/Error/ErrorRendererInterface.php new file mode 100644 index 000000000..c0829126b --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/ErrorRendererInterface.php @@ -0,0 +1,43 @@ + + */ + protected $_defaultConfig = [ + 'errorLevel' => E_ALL, + 'errorRenderer' => null, + 'log' => true, + 'logger' => ErrorLogger::class, + 'trace' => false, + ]; + + /** + * Constructor + * + * @param array $options An options array. See $_defaultConfig. + */ + public function __construct(array $options = []) + { + $this->setConfig($options); + } + + /** + * Choose an error renderer based on config or the SAPI + * + * @return class-string<\Cake\Error\ErrorRendererInterface> + */ + protected function chooseErrorRenderer(): string + { + $config = $this->getConfig('errorRenderer'); + if ($config !== null) { + return $config; + } + + /** @var class-string<\Cake\Error\ErrorRendererInterface> */ + return PHP_SAPI === 'cli' ? ConsoleErrorRenderer::class : HtmlErrorRenderer::class; + } + + /** + * Attach this ErrorTrap to PHP's default error handler. + * + * This will replace the existing error handler, and the + * previous error handler will be discarded. + * + * This method will also set the global error level + * via error_reporting(). + * + * @return void + */ + public function register(): void + { + $level = $this->_config['errorLevel'] ?? -1; + error_reporting($level); + set_error_handler([$this, 'handleError'], $level); + } + + /** + * Handle an error from PHP set_error_handler + * + * Will use the configured renderer to generate output + * and output it. + * + * This method will dispatch the `Error.beforeRender` event which can be listened + * to on the global event manager. + * + * @param int $code Code of error + * @param string $description Error description + * @param string|null $file File on which error occurred + * @param int|null $line Line that triggered the error + * @return bool True if error was handled + */ + public function handleError( + int $code, + string $description, + ?string $file = null, + ?int $line = null + ): bool { + if (!(error_reporting() & $code)) { + return false; + } + if ($code === E_USER_ERROR || $code === E_ERROR || $code === E_PARSE) { + throw new FatalErrorException($description, $code, $file, $line); + } + + /** @var array $trace */ + $trace = Debugger::trace(['start' => 1, 'format' => 'points']); + $error = new PhpError($code, $description, $file, $line, $trace); + + $debug = Configure::read('debug'); + $renderer = $this->renderer(); + + try { + // Log first incase rendering or event listeners fail + $this->logError($error); + $event = $this->dispatchEvent('Error.beforeRender', ['error' => $error]); + if ($event->isStopped()) { + return true; + } + $renderer->write($renderer->render($error, $debug)); + } catch (Exception $e) { + // Fatal errors always log. + $this->logger()->logMessage('error', 'Could not render error. Got: ' . $e->getMessage()); + + return false; + } + + return true; + } + + /** + * Logging helper method. + * + * @param \Cake\Error\PhpError $error The error object to log. + * @return void + */ + protected function logError(PhpError $error): void + { + if (!$this->_config['log']) { + return; + } + $logger = $this->logger(); + if (method_exists($logger, 'logError')) { + $logger->logError($error, Router::getRequest(), $this->_config['trace']); + } else { + $loggerClass = get_class($logger); + deprecationWarning( + "The configured logger `{$loggerClass}` does not implement `logError()` " . + 'which will be required in future versions of CakePHP.' + ); + $context = []; + if ($this->_config['trace']) { + $context = [ + 'trace' => $error->getTraceAsString(), + 'request' => Router::getRequest(), + ]; + } + $logger->logMessage($error->getLabel(), $error->getMessage(), $context); + } + } + + /** + * Get an instance of the renderer. + * + * @return \Cake\Error\ErrorRendererInterface + */ + public function renderer(): ErrorRendererInterface + { + /** @var class-string<\Cake\Error\ErrorRendererInterface> $class */ + $class = $this->getConfig('errorRenderer') ?: $this->chooseErrorRenderer(); + + return new $class($this->_config); + } + + /** + * Get an instance of the logger. + * + * @return \Cake\Error\ErrorLoggerInterface + */ + public function logger(): ErrorLoggerInterface + { + $oldConfig = $this->getConfig('errorLogger'); + if ($oldConfig !== null) { + deprecationWarning('The `errorLogger` configuration key is deprecated. Use `logger` instead.'); + $this->setConfig(['logger' => $oldConfig, 'errorLogger' => null]); + } + + /** @var class-string<\Cake\Error\ErrorLoggerInterface> $class */ + $class = $this->getConfig('logger', $this->_defaultConfig['logger']); + + return new $class($this->_config); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php b/app/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php index 9c0e6fad3..c4dab58a6 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php +++ b/app/vendor/cakephp/cakephp/src/Error/ExceptionRenderer.php @@ -16,460 +16,13 @@ */ namespace Cake\Error; -use Cake\Controller\Controller; -use Cake\Controller\ControllerFactory; -use Cake\Controller\Exception\InvalidParameterException; -use Cake\Controller\Exception\MissingActionException; -use Cake\Core\App; -use Cake\Core\Configure; -use Cake\Core\Container; -use Cake\Core\Exception\CakeException; -use Cake\Core\Exception\MissingPluginException; -use Cake\Datasource\Exception\PageOutOfBoundsException; -use Cake\Datasource\Exception\RecordNotFoundException; -use Cake\Event\Event; -use Cake\Http\Exception\HttpException; -use Cake\Http\Exception\MissingControllerException; -use Cake\Http\Response; -use Cake\Http\ServerRequest; -use Cake\Http\ServerRequestFactory; -use Cake\Routing\Exception\MissingRouteException; -use Cake\Routing\Router; -use Cake\Utility\Inflector; -use Cake\View\Exception\MissingLayoutException; -use Cake\View\Exception\MissingTemplateException; -use PDOException; -use Psr\Http\Message\ResponseInterface; -use Throwable; +use Cake\Error\Renderer\WebExceptionRenderer; /** - * Exception Renderer. + * Backwards compatible Exception Renderer. * - * Captures and handles all unhandled exceptions. Displays helpful framework errors when debug is true. - * When debug is false a ExceptionRenderer will render 404 or 500 errors. If an uncaught exception is thrown - * and it is a type that ExceptionHandler does not know about it will be treated as a 500 error. - * - * ### Implementing application specific exception rendering - * - * You can implement application specific exception handling by creating a subclass of - * ExceptionRenderer and configure it to be the `exceptionRenderer` in config/error.php - * - * #### Using a subclass of ExceptionRenderer - * - * Using a subclass of ExceptionRenderer gives you full control over how Exceptions are rendered, you - * can configure your class in your config/app.php. + * @deprecated 4.4.0 Use `Cake\Error\Renderer\WebExceptionRenderer` instead. */ -class ExceptionRenderer implements ExceptionRendererInterface +class ExceptionRenderer extends WebExceptionRenderer { - /** - * The exception being handled. - * - * @var \Throwable - */ - protected $error; - - /** - * Controller instance. - * - * @var \Cake\Controller\Controller - */ - protected $controller; - - /** - * Template to render for {@link \Cake\Core\Exception\CakeException} - * - * @var string - */ - protected $template = ''; - - /** - * The method corresponding to the Exception this object is for. - * - * @var string - */ - protected $method = ''; - - /** - * If set, this will be request used to create the controller that will render - * the error. - * - * @var \Cake\Http\ServerRequest|null - */ - protected $request; - - /** - * Map of exceptions to http status codes. - * - * This can be customized for users that don't want specific exceptions to throw 404 errors - * or want their application exceptions to be automatically converted. - * - * @var array - * @psalm-var array, int> - */ - protected $exceptionHttpCodes = [ - // Controller exceptions - InvalidParameterException::class => 404, - MissingActionException::class => 404, - // Datasource exceptions - PageOutOfBoundsException::class => 404, - RecordNotFoundException::class => 404, - // Http exceptions - MissingControllerException::class => 404, - // Routing exceptions - MissingRouteException::class => 404, - ]; - - /** - * Creates the controller to perform rendering on the error response. - * - * @param \Throwable $exception Exception. - * @param \Cake\Http\ServerRequest|null $request The request if this is set it will be used - * instead of creating a new one. - */ - public function __construct(Throwable $exception, ?ServerRequest $request = null) - { - $this->error = $exception; - $this->request = $request; - $this->controller = $this->_getController(); - } - - /** - * Get the controller instance to handle the exception. - * Override this method in subclasses to customize the controller used. - * This method returns the built in `ErrorController` normally, or if an error is repeated - * a bare controller will be used. - * - * @return \Cake\Controller\Controller - * @triggers Controller.startup $controller - */ - protected function _getController(): Controller - { - $request = $this->request; - $routerRequest = Router::getRequest(); - // Fallback to the request in the router or make a new one from - // $_SERVER - if ($request === null) { - $request = $routerRequest ?: ServerRequestFactory::fromGlobals(); - } - - // If the current request doesn't have routing data, but we - // found a request in the router context copy the params over - if ($request->getParam('controller') === null && $routerRequest !== null) { - $request = $request->withAttribute('params', $routerRequest->getAttribute('params')); - } - - $errorOccured = false; - try { - $params = $request->getAttribute('params'); - $params['controller'] = 'Error'; - - $factory = new ControllerFactory(new Container()); - $class = $factory->getControllerClass($request->withAttribute('params', $params)); - - if (!$class) { - /** @var string $class */ - $class = App::className('Error', 'Controller', 'Controller'); - } - - /** @var \Cake\Controller\Controller $controller */ - $controller = new $class($request); - $controller->startupProcess(); - } catch (Throwable $e) { - $errorOccured = true; - } - - if (!isset($controller)) { - return new Controller($request); - } - - // Retry RequestHandler, as another aspect of startupProcess() - // could have failed. Ignore any exceptions out of startup, as - // there could be userland input data parsers. - if ($errorOccured && isset($controller->RequestHandler)) { - try { - $event = new Event('Controller.startup', $controller); - $controller->RequestHandler->startup($event); - } catch (Throwable $e) { - } - } - - return $controller; - } - - /** - * Clear output buffers so error pages display properly. - * - * @return void - */ - protected function clearOutput(): void - { - if (in_array(PHP_SAPI, ['cli', 'phpdbg'])) { - return; - } - while (ob_get_level()) { - ob_end_clean(); - } - } - - /** - * Renders the response for the exception. - * - * @return \Cake\Http\Response The response to be sent. - */ - public function render(): ResponseInterface - { - $exception = $this->error; - $code = $this->getHttpCode($exception); - $method = $this->_method($exception); - $template = $this->_template($exception, $method, $code); - $this->clearOutput(); - - if (method_exists($this, $method)) { - return $this->_customMethod($method, $exception); - } - - $message = $this->_message($exception, $code); - $url = $this->controller->getRequest()->getRequestTarget(); - $response = $this->controller->getResponse(); - - if ($exception instanceof CakeException) { - /** @psalm-suppress DeprecatedMethod */ - foreach ((array)$exception->responseHeader() as $key => $value) { - $response = $response->withHeader($key, $value); - } - } - if ($exception instanceof HttpException) { - foreach ($exception->getHeaders() as $name => $value) { - $response = $response->withHeader($name, $value); - } - } - $response = $response->withStatus($code); - - $viewVars = [ - 'message' => $message, - 'url' => h($url), - 'error' => $exception, - 'code' => $code, - ]; - $serialize = ['message', 'url', 'code']; - - $isDebug = Configure::read('debug'); - if ($isDebug) { - $trace = (array)Debugger::formatTrace($exception->getTrace(), [ - 'format' => 'array', - 'args' => false, - ]); - $origin = [ - 'file' => $exception->getFile() ?: 'null', - 'line' => $exception->getLine() ?: 'null', - ]; - // Traces don't include the origin file/line. - array_unshift($trace, $origin); - $viewVars['trace'] = $trace; - $viewVars += $origin; - $serialize[] = 'file'; - $serialize[] = 'line'; - } - $this->controller->set($viewVars); - $this->controller->viewBuilder()->setOption('serialize', $serialize); - - if ($exception instanceof CakeException && $isDebug) { - $this->controller->set($exception->getAttributes()); - } - $this->controller->setResponse($response); - - return $this->_outputMessage($template); - } - - /** - * Render a custom error method/template. - * - * @param string $method The method name to invoke. - * @param \Throwable $exception The exception to render. - * @return \Cake\Http\Response The response to send. - */ - protected function _customMethod(string $method, Throwable $exception): Response - { - $result = $this->{$method}($exception); - $this->_shutdown(); - if (is_string($result)) { - $result = $this->controller->getResponse()->withStringBody($result); - } - - return $result; - } - - /** - * Get method name - * - * @param \Throwable $exception Exception instance. - * @return string - */ - protected function _method(Throwable $exception): string - { - [, $baseClass] = namespaceSplit(get_class($exception)); - - if (substr($baseClass, -9) === 'Exception') { - $baseClass = substr($baseClass, 0, -9); - } - - // $baseClass would be an empty string if the exception class is \Exception. - $method = $baseClass === '' ? 'error500' : Inflector::variable($baseClass); - - return $this->method = $method; - } - - /** - * Get error message. - * - * @param \Throwable $exception Exception. - * @param int $code Error code. - * @return string Error message - */ - protected function _message(Throwable $exception, int $code): string - { - $message = $exception->getMessage(); - - if ( - !Configure::read('debug') && - !($exception instanceof HttpException) - ) { - if ($code < 500) { - $message = __d('cake', 'Not Found'); - } else { - $message = __d('cake', 'An Internal Error Has Occurred.'); - } - } - - return $message; - } - - /** - * Get template for rendering exception info. - * - * @param \Throwable $exception Exception instance. - * @param string $method Method name. - * @param int $code Error code. - * @return string Template name - */ - protected function _template(Throwable $exception, string $method, int $code): string - { - if ($exception instanceof HttpException || !Configure::read('debug')) { - return $this->template = $code < 500 ? 'error400' : 'error500'; - } - - if ($exception instanceof PDOException) { - return $this->template = 'pdo_error'; - } - - return $this->template = $method; - } - - /** - * Gets the appropriate http status code for exception. - * - * @param \Throwable $exception Exception. - * @return int A valid HTTP status code. - */ - protected function getHttpCode(Throwable $exception): int - { - if ($exception instanceof HttpException) { - return $exception->getCode(); - } - - return $this->exceptionHttpCodes[get_class($exception)] ?? 500; - } - - /** - * Generate the response using the controller object. - * - * @param string $template The template to render. - * @return \Cake\Http\Response A response object that can be sent. - */ - protected function _outputMessage(string $template): Response - { - try { - $this->controller->render($template); - - return $this->_shutdown(); - } catch (MissingTemplateException $e) { - $attributes = $e->getAttributes(); - if ( - $e instanceof MissingLayoutException || - strpos($attributes['file'], 'error500') !== false - ) { - return $this->_outputMessageSafe('error500'); - } - - return $this->_outputMessage('error500'); - } catch (MissingPluginException $e) { - $attributes = $e->getAttributes(); - if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->getPlugin()) { - $this->controller->setPlugin(null); - } - - return $this->_outputMessageSafe('error500'); - } catch (Throwable $outer) { - try { - return $this->_outputMessageSafe('error500'); - } catch (Throwable $inner) { - throw $outer; - } - } - } - - /** - * A safer way to render error messages, replaces all helpers, with basics - * and doesn't call component methods. - * - * @param string $template The template to render. - * @return \Cake\Http\Response A response object that can be sent. - */ - protected function _outputMessageSafe(string $template): Response - { - $builder = $this->controller->viewBuilder(); - $builder - ->setHelpers([], false) - ->setLayoutPath('') - ->setTemplatePath('Error'); - $view = $this->controller->createView('View'); - - $response = $this->controller->getResponse() - ->withType('html') - ->withStringBody($view->render($template, 'error')); - $this->controller->setResponse($response); - - return $response; - } - - /** - * Run the shutdown events. - * - * Triggers the afterFilter and afterDispatch events. - * - * @return \Cake\Http\Response The response to serve. - */ - protected function _shutdown(): Response - { - $this->controller->dispatchEvent('Controller.shutdown'); - - return $this->controller->getResponse(); - } - - /** - * Returns an array that can be used to describe the internal state of this - * object. - * - * @return array - */ - public function __debugInfo(): array - { - return [ - 'error' => $this->error, - 'request' => $this->request, - 'controller' => $this->controller, - 'template' => $this->template, - 'method' => $this->method, - ]; - } } diff --git a/app/vendor/cakephp/cakephp/src/Error/ExceptionRendererInterface.php b/app/vendor/cakephp/cakephp/src/Error/ExceptionRendererInterface.php index 103e244ac..e6bc4f7a4 100644 --- a/app/vendor/cakephp/cakephp/src/Error/ExceptionRendererInterface.php +++ b/app/vendor/cakephp/cakephp/src/Error/ExceptionRendererInterface.php @@ -20,13 +20,17 @@ /** * Interface ExceptionRendererInterface + * + * @method \Psr\Http\Message\ResponseInterface|string render() Render the exception to a string or Http Response. + * @method void write(\Psr\Http\Message\ResponseInterface|string $output) Write the output to the output stream. + * This method is only called when exceptions are handled by a global default exception handler. */ interface ExceptionRendererInterface { /** * Renders the response for the exception. * - * @return \Cake\Http\Response The response to be sent. + * @return \Psr\Http\Message\ResponseInterface The response to be sent. */ public function render(): ResponseInterface; } diff --git a/app/vendor/cakephp/cakephp/src/Error/ExceptionTrap.php b/app/vendor/cakephp/cakephp/src/Error/ExceptionTrap.php new file mode 100644 index 000000000..3ae2f9ab0 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/ExceptionTrap.php @@ -0,0 +1,391 @@ + ['Cake\Http\Exception\NotFoundException', 'Cake\Http\Exception\UnauthorizedException'] + * ``` + * This option is forwarded to the configured `logger` + * - `extraFatalErrorMemory` - int - The number of megabytes to increase the memory limit by when a fatal error is + * encountered. This allows breathing room to complete logging or error handling. + * - `stderr` Used in console environments so that renderers have access to the current console output stream. + * + * @var array + */ + protected $_defaultConfig = [ + 'exceptionRenderer' => null, + 'logger' => ErrorLogger::class, + 'stderr' => null, + 'log' => true, + 'skipLog' => [], + 'trace' => false, + 'extraFatalErrorMemory' => 4, + ]; + + /** + * A list of handling callbacks. + * + * Callbacks are invoked for each error that is handled. + * Callbacks are invoked in the order they are attached. + * + * @var array<\Closure> + */ + protected $callbacks = []; + + /** + * The currently registered global exception handler + * + * This is best effort as we can't know if/when another + * exception handler is registered. + * + * @var \Cake\Error\ExceptionTrap|null + */ + protected static $registeredTrap = null; + + /** + * Track if this trap was removed from the global handler. + * + * @var bool + */ + protected $disabled = false; + + /** + * Constructor + * + * @param array $options An options array. See $_defaultConfig. + */ + public function __construct(array $options = []) + { + $this->setConfig($options); + } + + /** + * Get an instance of the renderer. + * + * @param \Throwable $exception Exception to render + * @param \Psr\Http\Message\ServerRequestInterface|null $request The request if possible. + * @return \Cake\Error\ExceptionRendererInterface + */ + public function renderer(Throwable $exception, $request = null) + { + $request = $request ?? Router::getRequest(); + + /** @var class-string|callable $class */ + $class = $this->getConfig('exceptionRenderer'); + $deprecatedConfig = ($class === ExceptionRenderer::class && PHP_SAPI === 'cli'); + if ($deprecatedConfig) { + deprecationWarning( + 'Your application is using a deprecated `Error.exceptionRenderer`. ' . + 'You can either remove the `Error.exceptionRenderer` config key to have CakePHP choose ' . + 'one of the default exception renderers, or define a class that is not `Cake\Error\ExceptionRenderer`.' + ); + } + if (!$class || $deprecatedConfig) { + // Default to detecting the exception renderer if we're + // in a CLI context and the Web renderer is currently selected. + // This indicates old configuration or user error, in both scenarios + // it is preferrable to use the Console renderer instead. + $class = $this->chooseRenderer(); + } + + if (is_string($class)) { + /** @psalm-suppress ArgumentTypeCoercion */ + if (!(method_exists($class, 'render') && method_exists($class, 'write'))) { + throw new InvalidArgumentException( + "Cannot use {$class} as an `exceptionRenderer`. " . + 'It must implement render() and write() methods.' + ); + } + + /** @var class-string<\Cake\Error\ExceptionRendererInterface> $class */ + return new $class($exception, $request, $this->_config); + } + + return $class($exception, $request); + } + + /** + * Choose an exception renderer based on config or the SAPI + * + * @return class-string<\Cake\Error\ExceptionRendererInterface> + */ + protected function chooseRenderer(): string + { + /** @var class-string<\Cake\Error\ExceptionRendererInterface> */ + return PHP_SAPI === 'cli' ? ConsoleExceptionRenderer::class : ExceptionRenderer::class; + } + + /** + * Get an instance of the logger. + * + * @return \Cake\Error\ErrorLoggerInterface + */ + public function logger(): ErrorLoggerInterface + { + /** @var class-string<\Cake\Error\ErrorLoggerInterface> $class */ + $class = $this->getConfig('logger', $this->_defaultConfig['logger']); + + return new $class($this->_config); + } + + /** + * Attach this ExceptionTrap to PHP's default exception handler. + * + * This will replace the existing exception handler, and the + * previous exception handler will be discarded. + * + * @return void + */ + public function register(): void + { + set_exception_handler([$this, 'handleException']); + register_shutdown_function([$this, 'handleShutdown']); + static::$registeredTrap = $this; + } + + /** + * Remove this instance from the singleton + * + * If this instance is not currently the registered singleton + * nothing happens. + * + * @return void + */ + public function unregister(): void + { + if (static::$registeredTrap == $this) { + $this->disabled = true; + static::$registeredTrap = null; + } + } + + /** + * Get the registered global instance if set. + * + * Keep in mind that the global state contained here + * is mutable and the object returned by this method + * could be a stale value. + * + * @return \Cake\Error\ExceptionTrap|null The global instance or null. + */ + public static function instance(): ?self + { + return static::$registeredTrap; + } + + /** + * Handle uncaught exceptions. + * + * Uses a template method provided by subclasses to display errors in an + * environment appropriate way. + * + * @param \Throwable $exception Exception instance. + * @return void + * @throws \Exception When renderer class not found + * @see https://secure.php.net/manual/en/function.set-exception-handler.php + */ + public function handleException(Throwable $exception): void + { + if ($this->disabled) { + return; + } + $request = Router::getRequest(); + + $this->logException($exception, $request); + + try { + $renderer = $this->renderer($exception); + $renderer->write($renderer->render()); + } catch (Throwable $exception) { + $this->logInternalError($exception); + } + // Use this constant as a proxy for cakephp tests. + if (PHP_SAPI == 'cli' && !env('FIXTURE_SCHEMA_METADATA')) { + exit(1); + } + } + + /** + * Shutdown handler + * + * Convert fatal errors into exceptions that we can render. + * + * @return void + */ + public function handleShutdown(): void + { + if ($this->disabled) { + return; + } + $megabytes = $this->_config['extraFatalErrorMemory'] ?? 4; + if ($megabytes > 0) { + $this->increaseMemoryLimit($megabytes * 1024); + } + $error = error_get_last(); + if (!is_array($error)) { + return; + } + $fatals = [ + E_USER_ERROR, + E_ERROR, + E_PARSE, + ]; + if (!in_array($error['type'], $fatals, true)) { + return; + } + $this->handleFatalError( + $error['type'], + $error['message'], + $error['file'], + $error['line'] + ); + } + + /** + * Increases the PHP "memory_limit" ini setting by the specified amount + * in kilobytes + * + * @param int $additionalKb Number in kilobytes + * @return void + */ + public function increaseMemoryLimit(int $additionalKb): void + { + $limit = ini_get('memory_limit'); + if ($limit === false || $limit === '' || $limit === '-1') { + return; + } + $limit = trim($limit); + $units = strtoupper(substr($limit, -1)); + $current = (int)substr($limit, 0, -1); + if ($units === 'M') { + $current *= 1024; + $units = 'K'; + } + if ($units === 'G') { + $current = $current * 1024 * 1024; + $units = 'K'; + } + + if ($units === 'K') { + ini_set('memory_limit', ceil($current + $additionalKb) . 'K'); + } + } + + /** + * Display/Log a fatal error. + * + * @param int $code Code of error + * @param string $description Error description + * @param string $file File on which error occurred + * @param int $line Line that triggered the error + * @return void + */ + public function handleFatalError(int $code, string $description, string $file, int $line): void + { + $this->handleException(new FatalErrorException('Fatal Error: ' . $description, 500, $file, $line)); + } + + /** + * Log an exception. + * + * Primarily a public function to ensure consistency between global exception handling + * and the ErrorHandlerMiddleware. This method will apply the `skipLog` filter + * skipping logging if the exception should not be logged. + * + * After logging is attempted the `Exception.beforeRender` event is triggered. + * + * @param \Throwable $exception The exception to log + * @param \Psr\Http\Message\ServerRequestInterface|null $request The optional request + * @return void + */ + public function logException(Throwable $exception, ?ServerRequestInterface $request = null): void + { + $shouldLog = $this->_config['log']; + if ($shouldLog) { + foreach ($this->getConfig('skipLog') as $class) { + if ($exception instanceof $class) { + $shouldLog = false; + } + } + } + if ($shouldLog) { + $logger = $this->logger(); + if (method_exists($logger, 'logException')) { + $logger->logException($exception, $request, $this->_config['trace']); + } else { + $loggerClass = get_class($logger); + deprecationWarning( + "The configured logger `{$loggerClass}` should implement `logException()` " . + 'to be compatible with future versions of CakePHP.' + ); + $this->logger()->log($exception, $request); + } + } + $this->dispatchEvent('Exception.beforeRender', ['exception' => $exception]); + } + + /** + * Trigger an error that occurred during rendering an exception. + * + * By triggering an E_USER_ERROR we can end up in the default + * exception handling which will log the rendering failure, + * and hopefully render an error page. + * + * @param \Throwable $exception Exception to log + * @return void + */ + public function logInternalError(Throwable $exception): void + { + $message = sprintf( + '[%s] %s (%s:%s)', // Keeping same message format + get_class($exception), + $exception->getMessage(), + $exception->getFile(), + $exception->getLine(), + ); + trigger_error($message, E_USER_ERROR); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php b/app/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php index 565935446..d1e7efae7 100644 --- a/app/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Error/Middleware/ErrorHandlerMiddleware.php @@ -20,7 +20,8 @@ use Cake\Core\Configure; use Cake\Core\InstanceConfigTrait; use Cake\Error\ErrorHandler; -use Cake\Error\ExceptionRenderer; +use Cake\Error\ExceptionTrap; +use Cake\Error\Renderer\WebExceptionRenderer; use Cake\Http\Exception\RedirectException; use Cake\Http\Response; use InvalidArgumentException; @@ -44,28 +45,17 @@ class ErrorHandlerMiddleware implements MiddlewareInterface /** * Default configuration values. * - * Ignored if contructor is passed an ErrorHandler instance. + * Ignored if contructor is passed an ExceptionTrap instance. * - * - `log` Enable logging of exceptions. - * - `skipLog` List of exceptions to skip logging. Exceptions that - * extend one of the listed exceptions will also not be logged. Example: - * - * ``` - * 'skipLog' => ['Cake\Error\NotFoundException', 'Cake\Error\UnauthorizedException'] - * ``` - * - * - `trace` Should error logs include stack traces? - * - `exceptionRenderer` The renderer instance or class name to use or a callable factory - * which returns a \Cake\Error\ExceptionRendererInterface instance. - * Defaults to \Cake\Error\ExceptionRenderer + * Configuration keys and values are shared with `ExceptionTrap`. + * This class will pass its configuration onto the ExceptionTrap + * class if you are using the array style constructor. * * @var array + * @see \Cake\Error\ExceptionTrap */ protected $_defaultConfig = [ - 'skipLog' => [], - 'log' => true, - 'trace' => false, - 'exceptionRenderer' => ExceptionRenderer::class, + 'exceptionRenderer' => WebExceptionRenderer::class, ]; /** @@ -73,12 +63,19 @@ class ErrorHandlerMiddleware implements MiddlewareInterface * * @var \Cake\Error\ErrorHandler|null */ - protected $errorHandler; + protected $errorHandler = null; + + /** + * ExceptionTrap instance + * + * @var \Cake\Error\ExceptionTrap|null + */ + protected $exceptionTrap = null; /** * Constructor * - * @param \Cake\Error\ErrorHandler|array $errorHandler The error handler instance + * @param \Cake\Error\ErrorHandler|\Cake\Error\ExceptionTrap|array $errorHandler The error handler instance * or config array. * @throws \InvalidArgumentException */ @@ -102,15 +99,23 @@ public function __construct($errorHandler = []) return; } + if ($errorHandler instanceof ErrorHandler) { + deprecationWarning( + 'Using an `ErrorHandler` is deprecated. You should migate to the `ExceptionTrap` sub-system instead.' + ); + $this->errorHandler = $errorHandler; - if (!$errorHandler instanceof ErrorHandler) { - throw new InvalidArgumentException(sprintf( - '$errorHandler argument must be a config array or ErrorHandler instance. Got `%s` instead.', - getTypeName($errorHandler) - )); + return; } + if ($errorHandler instanceof ExceptionTrap) { + $this->exceptionTrap = $errorHandler; - $this->errorHandler = $errorHandler; + return; + } + throw new InvalidArgumentException(sprintf( + '$errorHandler argument must be a config array or ExceptionTrap instance. Got `%s` instead.', + getTypeName($errorHandler) + )); } /** @@ -118,7 +123,7 @@ public function __construct($errorHandler = []) * * @param \Psr\Http\Message\ServerRequestInterface $request The request. * @param \Psr\Http\Server\RequestHandlerInterface $handler The request handler. - * @return \Psr\Http\Message\ResponseInterface A response. + * @return \Psr\Http\Message\ResponseInterface A response */ public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { @@ -136,22 +141,35 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface * * @param \Throwable $exception The exception to handle. * @param \Psr\Http\Message\ServerRequestInterface $request The request. - * @return \Psr\Http\Message\ResponseInterface A response + * @return \Psr\Http\Message\ResponseInterface A response. */ public function handleException(Throwable $exception, ServerRequestInterface $request): ResponseInterface { - $errorHandler = $this->getErrorHandler(); - $renderer = $errorHandler->getRenderer($exception, $request); + if ($this->errorHandler === null) { + $handler = $this->getExceptionTrap(); + $handler->logException($exception, $request); + + $renderer = $handler->renderer($exception, $request); + } else { + $handler = $this->getErrorHandler(); + $handler->logException($exception, $request); + + $renderer = $handler->getRenderer($exception, $request); + } try { - $errorHandler->logException($exception, $request); + /** @var \Psr\Http\Message\ResponseInterface|string $response */ $response = $renderer->render(); + if (is_string($response)) { + return new Response(['body' => $response, 'status' => 500]); + } + + return $response; } catch (Throwable $internalException) { - $errorHandler->logException($internalException, $request); - $response = $this->handleInternalError(); - } + $handler->logException($internalException, $request); - return $response; + return $this->handleInternalError(); + } } /** @@ -176,9 +194,10 @@ public function handleRedirect(RedirectException $exception): ResponseInterface */ protected function handleInternalError(): ResponseInterface { - $response = new Response(['body' => 'An Internal Server Error Occurred']); - - return $response->withStatus(500); + return new Response([ + 'body' => 'An Internal Server Error Occurred', + 'status' => 500, + ]); } /** @@ -196,4 +215,20 @@ protected function getErrorHandler(): ErrorHandler return $this->errorHandler; } + + /** + * Get a exception trap instance + * + * @return \Cake\Error\ExceptionTrap The exception trap. + */ + protected function getExceptionTrap(): ExceptionTrap + { + if ($this->exceptionTrap === null) { + /** @var class-string<\Cake\Error\ExceptionTrap> $className */ + $className = App::className('ExceptionTrap', 'Error'); + $this->exceptionTrap = new $className($this->getConfig()); + } + + return $this->exceptionTrap; + } } diff --git a/app/vendor/cakephp/cakephp/src/Error/PhpError.php b/app/vendor/cakephp/cakephp/src/Error/PhpError.php new file mode 100644 index 000000000..a0a5396fe --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/PhpError.php @@ -0,0 +1,191 @@ +> + */ + private $trace; + + /** + * @var array + */ + private $levelMap = [ + E_PARSE => 'error', + E_ERROR => 'error', + E_CORE_ERROR => 'error', + E_COMPILE_ERROR => 'error', + E_USER_ERROR => 'error', + E_WARNING => 'warning', + E_USER_WARNING => 'warning', + E_COMPILE_WARNING => 'warning', + E_RECOVERABLE_ERROR => 'warning', + E_NOTICE => 'notice', + E_USER_NOTICE => 'notice', + E_STRICT => 'strict', + E_DEPRECATED => 'deprecated', + E_USER_DEPRECATED => 'deprecated', + ]; + + /** + * @var array + */ + private $logMap = [ + 'error' => LOG_ERR, + 'warning' => LOG_WARNING, + 'notice' => LOG_NOTICE, + 'strict' => LOG_NOTICE, + 'deprecated' => LOG_NOTICE, + ]; + + /** + * Constructor + * + * @param int $code The PHP error code constant + * @param string $message The error message. + * @param string|null $file The filename of the error. + * @param int|null $line The line number for the error. + * @param array $trace The backtrace for the error. + */ + public function __construct( + int $code, + string $message, + ?string $file = null, + ?int $line = null, + array $trace = [] + ) { + $this->code = $code; + $this->message = $message; + $this->file = $file; + $this->line = $line; + $this->trace = $trace; + } + + /** + * Get the PHP error constant. + * + * @return int + */ + public function getCode(): int + { + return $this->code; + } + + /** + * Get the mapped LOG_ constant. + * + * @return int + */ + public function getLogLevel(): int + { + $label = $this->getLabel(); + + return $this->logMap[$label] ?? LOG_ERR; + } + + /** + * Get the error code label + * + * @return string + */ + public function getLabel(): string + { + return $this->levelMap[$this->code] ?? 'error'; + } + + /** + * Get the error message. + * + * @return string + */ + public function getMessage(): string + { + return $this->message; + } + + /** + * Get the error file + * + * @return string|null + */ + public function getFile(): ?string + { + return $this->file; + } + + /** + * Get the error line number. + * + * @return int|null + */ + public function getLine(): ?int + { + return $this->line; + } + + /** + * Get the stacktrace as an array. + * + * @return array + */ + public function getTrace(): array + { + return $this->trace; + } + + /** + * Get the stacktrace as a string. + * + * @return string + */ + public function getTraceAsString(): string + { + $out = []; + foreach ($this->trace as $frame) { + $out[] = "{$frame['reference']} {$frame['file']}, line {$frame['line']}"; + } + + return implode("\n", $out); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleErrorRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleErrorRenderer.php new file mode 100644 index 000000000..eb1a2efac --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleErrorRenderer.php @@ -0,0 +1,84 @@ +output = $config['stderr'] ?? new ConsoleOutput('php://stderr'); + $this->trace = (bool)($config['trace'] ?? false); + } + + /** + * @inheritDoc + */ + public function write(string $out): void + { + $this->output->write($out); + } + + /** + * @inheritDoc + */ + public function render(PhpError $error, bool $debug): string + { + $trace = ''; + if ($this->trace) { + $trace = "\nStack Trace:\n\n" . $error->getTraceAsString(); + } + + return sprintf( + '%s: %s :: %s on line %s of %s%s', + $error->getLabel(), + $error->getCode(), + $error->getMessage(), + $error->getLine() ?? '', + $error->getFile() ?? '', + $trace + ); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleExceptionRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleExceptionRenderer.php new file mode 100644 index 000000000..988dcfa44 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/ConsoleExceptionRenderer.php @@ -0,0 +1,137 @@ +error = $error; + $this->output = $config['stderr'] ?? new ConsoleOutput('php://stderr'); + $this->trace = $config['trace'] ?? true; + } + + /** + * Render an exception into a plain text message. + * + * @return \Psr\Http\Message\ResponseInterface|string + */ + public function render() + { + $exceptions = [$this->error]; + $previous = $this->error->getPrevious(); + while ($previous !== null) { + $exceptions[] = $previous; + $previous = $previous->getPrevious(); + } + $out = []; + foreach ($exceptions as $i => $error) { + $out = array_merge($out, $this->renderException($error, $i)); + } + + return join("\n", $out); + } + + /** + * Render an individual exception + * + * @param \Throwable $exception The exception to render. + * @param int $index Exception index in the chain + * @return array + */ + protected function renderException(Throwable $exception, int $index): array + { + $out = [ + sprintf( + '%s[%s] %s in %s on line %s', + $index > 0 ? 'Caused by ' : '', + get_class($exception), + $exception->getMessage(), + $exception->getFile(), + $exception->getLine() + ), + ]; + + $debug = Configure::read('debug'); + if ($debug && $exception instanceof CakeException) { + $attributes = $exception->getAttributes(); + if ($attributes) { + $out[] = ''; + $out[] = 'Exception Attributes'; + $out[] = ''; + $out[] = var_export($exception->getAttributes(), true); + } + } + + if ($this->trace) { + $out[] = ''; + $out[] = 'Stack Trace:'; + $out[] = ''; + $out[] = $exception->getTraceAsString(); + $out[] = ''; + } + + return $out; + } + + /** + * Write output to the output stream + * + * @param string $output The output to print. + * @return void + */ + public function write($output): void + { + $this->output->write($output); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/HtmlErrorRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/HtmlErrorRenderer.php new file mode 100644 index 000000000..569445e0b --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/HtmlErrorRenderer.php @@ -0,0 +1,104 @@ +getFile(); + + // Some of the error data is not HTML safe so we escape everything. + $description = h($error->getMessage()); + $path = h($file); + $trace = h($error->getTraceAsString()); + $line = $error->getLine(); + + $errorMessage = sprintf( + '%s (%s)', + h(ucfirst($error->getLabel())), + h($error->getCode()) + ); + $toggle = $this->renderToggle($errorMessage, $id, 'trace'); + $codeToggle = $this->renderToggle('Code', $id, 'code'); + + $excerpt = []; + if ($file && $line) { + $excerpt = Debugger::excerpt($file, $line, 1); + } + $code = implode("\n", $excerpt); + + return << + {$toggle}: {$description} [in {$path}, line {$line}] + +
+HTML; + } + + /** + * Render a toggle link in the error content. + * + * @param string $text The text to insert. Assumed to be HTML safe. + * @param string $id The error id scope. + * @param string $suffix The element selector. + * @return string + */ + private function renderToggle(string $text, string $id, string $suffix): string + { + $selector = $id . '-' . $suffix; + + // phpcs:disable + return << + {$text} + +HTML; + // phpcs:enable + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/TextErrorRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/TextErrorRenderer.php new file mode 100644 index 000000000..ed98b15f0 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/TextErrorRenderer.php @@ -0,0 +1,56 @@ +getLabel(), + $error->getCode(), + $error->getMessage(), + $error->getLine() ?? '', + $error->getFile() ?? '', + $error->getTraceAsString(), + ); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/TextExceptionRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/TextExceptionRenderer.php new file mode 100644 index 000000000..42fbda2bf --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/TextExceptionRenderer.php @@ -0,0 +1,73 @@ +error = $error; + } + + /** + * Render an exception into a plain text message. + * + * @return \Psr\Http\Message\ResponseInterface|string + */ + public function render() + { + return sprintf( + "%s : %s on line %s of %s\nTrace:\n%s", + $this->error->getCode(), + $this->error->getMessage(), + $this->error->getLine(), + $this->error->getFile(), + $this->error->getTraceAsString(), + ); + } + + /** + * Write output to stdout. + * + * @param string $output The output to print. + * @return void + */ + public function write($output): void + { + echo $output; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Error/Renderer/WebExceptionRenderer.php b/app/vendor/cakephp/cakephp/src/Error/Renderer/WebExceptionRenderer.php new file mode 100644 index 000000000..5c7143c1b --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Error/Renderer/WebExceptionRenderer.php @@ -0,0 +1,504 @@ + + * @psalm-var array, int> + */ + protected $exceptionHttpCodes = [ + // Controller exceptions + InvalidParameterException::class => 404, + MissingActionException::class => 404, + // Datasource exceptions + PageOutOfBoundsException::class => 404, + RecordNotFoundException::class => 404, + // Http exceptions + MissingControllerException::class => 404, + // Routing exceptions + MissingRouteException::class => 404, + ]; + + /** + * Creates the controller to perform rendering on the error response. + * + * @param \Throwable $exception Exception. + * @param \Cake\Http\ServerRequest|null $request The request if this is set it will be used + * instead of creating a new one. + */ + public function __construct(Throwable $exception, ?ServerRequest $request = null) + { + $this->error = $exception; + $this->request = $request; + $this->controller = $this->_getController(); + } + + /** + * Get the controller instance to handle the exception. + * Override this method in subclasses to customize the controller used. + * This method returns the built in `ErrorController` normally, or if an error is repeated + * a bare controller will be used. + * + * @return \Cake\Controller\Controller + * @triggers Controller.startup $controller + */ + protected function _getController(): Controller + { + $request = $this->request; + $routerRequest = Router::getRequest(); + // Fallback to the request in the router or make a new one from + // $_SERVER + if ($request === null) { + $request = $routerRequest ?: ServerRequestFactory::fromGlobals(); + } + + // If the current request doesn't have routing data, but we + // found a request in the router context copy the params over + if ($request->getParam('controller') === null && $routerRequest !== null) { + $request = $request->withAttribute('params', $routerRequest->getAttribute('params')); + } + + $errorOccured = false; + try { + $params = $request->getAttribute('params'); + $params['controller'] = 'Error'; + + $factory = new ControllerFactory(new Container()); + $class = $factory->getControllerClass($request->withAttribute('params', $params)); + + if (!$class) { + /** @var string $class */ + $class = App::className('Error', 'Controller', 'Controller'); + } + + /** @var \Cake\Controller\Controller $controller */ + $controller = new $class($request); + $controller->startupProcess(); + } catch (Throwable $e) { + $errorOccured = true; + } + + if (!isset($controller)) { + return new Controller($request); + } + + // Retry RequestHandler, as another aspect of startupProcess() + // could have failed. Ignore any exceptions out of startup, as + // there could be userland input data parsers. + if ($errorOccured && isset($controller->RequestHandler)) { + try { + $event = new Event('Controller.startup', $controller); + $controller->RequestHandler->startup($event); + } catch (Throwable $e) { + } + } + + return $controller; + } + + /** + * Clear output buffers so error pages display properly. + * + * @return void + */ + protected function clearOutput(): void + { + if (in_array(PHP_SAPI, ['cli', 'phpdbg'])) { + return; + } + while (ob_get_level()) { + ob_end_clean(); + } + } + + /** + * Renders the response for the exception. + * + * @return \Cake\Http\Response The response to be sent. + */ + public function render(): ResponseInterface + { + $exception = $this->error; + $code = $this->getHttpCode($exception); + $method = $this->_method($exception); + $template = $this->_template($exception, $method, $code); + $this->clearOutput(); + + if (method_exists($this, $method)) { + return $this->_customMethod($method, $exception); + } + + $message = $this->_message($exception, $code); + $url = $this->controller->getRequest()->getRequestTarget(); + $response = $this->controller->getResponse(); + + if ($exception instanceof CakeException) { + /** @psalm-suppress DeprecatedMethod */ + foreach ((array)$exception->responseHeader() as $key => $value) { + $response = $response->withHeader($key, $value); + } + } + if ($exception instanceof HttpException) { + foreach ($exception->getHeaders() as $name => $value) { + $response = $response->withHeader($name, $value); + } + } + $response = $response->withStatus($code); + + $exceptions = [$exception]; + $previous = $exception->getPrevious(); + while ($previous != null) { + $exceptions[] = $previous; + $previous = $previous->getPrevious(); + } + + $viewVars = [ + 'message' => $message, + 'url' => h($url), + 'error' => $exception, + 'exceptions' => $exceptions, + 'code' => $code, + ]; + $serialize = ['message', 'url', 'code']; + + $isDebug = Configure::read('debug'); + if ($isDebug) { + $trace = (array)Debugger::formatTrace($exception->getTrace(), [ + 'format' => 'array', + 'args' => true, + ]); + $origin = [ + 'file' => $exception->getFile() ?: 'null', + 'line' => $exception->getLine() ?: 'null', + ]; + // Traces don't include the origin file/line. + array_unshift($trace, $origin); + $viewVars['trace'] = $trace; + $viewVars += $origin; + $serialize[] = 'file'; + $serialize[] = 'line'; + } + $this->controller->set($viewVars); + $this->controller->viewBuilder()->setOption('serialize', $serialize); + + if ($exception instanceof CakeException && $isDebug) { + $this->controller->set($exception->getAttributes()); + } + $this->controller->setResponse($response); + + return $this->_outputMessage($template); + } + + /** + * Emit the response content + * + * @param \Psr\Http\Message\ResponseInterface|string $output The response to output. + * @return void + */ + public function write($output): void + { + if (is_string($output)) { + echo $output; + + return; + } + + $emitter = new ResponseEmitter(); + $emitter->emit($output); + } + + /** + * Render a custom error method/template. + * + * @param string $method The method name to invoke. + * @param \Throwable $exception The exception to render. + * @return \Cake\Http\Response The response to send. + */ + protected function _customMethod(string $method, Throwable $exception): Response + { + $result = $this->{$method}($exception); + $this->_shutdown(); + if (is_string($result)) { + $result = $this->controller->getResponse()->withStringBody($result); + } + + return $result; + } + + /** + * Get method name + * + * @param \Throwable $exception Exception instance. + * @return string + */ + protected function _method(Throwable $exception): string + { + [, $baseClass] = namespaceSplit(get_class($exception)); + + if (substr($baseClass, -9) === 'Exception') { + $baseClass = substr($baseClass, 0, -9); + } + + // $baseClass would be an empty string if the exception class is \Exception. + $method = $baseClass === '' ? 'error500' : Inflector::variable($baseClass); + + return $this->method = $method; + } + + /** + * Get error message. + * + * @param \Throwable $exception Exception. + * @param int $code Error code. + * @return string Error message + */ + protected function _message(Throwable $exception, int $code): string + { + $message = $exception->getMessage(); + + if ( + !Configure::read('debug') && + !($exception instanceof HttpException) + ) { + if ($code < 500) { + $message = __d('cake', 'Not Found'); + } else { + $message = __d('cake', 'An Internal Error Has Occurred.'); + } + } + + return $message; + } + + /** + * Get template for rendering exception info. + * + * @param \Throwable $exception Exception instance. + * @param string $method Method name. + * @param int $code Error code. + * @return string Template name + */ + protected function _template(Throwable $exception, string $method, int $code): string + { + if ($exception instanceof HttpException || !Configure::read('debug')) { + return $this->template = $code < 500 ? 'error400' : 'error500'; + } + + if ($exception instanceof PDOException) { + return $this->template = 'pdo_error'; + } + + return $this->template = $method; + } + + /** + * Gets the appropriate http status code for exception. + * + * @param \Throwable $exception Exception. + * @return int A valid HTTP status code. + */ + protected function getHttpCode(Throwable $exception): int + { + if ($exception instanceof HttpException) { + return $exception->getCode(); + } + + return $this->exceptionHttpCodes[get_class($exception)] ?? 500; + } + + /** + * Generate the response using the controller object. + * + * @param string $template The template to render. + * @return \Cake\Http\Response A response object that can be sent. + */ + protected function _outputMessage(string $template): Response + { + try { + $this->controller->render($template); + + return $this->_shutdown(); + } catch (MissingTemplateException $e) { + $attributes = $e->getAttributes(); + if ( + $e instanceof MissingLayoutException || + strpos($attributes['file'], 'error500') !== false + ) { + return $this->_outputMessageSafe('error500'); + } + + return $this->_outputMessage('error500'); + } catch (MissingPluginException $e) { + $attributes = $e->getAttributes(); + if (isset($attributes['plugin']) && $attributes['plugin'] === $this->controller->getPlugin()) { + $this->controller->setPlugin(null); + } + + return $this->_outputMessageSafe('error500'); + } catch (Throwable $outer) { + try { + return $this->_outputMessageSafe('error500'); + } catch (Throwable $inner) { + throw $outer; + } + } + } + + /** + * A safer way to render error messages, replaces all helpers, with basics + * and doesn't call component methods. + * + * @param string $template The template to render. + * @return \Cake\Http\Response A response object that can be sent. + */ + protected function _outputMessageSafe(string $template): Response + { + $builder = $this->controller->viewBuilder(); + $builder + ->setHelpers([], false) + ->setLayoutPath('') + ->setTemplatePath('Error'); + $view = $this->controller->createView('View'); + + $response = $this->controller->getResponse() + ->withType('html') + ->withStringBody($view->render($template, 'error')); + $this->controller->setResponse($response); + + return $response; + } + + /** + * Run the shutdown events. + * + * Triggers the afterFilter and afterDispatch events. + * + * @return \Cake\Http\Response The response to serve. + */ + protected function _shutdown(): Response + { + $this->controller->dispatchEvent('Controller.shutdown'); + + return $this->controller->getResponse(); + } + + /** + * Returns an array that can be used to describe the internal state of this + * object. + * + * @return array + */ + public function __debugInfo(): array + { + return [ + 'error' => $this->error, + 'request' => $this->request, + 'controller' => $this->controller, + 'template' => $this->template, + 'method' => $this->method, + ]; + } +} diff --git a/app/vendor/cakephp/cakephp/src/Event/Event.php b/app/vendor/cakephp/cakephp/src/Event/Event.php index 12f7be341..86e3fd03f 100644 --- a/app/vendor/cakephp/cakephp/src/Event/Event.php +++ b/app/vendor/cakephp/cakephp/src/Event/Event.php @@ -22,6 +22,7 @@ * Class Event * * @template TSubject + * @implements \Cake\Event\EventInterface */ class Event implements EventInterface { @@ -105,7 +106,6 @@ public function getName(): string * @return object * @throws \Cake\Core\Exception\CakeException * @psalm-return TSubject - * @psalm-suppress LessSpecificImplementedReturnType */ public function getSubject() { @@ -172,8 +172,7 @@ public function getData(?string $key = null) return $this->_data[$key] ?? null; } - /** @psalm-suppress RedundantCastGivenDocblockType */ - return (array)$this->_data; + return $this->_data; } /** diff --git a/app/vendor/cakephp/cakephp/src/Event/EventInterface.php b/app/vendor/cakephp/cakephp/src/Event/EventInterface.php index f11cb6d45..aca9956d6 100644 --- a/app/vendor/cakephp/cakephp/src/Event/EventInterface.php +++ b/app/vendor/cakephp/cakephp/src/Event/EventInterface.php @@ -20,6 +20,8 @@ * Represents the transport class of events across the system. It receives a name, subject and an optional * payload. The name can be any string that uniquely identifies the event across the application, while the subject * represents the object that the event applies to. + * + * @template TSubject */ interface EventInterface { @@ -34,6 +36,7 @@ public function getName(): string; * Returns the subject of this event. * * @return object + * @psalm-return TSubject */ public function getSubject(); diff --git a/app/vendor/cakephp/cakephp/src/Event/EventManager.php b/app/vendor/cakephp/cakephp/src/Event/EventManager.php index 8bea9679a..278261d56 100644 --- a/app/vendor/cakephp/cakephp/src/Event/EventManager.php +++ b/app/vendor/cakephp/cakephp/src/Event/EventManager.php @@ -363,14 +363,13 @@ public function prioritisedListeners(string $eventKey): array public function matchingListeners(string $eventKeyPattern): array { $matchPattern = '/' . preg_quote($eventKeyPattern, '/') . '/'; - $matches = array_intersect_key( + + return array_intersect_key( $this->_listeners, array_flip( preg_grep($matchPattern, array_keys($this->_listeners), 0) ) ); - - return $matches; } /** diff --git a/app/vendor/cakephp/cakephp/src/Event/EventManagerInterface.php b/app/vendor/cakephp/cakephp/src/Event/EventManagerInterface.php index 1581f7699..492319b0f 100644 --- a/app/vendor/cakephp/cakephp/src/Event/EventManagerInterface.php +++ b/app/vendor/cakephp/cakephp/src/Event/EventManagerInterface.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.6.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Event; diff --git a/app/vendor/cakephp/cakephp/src/Event/composer.json b/app/vendor/cakephp/cakephp/src/Event/composer.json index d3a9bc50b..7e7ed7474 100644 --- a/app/vendor/cakephp/cakephp/src/Event/composer.json +++ b/app/vendor/cakephp/cakephp/src/Event/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/event" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0" }, "autoload": { diff --git a/app/vendor/cakephp/cakephp/src/Filesystem/Filesystem.php b/app/vendor/cakephp/cakephp/src/Filesystem/Filesystem.php index d1ecebc3b..3f3921855 100644 --- a/app/vendor/cakephp/cakephp/src/Filesystem/Filesystem.php +++ b/app/vendor/cakephp/cakephp/src/Filesystem/Filesystem.php @@ -223,9 +223,7 @@ public function deleteDir(string $path): bool unset($iterator); // phpcs:ignore - $result = $result && @rmdir($path); - - return $result; + return $result && @rmdir($path); } /** diff --git a/app/vendor/cakephp/cakephp/src/Filesystem/Folder.php b/app/vendor/cakephp/cakephp/src/Filesystem/Folder.php index e593ccee8..00d11a454 100644 --- a/app/vendor/cakephp/cakephp/src/Filesystem/Folder.php +++ b/app/vendor/cakephp/cakephp/src/Filesystem/Folder.php @@ -617,7 +617,7 @@ public function tree(?string $path = null, $exceptions = false, ?string $type = * * @param string $pathname The directory structure to create. Either an absolute or relative * path. If the path is relative and exists in the process' cwd it will not be created. - * Otherwise relative paths will be prefixed with the current pwd(). + * Otherwise, relative paths will be prefixed with the current pwd(). * @param int|null $mode octal value 0755 * @return bool Returns TRUE on success, FALSE on failure */ @@ -646,13 +646,14 @@ public function create(string $pathname, ?int $mode = null): bool if ($this->create($nextPathname, $mode)) { if (!file_exists($pathname)) { $old = umask(0); - umask($old); if (mkdir($pathname, $mode, true)) { $this->_messages[] = sprintf('%s created', $pathname); + umask($old); return true; } $this->_errors[] = sprintf('%s NOT created', $pathname); + umask($old); return false; } diff --git a/app/vendor/cakephp/cakephp/src/Filesystem/composer.json b/app/vendor/cakephp/cakephp/src/Filesystem/composer.json index edaffd5b6..82688b7c1 100644 --- a/app/vendor/cakephp/cakephp/src/Filesystem/composer.json +++ b/app/vendor/cakephp/cakephp/src/Filesystem/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/filesystem" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0" }, "autoload": { diff --git a/app/vendor/cakephp/cakephp/src/Form/composer.json b/app/vendor/cakephp/cakephp/src/Form/composer.json index 794281138..016644ca5 100644 --- a/app/vendor/cakephp/cakephp/src/Form/composer.json +++ b/app/vendor/cakephp/cakephp/src/Form/composer.json @@ -21,7 +21,7 @@ "source": "https://github.com/cakephp/form" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/event": "^4.0", "cakephp/validation": "^4.0" }, diff --git a/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php b/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php index 1b072a71b..a8c381db3 100644 --- a/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php +++ b/app/vendor/cakephp/cakephp/src/Http/BaseApplication.php @@ -294,7 +294,7 @@ public function services(ContainerInterface $container): void /** * Invoke the application. * - * - Convert the PSR response into CakePHP equivalents. + * - Add the request to the container, enabling its injection into other services. * - Create the controller that will handle this request. * - Invoke the controller. * @@ -304,8 +304,11 @@ public function services(ContainerInterface $container): void public function handle( ServerRequestInterface $request ): ResponseInterface { + $container = $this->getContainer(); + $container->add(ServerRequest::class, $request); + if ($this->controllerFactory === null) { - $this->controllerFactory = new ControllerFactory($this->getContainer()); + $this->controllerFactory = new ControllerFactory($container); } if (Router::getRequest() !== $request) { diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php b/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php index 18bfa0af9..d77fb0a6d 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Adapter/Stream.php @@ -41,14 +41,14 @@ class Stream implements AdapterInterface /** * Array of options/content for the HTTP stream context. * - * @var array + * @var array */ protected $_contextOptions = []; /** * Array of options/content for the SSL stream context. * - * @var array + * @var array */ protected $_sslContextOptions = []; @@ -320,7 +320,7 @@ protected function _open(string $url, RequestInterface $request): void restore_error_handler(); } - if (!$this->_stream || !empty($this->_connectionErrors)) { + if (!$this->_stream || $this->_connectionErrors) { throw new RequestException(implode("\n", $this->_connectionErrors), $request); } } @@ -330,7 +330,7 @@ protected function _open(string $url, RequestInterface $request): void * * Useful for debugging and testing context creation. * - * @return array + * @return array */ public function contextOptions(): array { diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php b/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php index 286b842eb..329702195 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/FormData.php @@ -17,6 +17,7 @@ use Countable; use finfo; +use Psr\Http\Message\UploadedFileInterface; /** * Provides an interface for building @@ -101,7 +102,7 @@ public function add($name, $value = null) if (is_string($name)) { if (is_array($value)) { $this->addRecursive($name, $value); - } elseif (is_resource($value)) { + } elseif (is_resource($value) || $value instanceof UploadedFileInterface) { $this->addFile($name, $value); } else { $this->_parts[] = $this->newPart($name, (string)$value); @@ -136,7 +137,8 @@ public function addMany(array $data) * or a file handle. * * @param string $name The name to use. - * @param mixed $value Either a string filename, or a filehandle. + * @param string|resource|\Psr\Http\Message\UploadedFileInterface $value Either a string filename, or a filehandle, + * or a UploadedFileInterface instance. * @return \Cake\Http\Client\FormDataPart */ public function addFile(string $name, $value): FormDataPart @@ -145,7 +147,11 @@ public function addFile(string $name, $value): FormDataPart $filename = false; $contentType = 'application/octet-stream'; - if (is_resource($value)) { + if ($value instanceof UploadedFileInterface) { + $content = (string)$value->getStream(); + $contentType = $value->getClientMediaType(); + $filename = $value->getClientFilename(); + } elseif (is_resource($value)) { $content = stream_get_contents($value); if (stream_is_local($value)) { $finfo = new finfo(FILEINFO_MIME); diff --git a/app/vendor/cakephp/cakephp/src/Http/Client/Response.php b/app/vendor/cakephp/cakephp/src/Http/Client/Response.php index 74b3818be..13df4d3d1 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Client/Response.php +++ b/app/vendor/cakephp/cakephp/src/Http/Client/Response.php @@ -115,7 +115,7 @@ class Response extends Message implements ResponseInterface /** * Cached decoded JSON data. * - * @var array + * @var mixed */ protected $_json; diff --git a/app/vendor/cakephp/cakephp/src/Http/ContentTypeNegotiation.php b/app/vendor/cakephp/cakephp/src/Http/ContentTypeNegotiation.php new file mode 100644 index 000000000..e02e78b0d --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Http/ContentTypeNegotiation.php @@ -0,0 +1,165 @@ +> A mapping of preference values => content types + */ + public function parseAccept(RequestInterface $request): array + { + $header = $request->getHeaderLine('Accept'); + + return $this->parseQualifiers($header); + } + + /** + * Parse the Accept-Language header + * + * Only qualifiers will be extracted, other extensions will be ignored + * as they are not frequently used. + * + * @param \Psr\Http\Message\RequestInterface $request The request to get an accept from. + * @return array> A mapping of preference values => languages + */ + public function parseAcceptLanguage(RequestInterface $request): array + { + $header = $request->getHeaderLine('Accept-Language'); + + return $this->parseQualifiers($header); + } + + /** + * Parse a header value into preference => value mapping + * + * @param string $header The header value to parse + * @return array> + */ + protected function parseQualifiers(string $header): array + { + $accept = []; + if (!$header) { + return $accept; + } + $headers = explode(',', $header); + foreach (array_filter($headers) as $value) { + $prefValue = '1.0'; + $value = trim($value); + + $semiPos = strpos($value, ';'); + if ($semiPos !== false) { + $params = explode(';', $value); + $value = trim($params[0]); + foreach ($params as $param) { + $qPos = strpos($param, 'q='); + if ($qPos !== false) { + $prefValue = substr($param, $qPos + 2); + } + } + } + + if (!isset($accept[$prefValue])) { + $accept[$prefValue] = []; + } + if ($prefValue) { + $accept[$prefValue][] = $value; + } + } + krsort($accept); + + return $accept; + } + + /** + * Get the most preferred content type from a request. + * + * Parse the Accept header preferences and return the most + * preferred type. If multiple types are tied in preference + * the first type of that preference value will be returned. + * + * You can expect null when the request has no Accept header. + * + * @param \Psr\Http\Message\RequestInterface $request The request to use. + * @param array $choices The supported content type choices. + * @return string|null The prefered type or null if there is no match with choices or if the + * request had no Accept header. + */ + public function preferredType(RequestInterface $request, array $choices = []): ?string + { + $parsed = $this->parseAccept($request); + if (empty($parsed)) { + return null; + } + if (empty($choices)) { + $preferred = array_shift($parsed); + + return $preferred[0]; + } + + foreach ($parsed as $acceptTypes) { + $common = array_intersect($acceptTypes, $choices); + if ($common) { + return array_shift($common); + } + } + + return null; + } + + /** + * Get the normalized list of accepted languages + * + * Language codes in the request will be normalized to lower case and have + * `_` replaced with `-`. + * + * @param \Psr\Http\Message\RequestInterface $request The request to read headers from. + * @return array A list of language codes that are accepted. + */ + public function acceptedLanguages(RequestInterface $request): array + { + $raw = $this->parseAcceptLanguage($request); + $accept = []; + foreach ($raw as $languages) { + foreach ($languages as &$lang) { + if (strpos($lang, '_')) { + $lang = str_replace('_', '-', $lang); + } + $lang = strtolower($lang); + } + $accept = array_merge($accept, $languages); + } + + return $accept; + } + + /** + * Check if the request accepts a given language code. + * + * Language codes in the request will be normalized to lower case and have `_` replaced + * with `-`. + * + * @param \Psr\Http\Message\RequestInterface $request The request to read headers from. + * @param string $lang The language code to check. + * @return bool Whether the request accepts $lang + */ + public function acceptLanguage(RequestInterface $request, string $lang): bool + { + $accept = $this->acceptedLanguages($request); + + return in_array(strtolower($lang), $accept, true); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Http/Cookie/Cookie.php b/app/vendor/cakephp/cakephp/src/Http/Cookie/Cookie.php index 9ab9ed3ca..f4fea6736 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Cookie/Cookie.php +++ b/app/vendor/cakephp/cakephp/src/Http/Cookie/Cookie.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Cookie; @@ -134,7 +134,7 @@ class Cookie implements CookieInterface * The only difference is the 3rd argument which excepts null or an * DateTime or DateTimeImmutable object instead an integer. * - * @link http://php.net/manual/en/function.setcookie.php + * @link https://php.net/manual/en/function.setcookie.php * @param string $name Cookie name * @param array|string $value Value of the cookie * @param \DateTime|\DateTimeImmutable|null $expiresAt Expiration time and date @@ -236,7 +236,7 @@ public static function create(string $name, $value, array $options = []) * Converts non null expiry value into DateTimeInterface instance. * * @param mixed $expires Expiry value. - * @return \DateTime|\DatetimeImmutable|null + * @return \DateTime|\DateTimeImmutable|null */ protected static function dateTimeInstance($expires): ?DateTimeInterface { diff --git a/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieCollection.php b/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieCollection.php index 93057cbe2..d7c13295f 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieCollection.php +++ b/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieCollection.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Cookie; diff --git a/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieInterface.php b/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieInterface.php index dfcdeae1a..2befd1e11 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieInterface.php +++ b/app/vendor/cakephp/cakephp/src/Http/Cookie/CookieInterface.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Cookie; diff --git a/app/vendor/cakephp/cakephp/src/Http/Exception/HttpException.php b/app/vendor/cakephp/cakephp/src/Http/Exception/HttpException.php index 0a81d2476..e39ea89d2 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Exception/HttpException.php +++ b/app/vendor/cakephp/cakephp/src/Http/Exception/HttpException.php @@ -32,7 +32,7 @@ class HttpException extends CakeException protected $_defaultCode = 500; /** - * @var array + * @var array */ protected $headers = []; @@ -51,7 +51,7 @@ public function setHeader(string $header, $value = null): void /** * Sets HTTP response headers. * - * @param array $headers Array of header name and value pairs. + * @param array $headers Array of header name and value pairs. * @return void */ public function setHeaders(array $headers): void @@ -62,7 +62,7 @@ public function setHeaders(array $headers): void /** * Returns array of response headers. * - * @return array + * @return array */ public function getHeaders(): array { diff --git a/app/vendor/cakephp/cakephp/src/Http/Exception/MissingControllerException.php b/app/vendor/cakephp/cakephp/src/Http/Exception/MissingControllerException.php index 4cbe6c15f..63152bd05 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Exception/MissingControllerException.php +++ b/app/vendor/cakephp/cakephp/src/Http/Exception/MissingControllerException.php @@ -32,3 +32,10 @@ class MissingControllerException extends CakeException */ protected $_messageTemplate = 'Controller class %s could not be found.'; } + +// phpcs:disable +class_alias( + 'Cake\Http\Exception\MissingControllerException', + 'Cake\Routing\Exception\MissingControllerException' +); +// phpcs:enable diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/BodyParserMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/BodyParserMiddleware.php index bd8f0d201..8432bc610 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/BodyParserMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/BodyParserMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.6.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/CspMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/CspMiddleware.php index 082e4dec4..91d44d302 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/CspMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/CspMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 4.0.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php index 28e33bdf1..a350b24f4 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/CsrfProtectionMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; @@ -429,7 +429,7 @@ protected function _validateToken(ServerRequestInterface $request): void */ protected function _createCookie(string $value, ServerRequestInterface $request): CookieInterface { - $cookie = Cookie::create( + return Cookie::create( $this->_config['cookieName'], $value, [ @@ -440,7 +440,5 @@ protected function _createCookie(string $value, ServerRequestInterface $request) 'samesite' => $this->_config['samesite'], ] ); - - return $cookie; } } diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php index f9e0a4dca..c40e349ea 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/EncryptedCookieMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/HttpsEnforcerMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/HttpsEnforcerMiddleware.php index 9176b9a43..709cc6f10 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/HttpsEnforcerMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/HttpsEnforcerMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 4.0.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; @@ -23,6 +23,7 @@ use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; +use UnexpectedValueException; /** * Enforces use of HTTPS (SSL) for requests. @@ -38,6 +39,12 @@ class HttpsEnforcerMiddleware implements MiddlewareInterface * - `statusCode` - Status code to use in case of redirect, defaults to 301 - Permanent redirect. * - `headers` - Array of response headers in case of redirect. * - `disableOnDebug` - Whether HTTPS check should be disabled when debug is on. Default `true`. + * - 'hsts' - Strict-Transport-Security header for HTTPS response configuration. Defaults to `null`. + * If enabled, an array of config options: + * + * - 'maxAge' - `max-age` directive value in seconds. + * - 'includeSubDomains' - Whether to include `includeSubDomains` directive. Defaults to `false`. + * - 'preload' - Whether to include 'preload' directive. Defauls to `false`. * * @var array */ @@ -46,6 +53,7 @@ class HttpsEnforcerMiddleware implements MiddlewareInterface 'statusCode' => 301, 'headers' => [], 'disableOnDebug' => true, + 'hsts' => null, ]; /** @@ -77,7 +85,12 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface || ($this->config['disableOnDebug'] && Configure::read('debug')) ) { - return $handler->handle($request); + $response = $handler->handle($request); + if ($this->config['hsts']) { + $response = $this->addHsts($response); + } + + return $response; } if ($this->config['redirect'] && $request->getMethod() === 'GET') { @@ -98,4 +111,28 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface 'Requests to this URL must be made with HTTPS.' ); } + + /** + * Adds Strict-Transport-Security header to response. + * + * @param \Psr\Http\Message\ResponseInterface $response Response + * @return \Psr\Http\Message\ResponseInterface + */ + protected function addHsts(ResponseInterface $response): ResponseInterface + { + $config = $this->config['hsts']; + if (!is_array($config)) { + throw new UnexpectedValueException('The `hsts` config must be an array.'); + } + + $value = 'max-age=' . $config['maxAge']; + if ($config['includeSubDomains'] ?? false) { + $value .= '; includeSubDomains'; + } + if ($config['preload'] ?? false) { + $value .= '; preload'; + } + + return $response->withHeader('strict-transport-security', $value); + } } diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/SecurityHeadersMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/SecurityHeadersMiddleware.php index f8249b9a6..eeb05e14b 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/SecurityHeadersMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/SecurityHeadersMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; @@ -98,7 +98,7 @@ class SecurityHeadersMiddleware implements MiddlewareInterface /** * Security related headers to set * - * @var array + * @var array */ protected $headers = []; diff --git a/app/vendor/cakephp/cakephp/src/Http/Middleware/SessionCsrfProtectionMiddleware.php b/app/vendor/cakephp/cakephp/src/Http/Middleware/SessionCsrfProtectionMiddleware.php index b4c0b0734..abba6cd1a 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Middleware/SessionCsrfProtectionMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Http/Middleware/SessionCsrfProtectionMiddleware.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 4.2.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Http\Middleware; @@ -43,7 +43,7 @@ * * If you use this middleware *do not* also use CsrfProtectionMiddleware. * - * @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#sychronizer-token-pattern + * @see https://cheatsheetseries.owasp.org/cheatsheets/Cross-Site_Request_Forgery_Prevention_Cheat_Sheet.html#synchronizer-token-pattern */ class SessionCsrfProtectionMiddleware implements MiddlewareInterface { diff --git a/app/vendor/cakephp/cakephp/src/Http/Response.php b/app/vendor/cakephp/cakephp/src/Http/Response.php index 6bf4bea2a..3feb4b4b1 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Response.php +++ b/app/vendor/cakephp/cakephp/src/Http/Response.php @@ -401,7 +401,7 @@ class Response implements ResponseInterface * Holds all the cache directives that will be converted * into headers when sending the request * - * @var array + * @var array */ protected $_cacheDirectives = []; @@ -660,7 +660,7 @@ protected function _setStatus(int $code, string $reasonPhrase = ''): void * status code. * * @link https://tools.ietf.org/html/rfc7231#section-6 - * @link http://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml + * @link https://www.iana.org/assignments/http-status-codes/http-status-codes.xhtml * @return string Reason phrase; must return an empty string if none present. */ public function getReasonPhrase(): string @@ -989,10 +989,15 @@ public function withModified($time) * * *Warning* This method mutates the response in-place and should be avoided. * + * @deprecated 4.4.0 Use `withNotModified()` instead. * @return void */ public function notModified(): void { + deprecationWarning( + 'The `notModified()` method is deprecated. ' . + 'Use `withNotModified() instead, and remember immutability of with* methods.' + ); $this->_createStream(); $this->_setStatus(304); @@ -1192,19 +1197,16 @@ public function withAddedLink(string $url, array $options = []) /** * Checks whether a response has not been modified according to the 'If-None-Match' * (Etags) and 'If-Modified-Since' (last modification date) request - * headers. If the response is detected to be not modified, it - * is marked as so accordingly so the client can be informed of that. - * - * In order to mark a response as not modified, you need to set at least - * the Last-Modified etag response header before calling this method. Otherwise - * a comparison will not be possible. + * headers. * - * *Warning* This method mutates the response in-place and should be avoided. + * In order to interact with this method you must mark responses as not modified. + * You need to set at least one of the `Last-Modified` or `Etag` response headers + * before calling this method. Otherwise, a comparison will not be possible. * * @param \Cake\Http\ServerRequest $request Request object - * @return bool Whether the response was marked as not modified or not. + * @return bool Whether the response is 'modified' based on cache headers. */ - public function checkNotModified(ServerRequest $request): bool + public function isNotModified(ServerRequest $request): bool { $etags = preg_split('/\s*,\s*/', $request->getHeaderLine('If-None-Match'), 0, PREG_SPLIT_NO_EMPTY); $responseTag = $this->getHeaderLine('Etag'); @@ -1221,12 +1223,39 @@ public function checkNotModified(ServerRequest $request): bool if ($etagMatches === null && $timeMatches === null) { return false; } - $notModified = $etagMatches !== false && $timeMatches !== false; - if ($notModified) { + + return $etagMatches !== false && $timeMatches !== false; + } + + /** + * Checks whether a response has not been modified according to the 'If-None-Match' + * (Etags) and 'If-Modified-Since' (last modification date) request + * headers. If the response is detected to be not modified, it + * is marked as so accordingly so the client can be informed of that. + * + * In order to mark a response as not modified, you need to set at least + * the Last-Modified etag response header before calling this method. Otherwise + * a comparison will not be possible. + * + * *Warning* This method mutates the response in-place and should be avoided. + * + * @param \Cake\Http\ServerRequest $request Request object + * @return bool Whether the response was marked as not modified or not. + * @deprecated 4.4.0 Use `isNotModified()` and `withNotModified()` instead. + */ + public function checkNotModified(ServerRequest $request): bool + { + deprecationWarning( + 'The `checkNotModified()` method is deprecated. ' . + 'Use `isNotModified() instead and `withNoModified()` instead.' + ); + if ($this->isNotModified($request)) { $this->notModified(); + + return true; } - return $notModified; + return false; } /** @@ -1310,7 +1339,7 @@ public function getCookie(string $name): ?array * * Returns an associative array of cookie name => cookie data. * - * @return array + * @return array */ public function getCookies(): array { diff --git a/app/vendor/cakephp/cakephp/src/Http/Runner.php b/app/vendor/cakephp/cakephp/src/Http/Runner.php index f9ced44c3..b6ea82fd0 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Runner.php +++ b/app/vendor/cakephp/cakephp/src/Http/Runner.php @@ -16,6 +16,8 @@ */ namespace Cake\Http; +use Cake\Routing\Router; +use Cake\Routing\RoutingApplicationInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\RequestHandlerInterface; @@ -55,6 +57,13 @@ public function run( $this->queue->rewind(); $this->fallbackHandler = $fallbackHandler; + if ( + $fallbackHandler instanceof RoutingApplicationInterface && + $request instanceof ServerRequest + ) { + Router::setRequest($request); + } + return $this->handle($request); } @@ -77,12 +86,10 @@ public function handle(ServerRequestInterface $request): ResponseInterface return $this->fallbackHandler->handle($request); } - $response = new Response([ + return new Response([ 'body' => 'Middleware queue was exhausted without returning a response ' . 'and no fallback request handler was set for Runner', 'status' => 500, ]); - - return $response; } } diff --git a/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php b/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php index 183d01ebb..eaf661177 100644 --- a/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php +++ b/app/vendor/cakephp/cakephp/src/Http/ServerRequest.php @@ -69,14 +69,14 @@ class ServerRequest implements ServerRequestInterface /** * Array of cookie data. * - * @var array + * @var array */ protected $cookies = []; /** * Array of environment data. * - * @var array + * @var array */ protected $_environment = []; @@ -129,13 +129,18 @@ class ServerRequest implements ServerRequestInterface 'ssl' => ['env' => 'HTTPS', 'options' => [1, 'on']], 'ajax' => ['env' => 'HTTP_X_REQUESTED_WITH', 'value' => 'XMLHttpRequest'], 'json' => ['accept' => ['application/json'], 'param' => '_ext', 'value' => 'json'], - 'xml' => ['accept' => ['application/xml', 'text/xml'], 'param' => '_ext', 'value' => 'xml'], + 'xml' => [ + 'accept' => ['application/xml', 'text/xml'], + 'exclude' => ['text/html'], + 'param' => '_ext', + 'value' => 'xml', + ], ]; /** * Instance cache for results of is(something) calls * - * @var array + * @var array */ protected $_detectorCache = []; @@ -170,7 +175,7 @@ class ServerRequest implements ServerRequestInterface /** * Store the additional attributes attached to the request. * - * @var array + * @var array */ protected $attributes = []; @@ -404,6 +409,7 @@ public function setTrustedProxies(array $proxies): void { $this->trustedProxies = $proxies; $this->trustProxy = true; + $this->uri = $this->uri->withScheme($this->scheme()); } /** @@ -552,14 +558,26 @@ protected function _is(string $type, array $args): bool */ protected function _acceptHeaderDetector(array $detect): bool { - $acceptHeaders = explode(',', (string)$this->getEnv('HTTP_ACCEPT')); - foreach ($detect['accept'] as $header) { - if (in_array($header, $acceptHeaders, true)) { - return true; - } + $content = new ContentTypeNegotiation(); + $options = $detect['accept']; + + // Some detectors overlap with the default browser Accept header + // For these types we use an exclude list to refine our content type + // detection. + $exclude = $detect['exclude'] ?? null; + if ($exclude) { + $options = array_merge($options, $exclude); } - return false; + $accepted = $content->preferredType($this, $options); + if ($accepted === null) { + return false; + } + if ($exclude && in_array($accepted, $exclude, true)) { + return false; + } + + return true; } /** @@ -769,7 +787,7 @@ protected function normalizeHeaderName(string $name): string * the headers. * * @return array An associative array of headers and their values. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getHeaders(): array { @@ -797,7 +815,7 @@ public function getHeaders(): array * * @param string $name The header you want to get (case-insensitive) * @return bool Whether the header is defined. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function hasHeader($name): bool { @@ -815,7 +833,7 @@ public function hasHeader($name): bool * @param string $name The header you want to get (case-insensitive) * @return array An associative array of headers and their values. * If the header doesn't exist, an empty array will be returned. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getHeader($name): array { @@ -832,7 +850,7 @@ public function getHeader($name): array * * @param string $name The header you want to get (case-insensitive) * @return string Header values collapsed into a comma separated string. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getHeaderLine($name): string { @@ -847,7 +865,7 @@ public function getHeaderLine($name): string * @param string $name The header name. * @param array|string $value The header value * @return static - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function withHeader($name, $value) { @@ -867,7 +885,7 @@ public function withHeader($name, $value) * @param string $name The header name. * @param array|string $value The header value * @return static - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function withAddedHeader($name, $value) { @@ -888,7 +906,7 @@ public function withAddedHeader($name, $value) * * @param string $name The header name to remove. * @return static - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function withoutHeader($name) { @@ -911,7 +929,7 @@ public function withoutHeader($name) * by CakePHP internally, and will effect the result of this method. * * @return string The name of the HTTP method used. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getMethod(): string { @@ -923,7 +941,7 @@ public function getMethod(): string * * @param string $method The HTTP method to use. * @return static A new instance with the updated method. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function withMethod($method) { @@ -950,7 +968,7 @@ public function withMethod($method) * used to create this request. * * @return array - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getServerParams(): array { @@ -962,7 +980,7 @@ public function getServerParams(): array * use the alternative getQuery() method. * * @return array - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function getQueryParams(): array { @@ -974,7 +992,7 @@ public function getQueryParams(): array * * @param array $query The query string data to use * @return static A new instance with the updated query string data. - * @link http://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. + * @link https://www.php-fig.org/psr/psr-7/ This method is part of the PSR-7 server request interface. */ public function withQueryParams(array $query) { @@ -1092,16 +1110,17 @@ public function subdomains(int $tldLength = 1): array */ public function accepts(?string $type = null) { - $raw = $this->parseAccept(); + $content = new ContentTypeNegotiation(); + if ($type) { + return $content->preferredType($this, [$type]) !== null; + } + $accept = []; - foreach ($raw as $types) { + foreach ($content->parseAccept($this) as $types) { $accept = array_merge($accept, $types); } - if ($type === null) { - return $accept; - } - return in_array($type, $accept, true); + return $accept; } /** @@ -1112,10 +1131,11 @@ public function accepts(?string $type = null) * of the accepted content types. * * @return array An array of `prefValue => [content/types]` + * @deprecated 4.4.0 Use `accepts()` or `ContentTypeNegotiation` class instead. */ public function parseAccept(): array { - return $this->_parseAcceptWithQualifier($this->getHeaderLine('Accept')); + return (new ContentTypeNegotiation())->parseAccept($this); } /** @@ -1123,74 +1143,23 @@ public function parseAccept(): array * * Get the list of accepted languages: * - * ``` \Cake\Http\ServerRequest::acceptLanguage(); ``` + * ```$request->acceptLanguage();``` * * Check if a specific language is accepted: * - * ``` \Cake\Http\ServerRequest::acceptLanguage('es-es'); ``` + * ```$request->acceptLanguage('es-es');``` * * @param string|null $language The language to test. - * @return array|bool If a $language is provided, a boolean. Otherwise the array of accepted languages. + * @return array|bool If a $language is provided, a boolean. Otherwise, the array of accepted languages. */ public function acceptLanguage(?string $language = null) { - $raw = $this->_parseAcceptWithQualifier($this->getHeaderLine('Accept-Language')); - $accept = []; - foreach ($raw as $languages) { - foreach ($languages as &$lang) { - if (strpos($lang, '_')) { - $lang = str_replace('_', '-', $lang); - } - $lang = strtolower($lang); - } - $accept = array_merge($accept, $languages); - } - if ($language === null) { - return $accept; - } - - return in_array(strtolower($language), $accept, true); - } - - /** - * Parse Accept* headers with qualifier options. - * - * Only qualifiers will be extracted, any other accept extensions will be - * discarded as they are not frequently used. - * - * @param string $header Header to parse. - * @return array - */ - protected function _parseAcceptWithQualifier(string $header): array - { - $accept = []; - $headers = explode(',', $header); - foreach (array_filter($headers) as $value) { - $prefValue = '1.0'; - $value = trim($value); - - $semiPos = strpos($value, ';'); - if ($semiPos !== false) { - $params = explode(';', $value); - $value = trim($params[0]); - foreach ($params as $param) { - $qPos = strpos($param, 'q='); - if ($qPos !== false) { - $prefValue = substr($param, $qPos + 2); - } - } - } - - if (!isset($accept[$prefValue])) { - $accept[$prefValue] = []; - } - if ($prefValue) { - $accept[$prefValue][] = $value; - } + $content = new ContentTypeNegotiation(); + if ($language !== null) { + return $content->acceptLanguage($this, $language); } - krsort($accept); - return $accept; + return $content->acceptedLanguages($this); } /** @@ -1363,7 +1332,7 @@ public function withCookieCollection(CookieCollection $cookies) /** * Get all the cookie data from the request. * - * @return array An array of cookie data. + * @return array An array of cookie data. */ public function getCookieParams(): array { @@ -1667,7 +1636,7 @@ public function getAttribute($name, $default = null) * This will include the params, webroot, base, and here attributes that CakePHP * provides. * - * @return array + * @return array */ public function getAttributes(): array { diff --git a/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php b/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php index 4746fb78a..fe6e4f9f4 100644 --- a/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php +++ b/app/vendor/cakephp/cakephp/src/Http/ServerRequestFactory.php @@ -17,6 +17,7 @@ namespace Cake\Http; use Cake\Core\Configure; +use Cake\Http\Uri as CakeUri; use Cake\Utility\Hash; use Psr\Http\Message\ServerRequestFactoryInterface; use Psr\Http\Message\ServerRequestInterface; @@ -29,9 +30,9 @@ /** * Factory for making ServerRequest instances. * - * This subclass adds in CakePHP specific behavior to populate - * the basePath and webroot attributes. Furthermore the Uri's path - * is corrected to only contain the 'virtual' path for the request. + * This adds in CakePHP specific behavior to populate the basePath and webroot + * attributes. Furthermore the Uri's path is corrected to only contain the + * 'virtual' path for the request. */ abstract class ServerRequestFactory implements ServerRequestFactoryInterface { @@ -41,10 +42,6 @@ abstract class ServerRequestFactory implements ServerRequestFactoryInterface * If any argument is not supplied, the corresponding superglobal value will * be used. * - * The ServerRequest created is then passed to the fromServer() method in - * order to marshal the request URI and headers. - * - * @see fromServer() * @param array|null $server $_SERVER superglobal * @param array|null $query $_GET superglobal * @param array|null $parsedBody $_POST superglobal @@ -63,29 +60,44 @@ public static function fromGlobals( $server = normalizeServer($server ?: $_SERVER); $uri = static::createUri($server); + $webroot = ''; + $base = ''; + if ($uri instanceof CakeUri) { + // Unwrap our shim for base and webroot. + // For 5.x we should change the interface on createUri() to return a + // tuple of [$uri, $base, $webroot] and remove the wrapper. + $webroot = $uri->getWebroot(); + $base = $uri->getBase(); + $uri->getUri(); + } + /** @psalm-suppress NoInterfaceProperties */ $sessionConfig = (array)Configure::read('Session') + [ 'defaults' => 'php', - 'cookiePath' => $uri->webroot, + 'cookiePath' => $webroot, ]; $session = Session::create($sessionConfig); - /** @psalm-suppress NoInterfaceProperties */ $request = new ServerRequest([ 'environment' => $server, 'uri' => $uri, 'cookies' => $cookies ?: $_COOKIE, 'query' => $query ?: $_GET, - 'webroot' => $uri->webroot, - 'base' => $uri->base, + 'webroot' => $webroot, + 'base' => $base, 'session' => $session, 'input' => $server['CAKEPHP_INPUT'] ?? null, ]); $request = static::marshalBodyAndRequestMethod($parsedBody ?? $_POST, $request); - $request = static::marshalFiles($files ?? $_FILES, $request); - - return $request; + // This is required as `ServerRequest::scheme()` ignores the value of + // `HTTP_X_FORWARDED_PROTO` unless `trustProxy` is enabled, while the + // `Uri` instance intially created always takes values of `HTTP_X_FORWARDED_PROTO` + // into account. + $uri = $request->getUri()->withScheme($request->scheme()); + $request = $request->withUri($uri, true); + + return static::marshalFiles($files ?? $_FILES, $request); } /** @@ -228,10 +240,11 @@ public static function createUri(array $server = []): UriInterface * * @param array $server The server parameters. * @param array $headers The normalized headers - * @return \Psr\Http\Message\UriInterface a constructed Uri + * @return \Cake\Http\Uri A constructed Uri */ protected static function marshalUriFromSapi(array $server, array $headers): UriInterface { + /** @psalm-suppress DeprecatedFunction */ $uri = marshalUriFromSapi($server, $headers); [$base, $webroot] = static::getBase($uri, $server); @@ -248,14 +261,7 @@ protected static function marshalUriFromSapi(array $server, array $headers): Uri $uri = $uri->withHost('localhost'); } - // Splat on some extra attributes to save - // some method calls. - /** @psalm-suppress NoInterfaceProperties */ - $uri->base = $base; - /** @psalm-suppress NoInterfaceProperties */ - $uri->webroot = $webroot; - - return $uri; + return new CakeUri($uri, $base, $webroot); } /** diff --git a/app/vendor/cakephp/cakephp/src/Http/Session.php b/app/vendor/cakephp/cakephp/src/Http/Session.php index 2556b6916..a9a0687b0 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Session.php +++ b/app/vendor/cakephp/cakephp/src/Http/Session.php @@ -263,22 +263,16 @@ public function engine($class = null, array $options = []): ?SessionHandlerInter if ($class instanceof SessionHandlerInterface) { return $this->setEngine($class); } - $className = App::className($class, 'Http/Session'); - if (!$className) { + /** @var class-string<\SessionHandlerInterface>|null $className */ + $className = App::className($class, 'Http/Session'); + if ($className === null) { throw new InvalidArgumentException( sprintf('The class "%s" does not exist and cannot be used as a session engine', $class) ); } - $handler = new $className($options); - if (!($handler instanceof SessionHandlerInterface)) { - throw new InvalidArgumentException( - 'The chosen SessionHandler does not implement SessionHandlerInterface, it cannot be used as an engine.' - ); - } - - return $this->setEngine($handler); + return $this->setEngine(new $className($options)); } /** diff --git a/app/vendor/cakephp/cakephp/src/Http/Session/CacheSession.php b/app/vendor/cakephp/cakephp/src/Http/Session/CacheSession.php index 668ba0e76..2959521c5 100644 --- a/app/vendor/cakephp/cakephp/src/Http/Session/CacheSession.php +++ b/app/vendor/cakephp/cakephp/src/Http/Session/CacheSession.php @@ -32,7 +32,7 @@ class CacheSession implements SessionHandlerInterface /** * Options for this session engine * - * @var array + * @var array */ protected $_options = []; diff --git a/app/vendor/cakephp/cakephp/src/Http/TestSuite/HttpClientTrait.php b/app/vendor/cakephp/cakephp/src/Http/TestSuite/HttpClientTrait.php new file mode 100644 index 000000000..0c5f75b15 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Http/TestSuite/HttpClientTrait.php @@ -0,0 +1,117 @@ + $headers A list of headers for the response. Example `Content-Type: application/json` + * @param string $body The body for the response. + * @return \Cake\Http\Client\Response + */ + public function newClientResponse(int $code = 200, array $headers = [], string $body = ''): Response + { + $headers = array_merge(["HTTP/1.1 {$code}"], $headers); + + return new Response($headers, $body); + } + + /** + * Add a mock response for a POST request. + * + * @param string $url The URL to mock + * @param \Cake\Http\Client\Response $response The response for the mock. + * @param array $options Additional options. See Client::addMockResponse() + * @return void + */ + public function mockClientPost(string $url, Response $response, array $options = []): void + { + Client::addMockResponse('POST', $url, $response, $options); + } + + /** + * Add a mock response for a GET request. + * + * @param string $url The URL to mock + * @param \Cake\Http\Client\Response $response The response for the mock. + * @param array $options Additional options. See Client::addMockResponse() + * @return void + */ + public function mockClientGet(string $url, Response $response, array $options = []): void + { + Client::addMockResponse('GET', $url, $response, $options); + } + + /** + * Add a mock response for a PATCH request. + * + * @param string $url The URL to mock + * @param \Cake\Http\Client\Response $response The response for the mock. + * @param array $options Additional options. See Client::addMockResponse() + * @return void + */ + public function mockClientPatch(string $url, Response $response, array $options = []): void + { + Client::addMockResponse('PATCH', $url, $response, $options); + } + + /** + * Add a mock response for a PUT request. + * + * @param string $url The URL to mock + * @param \Cake\Http\Client\Response $response The response for the mock. + * @param array $options Additional options. See Client::addMockResponse() + * @return void + */ + public function mockClientPut(string $url, Response $response, array $options = []): void + { + Client::addMockResponse('PUT', $url, $response, $options); + } + + /** + * Add a mock response for a DELETE request. + * + * @param string $url The URL to mock + * @param \Cake\Http\Client\Response $response The response for the mock. + * @param array $options Additional options. See Client::addMockResponse() + * @return void + */ + public function mockClientDelete(string $url, Response $response, array $options = []): void + { + Client::addMockResponse('DELETE', $url, $response, $options); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Http/Uri.php b/app/vendor/cakephp/cakephp/src/Http/Uri.php new file mode 100644 index 000000000..f929836d9 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Http/Uri.php @@ -0,0 +1,255 @@ +uri = $uri; + $this->base = $base; + $this->webroot = $webroot; + } + + /** + * Backwards compatibility shim for previously dynamic properties. + * + * @param string $name The attribute to read. + * @return mixed + */ + public function __get(string $name) + { + if ($name === 'base' || $name === 'webroot') { + return $this->{$name}; + } + throw new UnexpectedValueException("Undefined property via __get('{$name}')"); + } + + /** + * Get the decorated URI + * + * @return \Psr\Http\Message\UriInterface + */ + public function getUri(): UriInterface + { + return $this->uri; + } + + /** + * Get the application base path. + * + * @return string + */ + public function getBase(): string + { + return $this->base; + } + + /** + * Get the application webroot path. + * + * @return string + */ + public function getWebroot(): string + { + return $this->webroot; + } + + /** + * @inheritDoc + */ + public function getScheme() + { + return $this->uri->getScheme(); + } + + /** + * @inheritDoc + */ + public function getAuthority() + { + return $this->uri->getAuthority(); + } + + /** + * @inheritDoc + */ + public function getUserInfo() + { + return $this->uri->getUserInfo(); + } + + /** + * @inheritDoc + */ + public function getHost() + { + return $this->uri->getHost(); + } + + /** + * @inheritDoc + */ + public function getPort() + { + return $this->uri->getPort(); + } + + /** + * @inheritDoc + */ + public function getPath() + { + return $this->uri->getPath(); + } + + /** + * @inheritDoc + */ + public function getQuery() + { + return $this->uri->getQuery(); + } + + /** + * @inheritDoc + */ + public function getFragment() + { + return $this->uri->getFragment(); + } + + /** + * @inheritDoc + */ + public function withScheme($scheme) + { + $new = clone $this; + $new->uri = $this->uri->withScheme($scheme); + + return $new; + } + + /** + * @inheritDoc + */ + public function withUserInfo($user, $password = null) + { + $new = clone $this; + $new->uri = $this->uri->withUserInfo($user, $password); + + return $new; + } + + /** + * @inheritDoc + */ + public function withHost($host) + { + $new = clone $this; + $new->uri = $this->uri->withHost($host); + + return $new; + } + + /** + * @inheritDoc + */ + public function withPort($port) + { + $new = clone $this; + $new->uri = $this->uri->withPort($port); + + return $new; + } + + /** + * @inheritDoc + */ + public function withPath($path) + { + $new = clone $this; + $new->uri = $this->uri->withPath($path); + + return $new; + } + + /** + * @inheritDoc + */ + public function withQuery($query) + { + $new = clone $this; + $new->uri = $this->uri->withQuery($query); + + return $new; + } + + /** + * @inheritDoc + */ + public function withFragment($fragment) + { + $new = clone $this; + $new->uri = $this->uri->withFragment($fragment); + + return $new; + } + + /** + * @inheritDoc + */ + public function __toString() + { + return $this->uri->__toString(); + } +} diff --git a/app/vendor/cakephp/cakephp/src/Http/composer.json b/app/vendor/cakephp/cakephp/src/Http/composer.json index 5802f3e21..c5d38425d 100644 --- a/app/vendor/cakephp/cakephp/src/Http/composer.json +++ b/app/vendor/cakephp/cakephp/src/Http/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/http" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "cakephp/event": "^4.0", "cakephp/utility": "^4.0", diff --git a/app/vendor/cakephp/cakephp/src/I18n/Date.php b/app/vendor/cakephp/cakephp/src/I18n/Date.php index 0ba24c7e0..3dcc47eb2 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/Date.php +++ b/app/vendor/cakephp/cakephp/src/I18n/Date.php @@ -36,7 +36,7 @@ class Date extends MutableDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -52,7 +52,7 @@ class Date extends MutableDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -77,7 +77,7 @@ class Date extends MutableDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position diff --git a/app/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php b/app/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php index a42d79bb2..bd23d8cb5 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php +++ b/app/vendor/cakephp/cakephp/src/I18n/DateFormatTrait.php @@ -16,7 +16,9 @@ */ namespace Cake\I18n; +use Cake\Chronos\ChronosInterface; use Cake\Chronos\DifferenceFormatterInterface; +use Cake\Core\Exception\CakeException; use Closure; use DateTime; use DateTimeZone; @@ -287,7 +289,7 @@ public static function resetToStringFormat(): void * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -359,6 +361,9 @@ public static function parseDateTime(string $time, $format = null, $tz = null) null, $pattern ); + if (!$formatter) { + throw new CakeException('Unable to create IntlDateFormatter instance'); + } $formatter->setLenient(static::$lenientParsing); $time = $formatter->parse($time); @@ -479,6 +484,34 @@ public static function setDiffFormatter(DifferenceFormatterInterface $formatter) static::$diffFormatter = $formatter; } + /** + * Get the difference in a human readable format. + * + * When comparing a value in the past to default now: + * 1 hour ago + * 5 months ago + * + * When comparing a value in the future to default now: + * 1 hour from now + * 5 months from now + * + * When comparing a value in the past to another value: + * 1 hour before + * 5 months before + * + * When comparing a value in the future to another value: + * 1 hour after + * 5 months after + * + * @param \Cake\Chronos\ChronosInterface|null $other The datetime to compare with. + * @param bool $absolute removes time difference modifiers ago, after, etc + * @return string + */ + public function diffForHumans(?ChronosInterface $other = null, bool $absolute = false): string + { + return static::getDiffFormatter()->diffForHumans($this, $other, $absolute); + } + /** * Returns the data that should be displayed when debugging this object * diff --git a/app/vendor/cakephp/cakephp/src/I18n/FormatterLocator.php b/app/vendor/cakephp/cakephp/src/I18n/FormatterLocator.php index 53631f9cc..d1d1fa0be 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/FormatterLocator.php +++ b/app/vendor/cakephp/cakephp/src/I18n/FormatterLocator.php @@ -29,7 +29,7 @@ class FormatterLocator /** * A registry to retain formatter objects. * - * @var array + * @var array> */ protected $registry = []; @@ -44,7 +44,7 @@ class FormatterLocator /** * Constructor. * - * @param array $registry An array of key-value pairs where the key is the + * @param array> $registry An array of key-value pairs where the key is the * formatter name the value is a FQCN for the formatter. */ public function __construct(array $registry = []) @@ -58,7 +58,7 @@ public function __construct(array $registry = []) * Sets a formatter into the registry by name. * * @param string $name The formatter name. - * @param string $className A FQCN for a formatter. + * @param class-string<\Cake\I18n\FormatterInterface> $className A FQCN for a formatter. * @return void */ public function set(string $name, string $className): void @@ -81,10 +81,13 @@ public function get(string $name): FormatterInterface } if (!$this->converted[$name]) { - $this->registry[$name] = new $this->registry[$name](); + /** @var class-string<\Cake\I18n\FormatterInterface> $formatter */ + $formatter = $this->registry[$name]; + $this->registry[$name] = new $formatter(); $this->converted[$name] = true; } + /** @var \Cake\I18n\FormatterInterface */ return $this->registry[$name]; } } diff --git a/app/vendor/cakephp/cakephp/src/I18n/FrozenDate.php b/app/vendor/cakephp/cakephp/src/I18n/FrozenDate.php index c20fe7f68..4596bb0ea 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/FrozenDate.php +++ b/app/vendor/cakephp/cakephp/src/I18n/FrozenDate.php @@ -36,7 +36,7 @@ class FrozenDate extends ChronosDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -52,7 +52,7 @@ class FrozenDate extends ChronosDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -77,7 +77,7 @@ class FrozenDate extends ChronosDate implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position diff --git a/app/vendor/cakephp/cakephp/src/I18n/FrozenTime.php b/app/vendor/cakephp/cakephp/src/I18n/FrozenTime.php index 9711bf479..f1e6d6215 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/FrozenTime.php +++ b/app/vendor/cakephp/cakephp/src/I18n/FrozenTime.php @@ -37,7 +37,7 @@ class FrozenTime extends Chronos implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -53,7 +53,7 @@ class FrozenTime extends Chronos implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -69,7 +69,7 @@ class FrozenTime extends Chronos implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position diff --git a/app/vendor/cakephp/cakephp/src/I18n/I18nDateTimeInterface.php b/app/vendor/cakephp/cakephp/src/I18n/I18nDateTimeInterface.php index 5ccc6b0c8..52a5fc153 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/I18nDateTimeInterface.php +++ b/app/vendor/cakephp/cakephp/src/I18n/I18nDateTimeInterface.php @@ -60,7 +60,7 @@ public function nice($timezone = null, $locale = null): string; * It is possible to specify the desired format for the string to be displayed. * You can either pass `IntlDateFormatter` constants as the first argument of this * function, or pass a full ICU date formatting string as specified in the following - * resource: http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details. + * resource: https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details. * * Additional to `IntlDateFormatter` constants and date formatting string you can use * Time::UNIX_TIMESTAMP_FORMAT to get a unix timestamp @@ -132,7 +132,7 @@ public static function setToStringFormat($format): void; * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position diff --git a/app/vendor/cakephp/cakephp/src/I18n/PackageLocator.php b/app/vendor/cakephp/cakephp/src/I18n/PackageLocator.php index cbc037cff..e4d4296a6 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/PackageLocator.php +++ b/app/vendor/cakephp/cakephp/src/I18n/PackageLocator.php @@ -33,7 +33,7 @@ class PackageLocator * key is a package name, the second key is a locale code, and the value * is a callable that returns a Package object for that name and locale. * - * @var array + * @var array> */ protected $registry = []; @@ -41,14 +41,14 @@ class PackageLocator * Tracks whether a registry entry has been converted from a * callable to a Package object. * - * @var array + * @var array> */ protected $converted = []; /** * Constructor. * - * @param array $registry A registry of packages. + * @param array> $registry A registry of packages. * @see PackageLocator::$registry */ public function __construct(array $registry = []) @@ -88,11 +88,13 @@ public function get(string $name, string $locale): Package } if (!$this->converted[$name][$locale]) { + /** @var callable $func */ $func = $this->registry[$name][$locale]; $this->registry[$name][$locale] = $func(); $this->converted[$name][$locale] = true; } + /** @var \Cake\I18n\Package */ return $this->registry[$name][$locale]; } diff --git a/app/vendor/cakephp/cakephp/src/I18n/Time.php b/app/vendor/cakephp/cakephp/src/I18n/Time.php index e82f29a3e..9528e9de3 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/Time.php +++ b/app/vendor/cakephp/cakephp/src/I18n/Time.php @@ -37,7 +37,7 @@ class Time extends MutableDateTime implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -53,7 +53,7 @@ class Time extends MutableDateTime implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position @@ -69,7 +69,7 @@ class Time extends MutableDateTime implements I18nDateTimeInterface * * The format should be either the formatting constants from IntlDateFormatter as * described in (https://secure.php.net/manual/en/class.intldateformatter.php) or a pattern - * as specified in (http://www.icu-project.org/apiref/icu4c/classSimpleDateFormat.html#details) + * as specified in (https://unicode-org.github.io/icu-docs/apidoc/released/icu4c/classSimpleDateFormat.html#details) * * It is possible to provide an array of 2 constants. In this case, the first position * will be used for formatting the date part of the object and the second position diff --git a/app/vendor/cakephp/cakephp/src/I18n/Translator.php b/app/vendor/cakephp/cakephp/src/I18n/Translator.php index 879591a3f..f657ac81a 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/Translator.php +++ b/app/vendor/cakephp/cakephp/src/I18n/Translator.php @@ -157,6 +157,11 @@ public function translate(string $key, array $tokensValues = []): string if ($message === '') { $message = $key; + + // If singular haven't been translated, fallback to the key. + if (isset($tokensValues['_singular']) && $tokensValues['_count'] === 1) { + $message = $tokensValues['_singular']; + } } unset($tokensValues['_count'], $tokensValues['_singular']); diff --git a/app/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php b/app/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php index 2895b61ed..0ba3cee7b 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php +++ b/app/vendor/cakephp/cakephp/src/I18n/TranslatorRegistry.php @@ -340,7 +340,8 @@ public function setLoaderFallback(string $name, callable $loader): callable if (!$this->_useFallback || $name === $fallbackDomain) { return $loader; } - $loader = function () use ($loader, $fallbackDomain) { + + return function () use ($loader, $fallbackDomain) { /** @var \Cake\I18n\Package $package */ $package = $loader(); if (!$package->getFallback()) { @@ -349,7 +350,5 @@ public function setLoaderFallback(string $name, callable $loader): callable return $package; }; - - return $loader; } } diff --git a/app/vendor/cakephp/cakephp/src/I18n/composer.json b/app/vendor/cakephp/cakephp/src/I18n/composer.json index 8b75144a9..5b75e5983 100644 --- a/app/vendor/cakephp/cakephp/src/I18n/composer.json +++ b/app/vendor/cakephp/cakephp/src/I18n/composer.json @@ -28,7 +28,7 @@ "source": "https://github.com/cakephp/i18n" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "ext-intl": "*", "cakephp/core": "^4.0", "cakephp/chronos": "^2.0.0" diff --git a/app/vendor/cakephp/cakephp/src/Log/Engine/ArrayLog.php b/app/vendor/cakephp/cakephp/src/Log/Engine/ArrayLog.php index c82e183ec..1083f5ded 100644 --- a/app/vendor/cakephp/cakephp/src/Log/Engine/ArrayLog.php +++ b/app/vendor/cakephp/cakephp/src/Log/Engine/ArrayLog.php @@ -44,7 +44,7 @@ class ArrayLog extends BaseLog /** * Captured messages * - * @var array + * @var array */ protected $content = []; diff --git a/app/vendor/cakephp/cakephp/src/Log/README.md b/app/vendor/cakephp/cakephp/src/Log/README.md index 5056f84e5..d43cb9e55 100644 --- a/app/vendor/cakephp/cakephp/src/Log/README.md +++ b/app/vendor/cakephp/cakephp/src/Log/README.md @@ -8,28 +8,26 @@ multiple logging backends using a simple interface. With the `Log` class it is possible to send a single message to multiple logging backends at the same time or just a subset of them based on the log level or context. -By default, you can use Files or Syslog as logging backends, but you can use any +By default, you can use `File` or `Syslog` as logging backends, but you can use any object implementing `Psr\Log\LoggerInterface` as an engine for the `Log` class. ## Usage You can define as many or as few loggers as your application needs. Loggers -should be configured using `Cake\Core\Log.` An example would be: +should be configured using `Cake\Log\Log.` An example would be: ```php -use Cake\Cache\Cache; - use Cake\Log\Log; // Short classname -Log::config('local', [ - 'className' => 'FileLog', +Log::setConfig('local', [ + 'className' => 'File', 'levels' => ['notice', 'info', 'debug'], 'file' => '/path/to/file.log', ]); // Fully namespaced name. -Log::config('production', [ +Log::setConfig('production', [ 'className' => \Cake\Log\Engine\SyslogLog::class, 'levels' => ['warning', 'error', 'critical', 'alert', 'emergency'], ]); @@ -38,7 +36,7 @@ Log::config('production', [ It is also possible to create loggers by providing a closure. ```php -Log::config('special', function () { +Log::setConfig('special', function () { // Return any PSR-3 compatible logger return new MyPSR3CompatibleLogger(); }); @@ -47,7 +45,7 @@ Log::config('special', function () { Or by injecting an instance directly: ```php -Log::config('special', new MyPSR3CompatibleLogger()); +Log::setConfig('special', new MyPSR3CompatibleLogger()); ``` You can then use the `Log` class to pass messages to the logging backends: @@ -68,8 +66,8 @@ you can limit the logging engines that receive a particular message. ```php // Configure /logs/payments.log to receive all levels, but only // those with `payments` scope. -Log::config('payments', [ - 'className' => 'FileLog', +Log::setConfig('payments', [ + 'className' => 'File', 'levels' => ['error', 'info', 'warning'], 'scopes' => ['payments'], 'file' => '/logs/payments.log', diff --git a/app/vendor/cakephp/cakephp/src/Log/composer.json b/app/vendor/cakephp/cakephp/src/Log/composer.json index 81d234e8d..25512558f 100644 --- a/app/vendor/cakephp/cakephp/src/Log/composer.json +++ b/app/vendor/cakephp/cakephp/src/Log/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/log" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "psr/log": "^1.0 || ^2.0" }, diff --git a/app/vendor/cakephp/cakephp/src/Mailer/Email.php b/app/vendor/cakephp/cakephp/src/Mailer/Email.php index 27323f3c1..bc2358b13 100644 --- a/app/vendor/cakephp/cakephp/src/Mailer/Email.php +++ b/app/vendor/cakephp/cakephp/src/Mailer/Email.php @@ -93,7 +93,7 @@ class Email implements JsonSerializable, Serializable * A copy of the configuration profile for this * instance. This copy can be modified with Email::profile(). * - * @var array + * @var array */ protected $_profile = []; @@ -207,7 +207,7 @@ public function getViewRenderer(): string /** * Sets variables to be set on render. * - * @param array $viewVars Variables to set for view. + * @param array $viewVars Variables to set for view. * @return $this */ public function setViewVars(array $viewVars) @@ -220,7 +220,7 @@ public function setViewVars(array $viewVars) /** * Gets variables to be set on render. * - * @return array + * @return array */ public function getViewVars(): array { @@ -305,7 +305,7 @@ public function setProfile($config) unset($name); } - $this->_profile = array_merge($this->_profile, $config); + $this->_profile = $config + $this->_profile; $simpleMethods = [ 'transport', @@ -348,7 +348,7 @@ public function setProfile($config) /** * Gets the configuration profile to use for this instance. * - * @return array + * @return array */ public function getProfile(): array { @@ -443,7 +443,7 @@ public function setRenderer(Renderer $renderer) /** * Log the email message delivery. * - * @param array $contents The content with 'headers' and 'message' keys. + * @param array $contents The content with 'headers' and 'message' keys. * @return void */ protected function _logDelivery(array $contents): void diff --git a/app/vendor/cakephp/cakephp/src/Mailer/Mailer.php b/app/vendor/cakephp/cakephp/src/Mailer/Mailer.php index 9c8e67783..ce1b87fab 100644 --- a/app/vendor/cakephp/cakephp/src/Mailer/Mailer.php +++ b/app/vendor/cakephp/cakephp/src/Mailer/Mailer.php @@ -131,6 +131,7 @@ * @method array|string getBody(?string $type = null) Get generated message body as array. * {@see \Cake\Mailer\Message::getBody()} */ +#[\AllowDynamicProperties] class Mailer implements EventListenerInterface { use ModelAwareTrait; @@ -458,6 +459,12 @@ public function setProfile($config) $this->viewBuilder()->setVars($config['viewVars']); unset($config['viewVars']); } + if (isset($config['autoLayout'])) { + if ($config['autoLayout'] === false) { + $this->viewBuilder()->disableAutoLayout(); + } + unset($config['autoLayout']); + } if (isset($config['log'])) { $this->setLogConfig($config['log']); diff --git a/app/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php b/app/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php index 863236065..68be51147 100644 --- a/app/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php +++ b/app/vendor/cakephp/cakephp/src/Mailer/Transport/SmtpTransport.php @@ -28,6 +28,9 @@ */ class SmtpTransport extends AbstractTransport { + protected const AUTH_PLAIN = 'PLAIN'; + protected const AUTH_LOGIN = 'LOGIN'; + /** * Default config for this class * @@ -54,7 +57,7 @@ class SmtpTransport extends AbstractTransport /** * Content of email to return * - * @var array + * @var array */ protected $_content = []; @@ -65,6 +68,13 @@ class SmtpTransport extends AbstractTransport */ protected $_lastResponse = []; + /** + * Detected authentication type. + * + * @var string|null + */ + protected $authType = null; + /** * Destructor * @@ -169,9 +179,8 @@ public function getLastResponse(): array * Send mail * * @param \Cake\Mailer\Message $message Message instance - * @return array + * @return array{headers: string, message: string} * @throws \Cake\Network\Exception\SocketException - * @psalm-return array{headers: string, message: string} */ public function send(Message $message): array { @@ -214,6 +223,36 @@ protected function _bufferResponseLines(array $responseLines): void $this->_lastResponse = array_merge($this->_lastResponse, $response); } + /** + * Parses the last response line and extract the preferred authentication type. + * + * @return void + */ + protected function _parseAuthType(): void + { + $this->authType = null; + + $auth = ''; + foreach ($this->_lastResponse as $line) { + if (strlen($line['message']) === 0 || substr($line['message'], 0, 5) === 'AUTH ') { + $auth = $line['message']; + break; + } + } + + if (strpos($auth, self::AUTH_PLAIN) !== false) { + $this->authType = self::AUTH_PLAIN; + + return; + } + + if (strpos($auth, self::AUTH_LOGIN) !== false) { + $this->authType = self::AUTH_LOGIN; + + return; + } + } + /** * Connect to SMTP Server * @@ -265,6 +304,8 @@ protected function _connect(): void throw new SocketException('SMTP server did not accept the connection.', null, $e2); } } + + $this->_parseAuthType(); } /** @@ -281,13 +322,28 @@ protected function _auth(): void $username = $this->_config['username']; $password = $this->_config['password']; + if (empty($this->authType)) { + $replyCode = $this->_authPlain($username, $password); + if ($replyCode === '235') { + return; + } + + $this->_authLogin($username, $password); - $replyCode = $this->_authPlain($username, $password); - if ($replyCode === '235') { return; } - $this->_authLogin($username, $password); + if ($this->authType === self::AUTH_PLAIN) { + $this->_authPlain($username, $password); + + return; + } + + if ($this->authType === self::AUTH_LOGIN) { + $this->_authLogin($username, $password); + + return; + } } /** @@ -415,7 +471,7 @@ protected function _prepareMessage(Message $message): string /** * Send emails * - * @param \Cake\Mailer\Message $message Message message + * @param \Cake\Mailer\Message $message Message instance * @throws \Cake\Network\Exception\SocketException * @return void */ @@ -433,7 +489,7 @@ protected function _sendRcpt(Message $message): void /** * Send Data * - * @param \Cake\Mailer\Message $message Message message + * @param \Cake\Mailer\Message $message Message instance * @return void * @throws \Cake\Network\Exception\SocketException */ @@ -467,6 +523,7 @@ protected function _disconnect(): void { $this->_smtpSend('QUIT', false); $this->_socket()->disconnect(); + $this->authType = null; } /** diff --git a/app/vendor/cakephp/cakephp/src/Network/Socket.php b/app/vendor/cakephp/cakephp/src/Network/Socket.php index 0bc610e03..e94d8eab9 100644 --- a/app/vendor/cakephp/cakephp/src/Network/Socket.php +++ b/app/vendor/cakephp/cakephp/src/Network/Socket.php @@ -63,7 +63,7 @@ class Socket /** * This variable contains an array with the last error number (num) and string (str) * - * @var array + * @var array */ protected $lastError = []; @@ -96,7 +96,7 @@ class Socket * Used to capture connection warnings which can happen when there are * SSL errors for example. * - * @var array + * @var array */ protected $_connectionErrors = []; diff --git a/app/vendor/cakephp/cakephp/src/ORM/Association.php b/app/vendor/cakephp/cakephp/src/ORM/Association.php index 86ef6984c..9621dd2c4 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Association.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Association.php @@ -17,11 +17,13 @@ namespace Cake\ORM; use Cake\Collection\Collection; +use Cake\Collection\CollectionInterface; use Cake\Core\App; use Cake\Core\ConventionsTrait; use Cake\Database\Expression\IdentifierExpression; use Cake\Datasource\EntityInterface; use Cake\Datasource\ResultSetDecorator; +use Cake\Datasource\ResultSetInterface; use Cake\ORM\Locator\LocatorAwareTrait; use Cake\Utility\Inflector; use Closure; @@ -837,10 +839,10 @@ public function transformRow(array $row, string $nestKey, bool $joined, ?string * with the default empty value according to whether the association was * joined or fetched externally. * - * @param array $row The row to set a default on. + * @param array $row The row to set a default on. * @param bool $joined Whether the row is a result of a direct join * with this association - * @return array + * @return array */ public function defaultRowValue(array $row, bool $joined): array { @@ -1003,35 +1005,40 @@ protected function _formatAssociationResults(Query $query, Query $surrogate, arr $property = $options['propertyPath']; $propertyPath = explode('.', $property); - $query->formatResults(function ($results, $query) use ($formatters, $property, $propertyPath) { - $extracted = []; - foreach ($results as $result) { - foreach ($propertyPath as $propertyPathItem) { - if (!isset($result[$propertyPathItem])) { - $result = null; - break; + $query->formatResults( + function (CollectionInterface $results, $query) use ($formatters, $property, $propertyPath) { + $extracted = []; + foreach ($results as $result) { + foreach ($propertyPath as $propertyPathItem) { + if (!isset($result[$propertyPathItem])) { + $result = null; + break; + } + $result = $result[$propertyPathItem]; + } + $extracted[] = $result; + } + $extracted = new Collection($extracted); + foreach ($formatters as $callable) { + $extracted = $callable($extracted, $query); + if (!$extracted instanceof ResultSetInterface) { + $extracted = new ResultSetDecorator($extracted); } - $result = $result[$propertyPathItem]; } - $extracted[] = $result; - } - $extracted = new Collection($extracted); - foreach ($formatters as $callable) { - $extracted = new ResultSetDecorator($callable($extracted, $query)); - } - /** @var \Cake\Collection\CollectionInterface $results */ - $results = $results->insert($property, $extracted); - if ($query->isHydrationEnabled()) { - $results = $results->map(function ($result) { - $result->clean(); + $results = $results->insert($property, $extracted); + if ($query->isHydrationEnabled()) { + $results = $results->map(function ($result) { + $result->clean(); - return $result; - }); - } + return $result; + }); + } - return $results; - }, Query::PREPEND); + return $results; + }, + Query::PREPEND + ); } /** diff --git a/app/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php b/app/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php index a781e32ba..f43402258 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Association/BelongsToMany.php @@ -36,6 +36,7 @@ * that contains the association fields between the source and the target table. * * An example of a BelongsToMany association would be Article belongs to many Tags. + * In this example 'Article' is the source table and 'Tags' is the target table. */ class BelongsToMany extends Association { @@ -1266,26 +1267,42 @@ protected function _diffLinks( $assocForeignKey = (array)$belongsTo->getForeignKey(); $keys = array_merge($foreignKey, $assocForeignKey); - $deletes = $indexed = $present = []; + $deletes = $unmatchedEntityKeys = $present = []; foreach ($jointEntities as $i => $entity) { - $indexed[$i] = $entity->extract($keys); + $unmatchedEntityKeys[$i] = $entity->extract($keys); $present[$i] = array_values($entity->extract($assocForeignKey)); } - foreach ($existing as $result) { - $fields = $result->extract($keys); + foreach ($existing as $existingLink) { + $existingKeys = $existingLink->extract($keys); $found = false; - foreach ($indexed as $i => $data) { - if ($fields === $data) { - unset($indexed[$i]); + foreach ($unmatchedEntityKeys as $i => $unmatchedKeys) { + $matched = false; + foreach ($keys as $key) { + if (is_object($unmatchedKeys[$key]) && is_object($existingKeys[$key])) { + // If both sides are an object then use == so that value objects + // are seen as equivalent. + $matched = $existingKeys[$key] == $unmatchedKeys[$key]; + } else { + // Use strict equality for all other values. + $matched = $existingKeys[$key] === $unmatchedKeys[$key]; + } + // Stop checks on first failure. + if (!$matched) { + break; + } + } + if ($matched) { + // Remove the unmatched entity so we don't look at it again. + unset($unmatchedEntityKeys[$i]); $found = true; break; } } if (!$found) { - $deletes[] = $result; + $deletes[] = $existingLink; } } diff --git a/app/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteHelper.php b/app/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteHelper.php index 52b6289b1..e965d5de3 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteHelper.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Association/DependentDeleteHelper.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\ORM\Association; diff --git a/app/vendor/cakephp/cakephp/src/ORM/Association/Loader/SelectLoader.php b/app/vendor/cakephp/cakephp/src/ORM/Association/Loader/SelectLoader.php index 6a2591d49..dce3b3200 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Association/Loader/SelectLoader.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Association/Loader/SelectLoader.php @@ -133,7 +133,7 @@ public function buildEagerLoader(array $options): Closure /** * Returns the default options to use for the eagerLoader * - * @return array + * @return array */ protected function _defaultOptions(): array { diff --git a/app/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php b/app/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php index f73f05923..5e7d6ff2c 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php +++ b/app/vendor/cakephp/cakephp/src/ORM/AssociationCollection.php @@ -82,6 +82,7 @@ public function add(string $alias, Association $association): Association * @param array $options List of options to configure the association definition. * @return \Cake\ORM\Association * @throws \InvalidArgumentException + * @psalm-param class-string<\Cake\ORM\Association> $className */ public function load(string $className, string $associated, array $options = []): Association { @@ -90,14 +91,6 @@ public function load(string $className, string $associated, array $options = []) ]; $association = new $className($associated, $options); - if (!$association instanceof Association) { - $message = sprintf( - 'The association must extend `%s` class, `%s` given.', - Association::class, - get_class($association) - ); - throw new InvalidArgumentException($message); - } return $this->add($association->getName(), $association); } diff --git a/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/ShadowTableStrategy.php b/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/ShadowTableStrategy.php index 328fbcbe5..3284c3dc1 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/ShadowTableStrategy.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/ShadowTableStrategy.php @@ -537,7 +537,10 @@ protected function rowMapper($results, $locale) public function groupTranslations($results): CollectionInterface { return $results->map(function ($row) { - $translations = (array)$row['_i18n']; + if (!($row instanceof EntityInterface)) { + return $row; + } + $translations = (array)$row->get('_i18n'); if (empty($translations) && $row->get('_translations')) { return $row; } @@ -593,7 +596,7 @@ protected function bundleTranslatedFields($entity) /** * Lazy define and return the main table fields. * - * @return array + * @return array */ protected function mainFields() { @@ -613,7 +616,7 @@ protected function mainFields() /** * Lazy define and return the translation table fields. * - * @return array + * @return array */ protected function translatedFields() { diff --git a/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateStrategyInterface.php b/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateStrategyInterface.php index 9f8d9a200..41536e6c4 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateStrategyInterface.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Behavior/Translate/TranslateStrategyInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 4.0.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\ORM\Behavior\Translate; diff --git a/app/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php b/app/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php index 154d10d20..b009d0d52 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Behavior/TreeBehavior.php @@ -75,6 +75,7 @@ class TreeBehavior extends Behavior 'scope' => null, 'level' => null, 'recoverOrder' => null, + 'cascadeCallbacks' => false, ]; /** @@ -227,15 +228,22 @@ public function beforeDelete(EventInterface $event, EntityInterface $entity) if ($diff > 2) { $query = $this->_scope($this->_table->query()) - ->delete() ->where(function ($exp) use ($config, $left, $right) { /** @var \Cake\Database\Expression\QueryExpression $exp */ return $exp ->gte($config['leftField'], $left + 1) ->lte($config['leftField'], $right - 1); }); - $statement = $query->execute(); - $statement->closeCursor(); + if ($this->getConfig('cascadeCallbacks')) { + $entities = $query->toArray(); + foreach ($entities as $entityToDelete) { + $this->_table->delete($entityToDelete, ['atomic' => false]); + } + } else { + $query->delete(); + $statement = $query->execute(); + $statement->closeCursor(); + } } $this->_sync($diff, '-', "> {$right}"); diff --git a/app/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php b/app/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php index 9afbb9a62..e4b76e1c3 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php +++ b/app/vendor/cakephp/cakephp/src/ORM/BehaviorRegistry.php @@ -46,14 +46,14 @@ class BehaviorRegistry extends ObjectRegistry implements EventDispatcherInterfac /** * Method mappings. * - * @var array + * @var array */ protected $_methodMap = []; /** * Finder method mappings. * - * @var array + * @var array */ protected $_finderMap = []; diff --git a/app/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php b/app/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php index 411f1ebb7..fc5e226f2 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php +++ b/app/vendor/cakephp/cakephp/src/ORM/EagerLoadable.php @@ -51,7 +51,7 @@ class EagerLoadable * A list of options to pass to the association object for loading * the records. * - * @var array + * @var array */ protected $_config = []; @@ -250,7 +250,7 @@ public function setConfig(array $config) * Gets the list of options to pass to the association object for loading * the records. * - * @return array + * @return array */ public function getConfig(): array { @@ -291,7 +291,7 @@ public function targetProperty(): ?string * Returns a representation of this object that can be passed to * Cake\ORM\EagerLoader::contain() * - * @return array + * @return array */ public function asContainArray(): array { diff --git a/app/vendor/cakephp/cakephp/src/ORM/EagerLoader.php b/app/vendor/cakephp/cakephp/src/ORM/EagerLoader.php index 44412c04b..1778c32de 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/EagerLoader.php +++ b/app/vendor/cakephp/cakephp/src/ORM/EagerLoader.php @@ -91,7 +91,7 @@ class EagerLoader * A map of table aliases pointing to the association objects they represent * for the query. * - * @var array + * @var array */ protected $_joinsMap = []; @@ -706,9 +706,8 @@ public function associationsMap(Table $table): array /** @psalm-suppress PossiblyNullReference */ $map = $this->_buildAssociationsMap($map, $this->_matching->normalized($table), true); $map = $this->_buildAssociationsMap($map, $this->normalized($table)); - $map = $this->_buildAssociationsMap($map, $this->_joinsMap); - return $map; + return $this->_buildAssociationsMap($map, $this->_joinsMap); } /** diff --git a/app/vendor/cakephp/cakephp/src/ORM/LazyEagerLoader.php b/app/vendor/cakephp/cakephp/src/ORM/LazyEagerLoader.php index 2fd6cb9e2..0e7a0103d 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/LazyEagerLoader.php +++ b/app/vendor/cakephp/cakephp/src/ORM/LazyEagerLoader.php @@ -135,11 +135,11 @@ protected function _getPropertyMap(Table $source, array $associations): array * Injects the results of the eager loader query into the original list of * entities. * - * @param \Traversable|array<\Cake\Datasource\EntityInterface> $objects The original list of entities + * @param iterable<\Cake\Datasource\EntityInterface> $objects The original list of entities * @param \Cake\ORM\Query $results The loaded results * @param array $associations The top level associations that were loaded * @param \Cake\ORM\Table $source The table where the entities came from - * @return array + * @return array<\Cake\Datasource\EntityInterface> */ protected function _injectResults(iterable $objects, $results, array $associations, Table $source): array { diff --git a/app/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php b/app/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php index 157130527..1aa4a9e39 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Locator/LocatorAwareTrait.php @@ -16,9 +16,9 @@ */ namespace Cake\ORM\Locator; -use Cake\Core\Exception\CakeException; use Cake\Datasource\FactoryLocator; use Cake\ORM\Table; +use UnexpectedValueException; /** * Contains method for setting and accessing LocatorInterface instance @@ -83,8 +83,10 @@ public function getTableLocator(): LocatorInterface public function fetchTable(?string $alias = null, array $options = []): Table { $alias = $alias ?? $this->defaultTable; - if ($alias === null) { - throw new CakeException('You must provide an `$alias` or set the `$defaultTable` property.'); + if (empty($alias)) { + throw new UnexpectedValueException( + 'You must provide an `$alias` or set the `$defaultTable` property to a non empty string.' + ); } return $this->getTableLocator()->get($alias, $options); diff --git a/app/vendor/cakephp/cakephp/src/ORM/Locator/TableLocator.php b/app/vendor/cakephp/cakephp/src/ORM/Locator/TableLocator.php index 7f9fd0294..67a875201 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Locator/TableLocator.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Locator/TableLocator.php @@ -215,8 +215,6 @@ protected function createInstance(string $alias, array $options) $options = ['alias' => $classAlias] + $options; } elseif (!isset($options['alias'])) { $options['className'] = $alias; - /** @psalm-suppress PossiblyFalseOperand */ - $alias = substr($alias, strrpos($alias, '\\') + 1, -5); } if (isset($this->_config[$alias])) { diff --git a/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php b/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php index 6d52e7e16..7511aafa4 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Marshaller.php @@ -287,7 +287,7 @@ protected function _prepareDataAndOptions(array $data, array $options): array $options += ['validate' => true]; $tableName = $this->_table->getAlias(); - if (isset($data[$tableName])) { + if (isset($data[$tableName]) && is_array($data[$tableName])) { $data += $data[$tableName]; unset($data[$tableName]); } diff --git a/app/vendor/cakephp/cakephp/src/ORM/Query.php b/app/vendor/cakephp/cakephp/src/ORM/Query.php index cdba19ae6..7ba368007 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Query.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Query.php @@ -43,7 +43,7 @@ * @method \Cake\ORM\Table getRepository() Returns the default table object that will be used by this query, * that is, the table that will appear in the from clause. * @method \Cake\Collection\CollectionInterface each(callable $c) Passes each of the query results to the callable - * @method \Cake\Collection\CollectionInterface sortBy($callback, int $dir) Sorts the query with the callback + * @method \Cake\Collection\CollectionInterface sortBy(callable|string $path, int $order = \SORT_DESC, int $sort = \SORT_NUMERIC) Sorts the query with the callback * @method \Cake\Collection\CollectionInterface filter(callable $c = null) Keeps the results using passing the callable test * @method \Cake\Collection\CollectionInterface reject(callable $c) Removes the results passing the callable test * @method bool every(callable $c) Returns true if all the results pass the callable test @@ -1306,7 +1306,7 @@ public function delete(?string $table = null) * Can be combined with the where() method to create delete queries. * * @param array $columns The columns to insert into. - * @param array $types A map between columns & their datatypes. + * @param array $types A map between columns & their datatypes. * @return $this */ public function insert(array $columns, array $types = []) diff --git a/app/vendor/cakephp/cakephp/src/ORM/ResultSet.php b/app/vendor/cakephp/cakephp/src/ORM/ResultSet.php index d81d63510..1fe3cf69d 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/ResultSet.php +++ b/app/vendor/cakephp/cakephp/src/ORM/ResultSet.php @@ -73,7 +73,7 @@ class ResultSet implements ResultSetInterface * List of associations that should be placed under the `_matchingData` * result key. * - * @var array + * @var array */ protected $_matchingMap = []; @@ -88,7 +88,7 @@ class ResultSet implements ResultSetInterface * Map of fields that are fetched from the statement with * their type and the table they belong to * - * @var array + * @var array */ protected $_map = []; @@ -96,7 +96,7 @@ class ResultSet implements ResultSetInterface * List of matching associations and the column keys to expect * from each of them. * - * @var array + * @var array */ protected $_matchingMapColumns = []; @@ -568,12 +568,17 @@ protected function _groupResult(array $row) * Returns an array that can be used to describe the internal state of this * object. * - * @return array + * @return array */ public function __debugInfo() { + $currentIndex = $this->_index; + // toArray() adjusts the current index, so we have to reset it + $items = $this->toArray(); + $this->_index = $currentIndex; + return [ - 'items' => $this->toArray(), + 'items' => $items, ]; } } diff --git a/app/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php b/app/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php index f06f51400..a86bfe3e2 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Rule/IsUnique.php @@ -93,7 +93,7 @@ public function __invoke(EntityInterface $entity, array $options): bool * * @param string $alias The alias to add. * @param array $conditions The conditions to alias. - * @return array + * @return array */ protected function _alias(string $alias, array $conditions): array { diff --git a/app/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php b/app/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php index 96023d0f6..ad81f9055 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php +++ b/app/vendor/cakephp/cakephp/src/ORM/SaveOptionsBuilder.php @@ -26,6 +26,7 @@ * you to avoid mistakes by validating the options as you build them. * * @see \Cake\Datasource\RulesChecker + * @deprecated 4.4.0 Use a normal array for options instead. */ class SaveOptionsBuilder extends ArrayObject { @@ -34,7 +35,7 @@ class SaveOptionsBuilder extends ArrayObject /** * Options * - * @var array + * @var array */ protected $_options = []; @@ -65,7 +66,7 @@ public function __construct(Table $table, array $options = []) * This can be used to turn an options array into the object. * * @throws \InvalidArgumentException If a given option key does not exist. - * @param array $array Options array. + * @param array $array Options array. * @return $this */ public function parseArrayOptions(array $array) @@ -200,7 +201,7 @@ public function atomic(bool $atomic) } /** - * @return array + * @return array */ public function toArray(): array { diff --git a/app/vendor/cakephp/cakephp/src/ORM/Table.php b/app/vendor/cakephp/cakephp/src/ORM/Table.php index 859eff21a..0c8250691 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/Table.php +++ b/app/vendor/cakephp/cakephp/src/ORM/Table.php @@ -20,6 +20,7 @@ use BadMethodCallException; use Cake\Core\App; use Cake\Core\Configure; +use Cake\Core\Exception\CakeException; use Cake\Database\Connection; use Cake\Database\Schema\TableSchemaInterface; use Cake\Database\TypeFactory; @@ -387,9 +388,11 @@ public function getTable(): string { if ($this->_table === null) { $table = namespaceSplit(static::class); - $table = substr(end($table), 0, -5); + $table = substr(end($table), 0, -5) ?: $this->_alias; if (!$table) { - $table = $this->getAlias(); + throw new CakeException( + 'You must specify either the `alias` or the `table` option for the constructor.' + ); } $this->_table = Inflector::underscore($table); } @@ -419,7 +422,12 @@ public function getAlias(): string { if ($this->_alias === null) { $alias = namespaceSplit(static::class); - $alias = substr(end($alias), 0, -5) ?: $this->getTable(); + $alias = substr(end($alias), 0, -5) ?: $this->_table; + if (!$alias) { + throw new CakeException( + 'You must specify either the `alias` or the `table` option for the constructor.' + ); + } $this->_alias = $alias; } @@ -859,9 +867,7 @@ public function getBehavior(string $name): Behavior )); } - $behavior = $this->_behaviors->get($name); - - return $behavior; + return $this->_behaviors->get($name); } /** @@ -1446,7 +1452,7 @@ public function findThreaded(Query $query, array $options): Query * @param array $options the original options passed to a finder * @param array $keys the keys to check in $options to build matchers from * the associated value - * @return array + * @return array */ protected function _setFieldMatchers(array $options, array $keys): array { @@ -1498,12 +1504,21 @@ protected function _setFieldMatchers(array $options, array $keys): array */ public function get($primaryKey, array $options = []): EntityInterface { + if ($primaryKey === null) { + throw new InvalidPrimaryKeyException(sprintf( + 'Record not found in table "%s" with primary key [NULL]', + $this->getTable() + )); + } + $key = (array)$this->getPrimaryKey(); $alias = $this->getAlias(); foreach ($key as $index => $keyname) { $key[$index] = $alias . '.' . $keyname; } - $primaryKey = (array)$primaryKey; + if (!is_array($primaryKey)) { + $primaryKey = [$primaryKey]; + } if (count($key) !== count($primaryKey)) { $primaryKey = $primaryKey ?: [null]; $primaryKey = array_map(function ($key) { @@ -1843,6 +1858,7 @@ public function exists($conditions): bool public function save(EntityInterface $entity, $options = []) { if ($options instanceof SaveOptionsBuilder) { + deprecationWarning('SaveOptionsBuilder is deprecated. Use a normal array for options instead.'); $options = $options->toArray(); } @@ -1852,6 +1868,7 @@ public function save(EntityInterface $entity, $options = []) 'checkRules' => true, 'checkExisting' => true, '_primary' => true, + '_cleanOnSuccess' => true, ]); if ($entity->hasErrors((bool)$options['associated'])) { @@ -1871,8 +1888,10 @@ public function save(EntityInterface $entity, $options = []) $this->dispatchEvent('Model.afterSaveCommit', compact('entity', 'options')); } if ($options['atomic'] || $options['_primary']) { - $entity->clean(); - $entity->setNew(false); + if ($options['_cleanOnSuccess']) { + $entity->clean(); + $entity->setNew(false); + } $entity->setSource($this->getRegistryAlias()); } } @@ -2167,9 +2186,9 @@ protected function _update(EntityInterface $entity, array $data) * any one of the records fails to save due to failed validation or database * error. * - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to save. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to save. * @param \Cake\ORM\SaveOptionsBuilder|\ArrayAccess|array $options Options used when calling Table::save() for each entity. - * @return \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface>|false False on failure, entities list on success. + * @return iterable<\Cake\Datasource\EntityInterface>|false False on failure, entities list on success. * @throws \Exception */ public function saveMany(iterable $entities, $options = []) @@ -2188,9 +2207,9 @@ public function saveMany(iterable $entities, $options = []) * any one of the records fails to save due to failed validation or database * error. * - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to save. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to save. * @param \ArrayAccess|array $options Options used when calling Table::save() for each entity. - * @return \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> Entities list. + * @return iterable<\Cake\Datasource\EntityInterface> Entities list. * @throws \Exception * @throws \Cake\ORM\Exception\PersistenceFailedException If an entity couldn't be saved. */ @@ -2200,14 +2219,19 @@ public function saveManyOrFail(iterable $entities, $options = []): iterable } /** - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to save. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to save. * @param \Cake\ORM\SaveOptionsBuilder|\ArrayAccess|array $options Options used when calling Table::save() for each entity. * @throws \Cake\ORM\Exception\PersistenceFailedException If an entity couldn't be saved. * @throws \Exception If an entity couldn't be saved. - * @return \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> Entities list. + * @return iterable<\Cake\Datasource\EntityInterface> Entities list. */ protected function _saveMany(iterable $entities, $options = []): iterable { + if ($options instanceof SaveOptionsBuilder) { + deprecationWarning('SaveOptionsBuilder is deprecated. Use a normal array for options instead.'); + $options = $options->toArray(); + } + $options = new ArrayObject( (array)$options + [ 'atomic' => true, @@ -2215,10 +2239,11 @@ protected function _saveMany(iterable $entities, $options = []): iterable '_primary' => true, ] ); + $options['_cleanOnSuccess'] = false; /** @var array $isNew */ $isNew = []; - $cleanup = function ($entities) use (&$isNew): void { + $cleanupOnFailure = function ($entities) use (&$isNew): void { /** @var array<\Cake\Datasource\EntityInterface> $entities */ foreach ($entities as $key => $entity) { if (isset($isNew[$key]) && $isNew[$key]) { @@ -2243,20 +2268,40 @@ protected function _saveMany(iterable $entities, $options = []): iterable } }); } catch (Exception $e) { - $cleanup($entities); + $cleanupOnFailure($entities); throw $e; } if ($failed !== null) { - $cleanup($entities); + $cleanupOnFailure($entities); throw new PersistenceFailedException($failed, ['saveMany']); } + $cleanupOnSuccess = function (EntityInterface $entity) use (&$cleanupOnSuccess) { + $entity->clean(); + $entity->setNew(false); + + foreach (array_keys($entity->toArray()) as $field) { + $value = $entity->get($field); + + if ($value instanceof EntityInterface) { + $cleanupOnSuccess($value); + } elseif (is_array($value) && current($value) instanceof EntityInterface) { + foreach ($value as $associated) { + $cleanupOnSuccess($associated); + } + } + } + }; + if ($this->_transactionCommitted($options['atomic'], $options['_primary'])) { foreach ($entities as $entity) { $this->dispatchEvent('Model.afterSaveCommit', compact('entity', 'options')); + if ($options['atomic'] || $options['_primary']) { + $cleanupOnSuccess($entity); + } } } @@ -2322,9 +2367,9 @@ public function delete(EntityInterface $entity, $options = []): bool * any one of the records fails to delete due to failed validation or database * error. * - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to delete. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to delete. * @param \ArrayAccess|array $options Options used when calling Table::save() for each entity. - * @return \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface>|false Entities list + * @return iterable<\Cake\Datasource\EntityInterface>|false Entities list * on success, false on failure. * @see \Cake\ORM\Table::delete() for options and events related to this method. */ @@ -2346,9 +2391,9 @@ public function deleteMany(iterable $entities, $options = []) * any one of the records fails to delete due to failed validation or database * error. * - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to delete. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to delete. * @param \ArrayAccess|array $options Options used when calling Table::save() for each entity. - * @return \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> Entities list. + * @return iterable<\Cake\Datasource\EntityInterface> Entities list. * @throws \Cake\ORM\Exception\PersistenceFailedException * @see \Cake\ORM\Table::delete() for options and events related to this method. */ @@ -2364,7 +2409,7 @@ public function deleteManyOrFail(iterable $entities, $options = []): iterable } /** - * @param \Cake\Datasource\ResultSetInterface|array<\Cake\Datasource\EntityInterface> $entities Entities to delete. + * @param iterable<\Cake\Datasource\EntityInterface> $entities Entities to delete. * @param \ArrayAccess|array $options Options used. * @return \Cake\Datasource\EntityInterface|null */ @@ -2866,7 +2911,7 @@ public function patchEntity(EntityInterface $entity, array $data, array $options * You can use the `Model.beforeMarshal` event to modify request data * before it is converted into entities. * - * @param \Traversable|array<\Cake\Datasource\EntityInterface> $entities the entities that will get the + * @param iterable<\Cake\Datasource\EntityInterface> $entities the entities that will get the * data merged in * @param array $data list of arrays to be merged into the entities * @param array $options A list of options for the objects hydration. @@ -3014,6 +3059,7 @@ public function buildRules(RulesChecker $rules): RulesChecker * * @param array $options Options to parse by the builder. * @return \Cake\ORM\SaveOptionsBuilder + * @deprecated 4.4.0 Use a normal array for options instead. */ public function getSaveOptionsBuilder(array $options = []): SaveOptionsBuilder { @@ -3067,7 +3113,7 @@ protected function validationMethodExists(string $name): bool * Returns an array that can be used to describe the internal state of this * object. * - * @return array + * @return array */ public function __debugInfo() { diff --git a/app/vendor/cakephp/cakephp/src/ORM/composer.json b/app/vendor/cakephp/cakephp/src/ORM/composer.json index c0f2675d5..d3f1c8802 100644 --- a/app/vendor/cakephp/cakephp/src/ORM/composer.json +++ b/app/vendor/cakephp/cakephp/src/ORM/composer.json @@ -23,7 +23,7 @@ "source": "https://github.com/cakephp/orm" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/collection": "^4.0", "cakephp/core": "^4.0", "cakephp/datasource": "^4.0", diff --git a/app/vendor/cakephp/cakephp/src/Routing/Exception/FailedRouteCacheException.php b/app/vendor/cakephp/cakephp/src/Routing/Exception/FailedRouteCacheException.php new file mode 100644 index 000000000..44699962e --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/Routing/Exception/FailedRouteCacheException.php @@ -0,0 +1,26 @@ + $stream]); - $contentType = $response->getMimeType($file->getExtension()) ?: 'application/octet-stream'; + $contentType = (array)($response->getMimeType($file->getExtension()) ?: 'application/octet-stream'); $modified = $file->getMTime(); $expire = strtotime($this->cacheTime); $maxAge = $expire - time(); return $response - ->withHeader('Content-Type', $contentType) + ->withHeader('Content-Type', $contentType[0]) ->withHeader('Cache-Control', 'public,max-age=' . $maxAge) ->withHeader('Date', gmdate(DATE_RFC7231, time())) ->withHeader('Last-Modified', gmdate(DATE_RFC7231, $modified)) diff --git a/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php b/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php index 66d56a80b..6c46dc803 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php +++ b/app/vendor/cakephp/cakephp/src/Routing/Middleware/RoutingMiddleware.php @@ -17,14 +17,17 @@ namespace Cake\Routing\Middleware; use Cake\Cache\Cache; +use Cake\Cache\InvalidArgumentException; use Cake\Core\PluginApplicationInterface; use Cake\Http\Exception\RedirectException; use Cake\Http\MiddlewareQueue; use Cake\Http\Runner; +use Cake\Routing\Exception\FailedRouteCacheException; use Cake\Routing\Exception\RedirectException as DeprecatedRedirectException; use Cake\Routing\RouteCollection; use Cake\Routing\Router; use Cake\Routing\RoutingApplicationInterface; +use Exception; use Laminas\Diactoros\Response\RedirectResponse; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; @@ -67,6 +70,13 @@ class RoutingMiddleware implements MiddlewareInterface */ public function __construct(RoutingApplicationInterface $app, ?string $cacheConfig = null) { + if ($cacheConfig !== null) { + deprecationWarning( + 'Use of routing cache is deprecated and will be removed in 5.0. ' . + 'Upgrade to the new `CakeDC/CachedRouting` plugin. ' . + 'See https://github.com/CakeDC/cakephp-cached-routing' + ); + } $this->app = $app; $this->cacheConfig = $cacheConfig; } @@ -94,9 +104,21 @@ protected function loadRoutes(): void protected function buildRouteCollection(): RouteCollection { if (Cache::enabled() && $this->cacheConfig !== null) { - return Cache::remember(static::ROUTE_COLLECTION_CACHE_KEY, function () { - return $this->prepareRouteCollection(); - }, $this->cacheConfig); + try { + return Cache::remember(static::ROUTE_COLLECTION_CACHE_KEY, function () { + return $this->prepareRouteCollection(); + }, $this->cacheConfig); + } catch (InvalidArgumentException $e) { + throw $e; + } catch (Exception $e) { + throw new FailedRouteCacheException( + 'Unable to cache route collection. Cached routes must be serializable. Check for route-specific + middleware or other unserializable settings in your routes. The original exception message can + show what type of object failed to serialize.', + null, + $e + ); + } } return $this->prepareRouteCollection(); @@ -139,8 +161,11 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface $params = Router::parseRequest($request) + $params; if (isset($params['_middleware'])) { $middleware = $params['_middleware']; - unset($params['_middleware']); } + $route = $params['_route']; + unset($params['_middleware'], $params['_route']); + + $request = $request->withAttribute('route', $route); /** @var \Cake\Http\ServerRequest $request */ $request = $request->withAttribute('params', $params); Router::setRequest($request); diff --git a/app/vendor/cakephp/cakephp/src/Routing/Route/Route.php b/app/vendor/cakephp/cakephp/src/Routing/Route/Route.php index 89ce7d3fe..2315a07f2 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/Route/Route.php +++ b/app/vendor/cakephp/cakephp/src/Routing/Route/Route.php @@ -16,6 +16,7 @@ */ namespace Cake\Routing\Route; +use Cake\Http\Exception\BadRequestException; use InvalidArgumentException; use Psr\Http\Message\ServerRequestInterface; @@ -457,13 +458,18 @@ public function parseRequest(ServerRequestInterface $request): ?array * @param string $url The URL to attempt to parse. * @param string $method The HTTP method of the request being parsed. * @return array|null An array of request parameters, or `null` on failure. - * @throws \InvalidArgumentException When method is not an empty string or in `VALID_METHODS` list. + * @throws \Cake\Http\Exception\BadRequestException When method is not an empty string and not in `VALID_METHODS` list. */ public function parse(string $url, string $method): ?array { - if ($method !== '') { - $method = $this->normalizeAndValidateMethods($method); + try { + if ($method !== '') { + $method = $this->normalizeAndValidateMethods($method); + } + } catch (InvalidArgumentException $e) { + throw new BadRequestException($e->getMessage()); } + $compiledRoute = $this->compile(); [$url, $ext] = $this->_parseExtension($url); @@ -533,6 +539,8 @@ public function parse(string $url, string $method): ?array } } } + + $route['_route'] = $this; $route['_matchedRoute'] = $this->template; if (count($this->middleware) > 0) { $route['_middleware'] = $this->middleware; @@ -807,7 +815,10 @@ protected function _matchMethod(array $url): bool */ protected function _writeUrl(array $params, array $pass = [], array $query = []): string { - $pass = implode('/', array_map('rawurlencode', $pass)); + $pass = array_map(function ($value) { + return rawurlencode((string)$value); + }, $pass); + $pass = implode('/', $pass); $out = $this->template; $search = $replace = []; diff --git a/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php b/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php index 16aec336a..80952eee0 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php +++ b/app/vendor/cakephp/cakephp/src/Routing/RouteBuilder.php @@ -720,6 +720,7 @@ protected function parseDefaults($defaults): array protected function _makeRoute($route, $defaults, $options): Route { if (is_string($route)) { + /** @var class-string<\Cake\Routing\Route\Route>|null $routeClass */ $routeClass = App::className($options['routeClass'], 'Routing/Route'); if ($routeClass === null) { throw new InvalidArgumentException(sprintf( @@ -754,12 +755,7 @@ protected function _makeRoute($route, $defaults, $options): Route $route = new $routeClass($route, $defaults, $options); } - if ($route instanceof Route) { - return $route; - } - throw new InvalidArgumentException( - 'Route class not found, or route class is not a subclass of Cake\Routing\Route\Route' - ); + return $route; } /** diff --git a/app/vendor/cakephp/cakephp/src/Routing/RouteCollection.php b/app/vendor/cakephp/cakephp/src/Routing/RouteCollection.php index 122606058..5ceadaf14 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/RouteCollection.php +++ b/app/vendor/cakephp/cakephp/src/Routing/RouteCollection.php @@ -218,9 +218,9 @@ protected function _getNames(array $url): array $action = strtolower($url['action']); $names = [ - "${controller}:${action}", - "${controller}:_action", - "_controller:${action}", + "{$controller}:{$action}", + "{$controller}:_action", + "_controller:{$action}", '_controller:_action', ]; @@ -232,13 +232,13 @@ protected function _getNames(array $url): array // Only a plugin if ($prefix === false) { return [ - "${plugin}.${controller}:${action}", - "${plugin}.${controller}:_action", - "${plugin}._controller:${action}", - "${plugin}._controller:_action", - "_plugin.${controller}:${action}", - "_plugin.${controller}:_action", - "_plugin._controller:${action}", + "{$plugin}.{$controller}:{$action}", + "{$plugin}.{$controller}:_action", + "{$plugin}._controller:{$action}", + "{$plugin}._controller:_action", + "_plugin.{$controller}:{$action}", + "_plugin.{$controller}:_action", + "_plugin._controller:{$action}", '_plugin._controller:_action', ]; } @@ -246,13 +246,13 @@ protected function _getNames(array $url): array // Only a prefix if ($plugin === false) { return [ - "${prefix}:${controller}:${action}", - "${prefix}:${controller}:_action", - "${prefix}:_controller:${action}", - "${prefix}:_controller:_action", - "_prefix:${controller}:${action}", - "_prefix:${controller}:_action", - "_prefix:_controller:${action}", + "{$prefix}:{$controller}:{$action}", + "{$prefix}:{$controller}:_action", + "{$prefix}:_controller:{$action}", + "{$prefix}:_controller:_action", + "_prefix:{$controller}:{$action}", + "_prefix:{$controller}:_action", + "_prefix:_controller:{$action}", '_prefix:_controller:_action', ]; } @@ -260,21 +260,21 @@ protected function _getNames(array $url): array // Prefix and plugin has the most options // as there are 4 factors. return [ - "${prefix}:${plugin}.${controller}:${action}", - "${prefix}:${plugin}.${controller}:_action", - "${prefix}:${plugin}._controller:${action}", - "${prefix}:${plugin}._controller:_action", - "${prefix}:_plugin.${controller}:${action}", - "${prefix}:_plugin.${controller}:_action", - "${prefix}:_plugin._controller:${action}", - "${prefix}:_plugin._controller:_action", - "_prefix:${plugin}.${controller}:${action}", - "_prefix:${plugin}.${controller}:_action", - "_prefix:${plugin}._controller:${action}", - "_prefix:${plugin}._controller:_action", - "_prefix:_plugin.${controller}:${action}", - "_prefix:_plugin.${controller}:_action", - "_prefix:_plugin._controller:${action}", + "{$prefix}:{$plugin}.{$controller}:{$action}", + "{$prefix}:{$plugin}.{$controller}:_action", + "{$prefix}:{$plugin}._controller:{$action}", + "{$prefix}:{$plugin}._controller:_action", + "{$prefix}:_plugin.{$controller}:{$action}", + "{$prefix}:_plugin.{$controller}:_action", + "{$prefix}:_plugin._controller:{$action}", + "{$prefix}:_plugin._controller:_action", + "_prefix:{$plugin}.{$controller}:{$action}", + "_prefix:{$plugin}.{$controller}:_action", + "_prefix:{$plugin}._controller:{$action}", + "_prefix:{$plugin}._controller:_action", + "_prefix:_plugin.{$controller}:{$action}", + "_prefix:_plugin.{$controller}:_action", + "_prefix:_plugin._controller:{$action}", '_prefix:_plugin._controller:_action', ]; } diff --git a/app/vendor/cakephp/cakephp/src/Routing/Router.php b/app/vendor/cakephp/cakephp/src/Routing/Router.php index c6808c922..9b4235cc3 100644 --- a/app/vendor/cakephp/cakephp/src/Routing/Router.php +++ b/app/vendor/cakephp/cakephp/src/Routing/Router.php @@ -107,7 +107,7 @@ class Router /** * A hash of request context data. * - * @var array + * @var array */ protected static $_requestContext = []; @@ -159,7 +159,7 @@ class Router /** * Cache of parsed route paths * - * @var array + * @var array */ protected static $_routePaths = []; @@ -221,7 +221,7 @@ public static function connect($route, $defaults = [], $options = []): void } /** - * Get the routing parameters for the request is possible. + * Get the routing parameters for the request if possible. * * @param \Cake\Http\ServerRequest $request The request to parse request data from. * @return array Parsed elements from URL. @@ -643,7 +643,9 @@ public static function fullBaseUrl(?string $base = null): string */ public static function reverseToArray($params): array { + $route = null; if ($params instanceof ServerRequest) { + $route = $params->getAttribute('route'); $queryString = $params->getQueryParams(); $params = $params->getAttribute('params'); $params['?'] = $queryString; @@ -656,8 +658,7 @@ public static function reverseToArray($params): array $params['_matchedRoute'], $params['_name'] ); - $route = null; - if ($template) { + if (!$route && $template) { // Locate the route that was used to match this route // so we can access the pass parameter configuration. foreach (static::getRouteCollection()->routes() as $maybe) { @@ -672,9 +673,8 @@ public static function reverseToArray($params): array $routePass = $route->options['pass'] ?? []; $pass = array_slice($pass, count($routePass)); } - $params = array_merge($params, $pass); - return $params; + return array_merge($params, $pass); } /** diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php index 5e42cdeae..09c2252d8 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestCase.php @@ -2,19 +2,21 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite; +use Cake\Console\TestSuite\ConsoleIntegrationTestTrait; + /** * A test case class intended to make integration tests of cake console commands * easier. diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestTrait.php b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestTrait.php index e29330321..2b41c39f1 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestTrait.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/ConsoleIntegrationTestTrait.php @@ -1,347 +1,6 @@ makeRunner(); - - if ($this->_out === null) { - $this->_out = new ConsoleOutput(); - } - if ($this->_err === null) { - $this->_err = new ConsoleOutput(); - } - if ($this->_in === null) { - $this->_in = new ConsoleInput($input); - } elseif ($input) { - throw new RuntimeException('You can use `$input` only if `$_in` property is null and will be reset.'); - } - - $args = $this->commandStringToArgs("cake $command"); - $io = new ConsoleIo($this->_out, $this->_err, $this->_in); - - try { - $this->_exitCode = $runner->run($args, $io); - } catch (MissingConsoleInputException $e) { - $messages = $this->_out->messages(); - if (count($messages)) { - $e->setQuestion($messages[count($messages) - 1]); - } - throw $e; - } catch (StopException $exception) { - $this->_exitCode = $exception->getCode(); - } - } - - /** - * Cleans state to get ready for the next test - * - * @after - * @return void - * @psalm-suppress PossiblyNullPropertyAssignmentValue - */ - public function cleanupConsoleTrait(): void - { - $this->_exitCode = null; - $this->_out = null; - $this->_err = null; - $this->_in = null; - $this->_useCommandRunner = false; - } - - /** - * Set this test case to use the CommandRunner rather than the legacy - * ShellDispatcher - * - * @return void - */ - public function useCommandRunner(): void - { - $this->_useCommandRunner = true; - } - - /** - * Asserts shell exited with the expected code - * - * @param int $expected Expected exit code - * @param string $message Failure message - * @return void - */ - public function assertExitCode(int $expected, string $message = ''): void - { - $this->assertThat($expected, new ExitCode($this->_exitCode), $message); - } - - /** - * Asserts shell exited with the Command::CODE_SUCCESS - * - * @param string $message Failure message - * @return void - */ - public function assertExitSuccess($message = '') - { - $this->assertThat(Command::CODE_SUCCESS, new ExitCode($this->_exitCode), $message); - } - - /** - * Asserts shell exited with Command::CODE_ERROR - * - * @param string $message Failure message - * @return void - */ - public function assertExitError($message = '') - { - $this->assertThat(Command::CODE_ERROR, new ExitCode($this->_exitCode), $message); - } - - /** - * Asserts that `stdout` is empty - * - * @param string $message The message to output when the assertion fails. - * @return void - */ - public function assertOutputEmpty(string $message = ''): void - { - $this->assertThat(null, new ContentsEmpty($this->_out->messages(), 'output'), $message); - } - - /** - * Asserts `stdout` contains expected output - * - * @param string $expected Expected output - * @param string $message Failure message - * @return void - */ - public function assertOutputContains(string $expected, string $message = ''): void - { - $this->assertThat($expected, new ContentsContain($this->_out->messages(), 'output'), $message); - } - - /** - * Asserts `stdout` does not contain expected output - * - * @param string $expected Expected output - * @param string $message Failure message - * @return void - */ - public function assertOutputNotContains(string $expected, string $message = ''): void - { - $this->assertThat($expected, new ContentsNotContain($this->_out->messages(), 'output'), $message); - } - - /** - * Asserts `stdout` contains expected regexp - * - * @param string $pattern Expected pattern - * @param string $message Failure message - * @return void - */ - public function assertOutputRegExp(string $pattern, string $message = ''): void - { - $this->assertThat($pattern, new ContentsRegExp($this->_out->messages(), 'output'), $message); - } - - /** - * Check that a row of cells exists in the output. - * - * @param array $row Row of cells to ensure exist in the output. - * @param string $message Failure message. - * @return void - */ - protected function assertOutputContainsRow(array $row, string $message = ''): void - { - $this->assertThat($row, new ContentsContainRow($this->_out->messages(), 'output'), $message); - } - - /** - * Asserts `stderr` contains expected output - * - * @param string $expected Expected output - * @param string $message Failure message - * @return void - */ - public function assertErrorContains(string $expected, string $message = ''): void - { - $this->assertThat($expected, new ContentsContain($this->_err->messages(), 'error output'), $message); - } - - /** - * Asserts `stderr` contains expected regexp - * - * @param string $pattern Expected pattern - * @param string $message Failure message - * @return void - */ - public function assertErrorRegExp(string $pattern, string $message = ''): void - { - $this->assertThat($pattern, new ContentsRegExp($this->_err->messages(), 'error output'), $message); - } - - /** - * Asserts that `stderr` is empty - * - * @param string $message The message to output when the assertion fails. - * @return void - */ - public function assertErrorEmpty(string $message = ''): void - { - $this->assertThat(null, new ContentsEmpty($this->_err->messages(), 'error output'), $message); - } - - /** - * Builds the appropriate command dispatcher - * - * @return \Cake\Console\CommandRunner|\Cake\TestSuite\LegacyCommandRunner - */ - protected function makeRunner() - { - if ($this->_useCommandRunner) { - /** @var \Cake\Core\ConsoleApplicationInterface $app */ - $app = $this->createApp(); - - return new CommandRunner($app); - } - - return new LegacyCommandRunner(); - } - - /** - * Creates an $argv array from a command string - * - * @param string $command Command string - * @return array - */ - protected function commandStringToArgs(string $command): array - { - $charCount = strlen($command); - $argv = []; - $arg = ''; - $inDQuote = false; - $inSQuote = false; - for ($i = 0; $i < $charCount; $i++) { - $char = substr($command, $i, 1); - - // end of argument - if ($char === ' ' && !$inDQuote && !$inSQuote) { - if ($arg !== '') { - $argv[] = $arg; - } - $arg = ''; - continue; - } - - // exiting single quote - if ($inSQuote && $char === "'") { - $inSQuote = false; - continue; - } - - // exiting double quote - if ($inDQuote && $char === '"') { - $inDQuote = false; - continue; - } - - // entering double quote - if ($char === '"' && !$inSQuote) { - $inDQuote = true; - continue; - } - - // entering single quote - if ($char === "'" && !$inDQuote) { - $inSQuote = true; - continue; - } - - $arg .= $char; - } - $argv[] = $arg; - - return $argv; - } -} +class_alias(ConsoleIntegrationTestTrait::class, 'Cake\TestSuite\ConsoleIntegrationTestTrait'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsBase.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsBase.php index 9ebd33fe7..81653f83d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsBase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsBase.php @@ -1,48 +1,6 @@ $contents Contents - * @param string $output Output type - */ - public function __construct(array $contents, string $output) - { - $this->contents = implode(PHP_EOL, $contents); - $this->output = $output; - } -} +class_alias(ContentsBase::class, 'Cake\TestSuite\Constraint\Console\ContentsBase'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContain.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContain.php index d700c9664..e8a76013d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContain.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContain.php @@ -1,45 +1,6 @@ contents, $other) !== false; - } - - /** - * Assertion message - * - * @return string - */ - public function toString(): string - { - return sprintf('is in %s,' . PHP_EOL . 'actual result:' . PHP_EOL, $this->output) . $this->contents; - } -} +class_alias(ContentsContain::class, 'Cake\TestSuite\Constraint\Console\ContentsContain'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContainRow.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContainRow.php index 3ee85920e..6ea1f2597 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContainRow.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsContainRow.php @@ -1,61 +1,6 @@ contents) > 0; - } - - /** - * Assertion message - * - * @return string - */ - public function toString(): string - { - return sprintf('row was in %s', $this->output); - } - - /** - * @param mixed $other Expected content - * @return string - */ - public function failureDescription($other): string - { - return '`' . $this->exporter()->shortenedExport($other) . '` ' . $this->toString(); - } -} +class_alias(ContentsContainRow::class, 'Cake\TestSuite\Constraint\Console\ContentsContainRow'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsEmpty.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsEmpty.php index cbc96d2ce..250e7acef 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsEmpty.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsEmpty.php @@ -1,56 +1,6 @@ contents === ''; - } - - /** - * Assertion message - * - * @return string - */ - public function toString(): string - { - return sprintf('%s is empty', $this->output); - } - - /** - * Overwrites the descriptions so we can remove the automatic "expected" message - * - * @param mixed $other Value - * @return string - */ - protected function failureDescription($other): string - { - return $this->toString(); - } -} +class_alias(ContentsEmpty::class, 'Cake\TestSuite\Constraint\Console\ContentsEmpty'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsNotContain.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsNotContain.php index 9515c37d9..e53d68b62 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsNotContain.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsNotContain.php @@ -1,45 +1,6 @@ contents, $other) === false; - } - - /** - * Assertion message - * - * @return string - */ - public function toString(): string - { - return sprintf('is not in %s', $this->output); - } -} +class_alias(ContentsNotContain::class, 'Cake\TestSuite\Constraint\Console\ContentsNotContain'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsRegExp.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsRegExp.php index e97b08540..eb9652e07 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsRegExp.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ContentsRegExp.php @@ -1,54 +1,6 @@ contents) > 0; - } - - /** - * Assertion message - * - * @return string - */ - public function toString(): string - { - return sprintf('PCRE pattern found in %s', $this->output); - } - - /** - * @param mixed $other Expected - * @return string - */ - public function failureDescription($other): string - { - return '`' . $other . '` ' . $this->toString(); - } -} +class_alias(ContentsRegExp::class, 'Cake\TestSuite\Constraint\Console\ContentsRegExp'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ExitCode.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ExitCode.php index 913bbc4ab..311eeb535 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ExitCode.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Console/ExitCode.php @@ -1,62 +1,6 @@ exitCode = $exitCode; - } - - /** - * Checks if event is in fired array - * - * @param mixed $other Constraint check - * @return bool - */ - public function matches($other): bool - { - return $other === $this->exitCode; - } - - /** - * Assertion message string - * - * @return string - */ - public function toString(): string - { - return sprintf('matches exit code %s', $this->exitCode ?? 'null'); - } -} +class_alias(ExitCode::class, 'Cake\TestSuite\Constraint\Console\ExitCode'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Email/MailSentWith.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Email/MailSentWith.php index 46aa85fa2..16a9e761c 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Email/MailSentWith.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Email/MailSentWith.php @@ -55,15 +55,16 @@ public function matches($other): bool $emails = $this->getMessages(); foreach ($emails as $email) { $value = $email->{'get' . ucfirst($this->method)}(); + if ($value === $other) { + return true; + } if ( - in_array($this->method, ['to', 'cc', 'bcc', 'from', 'replyTo', 'sender'], true) + !is_array($other) + && in_array($this->method, ['to', 'cc', 'bcc', 'from', 'replyTo', 'sender']) && array_key_exists($other, $value) ) { return true; } - if ($value === $other) { - return true; - } } return false; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php index dfb29f289..a02964f93 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/EventFired.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.2.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyContains.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyContains.php index 357f6bee3..b63c482d6 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyContains.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyContains.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEmpty.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEmpty.php index 1f74ed403..c1b076a77 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEmpty.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEmpty.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEquals.php index 5d8bfea56..19e61cd65 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotContains.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotContains.php index 7914cfe3d..66fe3fef4 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotContains.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotContains.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEmpty.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEmpty.php index 8ec4a568d..8ae4bfc05 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEmpty.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEmpty.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEquals.php index 88e75e006..1cd4385ce 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotRegExp.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotRegExp.php index 9b1a4d241..6bb16968f 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotRegExp.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyNotRegExp.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyRegExp.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyRegExp.php index bace6d6ec..bf35f12cc 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyRegExp.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/BodyRegExp.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ContentType.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ContentType.php index 93b38d912..7a21522c6 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ContentType.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ContentType.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEncryptedEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEncryptedEquals.php index 7cc9ff58c..3bc281407 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEncryptedEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEncryptedEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEquals.php index 3b5ca1081..0522f86cd 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieNotSet.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieNotSet.php index bfd7fa7c6..f67e58102 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieNotSet.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieNotSet.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieSet.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieSet.php index 7c56262fa..370c40c6d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieSet.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/CookieSet.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSent.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSent.php index e11e21f0c..6143eab4c 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSent.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSent.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSentAs.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSentAs.php index 5c995af59..7ea144e84 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSentAs.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/FileSentAs.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; @@ -35,8 +35,12 @@ class FileSentAs extends ResponseBase */ public function matches($other): bool { - /** @psalm-suppress PossiblyNullReference */ - return $this->response->getFile()->getPathName() === $other; + $file = $this->response->getFile(); + if (!$file) { + return false; + } + + return $file->getPathName() === $other; } /** diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderContains.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderContains.php index c0e1bb181..1fef513bd 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderContains.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderContains.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderEquals.php index 35bace044..a00756393 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotContains.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotContains.php index 51f29a923..3717e72f5 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotContains.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotContains.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotSet.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotSet.php index 671090fd8..2e655925f 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotSet.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderNotSet.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderSet.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderSet.php index 9fc5e4843..4ec5d2dad 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderSet.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/HeaderSet.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ResponseBase.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ResponseBase.php index 2ba009db5..c17f9956d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ResponseBase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/ResponseBase.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCode.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCode.php index c2387bc99..2ef29e4f0 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCode.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCode.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCodeBase.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCodeBase.php index d41e4da33..7e9ae6488 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCodeBase.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusCodeBase.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusError.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusError.php index b46c155df..30448297b 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusError.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusError.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusFailure.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusFailure.php index 21561261e..71d23ca77 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusFailure.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusFailure.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusOk.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusOk.php index c8f67d868..1d2496402 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusOk.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusOk.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusSuccess.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusSuccess.php index f7dfff5aa..6248457fd 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusSuccess.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Response/StatusSuccess.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Response; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/FlashParamEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/FlashParamEquals.php index a1de975d0..592ceecae 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/FlashParamEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/FlashParamEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Session; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionEquals.php index 6d96c2707..577d8d7df 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Session; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionHasKey.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionHasKey.php index e529249c8..d7ffa7872 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionHasKey.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/Session/SessionHasKey.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 4.1.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\Session; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/LayoutFileEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/LayoutFileEquals.php index 650c4a968..662bb24aa 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/LayoutFileEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/LayoutFileEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\View; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/TemplateFileEquals.php b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/TemplateFileEquals.php index d55c73f4a..1f7fff21d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/TemplateFileEquals.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Constraint/View/TemplateFileEquals.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * @since 3.7.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\TestSuite\Constraint\View; diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/ContainerStubTrait.php b/app/vendor/cakephp/cakephp/src/TestSuite/ContainerStubTrait.php index 0ca276906..7e564fc3d 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/ContainerStubTrait.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/ContainerStubTrait.php @@ -1,169 +1,6 @@ |class-string<\Cake\Core\ConsoleApplicationInterface>|null - * @var string|null - */ - protected $_appClass; - - /** - * The customized application constructor arguments. - * - * @var array|null - */ - protected $_appArgs; - - /** - * The collection of container services. - * - * @var array - */ - private $containerServices = []; - - /** - * Configure the application class to use in integration tests. - * - * @param string $class The application class name. - * @param array|null $constructorArgs The constructor arguments for your application class. - * @return void - * @psalm-param class-string<\Cake\Core\HttpApplicationInterface>|class-string<\Cake\Core\ConsoleApplicationInterface> $class - */ - public function configApplication(string $class, ?array $constructorArgs): void - { - $this->_appClass = $class; - $this->_appArgs = $constructorArgs; - } - - /** - * Create an application instance. - * - * Uses the configuration set in `configApplication()`. - * - * @return \Cake\Core\HttpApplicationInterface|\Cake\Core\ConsoleApplicationInterface - */ - protected function createApp() - { - if ($this->_appClass) { - $appClass = $this->_appClass; - } else { - /** @psalm-var class-string<\Cake\Http\BaseApplication> */ - $appClass = Configure::read('App.namespace') . '\Application'; - } - if (!class_exists($appClass)) { - throw new LogicException("Cannot load `{$appClass}` for use in integration testing."); - } - $appArgs = $this->_appArgs ?: [CONFIG]; - - $app = new $appClass(...$appArgs); - if (!empty($this->containerServices) && method_exists($app, 'getEventManager')) { - $app->getEventManager()->on('Application.buildContainer', [$this, 'modifyContainer']); - } - - return $app; - } - - /** - * Add a mocked service to the container. - * - * When the container is created the provided classname - * will be mapped to the factory function. The factory - * function will be used to create mocked services. - * - * @param string $class The class or interface you want to define. - * @param \Closure $factory The factory function for mocked services. - * @return $this - */ - public function mockService(string $class, Closure $factory) - { - $this->containerServices[$class] = $factory; - - return $this; - } - - /** - * Remove a mocked service to the container. - * - * @param string $class The class or interface you want to remove. - * @return $this - */ - public function removeMockService(string $class) - { - unset($this->containerServices[$class]); - - return $this; - } - - /** - * Wrap the application's container with one containing mocks. - * - * If any mocked services are defined, the application's container - * will be replaced with one containing mocks. The original - * container will be set as a delegate to the mock container. - * - * @param \Cake\Event\EventInterface $event The event - * @param \Cake\Core\ContainerInterface $container The container to wrap. - * @return \Cake\Core\ContainerInterface|null - */ - public function modifyContainer(EventInterface $event, ContainerInterface $container): ?ContainerInterface - { - if (empty($this->containerServices)) { - return null; - } - foreach ($this->containerServices as $key => $factory) { - if ($container->has($key)) { - $container->extend($key)->setConcrete($factory); - } else { - $container->add($key, $factory); - } - } - - return $container; - } - - /** - * Clears any mocks that were defined and cleans - * up application class configuration. - * - * @after - * @return void - */ - public function cleanupContainer(): void - { - $this->_appArgs = null; - $this->_appClass = null; - $this->containerServices = []; - } -} +class_alias(ContainerStubTrait::class, 'Cake\TestSuite\ContainerStubTrait'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/EmailTrait.php b/app/vendor/cakephp/cakephp/src/TestSuite/EmailTrait.php index 7d6926af5..e07b5aef4 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/EmailTrait.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/EmailTrait.php @@ -175,11 +175,11 @@ public function assertMailSentTo(string $address, string $message = ''): void /** * Asserts an email was sent from an address * - * @param string $address Email address + * @param array|string $address Email address * @param string $message Message * @return void */ - public function assertMailSentFrom(string $address, string $message = ''): void + public function assertMailSentFrom($address, string $message = ''): void { $this->assertThat($address, new MailSentFrom(), $message); } diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureHelper.php b/app/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureHelper.php index ce8210e60..852319d59 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureHelper.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Fixture/FixtureHelper.php @@ -168,7 +168,7 @@ protected function insertConnection(ConnectionInterface $connection, array $fixt } catch (PDOException $exception) { $message = sprintf( 'Unable to insert rows for table `%s`.' - . " Fixture records might have invalid data or unknown contraints.\n%s", + . " Fixture records might have invalid data or unknown constraints.\n%s", $fixture->sourceName(), $exception->getMessage() ); @@ -272,7 +272,7 @@ protected function sortByConstraint(Connection $connection, array $fixtures): ?a * * @param \Cake\Database\Connection $connection Database connection * @param \Cake\Datasource\FixtureInterface $fixture Database fixture - * @return array + * @return array */ protected function getForeignReferences(Connection $connection, FixtureInterface $fixture): array { diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/HttpClientTrait.php b/app/vendor/cakephp/cakephp/src/TestSuite/HttpClientTrait.php index 7f78675a2..c20b154db 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/HttpClientTrait.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/HttpClientTrait.php @@ -1,117 +1,6 @@ $headers A list of headers for the response. Example `Content-Type: application/json` - * @param string $body The body for the response. - * @return \Cake\Http\Client\Response - */ - public function newClientResponse(int $code = 200, array $headers = [], string $body = ''): Response - { - $headers = array_merge(["HTTP/1.1 {$code}"], $headers); - - return new Response($headers, $body); - } - - /** - * Add a mock response for a POST request. - * - * @param string $url The URL to mock - * @param \Cake\Http\Client\Response $response The response for the mock. - * @param array $options Additional options. See Client::addMockResponse() - * @return void - */ - public function mockClientPost(string $url, Response $response, array $options = []): void - { - Client::addMockResponse('POST', $url, $response, $options); - } - - /** - * Add a mock response for a GET request. - * - * @param string $url The URL to mock - * @param \Cake\Http\Client\Response $response The response for the mock. - * @param array $options Additional options. See Client::addMockResponse() - * @return void - */ - public function mockClientGet(string $url, Response $response, array $options = []): void - { - Client::addMockResponse('GET', $url, $response, $options); - } - - /** - * Add a mock response for a PATCH request. - * - * @param string $url The URL to mock - * @param \Cake\Http\Client\Response $response The response for the mock. - * @param array $options Additional options. See Client::addMockResponse() - * @return void - */ - public function mockClientPatch(string $url, Response $response, array $options = []): void - { - Client::addMockResponse('PATCH', $url, $response, $options); - } - - /** - * Add a mock response for a PUT request. - * - * @param string $url The URL to mock - * @param \Cake\Http\Client\Response $response The response for the mock. - * @param array $options Additional options. See Client::addMockResponse() - * @return void - */ - public function mockClientPut(string $url, Response $response, array $options = []): void - { - Client::addMockResponse('PUT', $url, $response, $options); - } - - /** - * Add a mock response for a DELETE request. - * - * @param string $url The URL to mock - * @param \Cake\Http\Client\Response $response The response for the mock. - * @param array $options Additional options. See Client::addMockResponse() - * @return void - */ - public function mockClientDelete(string $url, Response $response, array $options = []): void - { - Client::addMockResponse('DELETE', $url, $response, $options); - } -} +class_alias(HttpClientTrait::class, 'Cake\TestSuite\HttpClientTrait'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php b/app/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php index 04973d038..d367ba6c6 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/IntegrationTestTrait.php @@ -17,8 +17,9 @@ use Cake\Controller\Controller; use Cake\Core\Configure; +use Cake\Core\TestSuite\ContainerStubTrait; use Cake\Database\Exception\DatabaseException; -use Cake\Error\ExceptionRenderer; +use Cake\Error\Renderer\WebExceptionRenderer; use Cake\Event\EventInterface; use Cake\Event\EventManager; use Cake\Form\FormProtector; @@ -553,9 +554,9 @@ protected function _handleError(Throwable $exception): void { $class = Configure::read('Error.exceptionRenderer'); if (empty($class) || !class_exists($class)) { - $class = ExceptionRenderer::class; + $class = WebExceptionRenderer::class; } - /** @var \Cake\Error\ExceptionRenderer $instance */ + /** @var \Cake\Error\Renderer\WebExceptionRenderer $instance */ $instance = new $class($exception); $this->_response = $instance->render(); } @@ -627,9 +628,8 @@ protected function _buildRequest(string $url, $method, $data = []): array $props['cookies'] = $this->_cookie; $session->write($this->_session); - $props = Hash::merge($props, $this->_request); - return $props; + return Hash::merge($props, $this->_request); } /** @@ -1320,6 +1320,11 @@ public function assertFileResponse(string $expected, string $message = ''): void $verboseMessage = $this->extractVerboseMessage($message); $this->assertThat(null, new FileSent($this->_response), $verboseMessage); $this->assertThat($expected, new FileSentAs($this->_response), $verboseMessage); + + if (!$this->_response) { + return; + } + $this->_response->getBody()->close(); } /** @@ -1352,10 +1357,26 @@ protected function extractVerboseMessage(string $message): string */ protected function extractExceptionMessage(Exception $exception): string { - return PHP_EOL . - sprintf('Possibly related to %s: "%s" ', get_class($exception), $exception->getMessage()) . - PHP_EOL . - $exception->getTraceAsString(); + $exceptions = [$exception]; + $previous = $exception->getPrevious(); + while ($previous != null) { + $exceptions[] = $previous; + $previous = $previous->getPrevious(); + } + $message = PHP_EOL; + foreach ($exceptions as $i => $error) { + if ($i == 0) { + $message .= sprintf('Possibly related to %s: "%s"', get_class($error), $error->getMessage()); + $message .= PHP_EOL; + } else { + $message .= sprintf('Caused by %s: "%s"', get_class($error), $error->getMessage()); + $message .= PHP_EOL; + } + $message .= $error->getTraceAsString(); + $message .= PHP_EOL; + } + + return $message; } /** diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/LegacyCommandRunner.php b/app/vendor/cakephp/cakephp/src/TestSuite/LegacyCommandRunner.php index 33dca5c32..e598b17f4 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/LegacyCommandRunner.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/LegacyCommandRunner.php @@ -1,39 +1,6 @@ dispatch(); - } -} +class_alias(LegacyCommandRunner::class, 'Cake\TestSuite\LegacyCommandRunner'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/LegacyShellDispatcher.php b/app/vendor/cakephp/cakephp/src/TestSuite/LegacyShellDispatcher.php index dcf258c83..a1dda1744 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/LegacyShellDispatcher.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/LegacyShellDispatcher.php @@ -1,64 +1,6 @@ _io = $io; - parent::__construct($args, $bootstrap); - } - - /** - * Injects mock and stub io components into the shell - * - * @param string $className Class name - * @param string $shortName Short name - * @return \Cake\Console\Shell - */ - protected function _createShell(string $className, string $shortName): Shell - { - [$plugin] = pluginSplit($shortName); - /** @var \Cake\Console\Shell $instance */ - $instance = new $className($this->_io); - if ($plugin) { - $instance->plugin = trim($plugin, '.'); - } - - return $instance; - } -} +class_alias(LegacyShellDispatcher::class, 'Cake\TestSuite\LegacyShellDispatcher'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php b/app/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php index f9ce0efe6..6ca6e767e 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/MiddlewareDispatcher.php @@ -121,11 +121,10 @@ protected function _createRequest(array $spec): ServerRequest $spec['cookies'], $spec['files'] ); - $request = $request + + return $request ->withAttribute('session', $spec['session']) ->withAttribute('flash', new FlashMessage($spec['session'])); - - return $request; } /** diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleInput.php b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleInput.php index 80cd376ed..0a84f53a8 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleInput.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleInput.php @@ -1,88 +1,6 @@ - */ - protected $replies = []; - - /** - * Current message index - * - * @var int - */ - protected $currentIndex = -1; - - /** - * Constructor - * - * @param array $replies A list of replies for read() - */ - public function __construct(array $replies) - { - parent::__construct(); - - $this->replies = $replies; - } - - /** - * Read a reply - * - * @return string The value of the reply - */ - public function read(): string - { - $this->currentIndex += 1; - - if (!isset($this->replies[$this->currentIndex])) { - $total = count($this->replies); - $formatter = new NumberFormatter('en', NumberFormatter::ORDINAL); - $nth = $formatter->format($this->currentIndex + 1); - - $replies = implode(', ', $this->replies); - $message = "There are no more input replies available. This is the {$nth} read operation, " . - "only {$total} replies were set.\nThe provided replies are: {$replies}"; - throw new MissingConsoleInputException($message); - } - - return $this->replies[$this->currentIndex]; - } - - /** - * Check if data is available on stdin - * - * @param int $timeout An optional time to wait for data - * @return bool True for data available, false otherwise - */ - public function dataAvailable($timeout = 0): bool - { - return true; - } -} +class_alias(StubConsoleInput::class, 'Cake\TestSuite\Stub\ConsoleInput'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php index 24ee50d1d..3d299a8e9 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/ConsoleOutput.php @@ -1,84 +1,6 @@ - */ - protected $_out = []; - - /** - * Write output to the buffer. - * - * @param array|string $message A string or an array of strings to output - * @param int $newlines Number of newlines to append - * @return int - */ - public function write($message, int $newlines = 1): int - { - foreach ((array)$message as $line) { - $this->_out[] = $line; - } - - $newlines--; - while ($newlines > 0) { - $this->_out[] = ''; - $newlines--; - } - - return 0; - } - - /** - * Get the buffered output. - * - * @return array - */ - public function messages(): array - { - return $this->_out; - } - - /** - * Get the output as a string - * - * @return string - */ - public function output(): string - { - return implode("\n", $this->_out); - } -} +class_alias(StubConsoleOutput::class, 'Cake\TestSuite\Stub\ConsoleOutput'); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/MissingConsoleInputException.php b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/MissingConsoleInputException.php index 3055b282a..bb023f841 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/MissingConsoleInputException.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/MissingConsoleInputException.php @@ -1,35 +1,6 @@ message .= "\nThe question asked was: " . $question; - } -} +class_exists(MissingConsoleInputException::class); diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/TestExceptionRenderer.php b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/TestExceptionRenderer.php index 3122bdac7..89107c76a 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/Stub/TestExceptionRenderer.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/Stub/TestExceptionRenderer.php @@ -16,6 +16,9 @@ */ namespace Cake\TestSuite\Stub; +use Cake\Error\ExceptionRendererInterface; +use LogicException; +use Psr\Http\Message\ResponseInterface; use Throwable; /** @@ -28,7 +31,7 @@ * @see \Cake\TestSuite\IntegrationTestCase::disableErrorHandlerMiddleware() * @internal */ -class TestExceptionRenderer +class TestExceptionRenderer implements ExceptionRendererInterface { /** * Simply rethrow the given exception @@ -41,4 +44,22 @@ public function __construct(Throwable $exception) { throw $exception; } + + /** + * @inheritDoc + */ + public function render(): ResponseInterface + { + throw new LogicException('You cannot use this class to render exceptions.'); + } + + /** + * Part of upcoming interface requirements + * + * @param \Psr\Http\Message\ResponseInterface|string $output The output or response to send. + * @return void + */ + public function write($output): void + { + } } diff --git a/app/vendor/cakephp/cakephp/src/TestSuite/TestEmailTransport.php b/app/vendor/cakephp/cakephp/src/TestSuite/TestEmailTransport.php index 8d2694d77..dee56b7d6 100644 --- a/app/vendor/cakephp/cakephp/src/TestSuite/TestEmailTransport.php +++ b/app/vendor/cakephp/cakephp/src/TestSuite/TestEmailTransport.php @@ -38,8 +38,7 @@ class TestEmailTransport extends DebugTransport * Stores email for later assertions * * @param \Cake\Mailer\Message $message Message - * @return array - * @psalm-return array{headers: string, message: string} + * @return array{headers: string, message: string} */ public function send(Message $message): array { diff --git a/app/vendor/cakephp/cakephp/src/Utility/Hash.php b/app/vendor/cakephp/cakephp/src/Utility/Hash.php index af52e9039..f30cc8271 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Hash.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Hash.php @@ -728,25 +728,28 @@ public static function flatten(array $data, string $separator = '.'): array */ public static function expand(array $data, string $separator = '.'): array { - $result = []; - foreach ($data as $flat => $value) { - $keys = explode($separator, (string)$flat); - $keys = array_reverse($keys); - $child = [ - $keys[0] => $value, - ]; - array_shift($keys); - foreach ($keys as $k) { - $child = [ - $k => $child, - ]; + $hash = []; + foreach ($data as $path => $value) { + $keys = explode($separator, (string)$path); + if (count($keys) === 1) { + $hash[$path] = $value; + continue; } - $stack = [[$child, &$result]]; - static::_merge($stack, $result); + $valueKey = end($keys); + $keys = array_slice($keys, 0, -1); + + $keyHash = &$hash; + foreach ($keys as $key) { + if (!array_key_exists($key, $keyHash)) { + $keyHash[$key] = []; + } + $keyHash = &$keyHash[$key]; + } + $keyHash[$valueKey] = $value; } - return $result; + return $hash; } /** @@ -1116,6 +1119,7 @@ public static function diff(array $data, array $compare): array next($intersection); } + /** @phpstan-ignore-next-line */ return $data + $compare; } diff --git a/app/vendor/cakephp/cakephp/src/Utility/Inflector.php b/app/vendor/cakephp/cakephp/src/Utility/Inflector.php index 33438c34d..9cb8c1f44 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Inflector.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Inflector.php @@ -166,7 +166,7 @@ class Inflector /** * Method cache array. * - * @var array + * @var array */ protected static $_cache = []; diff --git a/app/vendor/cakephp/cakephp/src/Utility/Security.php b/app/vendor/cakephp/cakephp/src/Utility/Security.php index df3952a7e..a46d3222b 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Security.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Security.php @@ -163,18 +163,16 @@ public static function insecureRandomBytes(int $length): string */ public static function engine($instance = null) { - if ($instance === null && static::$_instance === null) { - if (extension_loaded('openssl')) { - $instance = new OpenSsl(); - } - } if ($instance) { - static::$_instance = $instance; + return static::$_instance = $instance; } if (isset(static::$_instance)) { /** @psalm-suppress LessSpecificReturnStatement */ return static::$_instance; } + if (extension_loaded('openssl')) { + return static::$_instance = new OpenSsl(); + } throw new InvalidArgumentException( 'No compatible crypto engine available. ' . 'Load the openssl extension.' diff --git a/app/vendor/cakephp/cakephp/src/Utility/Text.php b/app/vendor/cakephp/cakephp/src/Utility/Text.php index 570a24745..95cf22c9e 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Text.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Text.php @@ -53,7 +53,7 @@ class Text * Generate a random UUID version 4 * * Warning: This method should not be used as a random seed for any cryptographic operations. - * Instead, you should use the openssl or mcrypt extensions. + * Instead, you should use `Security::randomBytes()` or `Security::randomString()` instead. * * It should also not be used to create identifiers that have security implications, such as * 'unguessable' URL identifiers. Instead, you should use {@link \Cake\Utility\Security::randomBytes()}` for that. @@ -377,13 +377,6 @@ public static function wrapBlock(string $text, $options = []): string } $options += ['width' => 72, 'wordWrap' => true, 'indent' => null, 'indentAt' => 0]; - if (!empty($options['indentAt']) && $options['indentAt'] === 0) { - $indentLength = !empty($options['indent']) ? strlen($options['indent']) : 0; - $options['width'] -= $indentLength; - - return self::wrap($text, $options); - } - $wrapped = self::wrap($text, $options); if (!empty($options['indent'])) { @@ -904,9 +897,8 @@ public static function excerpt(string $text, string $phrase, int $radius = 100, } $excerpt = mb_substr($text, $startPos, $endPos - $startPos); - $excerpt = $prepend . $excerpt . $append; - return $excerpt; + return $prepend . $excerpt . $append; } /** @@ -955,7 +947,7 @@ public static function isMultibyte(string $string): bool * to the decimal value of the character * * @param string $string String to convert. - * @return array + * @return array */ public static function utf8(string $string): array { @@ -1180,8 +1172,7 @@ public static function slug(string $string, $options = []): string if (is_string($options['replacement']) && $options['replacement'] !== '') { $map[sprintf('/[%s]+/mu', $quotedReplacement)] = $options['replacement']; } - $string = preg_replace(array_keys($map), $map, $string); - return $string; + return preg_replace(array_keys($map), $map, $string); } } diff --git a/app/vendor/cakephp/cakephp/src/Utility/Xml.php b/app/vendor/cakephp/cakephp/src/Utility/Xml.php index d02f59135..069177af4 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/Xml.php +++ b/app/vendor/cakephp/cakephp/src/Utility/Xml.php @@ -51,7 +51,7 @@ class Xml * Building XML from a file path: * * ``` - * $xml = Xml::build('/path/to/an/xml/file.xml'); + * $xml = Xml::build('/path/to/an/xml/file.xml', ['readFile' => true]); * ``` * * Building XML from a remote URL: @@ -453,7 +453,7 @@ public static function toArray($obj): array * Recursive method to toArray * * @param \SimpleXMLElement $xml SimpleXMLElement object - * @param array $parentData Parent array with data + * @param array $parentData Parent array with data * @param string $ns Namespace of current child * @param array $namespaces List of namespaces in XML * @return void diff --git a/app/vendor/cakephp/cakephp/src/Utility/composer.json b/app/vendor/cakephp/cakephp/src/Utility/composer.json index fccb2f884..949ca6012 100644 --- a/app/vendor/cakephp/cakephp/src/Utility/composer.json +++ b/app/vendor/cakephp/cakephp/src/Utility/composer.json @@ -25,7 +25,7 @@ "source": "https://github.com/cakephp/utility" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0" }, "suggest": { diff --git a/app/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php b/app/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php index 9defaa34a..d37b09c15 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php +++ b/app/vendor/cakephp/cakephp/src/Validation/ValidatableInterface.php @@ -18,6 +18,8 @@ /** * Describes objects that can be validated by passing a Validator object. + * + * @deprecated 4.4.5 This interface is unused. */ interface ValidatableInterface { diff --git a/app/vendor/cakephp/cakephp/src/Validation/Validation.php b/app/vendor/cakephp/cakephp/src/Validation/Validation.php index d250a53a2..c70c3d80e 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/Validation.php +++ b/app/vendor/cakephp/cakephp/src/Validation/Validation.php @@ -696,7 +696,7 @@ public static function localizedTime($check, string $type = 'datetime', $format * The list of what is considered to be boolean values, may be set via $booleanValues. * * @param string|int|bool $check Value to check. - * @param array $booleanValues List of valid boolean values, defaults to `[true, false, 0, 1, '0', '1']`. + * @param array $booleanValues List of valid boolean values, defaults to `[true, false, 0, 1, '0', '1']`. * @return bool Success. */ public static function boolean($check, array $booleanValues = []): bool @@ -714,7 +714,7 @@ public static function boolean($check, array $booleanValues = []): bool * The list of what is considered to be truthy values, may be set via $truthyValues. * * @param string|int|bool $check Value to check. - * @param array $truthyValues List of valid truthy values, defaults to `[true, 1, '1']`. + * @param array $truthyValues List of valid truthy values, defaults to `[true, 1, '1']`. * @return bool Success. */ public static function truthy($check, array $truthyValues = []): bool @@ -732,7 +732,7 @@ public static function truthy($check, array $truthyValues = []): bool * The list of what is considered to be falsey values, may be set via $falseyValues. * * @param string|int|bool $check Value to check. - * @param array $falseyValues List of valid falsey values, defaults to `[false, 0, '0']`. + * @param array $falseyValues List of valid falsey values, defaults to `[false, 0, '0']`. * @return bool Success. */ public static function falsey($check, array $falseyValues = []): bool @@ -1332,7 +1332,11 @@ public static function uploadError($check, bool $allowNoFile = false): bool { if ($check instanceof UploadedFileInterface) { $code = $check->getError(); - } elseif (is_array($check) && isset($check['error'])) { + } elseif (is_array($check)) { + if (!isset($check['error'])) { + return false; + } + $code = $check['error']; } else { $code = $check; diff --git a/app/vendor/cakephp/cakephp/src/Validation/ValidationRule.php b/app/vendor/cakephp/cakephp/src/Validation/ValidationRule.php index 326e7556e..6ebd5a749 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/ValidationRule.php +++ b/app/vendor/cakephp/cakephp/src/Validation/ValidationRule.php @@ -74,7 +74,7 @@ class ValidationRule /** * Constructor * - * @param array $validator [optional] The validator properties + * @param array $validator [optional] The validator properties */ public function __construct(array $validator = []) { @@ -184,7 +184,7 @@ protected function _skip(array $context): bool /** * Sets the rule properties from the rule entry in validate * - * @param array $validator [optional] + * @param array $validator [optional] * @return void */ protected function _addValidatorProps(array $validator = []): void diff --git a/app/vendor/cakephp/cakephp/src/Validation/Validator.php b/app/vendor/cakephp/cakephp/src/Validation/Validator.php index ef574a78b..bbc06bef3 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/Validator.php +++ b/app/vendor/cakephp/cakephp/src/Validation/Validator.php @@ -155,7 +155,7 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable * Contains the validation messages associated with checking the presence * for each corresponding field. * - * @var array + * @var array */ protected $_presenceMessages = []; @@ -170,14 +170,14 @@ class Validator implements ArrayAccess, IteratorAggregate, Countable * Contains the validation messages associated with checking the emptiness * for each corresponding field. * - * @var array + * @var array */ protected $_allowEmptyMessages = []; /** * Contains the flags which specify what is empty for each corresponding field. * - * @var array + * @var array */ protected $_allowEmptyFlags = []; diff --git a/app/vendor/cakephp/cakephp/src/Validation/ValidatorAwareInterface.php b/app/vendor/cakephp/cakephp/src/Validation/ValidatorAwareInterface.php index 9b71ef267..ee7425506 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/ValidatorAwareInterface.php +++ b/app/vendor/cakephp/cakephp/src/Validation/ValidatorAwareInterface.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.5.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace Cake\Validation; diff --git a/app/vendor/cakephp/cakephp/src/Validation/composer.json b/app/vendor/cakephp/cakephp/src/Validation/composer.json index eceaafd2e..a8998a9c1 100644 --- a/app/vendor/cakephp/cakephp/src/Validation/composer.json +++ b/app/vendor/cakephp/cakephp/src/Validation/composer.json @@ -22,7 +22,7 @@ "source": "https://github.com/cakephp/validation" }, "require": { - "php": ">=7.2.0", + "php": ">=7.4.0", "cakephp/core": "^4.0", "cakephp/utility": "^4.0", "psr/http-message": "^1.0.0" diff --git a/app/vendor/cakephp/cakephp/src/View/AjaxView.php b/app/vendor/cakephp/cakephp/src/View/AjaxView.php index 064f31fad..a99c14574 100644 --- a/app/vendor/cakephp/cakephp/src/View/AjaxView.php +++ b/app/vendor/cakephp/cakephp/src/View/AjaxView.php @@ -29,11 +29,12 @@ class AjaxView extends View protected $layout = 'ajax'; /** - * @inheritDoc + * Get content type for this view. + * + * @return string */ - public function initialize(): void + public static function contentType(): string { - parent::initialize(); - $this->setResponse($this->getResponse()->withType('ajax')); + return 'text/html'; } } diff --git a/app/vendor/cakephp/cakephp/src/View/Cell.php b/app/vendor/cakephp/cakephp/src/View/Cell.php index 00ac8e652..49cf528b5 100644 --- a/app/vendor/cakephp/cakephp/src/View/Cell.php +++ b/app/vendor/cakephp/cakephp/src/View/Cell.php @@ -36,6 +36,7 @@ /** * Cell base. */ +#[\AllowDynamicProperties] abstract class Cell implements EventDispatcherInterface { use EventDispatcherTrait; diff --git a/app/vendor/cakephp/cakephp/src/View/CellTrait.php b/app/vendor/cakephp/cakephp/src/View/CellTrait.php index c1a1c810a..5252c98c9 100644 --- a/app/vendor/cakephp/cakephp/src/View/CellTrait.php +++ b/app/vendor/cakephp/cakephp/src/View/CellTrait.php @@ -76,9 +76,8 @@ protected function cell(string $cell, array $data = [], array $options = []): Ce $data = array_values($data); } $options = ['action' => $action, 'args' => $data] + $options; - $cell = $this->_createCell($className, $action, $plugin, $options); - return $cell; + return $this->_createCell($className, $action, $plugin, $options); } /** diff --git a/app/vendor/cakephp/cakephp/src/View/Form/ArrayContext.php b/app/vendor/cakephp/cakephp/src/View/Form/ArrayContext.php index 5abddef3f..8271c92b9 100644 --- a/app/vendor/cakephp/cakephp/src/View/Form/ArrayContext.php +++ b/app/vendor/cakephp/cakephp/src/View/Form/ArrayContext.php @@ -73,7 +73,7 @@ class ArrayContext implements ContextInterface /** * Context data for this object. * - * @var array + * @var array */ protected $_context; diff --git a/app/vendor/cakephp/cakephp/src/View/Form/EntityContext.php b/app/vendor/cakephp/cakephp/src/View/Form/EntityContext.php index 30d7a6799..87e2ce4e1 100644 --- a/app/vendor/cakephp/cakephp/src/View/Form/EntityContext.php +++ b/app/vendor/cakephp/cakephp/src/View/Form/EntityContext.php @@ -55,7 +55,7 @@ class EntityContext implements ContextInterface /** * Context data for this object. * - * @var array + * @var array */ protected $_context; @@ -91,7 +91,7 @@ class EntityContext implements ContextInterface /** * Constructor. * - * @param array $context Context info. + * @param array $context Context info. */ public function __construct(array $context) { @@ -400,7 +400,7 @@ public function entity(?array $path = null) * * Traverse the path until an entity cannot be found. Lists containing * entities will be traversed if the first element contains an entity. - * Otherwise the containing Entity will be assumed to be the terminal one. + * Otherwise, the containing Entity will be assumed to be the terminal one. * * @param array|null $path Each one of the parts in a path for a field name * or null to get the entity passed in constructor context. diff --git a/app/vendor/cakephp/cakephp/src/View/Form/FormContext.php b/app/vendor/cakephp/cakephp/src/View/Form/FormContext.php index 32c9ffdaf..007e2dcb1 100644 --- a/app/vendor/cakephp/cakephp/src/View/Form/FormContext.php +++ b/app/vendor/cakephp/cakephp/src/View/Form/FormContext.php @@ -16,6 +16,8 @@ */ namespace Cake\View\Form; +use Cake\Core\Exception\CakeException; +use Cake\Form\Form; use Cake\Utility\Hash; /** @@ -33,17 +35,31 @@ class FormContext implements ContextInterface */ protected $_form; + /** + * Validator name. + * + * @var string|null + */ + protected $_validator = null; + /** * Constructor. * * @param array $context Context info. + * + * Keys: + * + * - `entity` The Form class instance this context is operating on. **(required)** + * - `validator` Optional name of the validation method to call on the Form object. */ public function __construct(array $context) { - $context += [ - 'entity' => null, - ]; + if (!isset($context['entity']) || !$context['entity'] instanceof Form) { + throw new CakeException('`$context[\'entity\']` must be an instance of Cake\Form\Form'); + } + $this->_form = $context['entity']; + $this->_validator = $context['validator'] ?? null; } /** @@ -126,7 +142,7 @@ protected function _schemaDefault(string $field) */ public function isRequired(string $field): ?bool { - $validator = $this->_form->getValidator(); + $validator = $this->_form->getValidator($this->_validator); if (!$validator->hasField($field)) { return null; } @@ -144,7 +160,7 @@ public function getRequiredMessage(string $field): ?string { $parts = explode('.', $field); - $validator = $this->_form->getValidator(); + $validator = $this->_form->getValidator($this->_validator); $fieldName = array_pop($parts); if (!$validator->hasField($fieldName)) { return null; @@ -163,7 +179,7 @@ public function getRequiredMessage(string $field): ?string */ public function getMaxLength(string $field): ?int { - $validator = $this->_form->getValidator(); + $validator = $this->_form->getValidator($this->_validator); if (!$validator->hasField($field)) { return null; } diff --git a/app/vendor/cakephp/cakephp/src/View/Helper.php b/app/vendor/cakephp/cakephp/src/View/Helper.php index 69530b026..35ca7dbbe 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper.php @@ -40,6 +40,7 @@ * - `afterRenderFile(EventInterface $event, $viewFile, $content)` - Called after any view fragment is rendered. * If a listener returns a non-null value, the output of the rendered file will be set to that. */ +#[\AllowDynamicProperties] class Helper implements EventListenerInterface { use InstanceConfigTrait; diff --git a/app/vendor/cakephp/cakephp/src/View/Helper/BreadcrumbsHelper.php b/app/vendor/cakephp/cakephp/src/View/Helper/BreadcrumbsHelper.php index d96a70a28..cc930d210 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper/BreadcrumbsHelper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper/BreadcrumbsHelper.php @@ -320,13 +320,11 @@ public function render(array $attributes = [], array $separator = []): string $crumbTrail .= $this->formatTemplate($template, $templateParams); } - $crumbTrail = $this->formatTemplate('wrapper', [ + return $this->formatTemplate('wrapper', [ 'content' => $crumbTrail, 'attrs' => $templater->formatAttributes($attributes, ['templateVars']), 'templateVars' => $attributes['templateVars'] ?? [], ]); - - return $crumbTrail; } /** diff --git a/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php b/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php index 1486b1cde..2b298118d 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper/FormHelper.php @@ -506,9 +506,7 @@ protected function _formUrl(ContextInterface $context, array $options) 'action' => $request->getParam('action'), ]; - $action = (array)$options['url'] + $actionDefaults; - - return $action; + return (array)$options['url'] + $actionDefaults; } /** @@ -1028,7 +1026,7 @@ public function fieldset(string $fields = '', array $options = []): string * @param string $fieldName This should be "modelname.fieldname" * @param array $options Each type of input takes different options. * @return string Completed form widget. - * @link https://book.cakephp.org/4/en/views/helpers/form.html#creating-form-inputs + * @link https://book.cakephp.org/4/en/views/helpers/form.html#creating-form-controls * @psalm-suppress InvalidReturnType * @psalm-suppress InvalidReturnStatement */ @@ -1234,9 +1232,7 @@ protected function _parseOptions(string $fieldName, array $options): array $options['type'] = $this->_inputType($fieldName, $options); } - $options = $this->_magicOptions($fieldName, $options, $needsMagicType); - - return $options; + return $this->_magicOptions($fieldName, $options, $needsMagicType); } /** @@ -1294,7 +1290,7 @@ protected function _inputType(string $fieldName, array $options): string * * @param string $fieldName The name of the field to find options for. * @param array $options Options list. - * @return array + * @return array */ protected function _optionsOptions(string $fieldName, array $options): array { @@ -1555,21 +1551,30 @@ public function radio(string $fieldName, iterable $options = [], array $attribut { $attributes['options'] = $options; $attributes['idPrefix'] = $this->_idPrefix; + + $generatedHiddenId = false; + if (!isset($attributes['id'])) { + $attributes['id'] = true; + $generatedHiddenId = true; + } $attributes = $this->_initInputField($fieldName, $attributes); $hiddenField = $attributes['hiddenField'] ?? true; unset($attributes['hiddenField']); - $radio = $this->widget('radio', $attributes); - $hidden = ''; if ($hiddenField !== false && is_scalar($hiddenField)) { $hidden = $this->hidden($fieldName, [ 'value' => $hiddenField === true ? '' : (string)$hiddenField, 'form' => $attributes['form'] ?? null, 'name' => $attributes['name'], + 'id' => $attributes['id'], ]); } + if ($generatedHiddenId) { + unset($attributes['id']); + } + $radio = $this->widget('radio', $attributes); return $hidden . $radio; } @@ -2112,6 +2117,13 @@ public function multiCheckbox(string $fieldName, iterable $options, array $attri 'hiddenField' => true, 'secure' => true, ]; + + $generatedHiddenId = false; + if (!isset($attributes['id'])) { + $attributes['id'] = true; + $generatedHiddenId = true; + } + $attributes = $this->_initInputField($fieldName, $attributes); $attributes['options'] = $options; $attributes['idPrefix'] = $this->_idPrefix; @@ -2123,11 +2135,16 @@ public function multiCheckbox(string $fieldName, iterable $options, array $attri 'value' => '', 'secure' => false, 'disabled' => $attributes['disabled'] === true || $attributes['disabled'] === 'disabled', + 'id' => $attributes['id'], ]; $hidden = $this->hidden($fieldName, $hiddenAttributes); } unset($attributes['hiddenField']); + if ($generatedHiddenId) { + unset($attributes['id']); + } + return $hidden . $this->widget('multicheckbox', $attributes); } diff --git a/app/vendor/cakephp/cakephp/src/View/Helper/HtmlHelper.php b/app/vendor/cakephp/cakephp/src/View/Helper/HtmlHelper.php index 1a2df5cd9..aa2d5ed02 100644 --- a/app/vendor/cakephp/cakephp/src/View/Helper/HtmlHelper.php +++ b/app/vendor/cakephp/cakephp/src/View/Helper/HtmlHelper.php @@ -850,9 +850,9 @@ public function tableCell(string $content, array $options = []): string * - `escape` Whether the contents should be html_entity escaped. * * @param string $name Tag name. - * @param string|null $text String content that will appear inside the div element. + * @param string|null $text String content that will appear inside the HTML element. * If null, only a start tag will be printed - * @param array $options Additional HTML attributes of the DIV tag, see above. + * @param array $options Additional HTML attributes of the HTML tag, see above. * @return string The formatted tag element */ public function tag(string $name, ?string $text = null, array $options = []): string diff --git a/app/vendor/cakephp/cakephp/src/View/JsonView.php b/app/vendor/cakephp/cakephp/src/View/JsonView.php index 02d47783f..ef9fc9162 100644 --- a/app/vendor/cakephp/cakephp/src/View/JsonView.php +++ b/app/vendor/cakephp/cakephp/src/View/JsonView.php @@ -72,13 +72,6 @@ class JsonView extends SerializedView */ protected $subDir = 'json'; - /** - * Response type. - * - * @var string - */ - protected $_responseType = 'json'; - /** * Default config options. * @@ -102,6 +95,16 @@ class JsonView extends SerializedView 'jsonp' => null, ]; + /** + * Mime-type this view class renders as. + * + * @return string The JSON content type. + */ + public static function contentType(): string + { + return 'application/json'; + } + /** * Render a JSON view. * diff --git a/app/vendor/cakephp/cakephp/src/View/NegotiationRequiredView.php b/app/vendor/cakephp/cakephp/src/View/NegotiationRequiredView.php new file mode 100644 index 000000000..f017ab994 --- /dev/null +++ b/app/vendor/cakephp/cakephp/src/View/NegotiationRequiredView.php @@ -0,0 +1,62 @@ +getResponse()->withStatus(406); + $this->setResponse($response); + } + + /** + * Renders view with no body and a 406 status code. + * + * @param string|null $template Name of template file to use + * @param string|false|null $layout Layout to use. False to disable. + * @return string Rendered content. + */ + public function render(?string $template = null, $layout = null): string + { + return ''; + } +} diff --git a/app/vendor/cakephp/cakephp/src/View/SerializedView.php b/app/vendor/cakephp/cakephp/src/View/SerializedView.php index a8a83bf04..b71bf84f6 100644 --- a/app/vendor/cakephp/cakephp/src/View/SerializedView.php +++ b/app/vendor/cakephp/cakephp/src/View/SerializedView.php @@ -29,6 +29,7 @@ abstract class SerializedView extends View * Response type. * * @var string + * @deprecated 4.4.0 Implement ``public static contentType(): string`` instead. */ protected $_responseType; @@ -54,7 +55,10 @@ abstract class SerializedView extends View public function initialize(): void { parent::initialize(); - $this->setResponse($this->getResponse()->withType($this->_responseType)); + if ($this->_responseType) { + $response = $this->getResponse()->withType($this->_responseType); + $this->setResponse($response); + } } /** diff --git a/app/vendor/cakephp/cakephp/src/View/StringTemplate.php b/app/vendor/cakephp/cakephp/src/View/StringTemplate.php index 442ad4a63..d5f875bed 100644 --- a/app/vendor/cakephp/cakephp/src/View/StringTemplate.php +++ b/app/vendor/cakephp/cakephp/src/View/StringTemplate.php @@ -182,7 +182,7 @@ protected function _compileTemplates(array $templates = []): void } $template = str_replace('%', '%%', $template); - preg_match_all('#\{\{([\w\._]+)\}\}#', $template, $matches); + preg_match_all('#\{\{([\w\.]+)\}\}#', $template, $matches); $this->_compiled[$name] = [ str_replace($matches[0], '%s', $template), $matches[1], @@ -373,8 +373,6 @@ public function addClass($input, $newClass, string $useIndex = 'class') $class = array_unique(array_merge($class, $newClass)); - $input = Hash::insert($input, $useIndex, $class); - - return $input; + return Hash::insert($input, $useIndex, $class); } } diff --git a/app/vendor/cakephp/cakephp/src/View/View.php b/app/vendor/cakephp/cakephp/src/View/View.php index 2e3c51950..adfe55169 100644 --- a/app/vendor/cakephp/cakephp/src/View/View.php +++ b/app/vendor/cakephp/cakephp/src/View/View.php @@ -70,6 +70,7 @@ * @property \Cake\View\Helper\UrlHelper $Url * @property \Cake\View\ViewBlock $Blocks */ +#[\AllowDynamicProperties] class View implements EventDispatcherInterface { use CellTrait { @@ -313,6 +314,14 @@ class View implements EventDispatcherInterface */ public const PLUGIN_TEMPLATE_FOLDER = 'plugin'; + /** + * The magic 'match-all' content type that views can use to + * behave as a fallback during content-type negotiation. + * + * @var string + */ + public const TYPE_MATCH_ALL = '_match_all_'; + /** * Constructor * @@ -363,6 +372,36 @@ public function __construct( */ public function initialize(): void { + $this->setContentType(); + } + + /** + * Set the response content-type based on the view's contentType() + * + * @return void + */ + protected function setContentType(): void + { + $viewContentType = $this->contentType(); + if (!$viewContentType || $viewContentType == static::TYPE_MATCH_ALL) { + return; + } + $response = $this->getResponse(); + $responseType = $response->getHeaderLine('Content-Type'); + if ($responseType === '' || substr($responseType, 0, 9) === 'text/html') { + $response = $response->withType($viewContentType); + } + $this->setResponse($response); + } + + /** + * Mime-type this view class renders as. + * + * @return string Either the content type or '' which means no type. + */ + public static function contentType(): string + { + return ''; } /** @@ -1562,8 +1601,8 @@ protected function _paths(?string $plugin = null, bool $cached = true): array $templatePaths = App::path(static::NAME_TEMPLATE); $pluginPaths = $themePaths = []; if (!empty($plugin)) { - for ($i = 0, $count = count($templatePaths); $i < $count; $i++) { - $pluginPaths[] = $templatePaths[$i] + foreach ($templatePaths as $templatePath) { + $pluginPaths[] = $templatePath . static::PLUGIN_TEMPLATE_FOLDER . DIRECTORY_SEPARATOR . $plugin @@ -1576,16 +1615,14 @@ protected function _paths(?string $plugin = null, bool $cached = true): array $themePaths[] = Plugin::templatePath(Inflector::camelize($this->theme)); if ($plugin) { - for ($i = 0, $count = count($themePaths); $i < $count; $i++) { - array_unshift( - $themePaths, - $themePaths[$i] - . static::PLUGIN_TEMPLATE_FOLDER - . DIRECTORY_SEPARATOR - . $plugin - . DIRECTORY_SEPARATOR - ); - } + array_unshift( + $themePaths, + $themePaths[0] + . static::PLUGIN_TEMPLATE_FOLDER + . DIRECTORY_SEPARATOR + . $plugin + . DIRECTORY_SEPARATOR + ); } } diff --git a/app/vendor/cakephp/cakephp/src/View/XmlView.php b/app/vendor/cakephp/cakephp/src/View/XmlView.php index d7cfb03c5..94f33a19d 100644 --- a/app/vendor/cakephp/cakephp/src/View/XmlView.php +++ b/app/vendor/cakephp/cakephp/src/View/XmlView.php @@ -74,13 +74,6 @@ class XmlView extends SerializedView */ protected $subDir = 'xml'; - /** - * Response type. - * - * @var string - */ - protected $_responseType = 'xml'; - /** * Default config options. * @@ -102,6 +95,16 @@ class XmlView extends SerializedView 'rootNode' => null, ]; + /** + * Mime-type this view class renders as. + * + * @return string The JSON content type. + */ + public static function contentType(): string + { + return 'application/xml'; + } + /** * @inheritDoc */ diff --git a/app/vendor/cakephp/cakephp/src/basics.php b/app/vendor/cakephp/cakephp/src/basics.php index c44a79741..7df55e2a7 100644 --- a/app/vendor/cakephp/cakephp/src/basics.php +++ b/app/vendor/cakephp/cakephp/src/basics.php @@ -105,7 +105,7 @@ function stackTrace(array $options = []): void * ``` * * @return string|null - * @link http://psysh.org/ + * @link https://psysh.org/ */ function breakpoint(): ?string { diff --git a/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace.php b/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace.php index c6a8aa4dd..b535be9b5 100644 --- a/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace.php +++ b/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace.php @@ -17,58 +17,64 @@ */ use Cake\Error\Debugger; -foreach ($trace as $i => $stack): - $excerpt = $params = []; +foreach ($exceptions as $level => $exc): + $stackTrace = Debugger::formatTrace($exc->getTrace(), [ + 'format' => 'array', + 'args' => true, + ]); + foreach ($stackTrace as $i => $stack): + $excerpt = $params = []; - $line = null; - if (isset($stack['file'], $stack['line']) && is_numeric($stack['line'])): - $line = $stack['line']; - $excerpt = Debugger::excerpt($stack['file'], $line, 4); - endif; - - if (isset($stack['file'])): - $file = $stack['file']; - else: - $file = '[internal function]'; - endif; + $line = null; + if (isset($stack['file'], $stack['line']) && is_numeric($stack['line'])): + $line = $stack['line']; + $excerpt = Debugger::excerpt($stack['file'], $line, 4); + endif; - if (isset($stack['function'])): - if (!empty($stack['args'])): - foreach ((array)$stack['args'] as $arg): - $params[] = Debugger::exportVar($arg, 4); - endforeach; + if (isset($stack['file'])): + $file = $stack['file']; else: - $params[] = 'No arguments'; + $file = '[internal function]'; endif; - endif; -?> -
-
- - - Html->link(Debugger::trimPath($file), Debugger::editorUrl($file, $line)); ?> - - - - - Toggle Arguments -
- - - $line): ?> - - - - - -
+ if (isset($stack['function'])): + if (!empty($stack['args'])): + foreach ((array)$stack['args'] as $arg): + $params[] = Debugger::exportVar($arg, 4); + endforeach; + else: + $params[] = 'No arguments'; + endif; + endif; + ?> +
+
+ + + Html->link(Debugger::trimPath($file), Debugger::editorUrl($file, $line)); ?> + + + + + Toggle Arguments +
- -
+ diff --git a/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace_nav.php b/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace_nav.php index 3c78b47d9..a152958e2 100644 --- a/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace_nav.php +++ b/app/vendor/cakephp/cakephp/templates/element/exception_stack_trace_nav.php @@ -12,32 +12,42 @@ * @since 3.0.0 * @license https://opensource.org/licenses/mit-license.php MIT License * @var array $trace + * @var \Throwable $error + * @var array<\Throwable> $exceptions */ use Cake\Error\Debugger; ?> Toggle Vendor Stack Frames diff --git a/app/vendor/cakephp/cakephp/templates/layout/dev_error.php b/app/vendor/cakephp/cakephp/templates/layout/dev_error.php index 3d12ded10..96e09e98b 100644 --- a/app/vendor/cakephp/cakephp/templates/layout/dev_error.php +++ b/app/vendor/cakephp/cakephp/templates/layout/dev_error.php @@ -146,6 +146,9 @@ margin: 0; padding: 0; } + .stack-previous { + margin: 24px 0 12px 8px; + } .stack-frame { background: #e5e5e5; padding: 10px; @@ -260,6 +263,7 @@ border-bottom: 1px solid #ccc; } +
diff --git a/app/vendor/cakephp/cakephp/tests/Fixture/CompositeKeyArticlesFixture.php b/app/vendor/cakephp/cakephp/tests/Fixture/CompositeKeyArticlesFixture.php new file mode 100644 index 000000000..731d2a4c2 --- /dev/null +++ b/app/vendor/cakephp/cakephp/tests/Fixture/CompositeKeyArticlesFixture.php @@ -0,0 +1,22 @@ + ['type' => 'integer'], + 'number_tree_id' => ['type' => 'integer', 'null' => true], + 'title' => ['type' => 'string', 'null' => true], + 'body' => 'text', + 'published' => ['type' => 'string', 'length' => 1, 'default' => 'N'], + '_constraints' => ['primary' => ['type' => 'primary', 'columns' => ['id']]], + ]; + + /** + * records property + * + * @var array + */ + public $records = [ + ['number_tree_id' => 1, 'title' => 'First Article', 'body' => 'First Article Body', 'published' => 'Y'], + ['number_tree_id' => 1, 'title' => 'Second Article', 'body' => 'Second Article Body', 'published' => 'Y'], + ['number_tree_id' => 11, 'title' => 'Third Article', 'body' => 'Third Article Body', 'published' => 'Y'], + ]; +} diff --git a/app/vendor/cakephp/cakephp/tests/Fixture/ProfilesFixture.php b/app/vendor/cakephp/cakephp/tests/Fixture/ProfilesFixture.php index 21b284e6d..8ba428744 100644 --- a/app/vendor/cakephp/cakephp/tests/Fixture/ProfilesFixture.php +++ b/app/vendor/cakephp/cakephp/tests/Fixture/ProfilesFixture.php @@ -1,16 +1,16 @@ 'composite_key_articles', + 'columns' => [ + 'author_id' => [ + 'type' => 'integer', + 'null' => false, + ], + 'created' => [ + 'type' => 'datetime', + 'null' => false, + ], + 'body' => [ + 'type' => 'text', + ], + ], + 'constraints' => [ + 'composite_article_pk' => [ + 'type' => 'primary', + 'columns' => [ + 'author_id', + 'created', + ], + ], + ], + ], + [ + 'table' => 'composite_key_articles_tags', + 'columns' => [ + 'author_id' => [ + 'type' => 'integer', + 'null' => false, + ], + 'created' => [ + 'type' => 'datetime', + 'null' => false, + ], + 'tag_id' => [ + 'type' => 'integer', + 'null' => false, + ], + ], + 'constraints' => [ + 'composite_article_tags_pk' => [ + 'type' => 'primary', + 'columns' => [ + 'author_id', + 'created', + 'tag_id', + ], + ], + ], + ], [ 'table' => 'profiles', 'columns' => [ @@ -1259,6 +1311,36 @@ ], ], ], + [ + 'table' => 'number_trees_articles', + 'columns' => [ + 'id' => [ + 'type' => 'integer', + ], + 'number_tree_id' => [ + 'type' => 'integer', + 'null' => true, + ], + 'title' => [ + 'type' => 'string', + 'null' => true, + ], + 'body' => 'text', + 'published' => [ + 'type' => 'string', + 'length' => 1, + 'default' => 'N', + ], + ], + 'constraints' => [ + 'primary' => [ + 'type' => 'primary', + 'columns' => [ + 'id', + ], + ], + ], + ], [ 'table' => 'composite_increments', 'columns' => [ diff --git a/app/vendor/cakephp/chronos/composer.json b/app/vendor/cakephp/chronos/composer.json index efce15054..6d83b7727 100644 --- a/app/vendor/cakephp/chronos/composer.json +++ b/app/vendor/cakephp/chronos/composer.json @@ -7,7 +7,7 @@ "time", "DateTime" ], - "homepage": "http://cakephp.org", + "homepage": "https://cakephp.org", "license": "MIT", "authors": [ { @@ -17,12 +17,11 @@ }, { "name": "The CakePHP Team", - "homepage": "http://cakephp.org" + "homepage": "https://cakephp.org" } ], "support": { "issues": "https://github.com/cakephp/chronos/issues", - "irc": "irc://irc.freenode.org/cakephp", "source": "https://github.com/cakephp/chronos" }, "require": { @@ -57,7 +56,12 @@ "stan": [ "@phpstan" ], - "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:^0.12.54 && mv composer.backup composer.json", + "stan-setup": "cp composer.json composer.backup && composer require --dev phpstan/phpstan:~1.8.0 && mv composer.backup composer.json", "test": "phpunit" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } } } diff --git a/app/vendor/cakephp/chronos/docs.Dockerfile b/app/vendor/cakephp/chronos/docs.Dockerfile index 3c6a7f509..032ed39c6 100644 --- a/app/vendor/cakephp/chronos/docs.Dockerfile +++ b/app/vendor/cakephp/chronos/docs.Dockerfile @@ -4,14 +4,20 @@ FROM markstory/cakephp-docs-builder as builder RUN pip install git+https://github.com/sphinx-contrib/video.git@master COPY docs /data/docs +ENV LANGS="en fr ja pt" # build docs with sphinx RUN cd /data/docs-builder && \ - make website LANGS="en fr ja pt" SOURCE=/data/docs DEST=/data/website + make website LANGS="$LANGS" SOURCE=/data/docs DEST=/data/website # Build a small nginx container with just the static site in it. -FROM nginx:1.15-alpine +FROM markstory/cakephp-docs-builder:runtime as runtime +ENV LANGS="en fr ja pt" +ENV SEARCH_SOURCE="/usr/share/nginx/html" +ENV SEARCH_URL_PREFIX="/chronos/2" + +COPY --from=builder /data/docs /data/docs COPY --from=builder /data/website /data/website COPY --from=builder /data/docs-builder/nginx.conf /etc/nginx/conf.d/default.conf diff --git a/app/vendor/cakephp/chronos/src/DifferenceFormatter.php b/app/vendor/cakephp/chronos/src/DifferenceFormatter.php index d1a47cd29..ad10c9582 100644 --- a/app/vendor/cakephp/chronos/src/DifferenceFormatter.php +++ b/app/vendor/cakephp/chronos/src/DifferenceFormatter.php @@ -64,17 +64,17 @@ public function diffForHumans( $unit = 'year'; $count = $diffInterval->y; break; - case $diffInterval->m > 0: + case $diffInterval->m >= 2: $unit = 'month'; $count = $diffInterval->m; break; + case $diffInterval->days >= ChronosInterface::DAYS_PER_WEEK * 3: + $unit = 'week'; + $count = (int)($diffInterval->days / ChronosInterface::DAYS_PER_WEEK); + break; case $diffInterval->d > 0: $unit = 'day'; $count = $diffInterval->d; - if ($count >= ChronosInterface::DAYS_PER_WEEK) { - $unit = 'week'; - $count = (int)($count / ChronosInterface::DAYS_PER_WEEK); - } break; case $diffInterval->h > 0: $unit = 'hour'; diff --git a/app/vendor/cakephp/chronos/src/Traits/DifferenceTrait.php b/app/vendor/cakephp/chronos/src/Traits/DifferenceTrait.php index e3f997988..7d4c74e58 100644 --- a/app/vendor/cakephp/chronos/src/Traits/DifferenceTrait.php +++ b/app/vendor/cakephp/chronos/src/Traits/DifferenceTrait.php @@ -36,7 +36,7 @@ trait DifferenceTrait /** * Instance of the diff formatting object. * - * @var \Cake\Chronos\DifferenceFormatterInterface + * @var \Cake\Chronos\DifferenceFormatterInterface|null */ protected static $diffFormatter; diff --git a/app/vendor/cakephp/chronos/src/Traits/ModifierTrait.php b/app/vendor/cakephp/chronos/src/Traits/ModifierTrait.php index f60f53cf4..adf177d7e 100644 --- a/app/vendor/cakephp/chronos/src/Traits/ModifierTrait.php +++ b/app/vendor/cakephp/chronos/src/Traits/ModifierTrait.php @@ -277,7 +277,7 @@ public function microsecond(int $value): ChronosInterface public function addYears(int $value): ChronosInterface { $month = $this->month; - $date = $this->modify($value . ' year'); + $date = $this->modify($value . ' years'); if ($date->month !== $month) { return $date->modify('last day of previous month'); @@ -309,7 +309,7 @@ public function addYear(int $value = 1): ChronosInterface */ public function subYears(int $value): ChronosInterface { - return $this->addYears(-1 * $value); + return $this->addYears(-$value); } /** @@ -322,7 +322,7 @@ public function subYears(int $value): ChronosInterface */ public function subYear(int $value = 1): ChronosInterface { - return $this->subYears($value); + return $this->addYears(-$value); } /** @@ -406,7 +406,7 @@ public function subYearWithOverflow(int $value = 1): ChronosInterface public function addMonths(int $value): ChronosInterface { $day = $this->day; - $date = $this->modify($value . ' month'); + $date = $this->modify($value . ' months'); if ($date->day !== $day) { return $date->modify('last day of previous month'); @@ -438,7 +438,7 @@ public function addMonth(int $value = 1): ChronosInterface */ public function subMonth(int $value = 1): ChronosInterface { - return $this->subMonths($value); + return $this->addMonths(-$value); } /** @@ -451,7 +451,7 @@ public function subMonth(int $value = 1): ChronosInterface */ public function subMonths(int $value): ChronosInterface { - return $this->addMonths(-1 * $value); + return $this->addMonths(-$value); } /** @@ -471,7 +471,7 @@ public function subMonths(int $value): ChronosInterface */ public function addMonthsWithOverflow(int $value): ChronosInterface { - return $this->modify($value . ' month'); + return $this->modify($value . ' months'); } /** @@ -484,7 +484,7 @@ public function addMonthsWithOverflow(int $value): ChronosInterface */ public function addMonthWithOverflow(int $value = 1): ChronosInterface { - return $this->modify($value . ' month'); + return $this->modify($value . ' months'); } /** @@ -522,7 +522,7 @@ public function subMonthWithOverflow(int $value = 1): ChronosInterface */ public function addDays(int $value): ChronosInterface { - return $this->modify("$value day"); + return $this->modify("$value days"); } /** @@ -533,7 +533,7 @@ public function addDays(int $value): ChronosInterface */ public function addDay(int $value = 1): ChronosInterface { - return $this->modify("$value day"); + return $this->modify("$value days"); } /** @@ -544,7 +544,7 @@ public function addDay(int $value = 1): ChronosInterface */ public function subDay(int $value = 1): ChronosInterface { - return $this->modify("-$value day"); + return $this->addDays(-$value); } /** @@ -555,7 +555,7 @@ public function subDay(int $value = 1): ChronosInterface */ public function subDays(int $value): ChronosInterface { - return $this->modify("-$value day"); + return $this->addDays(-$value); } /** @@ -567,7 +567,7 @@ public function subDays(int $value): ChronosInterface */ public function addWeekdays(int $value): ChronosInterface { - return $this->modify((int)$value . ' weekdays ' . $this->format('H:i:s')); + return $this->modify($value . ' weekdays, ' . $this->format('H:i:s')); } /** @@ -589,7 +589,7 @@ public function addWeekday(int $value = 1): ChronosInterface */ public function subWeekdays(int $value): ChronosInterface { - return $this->modify("$value weekdays ago, " . $this->format('H:i:s')); + return $this->addWeekdays(-$value); } /** @@ -600,7 +600,7 @@ public function subWeekdays(int $value): ChronosInterface */ public function subWeekday(int $value = 1): ChronosInterface { - return $this->subWeekdays($value); + return $this->addWeekdays(-$value); } /** @@ -634,7 +634,7 @@ public function addWeek(int $value = 1): ChronosInterface */ public function subWeek(int $value = 1): ChronosInterface { - return $this->modify("-$value week"); + return $this->addWeeks(-$value); } /** @@ -645,7 +645,7 @@ public function subWeek(int $value = 1): ChronosInterface */ public function subWeeks(int $value): ChronosInterface { - return $this->modify("-$value week"); + return $this->addWeeks(-$value); } /** @@ -679,7 +679,7 @@ public function addHour(int $value = 1): ChronosInterface */ public function subHour(int $value = 1): ChronosInterface { - return $this->modify("-$value hour"); + return $this->addHours(-$value); } /** @@ -690,7 +690,7 @@ public function subHour(int $value = 1): ChronosInterface */ public function subHours(int $value): ChronosInterface { - return $this->modify("-$value hour"); + return $this->addHours(-$value); } /** @@ -724,7 +724,7 @@ public function addMinute(int $value = 1): ChronosInterface */ public function subMinute(int $value = 1): ChronosInterface { - return $this->modify("-$value minute"); + return $this->addMinutes(-$value); } /** @@ -735,7 +735,7 @@ public function subMinute(int $value = 1): ChronosInterface */ public function subMinutes(int $value): ChronosInterface { - return $this->modify("-$value minute"); + return $this->addMinutes(-$value); } /** @@ -769,7 +769,7 @@ public function addSecond(int $value = 1): ChronosInterface */ public function subSecond(int $value = 1): ChronosInterface { - return $this->modify("-$value second"); + return $this->addSeconds(-$value); } /** @@ -780,7 +780,7 @@ public function subSecond(int $value = 1): ChronosInterface */ public function subSeconds(int $value): ChronosInterface { - return $this->modify("-$value second"); + return $this->addSeconds(-$value); } /** diff --git a/app/vendor/cakephp/debug_kit/.eslintrc.json b/app/vendor/cakephp/debug_kit/.eslintrc.json new file mode 100644 index 000000000..ec5d2f408 --- /dev/null +++ b/app/vendor/cakephp/debug_kit/.eslintrc.json @@ -0,0 +1,26 @@ +{ + "env": { + "browser": true, + "es2021": true, + "jquery": true + }, + "extends": [ + "airbnb-base" + ], + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "rules": { + "strict": 0, + "max-len": ["error", { "code": 150 }], + "no-underscore-dangle": ["error", { + "allow": ["__cakeDebugBlockInit", "_arguments"] + }], + "import/extensions": [0, { "": "always" }], + "no-param-reassign": 0, + "no-plusplus": 0, + "class-methods-use-this": 0, + "prefer-rest-params": 0 + } +} diff --git a/app/vendor/cakephp/debug_kit/composer.json b/app/vendor/cakephp/debug_kit/composer.json index 133ee97ed..248275f19 100644 --- a/app/vendor/cakephp/debug_kit/composer.json +++ b/app/vendor/cakephp/debug_kit/composer.json @@ -23,8 +23,8 @@ "source": "https://github.com/cakephp/debug_kit" }, "require": { - "php": ">=7.2", - "cakephp/cakephp": "^4.3.0", + "php": ">=7.4", + "cakephp/cakephp": "^4.4.0", "cakephp/chronos": "^2.0", "composer/composer": "^1.3 | ^2.0", "jdorn/sql-formatter": "^1.2" @@ -54,9 +54,21 @@ "scripts": { "cs-check": "phpcs --colors --parallel=16 -p src/ tests/", "cs-fix": "phpcbf --colors --parallel=16 -p src/ tests/", - "test": "phpunit", + "phpstan": "phpstan.phar analyse", "psalm": "psalm.phar --show-info=false", - "psalm-setup": "cp composer.json composer.backup && composer require --dev psalm/phar:^4.10 && mv composer.backup composer.json" + "stan": [ + "@phpstan", + "@psalm" + ], + "stan-baseline": "phpstan.phar --generate-baseline", + "psalm-baseline": "psalm.phar --set-baseline=psalm-baseline.xml", + "stan-setup": "cp composer.json composer.backup && composer require --dev symfony/polyfill-php81 phpstan/phpstan:~1.7.0 psalm/phar:~4.23.0 && mv composer.backup composer.json", + "test": "phpunit" }, - "prefer-stable": true + "prefer-stable": true, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true + } + } } diff --git a/app/vendor/cakephp/debug_kit/config/bootstrap.php b/app/vendor/cakephp/debug_kit/config/bootstrap.php index 6e8e0d64e..2afe7f8b5 100644 --- a/app/vendor/cakephp/debug_kit/config/bootstrap.php +++ b/app/vendor/cakephp/debug_kit/config/bootstrap.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ use Cake\Database\Query; use Cake\Datasource\ConnectionManager; diff --git a/app/vendor/cakephp/debug_kit/docs.Dockerfile b/app/vendor/cakephp/debug_kit/docs.Dockerfile index aa10f4314..cb30b3edf 100644 --- a/app/vendor/cakephp/debug_kit/docs.Dockerfile +++ b/app/vendor/cakephp/debug_kit/docs.Dockerfile @@ -19,7 +19,7 @@ FROM markstory/cakephp-docs-builder:runtime as runtime # Configure search index script ENV LANGS="en fr ja pt" -ENV SEARCH_SOURCE="/data/docs" +ENV SEARCH_SOURCE="/usr/share/nginx/html" ENV SEARCH_URL_PREFIX="/debugkit/4" COPY --from=builder /data/docs /data/docs diff --git a/app/vendor/cakephp/debug_kit/docs/en/index.rst b/app/vendor/cakephp/debug_kit/docs/en/index.rst index d672de9bd..049294e13 100644 --- a/app/vendor/cakephp/debug_kit/docs/en/index.rst +++ b/app/vendor/cakephp/debug_kit/docs/en/index.rst @@ -291,6 +291,20 @@ to include the panel:: The above would load all the default panels as well as the ``AppPanel``, and ``MyCustomPanel`` panel from ``MyPlugin``. +Accessing Toolbar without a frontend +==================================== + +If you have an application which only provides an API (and therefore no frontend) +the usual way of accessing the toolbar can't be used. + +Instead you have to call http://localhost/debug-kit/toolbar/```` + +The ```` can be found inside the HTTP headers of your API response. It should look something like that:: + + X-DEBUGKIT-ID: 5ef39604-ad5d-4ca4-85d8-8595e52373bb + +So you would have to call http://localhost/debug-kit/toolbar/5ef39604-ad5d-4ca4-85d8-8595e52373bb + Helper Functions ================ diff --git a/app/vendor/cakephp/debug_kit/docs/pt/index.rst b/app/vendor/cakephp/debug_kit/docs/pt/index.rst index 583de577e..e5ba22bc0 100644 --- a/app/vendor/cakephp/debug_kit/docs/pt/index.rst +++ b/app/vendor/cakephp/debug_kit/docs/pt/index.rst @@ -93,7 +93,7 @@ O painel History é uma das características mais frequentemente confundidas do DebugKit. Ele oferece uma forma de visualizar os dados de requisições anteriores na barra de ferramentas, incluindo erros e redirecionamentos. -.. figure:: /_static/img/history-panel.png +.. figure:: ../_static/history-panel.png :alt: Screenshot do painel History no DebugKit. Como você pode ver, o painel contém uma lista de requisições. Na esquerda você @@ -104,7 +104,7 @@ alternativos foram carregados. .. only:: html or epub - .. figure:: /_static/img/history-panel-use.gif + .. video:: ../_static/history-panel-use.mp4 :alt: Video do painel History em ação. Desenvolvendo seus próprios painéis diff --git a/app/vendor/cakephp/debug_kit/package.json b/app/vendor/cakephp/debug_kit/package.json new file mode 100644 index 000000000..e683acf89 --- /dev/null +++ b/app/vendor/cakephp/debug_kit/package.json @@ -0,0 +1,29 @@ +{ + "name": "debug_kit", + "version": "1.0.0", + "description": "CakePHP Debug Kit", + "author": "CakePHP Team", + "license": "MIT", + "homepage": "https://github.com/cakephp/debug_kit#readme", + "bugs": { + "url": "https://github.com/cakephp/debug_kit/issues" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/cakephp/debug_kit.git" + }, + "keywords": [ + "cakephp", + "debug", + "kit" + ], + "devDependencies": { + "eslint": "^8.17.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-plugin-import": "^2.26.0" + }, + "scripts": { + "cs-check": "npx eslint webroot/js/main.js webroot/js/inject-iframe.js webroot/js/modules/*.js", + "cs-fix": "npx eslint webroot/js/main.js webroot/js/inject-iframe.js webroot/js/modules/*.js --fix" + } +} diff --git a/app/vendor/cakephp/debug_kit/phpstan-baseline.neon b/app/vendor/cakephp/debug_kit/phpstan-baseline.neon new file mode 100644 index 000000000..c34e4a675 --- /dev/null +++ b/app/vendor/cakephp/debug_kit/phpstan-baseline.neon @@ -0,0 +1,36 @@ +parameters: + ignoreErrors: + - + message: "#^PHPDoc type array\\\\|Cake\\\\Cache\\\\CacheEngine of property DebugKit\\\\Cache\\\\Engine\\\\DebugEngine\\:\\:\\$_config is not covariant with PHPDoc type array\\ of overridden property Cake\\\\Cache\\\\CacheEngine\\:\\:\\$_config\\.$#" + count: 1 + path: src/Cache/Engine/DebugEngine.php + + - + message: "#^Property DebugKit\\\\Cache\\\\Engine\\\\DebugEngine\\:\\:\\$_engine \\(Cake\\\\Cache\\\\CacheEngine\\) in isset\\(\\) is not nullable\\.$#" + count: 1 + path: src/Cache/Engine/DebugEngine.php + + - + message: "#^Unreachable statement \\- code above always terminates\\.$#" + count: 1 + path: src/Cache/Engine/DebugEngine.php + + - + message: "#^Call to function file_get_contents\\(\\) on a separate line has no effect\\.$#" + count: 1 + path: src/Command/BenchmarkCommand.php + + - + message: "#^Method DebugKit\\\\Mailer\\\\Transport\\\\DebugKitTransport\\:\\:send\\(\\) should return array\\{headers\\: string, message\\: string\\} but returns array\\{headers\\: non\\-empty\\-array\\, message\\: array\\{text\\: string, html\\: string\\}\\}\\.$#" + count: 1 + path: src/Mailer/Transport/DebugKitTransport.php + + - + message: "#^Parameter \\#1 \\$request of method DebugKit\\\\ToolbarService\\:\\:saveData\\(\\) expects Cake\\\\Http\\\\ServerRequest, Psr\\\\Http\\\\Message\\\\ServerRequestInterface given\\.$#" + count: 1 + path: src/Middleware/DebugKitMiddleware.php + + - + message: "#^Call to an undefined method Cake\\\\ORM\\\\Locator\\\\LocatorInterface\\:\\:genericInstances\\(\\)\\.$#" + count: 1 + path: src/Panel/SqlLogPanel.php diff --git a/app/vendor/cakephp/debug_kit/phpstan.neon b/app/vendor/cakephp/debug_kit/phpstan.neon new file mode 100644 index 000000000..4fbb418e7 --- /dev/null +++ b/app/vendor/cakephp/debug_kit/phpstan.neon @@ -0,0 +1,13 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 6 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false + treatPhpDocTypesAsCertain: false + bootstrapFiles: + - tests/bootstrap.php + - vendor/cakephp/cakephp/src/Core/Exception/CakeException.php + paths: + - src/ diff --git a/app/vendor/cakephp/debug_kit/psalm-baseline.xml b/app/vendor/cakephp/debug_kit/psalm-baseline.xml index 2a067dad1..44e591c5d 100644 --- a/app/vendor/cakephp/debug_kit/psalm-baseline.xml +++ b/app/vendor/cakephp/debug_kit/psalm-baseline.xml @@ -45,11 +45,6 @@ new $className($config) - - - $request - - $pluginName @@ -66,11 +61,6 @@ $vendorName - - - count - - string|null @@ -83,16 +73,10 @@ - - !$connection instanceof ConnectionInterface - genericInstances - - - makeNeatArray diff --git a/app/vendor/cakephp/debug_kit/psalm.xml b/app/vendor/cakephp/debug_kit/psalm.xml index 02997ec3b..afe253290 100644 --- a/app/vendor/cakephp/debug_kit/psalm.xml +++ b/app/vendor/cakephp/debug_kit/psalm.xml @@ -1,7 +1,6 @@ + * @var array|\Cake\Cache\CacheEngine + * @psalm-suppress NonInvariantDocblockPropertyType */ protected $_config; /** * Proxied engine * - * @var mixed + * @var \Cake\Cache\CacheEngine */ protected $_engine; @@ -64,7 +65,7 @@ class DebugEngine extends CacheEngine /** * Constructor * - * @param mixed $config Config data or the proxied adapter. + * @param array|\Cake\Cache\CacheEngine $config Config data or the proxied adapter. * @param string $name The name of the proxied cache engine. * @param \Psr\Log\LoggerInterface $logger Logger for collecting cache operation logs. */ @@ -83,7 +84,7 @@ public function __construct($config, string $name, LoggerInterface $logger) */ public function init(array $config = []): bool { - if (is_object($this->_config)) { + if (!is_array($this->_config)) { $this->_engine = $this->_config; return true; @@ -311,7 +312,9 @@ public function getConfig(?string $key = null, $default = null) */ public function setConfig($key, $value = null, $merge = true) { - return $this->_engine->setConfig($key, $value, $merge); + $this->_engine->setConfig($key, $value, $merge); + + return $this; } /** @@ -336,12 +339,14 @@ public function clearGroup(string $group): bool */ public function __toString() { - if (!empty($this->_engine)) { + /** @psalm-suppress RedundantPropertyInitializationCheck */ + if (isset($this->_engine)) { [$ns, $class] = namespaceSplit(get_class($this->_engine)); return str_replace('Engine', '', $class); } + /** @psalm-suppress UndefinedMethod */ return $this->_config['className']; } } diff --git a/app/vendor/cakephp/debug_kit/src/Command/BenchmarkCommand.php b/app/vendor/cakephp/debug_kit/src/Command/BenchmarkCommand.php index 16ac83407..e66d00099 100644 --- a/app/vendor/cakephp/debug_kit/src/Command/BenchmarkCommand.php +++ b/app/vendor/cakephp/debug_kit/src/Command/BenchmarkCommand.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 1.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Command; @@ -54,7 +54,7 @@ public function execute(Arguments $args, ConsoleIo $io): ?int $options = array_merge($defaults, $args->getOptions()); $times = []; - $io->out(Text::insert(__d('debug_kit', '-> Testing :url'), compact('url'))); + $io->out(Text::insert('-> Testing :url', compact('url'))); $io->out(''); for ($i = 0; $i < $options['n']; $i++) { /** @psalm-suppress PossiblyInvalidOperand */ @@ -84,25 +84,25 @@ protected function _results($times) $duration = array_sum($times); $requests = count($times); - $this->io->out(Text::insert(__d('debug_kit', 'Total Requests made: :requests'), compact('requests'))); - $this->io->out(Text::insert(__d('debug_kit', 'Total Time elapsed: :duration (seconds)'), compact('duration'))); + $this->io->out(Text::insert('Total Requests made: :requests', compact('requests'))); + $this->io->out(Text::insert('Total Time elapsed: :duration (seconds)', compact('duration'))); $this->io->out(''); - $this->io->out(Text::insert(__d('debug_kit', 'Requests/Second: :rps req/sec'), [ + $this->io->out(Text::insert('Requests/Second: :rps req/sec', [ 'rps' => round($requests / $duration, 3), ])); - $this->io->out(Text::insert(__d('debug_kit', 'Average request time: :average-time seconds'), [ + $this->io->out(Text::insert('Average request time: :average-time seconds', [ 'average-time' => round($duration / $requests, 3), ])); - $this->io->out(Text::insert(__d('debug_kit', 'Standard deviation of average request time: :std-dev'), [ + $this->io->out(Text::insert('Standard deviation of average request time: :std-dev', [ 'std-dev' => round($this->_deviation($times, true), 3), ])); if (!empty($times)) { - $this->io->out(Text::insert(__d('debug_kit', 'Longest/shortest request: :longest sec/:shortest sec'), [ + $this->io->out(Text::insert('Longest/shortest request: :longest sec/:shortest sec', [ 'longest' => round(max($times), 3), 'shortest' => round(min($times), 3), ])); @@ -161,32 +161,28 @@ protected function _deviation($times, $sample = true) */ protected function buildOptionParser(ConsoleOptionParser $parser): ConsoleOptionParser { - $parser->setDescription(__d( - 'debug_kit', + $parser->setDescription( 'Allows you to obtain some rough benchmarking statistics' . 'about a fully qualified URL.' - )) + ) ->addArgument('url', [ - 'help' => __d('debug_kit', 'The URL to request.'), + 'help' => 'The URL to request.', 'required' => true, ]) ->addOption('n', [ 'default' => 10, - 'help' => __d('debug_kit', 'Number of iterations to perform.'), + 'help' => 'Number of iterations to perform.', ]) ->addOption('t', [ 'default' => 100, - 'help' => __d( - 'debug_kit', - 'Maximum total time for all iterations, in seconds.' . - 'If a single iteration takes more than the timeout, only one request will be made' - ), + 'help' => + 'Maximum total time for all iterations, in seconds. ' . + 'If a single iteration takes more than the timeout, only one request will be made', ]) - ->setEpilog(__d( - 'debug_kit', + ->setEpilog( 'Example Use: `cake benchmark --n 10 --t 100 http://localhost/testsite`. ' . 'Note: this benchmark does not include browser render times.' - )); + ); return $parser; } diff --git a/app/vendor/cakephp/debug_kit/src/Controller/ComposerController.php b/app/vendor/cakephp/debug_kit/src/Controller/ComposerController.php index f26d379d6..2403ac27a 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/ComposerController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/ComposerController.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 3.6.1 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; @@ -56,7 +56,7 @@ public function checkDependencies() $packages = []; foreach ($dependencies as $dependency) { if (strpos($dependency, 'php_network_getaddresses') !== false) { - throw new \RuntimeException(__d('debug_kit', 'You have to be connected to the internet')); + throw new \RuntimeException('You have to be connected to the internet'); } if (strpos($dependency, '') !== false) { $packages['semverCompatible'][] = $dependency; diff --git a/app/vendor/cakephp/debug_kit/src/Controller/DashboardController.php b/app/vendor/cakephp/debug_kit/src/Controller/DashboardController.php index a4cd4fa15..7ee4a9157 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/DashboardController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/DashboardController.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; @@ -62,6 +62,7 @@ public function index() public function reset() { $this->request->allowMethod('post'); + /** @var \DebugKit\Model\Table\RequestsTable $requestsModel */ $requestsModel = $this->fetchTable('DebugKit.Requests'); $requestsModel->Panels->deleteAll('1=1'); diff --git a/app/vendor/cakephp/debug_kit/src/Controller/DebugKitController.php b/app/vendor/cakephp/debug_kit/src/Controller/DebugKitController.php index d565bfc05..26a990450 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/DebugKitController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/DebugKitController.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; diff --git a/app/vendor/cakephp/debug_kit/src/Controller/MailPreviewController.php b/app/vendor/cakephp/debug_kit/src/Controller/MailPreviewController.php index 8378d593c..74edc8a09 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/MailPreviewController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/MailPreviewController.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.3 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; @@ -71,7 +71,7 @@ public function sent($panelId, $number) // @codingStandardsIgnoreEnd if (empty($content['emails'][$number])) { - throw new NotFoundException(__d('debug_kit', 'No emails found in this request')); + throw new NotFoundException('No emails found in this request'); } $email = $content['emails'][$number]; @@ -99,7 +99,7 @@ public function sent($panelId, $number) * * @param string $name The Mailer name * @param string $method The mailer preview method - * @return \Psr\Http\Message\ResponseInterface|null + * @return \Psr\Http\Message\ResponseInterface|void */ public function email($name, $method) { @@ -150,17 +150,16 @@ protected function respondWithPart($email, $partType) { $part = $this->findPart($email, $partType); - if ($part === false) { - throw new NotFoundException(__d('debug_kit', "Email part ''{0}'' not found in email", $partType)); + if ($part === null) { + throw new NotFoundException(sprintf("Email part '%s' not found in email", $partType)); } $response = $this->response->withType($partType); if ($partType === 'text') { - $part = '
' . (string)$part . '
'; + $part = '
' . $part . '
'; } - $response = $response->withStringBody($part); - return $response; + return $response->withStringBody($part); } /** @@ -188,7 +187,7 @@ protected function getMailPreviewClasses() return [[CorePlugin::classPath($plugin) . 'Mailer/Preview/'], "$plugin."]; }); - $appPaths = [App::path('Mailer/Preview'), '']; + $appPaths = [App::classPath('Mailer/Preview'), '']; return collection([$appPaths]) ->append($pluginPaths) @@ -274,9 +273,8 @@ protected function findPreview($previewName, $emailName, $plugin = '') $email = $mailPreview->find($emailName); if (!$email) { - throw new NotFoundException(__d( - 'debug_kit', - 'Mailer preview {0}::{1} not found', + throw new NotFoundException(sprintf( + 'Mailer preview %s::%s not found', $previewName, $emailName )); diff --git a/app/vendor/cakephp/debug_kit/src/Controller/PanelsController.php b/app/vendor/cakephp/debug_kit/src/Controller/PanelsController.php index ba579a50a..aa8ff0de0 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/PanelsController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/PanelsController.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; diff --git a/app/vendor/cakephp/debug_kit/src/Controller/RequestsController.php b/app/vendor/cakephp/debug_kit/src/Controller/RequestsController.php index b166752bb..22b626900 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/RequestsController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/RequestsController.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; diff --git a/app/vendor/cakephp/debug_kit/src/Controller/ToolbarController.php b/app/vendor/cakephp/debug_kit/src/Controller/ToolbarController.php index b047dcf2d..6efae2474 100644 --- a/app/vendor/cakephp/debug_kit/src/Controller/ToolbarController.php +++ b/app/vendor/cakephp/debug_kit/src/Controller/ToolbarController.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Controller; @@ -48,11 +48,15 @@ public function initialize(): void public function clearCache() { $this->request->allowMethod('post'); - if (!$this->request->getData('name')) { - throw new NotFoundException(__d('debug_kit', 'Invalid cache engine name.')); + $name = $this->request->getData('name'); + if (!$name) { + throw new NotFoundException('Invalid cache engine name.'); } - $result = Cache::clear($this->request->getData('name')); - $this->set('success', $result); - $this->viewBuilder()->setOption('serialize', ['success']); + $success = Cache::clear($name); + $message = $success ? + sprintf('%s cache cleared.', $name) : + sprintf('%s cache could not be cleared.', $name); + $this->set(compact('success', 'message')); + $this->viewBuilder()->setOption('serialize', ['success', 'message']); } } diff --git a/app/vendor/cakephp/debug_kit/src/Database/Log/DebugLog.php b/app/vendor/cakephp/debug_kit/src/Database/Log/DebugLog.php index d2055a2d5..7b8e99eb5 100644 --- a/app/vendor/cakephp/debug_kit/src/Database/Log/DebugLog.php +++ b/app/vendor/cakephp/debug_kit/src/Database/Log/DebugLog.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Database\Log; diff --git a/app/vendor/cakephp/debug_kit/src/DebugInclude.php b/app/vendor/cakephp/debug_kit/src/DebugInclude.php index 613f5aac7..2ece06704 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugInclude.php +++ b/app/vendor/cakephp/debug_kit/src/DebugInclude.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; diff --git a/app/vendor/cakephp/debug_kit/src/DebugMemory.php b/app/vendor/cakephp/debug_kit/src/DebugMemory.php index 221ca650f..203be1d0b 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugMemory.php +++ b/app/vendor/cakephp/debug_kit/src/DebugMemory.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 2.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; diff --git a/app/vendor/cakephp/debug_kit/src/DebugPanel.php b/app/vendor/cakephp/debug_kit/src/DebugPanel.php index 67f1bda2a..520637739 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugPanel.php +++ b/app/vendor/cakephp/debug_kit/src/DebugPanel.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 0.1 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; diff --git a/app/vendor/cakephp/debug_kit/src/DebugSql.php b/app/vendor/cakephp/debug_kit/src/DebugSql.php index 72d3c843f..b3e4b1692 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugSql.php +++ b/app/vendor/cakephp/debug_kit/src/DebugSql.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 3.11.4 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; @@ -73,7 +73,7 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $ $sql = (string)$query; if ($showValues) { - $sql = static::interpolate($sql, $query->getValueBinder()->bindings()); + $sql = self::interpolate($sql, $query->getValueBinder()->bindings()); } /** @var array $trace */ @@ -92,16 +92,16 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $ $file = str_replace($search, '', $file); } - $template = static::$templateHtml; + $template = self::$templateHtml; $sqlHighlight = true; if ((PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') || $showHtml === false) { - $template = static::$templateText; + $template = self::$templateText; $sqlHighlight = false; if ($file && $line) { $lineInfo = sprintf('%s (line %s)', $file, $line); } } - if ($showHtml === null && $template !== static::$templateText) { + if ($showHtml === null && $template !== self::$templateText) { $showHtml = true; } @@ -113,7 +113,7 @@ public static function sql(Query $query, $showValues = true, $showHtml = null, $ ); if ($showHtml) { - $template = static::$templateHtml; + $template = self::$templateHtml; if ($file && $line) { $lineInfo = sprintf('%s (line %s)', $file, $line); } diff --git a/app/vendor/cakephp/debug_kit/src/DebugTimer.php b/app/vendor/cakephp/debug_kit/src/DebugTimer.php index 23e8deef9..5b557703d 100644 --- a/app/vendor/cakephp/debug_kit/src/DebugTimer.php +++ b/app/vendor/cakephp/debug_kit/src/DebugTimer.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 0.1 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; @@ -132,7 +132,7 @@ public static function getAll($clear = false) $_end = $now; } $times['Core Processing (Derived from $_SERVER["REQUEST_TIME"])'] = [ - 'message' => __d('debug_kit', 'Core Processing (Derived from $_SERVER["REQUEST_TIME"])'), + 'message' => 'Core Processing (Derived from $_SERVER["REQUEST_TIME"])', 'start' => 0, 'end' => $_end - $start, 'time' => round($_end - $start, 6), diff --git a/app/vendor/cakephp/debug_kit/src/Locale/debug_kit.pot b/app/vendor/cakephp/debug_kit/src/Locale/debug_kit.pot deleted file mode 100644 index df4988dd1..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/debug_kit.pot +++ /dev/null @@ -1,138 +0,0 @@ -# LANGUAGE translation of Debug Kit Application -# Copyright 2008 Andy Dawson -# No version information was available in the source files. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: debug_kit-\n" -"POT-Creation-Date: 2009-05-27 09:47+0200\n" -"PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" -"Last-Translator: Andy Dawson \n" -"Language-Team:\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Basepath: ../../../\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "" - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "" - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "" - -#: views/elements/log_panel.ctp:28 -#: views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "" - diff --git a/app/vendor/cakephp/debug_kit/src/Locale/eng/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/eng/LC_MESSAGES/debug_kit.po deleted file mode 100644 index 9aec83297..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/eng/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,135 +0,0 @@ -# LANGUAGE translation of CakePHP Application -# Copyright YEAR NAME -# No version information was available in the source files. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PROJECT VERSION\n" - "POT-Creation-Date: 2009-05-27 09:47+0200\n" - "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" - "Last-Translator: NAME \n" - "Language-Team: LANGUAGE \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "" - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "" - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "" - -#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "" diff --git a/app/vendor/cakephp/debug_kit/src/Locale/fra/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/fra/LC_MESSAGES/debug_kit.po deleted file mode 100644 index 515574de0..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/fra/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,135 +0,0 @@ -# LANGUAGE translation of CakePHP Application -# Copyright YEAR NAME -# No version information was available in the source files. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PROJECT VERSION\n" - "POT-Creation-Date: 2013-06-04 12:00+0200\n" - "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" - "Last-Translator: cake17 \n" - "Language-Team: \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=2; plural=n>1;\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "Initialisation du component et démarrage" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "Action du Controller" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "Rendu de l'Action du Controller" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "Ne peut charger le panel %s de DebugToolbar" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "Il n'y a pas de panels actifs. Vous devez activer le panel pour voir sa sortie." - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "Historique des Requêtes" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "Pas de demandes antérieures enregistrées." - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "Des requêtes antérieures sont disponibles" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "Restaure la requête actuelle" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "Logs" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "Date" - -#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "Message" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "Il n'y avait pas d'entrées de log faîtes pour cette requête" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "Requête" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "Route actuelle" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "Session" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "Logs Sql" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "bascule (%s) requêtes expliquées pour %s" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "Pas de requêtes lentes!, ou votre base de données ne supporte pas EXPLAIN" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "Pas de connections actives de la base de données" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "Mémoire" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "Utilisation de la Mémoire Actuelle" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "Utilisation de la Mémoire au niveau maximum" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "Timers" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "%s (ms)" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "Total du Temps de Requête" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "Temps en ms" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "Graph" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "Variables du View" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "Début en %sms de la requête, et prend %sms" diff --git a/app/vendor/cakephp/debug_kit/src/Locale/lim/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/lim/LC_MESSAGES/debug_kit.po deleted file mode 100644 index bf3894ada..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/lim/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,136 +0,0 @@ -# LANGUAGE translation of Debug Kit Application -# Copyright 2008 Andy Dawson -# No version information was available in the source files. -# -msgid "" -msgstr "" -"Project-Id-Version: debug_kit-\n" -"POT-Creation-Date: 2009-05-27 09:47+0200\n" -"PO-Revision-Date: 2009-05-27 09:47+0200\n" -"Last-Translator: Automatically generated\n" -"Language-Team:none\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"X-Poedit-Basepath: ../../../\n" -"Language: lim\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "" - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "" - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "" - -#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "" diff --git a/app/vendor/cakephp/debug_kit/src/Locale/nld/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/nld/LC_MESSAGES/debug_kit.po deleted file mode 100644 index b6b754fe5..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/nld/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,141 +0,0 @@ -# LANGUAGE translation of Debug Kit Application -# Copyright 2008 Andy Dawson -# No version information was available in the source files. -# -msgid "" -msgstr "" -"Project-Id-Version: debug_kit-\n" -"POT-Creation-Date: 2009-05-27 09:47+0200\n" -"PO-Revision-Date: 2014-07-17 17:04+0200\n" -"Last-Translator: Marlin Cremers \n" -"Language-Team: \n" -"Language: nld\n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=utf-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=2; plural=n != 1;\n" -"X-Generator: Weblate 1.9\n" -"X-Poedit-Basepath: ../../../\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "Component initializatie en opstarten" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "Controller Actie" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "Produceer Controller Actie" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "Kon DebugToolbar paneel %s niet laden" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "" -"Er zijn geen actieve panelen. Je moet een paneel aanzetten om de uitvoer te " -"zien." - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "Aanvraag Geschiedenis" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "Geen vorige aanvragen gelogged." - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "vorige aanvraag beschikbaar" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "Herstel naar actuele aanvraag" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "Logs" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "Tijd" - -#: views/elements/log_panel.ctp:28 -#: views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "Bericht" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "Er zijn geen log vermeldingen gemaakt in deze aanvraag" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "Aanvraag" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "Huide Route" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "Sessie" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "Sql Logs" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "schakel (%s) aanvraag uitleg voor %s" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "Geen langzame vragen!, of je database ondersteund geen EXPLAIN" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "Geen actieve database verbindingen" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "Geheugen" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "Actueel Geheugen Gebruik" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "Hoogste Geheugen Gebruik" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "Timers" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "%s (ms)" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "Totale Aanvraag Tijd:" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "Tijd in ms" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "Diagram" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "View Variabelen" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "Starten %sms in de aanvraag, neemt %sms" diff --git a/app/vendor/cakephp/debug_kit/src/Locale/pt_BR/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/pt_BR/LC_MESSAGES/debug_kit.po deleted file mode 100644 index e1e4c4551..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/pt_BR/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,135 +0,0 @@ -# LANGUAGE translation of CakePHP Application -# Copyright YEAR NAME -# No version information was available in the source files. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PROJECT VERSION\n" - "POT-Creation-Date: 2014-01-23 08:29+0200\n" - "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" - "Last-Translator: Lincoln Brito \n" - "Language-Team: LANGUAGE \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=2; plural=n>1;\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "Inicialização de componente" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "Action do Controller" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "Renderizar Action do Controller" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "Não foi possível carregar o painel %s do DebugToolbar" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "Não existem painéis ativos. Você deve habilitar um painel para visualizar sua saída." - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "Histórico de requisições" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "Sem requisições anteriores logadas." - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "requisições anteriores disponíveis" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "Restaurar para requisição atual" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "Logs" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "Tempo" - -#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "Mensagem" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "Não houveram entradas no log para essa requisição " - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "Requisição" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "Rota Atual" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "Sessão" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "Logs Sql" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "alternar (%s) query explains por %s" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "Sem consultas lentas!, ou o seu banco de dados não suporta EXPLAIN" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "Sem conexões ativas de banco de dados" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "Memória" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "Uso atual de memória" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "Pico de uso de memória" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "Tempos" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "%s (ms)" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "Tempo Total de Requisição" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "Tempo em ms" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "Gráfico" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "Visualizar Variáveis" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "Começando %sms na requisição, levando %sms" diff --git a/app/vendor/cakephp/debug_kit/src/Locale/spa/LC_MESSAGES/debug_kit.po b/app/vendor/cakephp/debug_kit/src/Locale/spa/LC_MESSAGES/debug_kit.po deleted file mode 100644 index 0833a4942..000000000 --- a/app/vendor/cakephp/debug_kit/src/Locale/spa/LC_MESSAGES/debug_kit.po +++ /dev/null @@ -1,135 +0,0 @@ -# LANGUAGE translation of CakePHP Application -# Copyright YEAR NAME -# No version information was available in the source files. -# -#, fuzzy -msgid "" -msgstr "Project-Id-Version: PROJECT VERSION\n" - "POT-Creation-Date: 2009-05-27 09:47+0200\n" - "PO-Revision-Date: YYYY-mm-DD HH:MM+ZZZZ\n" - "Last-Translator: NAME \n" - "Language-Team: LANGUAGE \n" - "MIME-Version: 1.0\n" - "Content-Type: text/plain; charset=UTF-8\n" - "Content-Transfer-Encoding: 8bit\n" - "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: controllers/components/toolbar.php:91 -msgid "Component initialization and startup" -msgstr "" - -#: controllers/components/toolbar.php:140 -msgid "Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:167 -msgid "Render Controller Action" -msgstr "" - -#: controllers/components/toolbar.php:231 -msgid "Could not load DebugToolbar panel %s" -msgstr "" - -#: views/elements/debug_toolbar.ctp:25 -msgid "There are no active panels. You must enable a panel to see its output." -msgstr "" - -#: views/elements/history_panel.ctp:21 -msgid "Request History" -msgstr "" - -#: views/elements/history_panel.ctp:23 -msgid "No previous requests logged." -msgstr "" - -#: views/elements/history_panel.ctp:25 -msgid "previous requests available" -msgstr "" - -#: views/elements/history_panel.ctp:27 -msgid "Restore to current request" -msgstr "" - -#: views/elements/log_panel.ctp:21 -msgid "Logs" -msgstr "" - -#: views/elements/log_panel.ctp:28 -msgid "Time" -msgstr "" - -#: views/elements/log_panel.ctp:28 views/elements/timer_panel.ctp:54 -msgid "Message" -msgstr "" - -#: views/elements/log_panel.ctp:37 -msgid "There were no log entries made this request" -msgstr "" - -#: views/elements/request_panel.ctp:21 -msgid "Request" -msgstr "" - -#: views/elements/request_panel.ctp:35 -msgid "Current Route" -msgstr "" - -#: views/elements/session_panel.ctp:21 -msgid "Session" -msgstr "" - -#: views/elements/sql_log_panel.ctp:21 -msgid "Sql Logs" -msgstr "" - -#: views/elements/sql_log_panel.ctp:31 -msgid "toggle (%s) query explains for %s" -msgstr "" - -#: views/elements/sql_log_panel.ctp:39 -msgid "No slow queries!, or your database does not support EXPLAIN" -msgstr "" - -#: views/elements/sql_log_panel.ctp:44 -msgid "No active database connections" -msgstr "" - -#: views/elements/timer_panel.ctp:33 -msgid "Memory" -msgstr "" - -#: views/elements/timer_panel.ctp:35 -msgid "Current Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:39 -msgid "Peak Memory Use" -msgstr "" - -#: views/elements/timer_panel.ctp:43 -msgid "Timers" -msgstr "" - -#: views/elements/timer_panel.ctp:45 -msgid "%s (ms)" -msgstr "" - -#: views/elements/timer_panel.ctp:46 -msgid "Total Request Time:" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Time in ms" -msgstr "" - -#: views/elements/timer_panel.ctp:54 -msgid "Graph" -msgstr "" - -#: views/elements/variables_panel.ctp:21 -msgid "View Variables" -msgstr "" - -#: views/helpers/simple_graph.php:79 -msgid "Starting %sms into the request, taking %sms" -msgstr "" \ No newline at end of file diff --git a/app/vendor/cakephp/debug_kit/src/Log/Engine/DebugKitLog.php b/app/vendor/cakephp/debug_kit/src/Log/Engine/DebugKitLog.php index bff04c545..5671005e2 100644 --- a/app/vendor/cakephp/debug_kit/src/Log/Engine/DebugKitLog.php +++ b/app/vendor/cakephp/debug_kit/src/Log/Engine/DebugKitLog.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Log\Engine; diff --git a/app/vendor/cakephp/debug_kit/src/Mailer/AbstractResult.php b/app/vendor/cakephp/debug_kit/src/Mailer/AbstractResult.php index bfb3a4a32..6378cd8c5 100644 --- a/app/vendor/cakephp/debug_kit/src/Mailer/AbstractResult.php +++ b/app/vendor/cakephp/debug_kit/src/Mailer/AbstractResult.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Mailer; diff --git a/app/vendor/cakephp/debug_kit/src/Mailer/MailPreview.php b/app/vendor/cakephp/debug_kit/src/Mailer/MailPreview.php index 6663b07eb..4b467b09e 100644 --- a/app/vendor/cakephp/debug_kit/src/Mailer/MailPreview.php +++ b/app/vendor/cakephp/debug_kit/src/Mailer/MailPreview.php @@ -2,20 +2,20 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Mailer; -use Cake\Datasource\ModelAwareTrait; use Cake\Mailer\MailerAwareTrait; +use Cake\ORM\Locator\LocatorAwareTrait; use ReflectionClass; use ReflectionException; use ReflectionMethod; @@ -26,7 +26,7 @@ class MailPreview { use MailerAwareTrait; - use ModelAwareTrait; + use LocatorAwareTrait; /** * Returns the name of an email if it is valid diff --git a/app/vendor/cakephp/debug_kit/src/Mailer/PreviewResult.php b/app/vendor/cakephp/debug_kit/src/Mailer/PreviewResult.php index 7f55adcab..9eea58d08 100644 --- a/app/vendor/cakephp/debug_kit/src/Mailer/PreviewResult.php +++ b/app/vendor/cakephp/debug_kit/src/Mailer/PreviewResult.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Mailer; diff --git a/app/vendor/cakephp/debug_kit/src/Mailer/SentMailResult.php b/app/vendor/cakephp/debug_kit/src/Mailer/SentMailResult.php index d15674a0e..55d1647f6 100644 --- a/app/vendor/cakephp/debug_kit/src/Mailer/SentMailResult.php +++ b/app/vendor/cakephp/debug_kit/src/Mailer/SentMailResult.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Mailer; diff --git a/app/vendor/cakephp/debug_kit/src/Mailer/Transport/DebugKitTransport.php b/app/vendor/cakephp/debug_kit/src/Mailer/Transport/DebugKitTransport.php index e0f796803..82656de5e 100644 --- a/app/vendor/cakephp/debug_kit/src/Mailer/Transport/DebugKitTransport.php +++ b/app/vendor/cakephp/debug_kit/src/Mailer/Transport/DebugKitTransport.php @@ -16,7 +16,7 @@ class DebugKitTransport extends AbstractTransport /** * The transport object this class is decorating * - * @var \Cake\Mailer\AbstractTransport + * @var \Cake\Mailer\AbstractTransport|null */ protected $originalTransport; diff --git a/app/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php b/app/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php index c53994611..662d1b769 100644 --- a/app/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php +++ b/app/vendor/cakephp/debug_kit/src/Middleware/DebugKitMiddleware.php @@ -2,14 +2,14 @@ declare(strict_types=1); /** - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Middleware; @@ -63,6 +63,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface return $response; } + /** @psalm-suppress ArgumentTypeCoercion */ $row = $this->service->saveData($request, $response); if (!$row) { return $response; diff --git a/app/vendor/cakephp/debug_kit/src/Model/Behavior/TimedBehavior.php b/app/vendor/cakephp/debug_kit/src/Model/Behavior/TimedBehavior.php index 4a18f6a03..363b17274 100644 --- a/app/vendor/cakephp/debug_kit/src/Model/Behavior/TimedBehavior.php +++ b/app/vendor/cakephp/debug_kit/src/Model/Behavior/TimedBehavior.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 1.3 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Model\Behavior; diff --git a/app/vendor/cakephp/debug_kit/src/Model/Entity/Panel.php b/app/vendor/cakephp/debug_kit/src/Model/Entity/Panel.php index f862fd959..a5cdd591a 100644 --- a/app/vendor/cakephp/debug_kit/src/Model/Entity/Panel.php +++ b/app/vendor/cakephp/debug_kit/src/Model/Entity/Panel.php @@ -2,14 +2,14 @@ declare(strict_types=1); /** - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Model\Entity; diff --git a/app/vendor/cakephp/debug_kit/src/Model/Table/LazyTableTrait.php b/app/vendor/cakephp/debug_kit/src/Model/Table/LazyTableTrait.php index 3e7405d84..5d53421db 100644 --- a/app/vendor/cakephp/debug_kit/src/Model/Table/LazyTableTrait.php +++ b/app/vendor/cakephp/debug_kit/src/Model/Table/LazyTableTrait.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Model\Table; diff --git a/app/vendor/cakephp/debug_kit/src/Model/Table/PanelsTable.php b/app/vendor/cakephp/debug_kit/src/Model/Table/PanelsTable.php index f70b773fc..9612798af 100644 --- a/app/vendor/cakephp/debug_kit/src/Model/Table/PanelsTable.php +++ b/app/vendor/cakephp/debug_kit/src/Model/Table/PanelsTable.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Model\Table; @@ -57,7 +57,7 @@ public function initialize(array $config): void public function findByRequest(Query $query, array $options) { if (empty($options['requestId'])) { - throw new \RuntimeException(__d('debug_kit', 'Missing request id in {0}.', 'findByRequest()')); + throw new \RuntimeException('Missing request id in findByRequest().'); } return $query->where(['Panels.request_id' => $options['requestId']]) diff --git a/app/vendor/cakephp/debug_kit/src/Model/Table/RequestsTable.php b/app/vendor/cakephp/debug_kit/src/Model/Table/RequestsTable.php index 6461cfcae..c0318cf35 100644 --- a/app/vendor/cakephp/debug_kit/src/Model/Table/RequestsTable.php +++ b/app/vendor/cakephp/debug_kit/src/Model/Table/RequestsTable.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Model\Table; @@ -24,6 +24,7 @@ /** * The requests table tracks basic information about each request. * + * @property \DebugKit\Model\Table\PanelsTable $Panels * @method \DebugKit\Model\Entity\Request get($primaryKey, $options = []) * @method \DebugKit\Model\Entity\Request newEntity($data = null, array $options = []) * @method \DebugKit\Model\Entity\Request[] newEntities(array $data, array $options = []) diff --git a/app/vendor/cakephp/debug_kit/src/Panel/CachePanel.php b/app/vendor/cakephp/debug_kit/src/Panel/CachePanel.php index 9c86ca2f0..0265157ed 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/CachePanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/CachePanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -50,6 +50,7 @@ public function __construct() public function initialize() { foreach (Cache::configured() as $name) { + /** @var array $config */ $config = Cache::getConfig($name); if (isset($config['className']) && $config['className'] instanceof DebugEngine) { $instance = $config['className']; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/DeprecationsPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/DeprecationsPanel.php index 3ee9e0932..91974b496 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/DeprecationsPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/DeprecationsPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -59,10 +59,6 @@ protected function _prepare() foreach ($errors as $error) { $file = $error['file']; $line = $error['line']; - if (isset($error['context']['frame'])) { - $file = $error['context']['frame']['file']; - $line = $error['context']['frame']['line']; - } $errorData = [ 'file' => $file, @@ -93,15 +89,9 @@ protected function _prepare() } } - ksort($return['app']); - ksort($return['cake']); ksort($return['plugins']); ksort($return['vendor']); - foreach ($return['plugins'] as &$plugin) { - ksort($plugin); - } - return $return; } diff --git a/app/vendor/cakephp/debug_kit/src/Panel/EnvironmentPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/EnvironmentPanel.php index 23433342a..cab709a82 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/EnvironmentPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/EnvironmentPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -75,10 +75,6 @@ protected function _prepare() $var = get_defined_constants(true); $return['app'] = array_diff_key($var['user'], $return['cake'], $hiddenCakeConstants); - if (isset($var['hidef'])) { - $return['hidef'] = $var['hidef']; - } - return $return; } diff --git a/app/vendor/cakephp/debug_kit/src/Panel/HistoryPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/HistoryPanel.php index 14db336e9..03d42b4e8 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/HistoryPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/HistoryPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/IncludePanel.php b/app/vendor/cakephp/debug_kit/src/Panel/IncludePanel.php index 9fc6211cc..032e3e331 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/IncludePanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/IncludePanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/LogPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/LogPanel.php index 3aa23a69e..c783d32f7 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/LogPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/LogPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -56,6 +56,7 @@ public function data() */ public function summary() { + /** @var \DebugKit\Log\Engine\DebugKitLog|null $logger */ $logger = Log::engine('debug_kit_log_panel'); if (!$logger) { return '0'; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/MailPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/MailPanel.php index 0d5740624..6bffeba36 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/MailPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/MailPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/PackagesPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/PackagesPanel.php index f5af7950f..fc7957746 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/PackagesPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/PackagesPanel.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since DebugKit 3.5.2 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/PanelRegistry.php b/app/vendor/cakephp/debug_kit/src/Panel/PanelRegistry.php index cc6871b15..f79bfd2d7 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/PanelRegistry.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/PanelRegistry.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -63,7 +63,7 @@ protected function _resolveClassName(string $class): ?string */ protected function _throwMissingClassError(string $class, ?string $plugin): void { - throw new \RuntimeException(__d('debug_kit', "Unable to find ''{0}'' panel.", $class)); + throw new \RuntimeException(sprintf("Unable to find '%s' panel.", $class)); } /** diff --git a/app/vendor/cakephp/debug_kit/src/Panel/RequestPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/RequestPanel.php index 4cc705aea..3c1618f26 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/RequestPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/RequestPanel.php @@ -2,20 +2,21 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; use Cake\Event\EventInterface; use DebugKit\DebugPanel; +use Exception; /** * Provides debug information on the Current request params. @@ -33,8 +34,19 @@ public function shutdown(EventInterface $event) /** @var \Cake\Controller\Controller $controller */ $controller = $event->getSubject(); $request = $controller->getRequest(); + + $attributes = []; + foreach ($request->getAttributes() as $attr => $value) { + try { + serialize($value); + } catch (Exception $e) { + $value = "Could not serialize `{$attr}`. It failed with {$e->getMessage()}"; + } + $attributes[$attr] = $value; + } + $this->_data = [ - 'attributes' => $request->getAttributes(), + 'attributes' => $attributes, 'query' => $request->getQueryParams(), 'data' => $request->getData(), 'cookie' => $request->getCookieParams(), diff --git a/app/vendor/cakephp/debug_kit/src/Panel/RoutesPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/RoutesPanel.php index 96db53918..5ff31e3e8 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/RoutesPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/RoutesPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/SessionPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/SessionPanel.php index 217887eab..6b4fe3fe7 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/SessionPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/SessionPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -30,7 +30,7 @@ class SessionPanel extends DebugPanel */ public function shutdown(EventInterface $event) { - /** @var \Cake\Http\ServerRequest $request */ + /** @var \Cake\Http\ServerRequest|null $request */ $request = $event->getSubject()->getRequest(); if ($request) { $this->_data = ['content' => $request->getSession()->read()]; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php index 1e38c6dbd..7c20796ce 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/SqlLogPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/TimerPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/TimerPanel.php index 3523f56cb..85c8c0f32 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/TimerPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/TimerPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; diff --git a/app/vendor/cakephp/debug_kit/src/Panel/VariablesPanel.php b/app/vendor/cakephp/debug_kit/src/Panel/VariablesPanel.php index 1fdf04e02..df184ae72 100644 --- a/app/vendor/cakephp/debug_kit/src/Panel/VariablesPanel.php +++ b/app/vendor/cakephp/debug_kit/src/Panel/VariablesPanel.php @@ -2,15 +2,15 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\Panel; @@ -66,9 +66,8 @@ protected function _walkDebugInfo(callable $walker, $item) try { $info = $item->__debugInfo(); } catch (\Exception $exception) { - return __d( - 'debug_kit', - 'Could not retrieve debug info - {0}. Error: {1} in {2}, line {3}', + return sprintf( + 'Could not retrieve debug info - %s. Error: %s in %s, line %d', get_class($item), $exception->getMessage(), $exception->getFile(), diff --git a/app/vendor/cakephp/debug_kit/src/Plugin.php b/app/vendor/cakephp/debug_kit/src/Plugin.php index f9ff8cba7..03b4b9ea1 100644 --- a/app/vendor/cakephp/debug_kit/src/Plugin.php +++ b/app/vendor/cakephp/debug_kit/src/Plugin.php @@ -19,6 +19,8 @@ use Cake\Core\BasePlugin; use Cake\Core\Configure; use Cake\Core\PluginApplicationInterface; +use Cake\Error\PhpError; +use Cake\Event\EventInterface; use Cake\Event\EventManager; use Cake\Http\MiddlewareQueue; use DebugKit\Command\BenchmarkCommand; @@ -31,7 +33,7 @@ class Plugin extends BasePlugin { /** - * @var \DebugKit\ToolbarService + * @var \DebugKit\ToolbarService|null */ protected $service; @@ -45,12 +47,11 @@ public function bootstrap(PluginApplicationInterface $app): void { $service = new ToolbarService(EventManager::instance(), (array)Configure::read('DebugKit')); - if (!$service->isEnabled() || php_sapi_name() === 'cli' || php_sapi_name() === 'phpdbg') { + if (!$service->isEnabled()) { return; } $this->service = $service; - $this->setDeprecationHandler($service); // will load `config/bootstrap.php`. @@ -65,6 +66,7 @@ public function bootstrap(PluginApplicationInterface $app): void */ public function middleware(MiddlewareQueue $middlewareQueue): MiddlewareQueue { + // Only insert middleware if Toolbar Service is available (not in phpunit run) if ($this->service) { $middlewareQueue->insertAt(0, new DebugKitMiddleware($this->service)); } @@ -92,40 +94,30 @@ public function console(CommandCollection $commands): CommandCollection public function setDeprecationHandler($service) { if (!empty($service->getConfig('panels')['DebugKit.Deprecations'])) { - $previousHandler = set_error_handler( - function ($code, $message, $file, $line, $context = null) use (&$previousHandler) { - if ($code == E_USER_DEPRECATED || $code == E_DEPRECATED) { - // In PHP 8.0+ the $context variable has been removed from the set_error_handler callback - // Therefore we need to fetch the correct file and line string ourselves - if (PHP_VERSION_ID >= 80000) { - $trace = debug_backtrace(); - foreach ($trace as $idx => $traceEntry) { - if ($traceEntry['function'] !== 'deprecationWarning') { - continue; - } - $offset = 1; - // ['args'][1] refers to index of $stackFrame argument in deprecationWarning() - if (isset($traceEntry['args'][1])) { - $offset = $traceEntry['args'][1]; - } - $file = $trace[$idx + $offset]['file']; - $line = $trace[$idx + $offset]['line']; - break; - } - } - DeprecationsPanel::addDeprecatedError(compact('code', 'message', 'file', 'line', 'context')); - - return; - } - if ($previousHandler) { - $context['_trace_frame_offset'] = 1; - - return $previousHandler($code, $message, $file, $line, $context); - } + EventManager::instance()->on('Error.beforeRender', function (EventInterface $event, PhpError $error) { + $code = $error->getCode(); + if ($code !== E_USER_DEPRECATED && $code !== E_DEPRECATED) { + return; + } + $file = $error->getFile(); + $line = $error->getLine(); - return false; + // Extract the line/file from the message as deprecationWarning + // will calculate the application frame when generating the message. + preg_match('/\\n([^\n,]+?), line: (\d+)\\n/', $error->getMessage(), $matches); + if ($matches) { + $file = $matches[1]; + $line = $matches[2]; } - ); + + DeprecationsPanel::addDeprecatedError([ + 'code' => $code, + 'message' => $error->getMessage(), + 'file' => $file, + 'line' => $line, + ]); + $event->stopPropagation(); + }); } } } diff --git a/app/vendor/cakephp/debug_kit/src/ToolbarService.php b/app/vendor/cakephp/debug_kit/src/ToolbarService.php index e7ba153a4..8dac83c4b 100644 --- a/app/vendor/cakephp/debug_kit/src/ToolbarService.php +++ b/app/vendor/cakephp/debug_kit/src/ToolbarService.php @@ -2,14 +2,14 @@ declare(strict_types=1); /** - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit; @@ -100,9 +100,14 @@ public function registry() */ public function isEnabled() { - $enabled = (bool)Configure::read('debug'); + if (isset($GLOBALS['__PHPUNIT_BOOTSTRAP'])) { + return false; + } + $enabled = (bool)Configure::read('debug') + && !$this->isSuspiciouslyProduction() + && php_sapi_name() !== 'phpdbg'; - if ($enabled && !$this->isSuspiciouslyProduction()) { + if ($enabled) { return true; } $force = $this->getConfig('forceEnable'); @@ -140,9 +145,8 @@ protected function isSuspiciouslyProduction() $isIp = filter_var($host, FILTER_VALIDATE_IP) !== false; if ($isIp) { $flags = FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE; - $isPublicIp = filter_var($host, FILTER_VALIDATE_IP, $flags) !== false; - return $isPublicIp; + return filter_var($host, FILTER_VALIDATE_IP, $flags) !== false; } // So it's not an IP address. It must be a domain name. @@ -311,7 +315,7 @@ public function saveData(ServerRequest $request, ResponseInterface $response) */ public function getToolbarUrl() { - $url = 'js/toolbar.js'; + $url = 'js/inject-iframe.js'; $filePaths = [ str_replace('/', DIRECTORY_SEPARATOR, WWW_ROOT . 'debug_kit/' . $url), str_replace('/', DIRECTORY_SEPARATOR, CorePlugin::path('DebugKit') . 'webroot/' . $url), @@ -356,7 +360,7 @@ public function injectScripts($row, ResponseInterface $response) $url = Router::url('/', true); $script = sprintf( - '', + '', $row->id, $url, Router::url($this->getToolbarUrl()) diff --git a/app/vendor/cakephp/debug_kit/src/View/AjaxView.php b/app/vendor/cakephp/debug_kit/src/View/AjaxView.php index 911a0b6f2..c2844efdc 100644 --- a/app/vendor/cakephp/debug_kit/src/View/AjaxView.php +++ b/app/vendor/cakephp/debug_kit/src/View/AjaxView.php @@ -2,17 +2,17 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * For full copyright and license information, please see the LICENSE.txt * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.2.8 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\View; diff --git a/app/vendor/cakephp/debug_kit/src/View/Helper/CredentialsHelper.php b/app/vendor/cakephp/debug_kit/src/View/Helper/CredentialsHelper.php index 253fabd85..86b017cc9 100644 --- a/app/vendor/cakephp/debug_kit/src/View/Helper/CredentialsHelper.php +++ b/app/vendor/cakephp/debug_kit/src/View/Helper/CredentialsHelper.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 3.3.7 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\View\Helper; @@ -39,7 +39,7 @@ class CredentialsHelper extends Helper * Replace credentials in url's by ***** * Example mysql://username:password@localhost/my_db -> mysql://******@localhost/my_db * - * @param string $in variable to filter + * @param mixed $in variable to filter * @return string */ public function filter($in) diff --git a/app/vendor/cakephp/debug_kit/src/View/Helper/SimpleGraphHelper.php b/app/vendor/cakephp/debug_kit/src/View/Helper/SimpleGraphHelper.php index 340ad1cda..3a06bd005 100644 --- a/app/vendor/cakephp/debug_kit/src/View/Helper/SimpleGraphHelper.php +++ b/app/vendor/cakephp/debug_kit/src/View/Helper/SimpleGraphHelper.php @@ -2,16 +2,16 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 1.0.0 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\View\Helper; @@ -70,10 +70,10 @@ public function bar($value, $offset, $options = []) } return sprintf( - '
', + '
', "width: {$width}px", "margin-left: {$graphOffset}px; width: {$graphValue}px", - __d('debug_kit', 'Starting {0}ms into the request, taking {1}ms', $offset, $value) + "Starting {$offset}ms into the request, taking {$value}ms" ); } } diff --git a/app/vendor/cakephp/debug_kit/src/View/Helper/ToolbarHelper.php b/app/vendor/cakephp/debug_kit/src/View/Helper/ToolbarHelper.php index d59a8e12e..0574ec143 100644 --- a/app/vendor/cakephp/debug_kit/src/View/Helper/ToolbarHelper.php +++ b/app/vendor/cakephp/debug_kit/src/View/Helper/ToolbarHelper.php @@ -2,28 +2,25 @@ declare(strict_types=1); /** - * CakePHP(tm) : Rapid Development Framework (http://cakephp.org) - * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) + * CakePHP(tm) : Rapid Development Framework (https://cakephp.org) + * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) * * Licensed under The MIT License * Redistributions of files must retain the above copyright notice. * - * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org) - * @link http://cakephp.org CakePHP(tm) Project + * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org) + * @link https://cakephp.org CakePHP(tm) Project * @since 0.1 - * @license http://www.opensource.org/licenses/mit-license.php MIT License + * @license https://www.opensource.org/licenses/mit-license.php MIT License */ namespace DebugKit\View\Helper; -use ArrayAccess; use Cake\Error\Debug\ArrayItemNode; use Cake\Error\Debug\ArrayNode; use Cake\Error\Debug\HtmlFormatter; use Cake\Error\Debug\ScalarNode; use Cake\Error\Debugger; use Cake\View\Helper; -use Closure; -use Iterator; /** * Provides Base methods for content specific debug toolbar helpers. @@ -119,101 +116,4 @@ public function dump($value) '
', ]); } - - /** - * Recursively goes through an array and makes neat HTML out of it. - * - * @param mixed $values Array to make pretty. - * @param int $openDepth Depth to add open class - * @param int $currentDepth current depth. - * @param bool $doubleEncode Whether or not to double encode. - * @param \SplObjectStorage $currentAncestors Object references found down - * the path. - * @return string - * @deprecated 4.4.0 Use ToolbarHelper::dump() instead. - */ - public function makeNeatArray( - $values, - $openDepth = 0, - $currentDepth = 0, - $doubleEncode = false, - ?\SplObjectStorage $currentAncestors = null - ) { - if ($currentAncestors === null) { - $ancestors = new \SplObjectStorage(); - } elseif (is_object($values)) { - $ancestors = new \SplObjectStorage(); - $ancestors->addAll($currentAncestors); - $ancestors->attach($values); - } else { - $ancestors = $currentAncestors; - } - $className = "neat-array depth-$currentDepth"; - if ($openDepth > $currentDepth) { - $className .= ' expanded'; - } - $nextDepth = $currentDepth + 1; - $out = "
    "; - if (!is_array($values)) { - if (is_bool($values)) { - $values = [$values]; - } - if ($values === null) { - $values = [null]; - } - if (is_object($values) && method_exists($values, 'toArray')) { - $values = $values->toArray(); - } - } - if (empty($values)) { - $values[] = '(empty)'; - } - if ($this->sort && is_array($values) && $currentDepth === 0) { - ksort($values); - } - foreach ($values as $key => $value) { - $out .= '
  • ' . h($key, $doubleEncode) . ' '; - if (is_array($value) && count($value) > 0) { - $out .= '(array)'; - } elseif (is_object($value)) { - $out .= '(' . (get_class($value) ?: 'object') . ')'; - } - if ($value === null) { - $value = '(null)'; - } - if ($value === false) { - $value = '(false)'; - } - if ($value === true) { - $value = '(true)'; - } - if (empty($value) && $value != 0) { - $value = '(empty)'; - } - if ($value instanceof Closure) { - $value = 'function'; - } - - if (is_object($value) && $ancestors->contains($value)) { - $value = ' - recursion'; - } - - if ( - ( - $value instanceof ArrayAccess || - $value instanceof Iterator || - is_array($value) || - is_object($value) - ) && !empty($value) - ) { - $out .= $this->makeNeatArray($value, $openDepth, $nextDepth, $doubleEncode, $ancestors); - } else { - $out .= h($value, $doubleEncode); - } - $out .= '
  • '; - } - $out .= '
'; - - return $out; - } } diff --git a/app/vendor/cakephp/debug_kit/templates/Dashboard/index.php b/app/vendor/cakephp/debug_kit/templates/Dashboard/index.php index ee3566fd5..d7468e1f2 100644 --- a/app/vendor/cakephp/debug_kit/templates/Dashboard/index.php +++ b/app/vendor/cakephp/debug_kit/templates/Dashboard/index.php @@ -3,18 +3,18 @@ * @var \App\View\AppView $this */ ?> -

+

Debug Kit Dashboard

-

+

Database

    -
  • :
  • +
  • Driver:
  • -
  • : Number->format($connection['rows']) ?>
  • +
  • Requests: Number->format($connection['rows']) ?>
Form->postLink( - __d('debug_kit', 'Reset database'), + 'Reset database', ['_method' => 'POST', 'action' => 'reset'], ['confirm' => 'Are you sure?'] ); ?> @@ -22,5 +22,5 @@

Actions

    -
  • Html->link(__d('debug_kit', 'Mail Preview'), ['controller' => 'MailPreview']); ?>
  • +
  • Html->link('Mail Preview', ['controller' => 'MailPreview']); ?>
diff --git a/app/vendor/cakephp/debug_kit/templates/MailPreview/email.php b/app/vendor/cakephp/debug_kit/templates/MailPreview/email.php index 622089681..2529d93e1 100644 --- a/app/vendor/cakephp/debug_kit/templates/MailPreview/email.php +++ b/app/vendor/cakephp/debug_kit/templates/MailPreview/email.php @@ -1,4 +1,4 @@ -'.$this->dumpHeader; } - /** - * {@inheritdoc} - */ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut) { if ('' === $str && isset($cursor->attr['img-data'], $cursor->attr['content-type'])) { @@ -800,9 +788,6 @@ public function dumpString(Cursor $cursor, string $str, bool $bin, int $cut) } } - /** - * {@inheritdoc} - */ public function enterHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild) { if (Cursor::HASH_OBJECT === $type) { @@ -831,9 +816,6 @@ public function enterHash(Cursor $cursor, int $type, string|int|null $class, boo } } - /** - * {@inheritdoc} - */ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, bool $hasChild, int $cut) { $this->dumpEllipsis($cursor, $hasChild, $cut); @@ -843,9 +825,6 @@ public function leaveHash(Cursor $cursor, int $type, string|int|null $class, boo parent::leaveHash($cursor, $type, $class, $hasChild, 0); } - /** - * {@inheritdoc} - */ protected function style(string $style, string $value, array $attr = []): string { if ('' === $value) { @@ -864,7 +843,7 @@ protected function style(string $style, string $value, array $attr = []): string } if ('const' === $style && isset($attr['value'])) { - $style .= sprintf(' title="%s"', esc(is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); + $style .= sprintf(' title="%s"', esc(\is_scalar($attr['value']) ? $attr['value'] : json_encode($attr['value']))); } elseif ('public' === $style) { $style .= sprintf(' title="%s"', empty($attr['dynamic']) ? 'Public property' : 'Runtime added dynamic property'); } elseif ('str' === $style && 1 < $attr['length']) { @@ -938,9 +917,6 @@ protected function style(string $style, string $value, array $attr = []): string return $v; } - /** - * {@inheritdoc} - */ protected function dumpLine(int $depth, bool $endOfValue = false) { if (-1 === $this->lastDepth) { @@ -960,7 +936,7 @@ protected function dumpLine(int $depth, bool $endOfValue = false) } $this->lastDepth = $depth; - $this->line = mb_encode_numericentity($this->line, [0x80, 0xFFFF, 0, 0xFFFF], 'UTF-8'); + $this->line = mb_encode_numericentity($this->line, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'); if (-1 === $depth) { AbstractDumper::dumpLine(0); diff --git a/app/vendor/symfony/var-dumper/Dumper/ServerDumper.php b/app/vendor/symfony/var-dumper/Dumper/ServerDumper.php index 94795bf6d..f2c891b6a 100644 --- a/app/vendor/symfony/var-dumper/Dumper/ServerDumper.php +++ b/app/vendor/symfony/var-dumper/Dumper/ServerDumper.php @@ -22,8 +22,8 @@ */ class ServerDumper implements DataDumperInterface { - private $connection; - private $wrappedDumper; + private Connection $connection; + private ?DataDumperInterface $wrappedDumper; /** * @param string $host The server host @@ -41,9 +41,6 @@ public function getContextProviders(): array return $this->connection->getContextProviders(); } - /** - * {@inheritdoc} - */ public function dump(Data $data) { if (!$this->connection->write($data) && $this->wrappedDumper) { diff --git a/app/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php b/app/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php index 122f0d358..fd8eca9f1 100644 --- a/app/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php +++ b/app/vendor/symfony/var-dumper/Exception/ThrowingCasterException.php @@ -21,6 +21,6 @@ class ThrowingCasterException extends \Exception */ public function __construct(\Throwable $prev) { - parent::__construct('Unexpected '.\get_class($prev).' thrown from a caster: '.$prev->getMessage(), 0, $prev); + parent::__construct('Unexpected '.$prev::class.' thrown from a caster: '.$prev->getMessage(), 0, $prev); } } diff --git a/app/vendor/symfony/var-dumper/LICENSE b/app/vendor/symfony/var-dumper/LICENSE index a843ec124..72412a62b 100644 --- a/app/vendor/symfony/var-dumper/LICENSE +++ b/app/vendor/symfony/var-dumper/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2014-2022 Fabien Potencier +Copyright (c) 2014-2023 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 diff --git a/app/vendor/symfony/var-dumper/Resources/bin/var-dump-server b/app/vendor/symfony/var-dumper/Resources/bin/var-dump-server index 98c813a06..f398fcef7 100755 --- a/app/vendor/symfony/var-dumper/Resources/bin/var-dump-server +++ b/app/vendor/symfony/var-dumper/Resources/bin/var-dump-server @@ -10,6 +10,10 @@ * file that was distributed with this source code. */ +if ('cli' !== PHP_SAPI) { + throw new Exception('This script must be run from the command line.'); +} + /** * Starts a dump server to collect and output dumps on a single place with multiple formats support. * diff --git a/app/vendor/symfony/var-dumper/Server/DumpServer.php b/app/vendor/symfony/var-dumper/Server/DumpServer.php index 6a43c1204..8df05a150 100644 --- a/app/vendor/symfony/var-dumper/Server/DumpServer.php +++ b/app/vendor/symfony/var-dumper/Server/DumpServer.php @@ -25,7 +25,7 @@ class DumpServer { private string $host; - private $logger; + private ?LoggerInterface $logger; /** * @var resource|null @@ -56,25 +56,19 @@ public function listen(callable $callback): void } foreach ($this->getMessages() as $clientId => $message) { - if ($this->logger) { - $this->logger->info('Received a payload from client {clientId}', ['clientId' => $clientId]); - } + $this->logger?->info('Received a payload from client {clientId}', ['clientId' => $clientId]); $payload = @unserialize(base64_decode($message), ['allowed_classes' => [Data::class, Stub::class]]); // Impossible to decode the message, give up. if (false === $payload) { - if ($this->logger) { - $this->logger->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]); - } + $this->logger?->warning('Unable to decode a message from {clientId} client.', ['clientId' => $clientId]); continue; } if (!\is_array($payload) || \count($payload) < 2 || !$payload[0] instanceof Data || !\is_array($payload[1])) { - if ($this->logger) { - $this->logger->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]); - } + $this->logger?->warning('Invalid payload from {clientId} client. Expected an array of two elements (Data $data, array $context)', ['clientId' => $clientId]); continue; } diff --git a/app/vendor/symfony/var-dumper/VarDumper.php b/app/vendor/symfony/var-dumper/VarDumper.php index dfef9f410..840bfd649 100644 --- a/app/vendor/symfony/var-dumper/VarDumper.php +++ b/app/vendor/symfony/var-dumper/VarDumper.php @@ -48,6 +48,9 @@ public static function dump(mixed $var) public static function setHandler(callable $callable = null): ?callable { + if (1 > \func_num_args()) { + trigger_deprecation('symfony/var-dumper', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); + } $prevHandler = self::$handler; // Prevent replacing the handler with expected format as soon as the env var was set: @@ -96,7 +99,7 @@ private static function getDefaultContextProviders(): array { $contextProviders = []; - if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && (class_exists(Request::class))) { + if (!\in_array(\PHP_SAPI, ['cli', 'phpdbg'], true) && class_exists(Request::class)) { $requestStack = new RequestStack(); $requestStack->push(Request::createFromGlobals()); $contextProviders['request'] = new RequestContextProvider($requestStack); diff --git a/app/vendor/symfony/var-dumper/composer.json b/app/vendor/symfony/var-dumper/composer.json index db04f5884..71ec64c0d 100644 --- a/app/vendor/symfony/var-dumper/composer.json +++ b/app/vendor/symfony/var-dumper/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { diff --git a/app/vendor/twig/markdown-extra/LICENSE b/app/vendor/twig/markdown-extra/LICENSE index 9c907a46a..f37c76b59 100644 --- a/app/vendor/twig/markdown-extra/LICENSE +++ b/app/vendor/twig/markdown-extra/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2019-2022 Fabien Potencier +Copyright (c) 2019-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 diff --git a/app/vendor/twig/markdown-extra/composer.json b/app/vendor/twig/markdown-extra/composer.json index 56718f517..f26143525 100644 --- a/app/vendor/twig/markdown-extra/composer.json +++ b/app/vendor/twig/markdown-extra/composer.json @@ -23,7 +23,7 @@ "erusev/parsedown": "^1.7", "league/commonmark": "^1.0|^2.0", "league/html-to-markdown": "^4.8|^5.0", - "michelf/php-markdown": "^1.8" + "michelf/php-markdown": "^1.8|^2.0" }, "autoload": { "psr-4" : { "Twig\\Extra\\Markdown\\" : "" }, @@ -33,7 +33,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.5-dev" } } } diff --git a/app/vendor/twig/twig/.editorconfig b/app/vendor/twig/twig/.editorconfig deleted file mode 100644 index 270f1d1b7..000000000 --- a/app/vendor/twig/twig/.editorconfig +++ /dev/null @@ -1,18 +0,0 @@ -; top-most EditorConfig file -root = true - -; Unix-style newlines -[*] -end_of_line = LF - -[*.php] -indent_style = space -indent_size = 4 - -[*.test] -indent_style = space -indent_size = 4 - -[*.rst] -indent_style = space -indent_size = 4 diff --git a/app/vendor/twig/twig/.gitattributes b/app/vendor/twig/twig/.gitattributes deleted file mode 100644 index 1ce832b52..000000000 --- a/app/vendor/twig/twig/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -/doc/** export-ignore -/extra/** export-ignore -/tests export-ignore -/phpunit.xml.dist export-ignore diff --git a/app/vendor/twig/twig/.github/workflows/ci.yml b/app/vendor/twig/twig/.github/workflows/ci.yml deleted file mode 100644 index 775d8f782..000000000 --- a/app/vendor/twig/twig/.github/workflows/ci.yml +++ /dev/null @@ -1,146 +0,0 @@ -name: "CI" - -on: - pull_request: - push: - branches: - - '3.x' - -env: - SYMFONY_PHPUNIT_DISABLE_RESULT_CACHE: 1 - -jobs: - tests: - name: "PHP ${{ matrix.php-version }}" - - runs-on: 'ubuntu-latest' - - continue-on-error: ${{ matrix.experimental }} - - strategy: - matrix: - php-version: - - '7.2.5' - - '7.3' - - '7.4' - - '8.0' - - '8.1' - experimental: [false] - - steps: - - name: "Checkout code" - uses: actions/checkout@v2 - - - name: "Install PHP with extensions" - uses: shivammathur/setup-php@v2 - with: - coverage: "none" - php-version: ${{ matrix.php-version }} - ini-values: memory_limit=-1 - - - name: "Add PHPUnit matcher" - run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - - run: composer install - - - name: "Install PHPUnit" - run: vendor/bin/simple-phpunit install - - - name: "PHPUnit version" - run: vendor/bin/simple-phpunit --version - - - name: "Run tests" - run: vendor/bin/simple-phpunit - - extension-tests: - needs: - - 'tests' - - name: "${{ matrix.extension }} with PHP ${{ matrix.php-version }}" - - runs-on: 'ubuntu-latest' - - continue-on-error: true - - strategy: - matrix: - php-version: - - '7.2.5' - - '7.3' - - '7.4' - - '8.0' - - '8.1' - extension: - - 'extra/cache-extra' - - 'extra/cssinliner-extra' - - 'extra/html-extra' - - 'extra/inky-extra' - - 'extra/intl-extra' - - 'extra/markdown-extra' - - 'extra/string-extra' - - 'extra/twig-extra-bundle' - experimental: [false] - - steps: - - name: "Checkout code" - uses: actions/checkout@v2 - - - name: "Install PHP with extensions" - uses: shivammathur/setup-php@v2 - with: - coverage: "none" - php-version: ${{ matrix.php-version }} - ini-values: memory_limit=-1 - - - name: "Add PHPUnit matcher" - run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json" - - - run: composer install - - - name: "Install PHPUnit" - run: vendor/bin/simple-phpunit install - - - name: "PHPUnit version" - run: vendor/bin/simple-phpunit --version - - - name: "Composer install" - working-directory: ${{ matrix.extension}} - run: composer install - - - name: "Run tests" - working-directory: ${{ matrix.extension}} - run: ../../vendor/bin/simple-phpunit - -# -# Drupal does not support Twig 3 now! -# -# integration-tests: -# needs: -# - 'tests' -# -# name: "Integration tests with PHP ${{ matrix.php-version }}" -# -# runs-on: 'ubuntu-20.04' -# -# continue-on-error: true -# -# strategy: -# matrix: -# php-version: -# - '7.3' -# -# steps: -# - name: "Checkout code" -# uses: actions/checkout@v2 -# -# - name: "Install PHP with extensions" -# uses: shivammathur/setup-php@2 -# with: -# coverage: "none" -# extensions: "gd, pdo_sqlite" -# php-version: ${{ matrix.php-version }} -# ini-values: memory_limit=-1 -# tools: composer:v2 -# -# - run: bash ./tests/drupal_test.sh -# shell: "bash" diff --git a/app/vendor/twig/twig/.github/workflows/documentation.yml b/app/vendor/twig/twig/.github/workflows/documentation.yml deleted file mode 100644 index 0b3ca7159..000000000 --- a/app/vendor/twig/twig/.github/workflows/documentation.yml +++ /dev/null @@ -1,60 +0,0 @@ -name: "Documentation" - -on: - pull_request: - push: - branches: - - '3.x' - -jobs: - build: - name: "Build" - - runs-on: ubuntu-latest - - steps: - - name: "Checkout code" - uses: actions/checkout@v2 - - - name: "Set up Python 3.7" - uses: actions/setup-python@v1 - with: - python-version: '3.7' # Semantic version range syntax or exact version of a Python version - - - name: "Display Python version" - run: python -c "import sys; print(sys.version)" - - - name: "Install Sphinx dependencies" - run: sudo apt-get install python-dev build-essential - - - name: "Cache pip" - uses: actions/cache@v2 - with: - path: ~/.cache/pip - key: ${{ runner.os }}-pip-${{ hashFiles('_build/.requirements.txt') }} - restore-keys: | - ${{ runner.os }}-pip- - - - name: "Install Sphinx + requirements via pip" - working-directory: "doc" - run: pip install -r _build/.requirements.txt - - - name: "Build documentation" - working-directory: "doc" - run: make -C _build SPHINXOPTS="-nqW -j auto" html - - doctor-rst: - name: "DOCtor-RST" - - runs-on: ubuntu-latest - - steps: - - name: "Checkout code" - uses: actions/checkout@v2 - - - name: "Run DOCtor-RST" - uses: docker://oskarstark/doctor-rst - with: - args: --short - env: - DOCS_DIR: 'doc/' diff --git a/app/vendor/twig/twig/.gitignore b/app/vendor/twig/twig/.gitignore deleted file mode 100644 index cd52aeace..000000000 --- a/app/vendor/twig/twig/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -/composer.lock -/phpunit.xml -/vendor -.phpunit.result.cache diff --git a/app/vendor/twig/twig/.php-cs-fixer.dist.php b/app/vendor/twig/twig/.php-cs-fixer.dist.php deleted file mode 100644 index b07ac7fca..000000000 --- a/app/vendor/twig/twig/.php-cs-fixer.dist.php +++ /dev/null @@ -1,20 +0,0 @@ -setRules([ - '@Symfony' => true, - '@Symfony:risky' => true, - '@PHPUnit75Migration:risky' => true, - 'php_unit_dedicate_assert' => ['target' => '5.6'], - 'array_syntax' => ['syntax' => 'short'], - 'php_unit_fqcn_annotation' => true, - 'no_unreachable_default_argument_value' => false, - 'braces' => ['allow_single_line_closure' => true], - 'heredoc_to_nowdoc' => false, - 'ordered_imports' => true, - 'phpdoc_types_order' => ['null_adjustment' => 'always_last', 'sort_algorithm' => 'none'], - 'native_function_invocation' => ['include' => ['@compiler_optimized'], 'scope' => 'all'], - ]) - ->setRiskyAllowed(true) - ->setFinder((new PhpCsFixer\Finder())->in(__DIR__)) -; diff --git a/app/vendor/twig/twig/CHANGELOG b/app/vendor/twig/twig/CHANGELOG index a74f6de01..fd2c9c62e 100644 --- a/app/vendor/twig/twig/CHANGELOG +++ b/app/vendor/twig/twig/CHANGELOG @@ -1,3 +1,34 @@ +# 3.5.1 (2023-02-08) + + * Arrow functions passed to the "reduce" filter now accept the current key as a third argument + * Restores the leniency of the matches twig comparison + * Fix error messages in sandboxed mode for "has some" and "has every" + +# 3.5.0 (2022-12-27) + + * Make Twig\ExpressionParser non-internal + * Add "has some" and "has every" operators + * Add Compile::reset() + * Throw a better runtime error when the "matches" regexp is not valid + * Add "twig *_names" intl functions + * Fix optimizing closures callbacks + * Add a better exception when getting an undefined constant via `constant` + * Fix `if` nodes when outside of a block and with an empty body + +# 3.4.3 (2022-09-28) + + * Fix a security issue on filesystem loader (possibility to load a template outside a configured directory) + +# 3.4.2 (2022-08-12) + + * Allow inherited magic method to still run with calling class + * Fix CallExpression::reflectCallable() throwing TypeError + * Fix typo in naming (currency_code) + +# 3.4.1 (2022-05-17) + +* Fix optimizing non-public named closures + # 3.4.0 (2022-05-22) * Add support for named closures diff --git a/app/vendor/twig/twig/LICENSE b/app/vendor/twig/twig/LICENSE index 8711927f6..fd8234e51 100644 --- a/app/vendor/twig/twig/LICENSE +++ b/app/vendor/twig/twig/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2009-2022 by the Twig Team. +Copyright (c) 2009-present by the Twig Team. All rights reserved. diff --git a/app/vendor/twig/twig/composer.json b/app/vendor/twig/twig/composer.json index 33e46405c..18d3135bb 100644 --- a/app/vendor/twig/twig/composer.json +++ b/app/vendor/twig/twig/composer.json @@ -44,7 +44,7 @@ }, "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } } } diff --git a/app/vendor/twig/twig/src/Compiler.php b/app/vendor/twig/twig/src/Compiler.php index 95e1f183b..eb652c61a 100644 --- a/app/vendor/twig/twig/src/Compiler.php +++ b/app/vendor/twig/twig/src/Compiler.php @@ -46,7 +46,7 @@ public function getSource(): string /** * @return $this */ - public function compile(Node $node, int $indentation = 0) + public function reset(int $indentation = 0) { $this->lastLine = null; $this->source = ''; @@ -57,6 +57,15 @@ public function compile(Node $node, int $indentation = 0) $this->indentation = $indentation; $this->varNameSalt = 0; + return $this; + } + + /** + * @return $this + */ + public function compile(Node $node, int $indentation = 0) + { + $this->reset($indentation); $node->compile($this); return $this; diff --git a/app/vendor/twig/twig/src/Environment.php b/app/vendor/twig/twig/src/Environment.php index 7c9c8952d..dd721b412 100644 --- a/app/vendor/twig/twig/src/Environment.php +++ b/app/vendor/twig/twig/src/Environment.php @@ -25,6 +25,8 @@ use Twig\Loader\ArrayLoader; use Twig\Loader\ChainLoader; use Twig\Loader\LoaderInterface; +use Twig\Node\Expression\Binary\AbstractBinary; +use Twig\Node\Expression\Unary\AbstractUnary; use Twig\Node\ModuleNode; use Twig\Node\Node; use Twig\NodeVisitor\NodeVisitorInterface; @@ -38,11 +40,11 @@ */ class Environment { - public const VERSION = '3.4.0'; - public const VERSION_ID = 30400; + public const VERSION = '3.5.1'; + public const VERSION_ID = 30501; public const MAJOR_VERSION = 3; - public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 0; + public const MINOR_VERSION = 5; + public const RELEASE_VERSION = 1; public const EXTRA_VERSION = ''; private $charset; @@ -53,6 +55,7 @@ class Environment private $lexer; private $parser; private $compiler; + /** @var array */ private $globals = []; private $resolvedGlobals; private $loadedTemplates; @@ -775,6 +778,8 @@ public function addGlobal(string $name, $value) /** * @internal + * + * @return array */ public function getGlobals(): array { @@ -804,6 +809,8 @@ public function mergeGlobals(array $context): array /** * @internal + * + * @return array}> */ public function getUnaryOperators(): array { @@ -812,6 +819,8 @@ public function getUnaryOperators(): array /** * @internal + * + * @return array, associativity: ExpressionParser::OPERATOR_*}> */ public function getBinaryOperators(): array { diff --git a/app/vendor/twig/twig/src/ExpressionParser.php b/app/vendor/twig/twig/src/ExpressionParser.php index 70b6eb05c..2048c3c54 100644 --- a/app/vendor/twig/twig/src/ExpressionParser.php +++ b/app/vendor/twig/twig/src/ExpressionParser.php @@ -17,6 +17,7 @@ use Twig\Node\Expression\ArrayExpression; use Twig\Node\Expression\ArrowFunctionExpression; use Twig\Node\Expression\AssignNameExpression; +use Twig\Node\Expression\Binary\AbstractBinary; use Twig\Node\Expression\Binary\ConcatBinary; use Twig\Node\Expression\BlockReferenceExpression; use Twig\Node\Expression\ConditionalExpression; @@ -26,6 +27,7 @@ use Twig\Node\Expression\NameExpression; use Twig\Node\Expression\ParentExpression; use Twig\Node\Expression\TestExpression; +use Twig\Node\Expression\Unary\AbstractUnary; use Twig\Node\Expression\Unary\NegUnary; use Twig\Node\Expression\Unary\NotUnary; use Twig\Node\Expression\Unary\PosUnary; @@ -40,8 +42,6 @@ * @see https://en.wikipedia.org/wiki/Operator-precedence_parser * * @author Fabien Potencier - * - * @internal */ class ExpressionParser { @@ -50,7 +50,9 @@ class ExpressionParser private $parser; private $env; + /** @var array}> */ private $unaryOperators; + /** @var array, associativity: self::OPERATOR_*}> */ private $binaryOperators; public function __construct(Parser $parser, Environment $env) @@ -80,7 +82,7 @@ public function parseExpression($precedence = 0, $allowArrow = false) } elseif (isset($op['callable'])) { $expr = $op['callable']($this->parser, $expr); } else { - $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence']); + $expr1 = $this->parseExpression(self::OPERATOR_LEFT === $op['associativity'] ? $op['precedence'] + 1 : $op['precedence'], true); $class = $op['class']; $expr = new $class($expr, $expr1, $token->getLine()); } diff --git a/app/vendor/twig/twig/src/Extension/CoreExtension.php b/app/vendor/twig/twig/src/Extension/CoreExtension.php index b77985859..f99adda45 100644 --- a/app/vendor/twig/twig/src/Extension/CoreExtension.php +++ b/app/vendor/twig/twig/src/Extension/CoreExtension.php @@ -23,6 +23,8 @@ use Twig\Node\Expression\Binary\FloorDivBinary; use Twig\Node\Expression\Binary\GreaterBinary; use Twig\Node\Expression\Binary\GreaterEqualBinary; +use Twig\Node\Expression\Binary\HasEveryBinary; +use Twig\Node\Expression\Binary\HasSomeBinary; use Twig\Node\Expression\Binary\InBinary; use Twig\Node\Expression\Binary\LessBinary; use Twig\Node\Expression\Binary\LessEqualBinary; @@ -284,6 +286,8 @@ public function getOperators(): array 'matches' => ['precedence' => 20, 'class' => MatchesBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], 'starts with' => ['precedence' => 20, 'class' => StartsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], 'ends with' => ['precedence' => 20, 'class' => EndsWithBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'has some' => ['precedence' => 20, 'class' => HasSomeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], + 'has every' => ['precedence' => 20, 'class' => HasEveryBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], '..' => ['precedence' => 25, 'class' => RangeBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], '+' => ['precedence' => 30, 'class' => AddBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], '-' => ['precedence' => 30, 'class' => SubBinary::class, 'associativity' => ExpressionParser::OPERATOR_LEFT], @@ -1015,6 +1019,26 @@ function twig_compare($a, $b) return $a <=> $b; } +/** + * @param string $pattern + * @param string|null $subject + * + * @return int + * + * @throws RuntimeError When an invalid pattern is used + */ +function twig_matches(string $regexp, ?string $str) +{ + set_error_handler(function ($t, $m) use ($regexp) { + throw new RuntimeError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12)); + }); + try { + return preg_match($regexp, $str ?? ''); + } finally { + restore_error_handler(); + } +} + /** * Returns a trimmed string. * @@ -1366,6 +1390,10 @@ function twig_constant($constant, $object = null) $constant = \get_class($object).'::'.$constant; } + if (!\defined($constant)) { + throw new RuntimeError(sprintf('Constant "%s" is undefined.', $constant)); + } + return \constant($constant); } @@ -1675,15 +1703,42 @@ function twig_array_reduce(Environment $env, $array, $arrow, $initial = null) { twig_check_arrow_in_sandbox($env, $arrow, 'reduce', 'filter'); - if (!\is_array($array)) { - if (!$array instanceof \Traversable) { - throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array))); + if (!\is_array($array) && !$array instanceof \Traversable) { + throw new RuntimeError(sprintf('The "reduce" filter only works with arrays or "Traversable", got "%s" as first argument.', \gettype($array))); + } + + $accumulator = $initial; + foreach ($array as $key => $value) { + $accumulator = $arrow($accumulator, $value, $key); + } + + return $accumulator; +} + +function twig_array_some(Environment $env, $array, $arrow) +{ + twig_check_arrow_in_sandbox($env, $arrow, 'has some', 'operator'); + + foreach ($array as $k => $v) { + if ($arrow($v, $k)) { + return true; } + } - $array = iterator_to_array($array); + return false; +} + +function twig_array_every(Environment $env, $array, $arrow) +{ + twig_check_arrow_in_sandbox($env, $arrow, 'has every', 'operator'); + + foreach ($array as $k => $v) { + if (!$arrow($v, $k)) { + return false; + } } - return array_reduce($array, $arrow, $initial); + return true; } function twig_check_arrow_in_sandbox(Environment $env, $arrow, $thing, $type) diff --git a/app/vendor/twig/twig/src/Extension/ExtensionInterface.php b/app/vendor/twig/twig/src/Extension/ExtensionInterface.php index 75fa237e1..ab9c2c37c 100644 --- a/app/vendor/twig/twig/src/Extension/ExtensionInterface.php +++ b/app/vendor/twig/twig/src/Extension/ExtensionInterface.php @@ -11,6 +11,9 @@ namespace Twig\Extension; +use Twig\ExpressionParser; +use Twig\Node\Expression\Binary\AbstractBinary; +use Twig\Node\Expression\Unary\AbstractUnary; use Twig\NodeVisitor\NodeVisitorInterface; use Twig\TokenParser\TokenParserInterface; use Twig\TwigFilter; @@ -63,6 +66,11 @@ public function getFunctions(); * Returns a list of operators to add to the existing list. * * @return array First array of unary operators, second array of binary operators + * + * @psalm-return array{ + * array}>, + * array, associativity: ExpressionParser::OPERATOR_*}> + * } */ public function getOperators(); } diff --git a/app/vendor/twig/twig/src/Extension/GlobalsInterface.php b/app/vendor/twig/twig/src/Extension/GlobalsInterface.php index ec0c68292..6f1dfe8a7 100644 --- a/app/vendor/twig/twig/src/Extension/GlobalsInterface.php +++ b/app/vendor/twig/twig/src/Extension/GlobalsInterface.php @@ -21,5 +21,8 @@ */ interface GlobalsInterface { + /** + * @return array + */ public function getGlobals(): array; } diff --git a/app/vendor/twig/twig/src/ExtensionSet.php b/app/vendor/twig/twig/src/ExtensionSet.php index 36e5bbc59..d32200ceb 100644 --- a/app/vendor/twig/twig/src/ExtensionSet.php +++ b/app/vendor/twig/twig/src/ExtensionSet.php @@ -15,6 +15,8 @@ use Twig\Extension\ExtensionInterface; use Twig\Extension\GlobalsInterface; use Twig\Extension\StagingExtension; +use Twig\Node\Expression\Binary\AbstractBinary; +use Twig\Node\Expression\Unary\AbstractUnary; use Twig\NodeVisitor\NodeVisitorInterface; use Twig\TokenParser\TokenParserInterface; @@ -31,11 +33,17 @@ final class ExtensionSet private $staging; private $parsers; private $visitors; + /** @var array */ private $filters; + /** @var array */ private $tests; + /** @var array */ private $functions; + /** @var array}> */ private $unaryOperators; + /** @var array, associativity: ExpressionParser::OPERATOR_*}> */ private $binaryOperators; + /** @var array */ private $globals; private $functionCallbacks = []; private $filterCallbacks = []; @@ -305,6 +313,9 @@ public function registerUndefinedTokenParserCallback(callable $callable): void $this->parserCallbacks[] = $callable; } + /** + * @return array + */ public function getGlobals(): array { if (null !== $this->globals) { @@ -379,6 +390,9 @@ public function getTest(string $name): ?TwigTest return null; } + /** + * @return array}> + */ public function getUnaryOperators(): array { if (!$this->initialized) { @@ -388,6 +402,9 @@ public function getUnaryOperators(): array return $this->unaryOperators; } + /** + * @return array, associativity: ExpressionParser::OPERATOR_*}> + */ public function getBinaryOperators(): array { if (!$this->initialized) { diff --git a/app/vendor/twig/twig/src/Loader/FilesystemLoader.php b/app/vendor/twig/twig/src/Loader/FilesystemLoader.php index 859a898c5..62267a11c 100644 --- a/app/vendor/twig/twig/src/Loader/FilesystemLoader.php +++ b/app/vendor/twig/twig/src/Loader/FilesystemLoader.php @@ -183,9 +183,9 @@ protected function findTemplate(string $name, bool $throw = true) } try { - $this->validateName($name); - list($namespace, $shortname) = $this->parseName($name); + + $this->validateName($shortname); } catch (LoaderError $e) { if (!$throw) { return null; diff --git a/app/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php b/app/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php new file mode 100644 index 000000000..adfabd44c --- /dev/null +++ b/app/vendor/twig/twig/src/Node/Expression/Binary/HasEveryBinary.php @@ -0,0 +1,33 @@ +raw('twig_array_every($this->env, ') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw(''); + } +} diff --git a/app/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php b/app/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php new file mode 100644 index 000000000..270da3692 --- /dev/null +++ b/app/vendor/twig/twig/src/Node/Expression/Binary/HasSomeBinary.php @@ -0,0 +1,33 @@ +raw('twig_array_some($this->env, ') + ->subcompile($this->getNode('left')) + ->raw(', ') + ->subcompile($this->getNode('right')) + ->raw(')') + ; + } + + public function operator(Compiler $compiler): Compiler + { + return $compiler->raw(''); + } +} diff --git a/app/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php b/app/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php index bc97292cd..a8bce6f4e 100644 --- a/app/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php +++ b/app/vendor/twig/twig/src/Node/Expression/Binary/MatchesBinary.php @@ -18,7 +18,7 @@ class MatchesBinary extends AbstractBinary public function compile(Compiler $compiler): void { $compiler - ->raw('preg_match(') + ->raw('twig_matches(') ->subcompile($this->getNode('right')) ->raw(', ') ->subcompile($this->getNode('left')) diff --git a/app/vendor/twig/twig/src/Node/Expression/CallExpression.php b/app/vendor/twig/twig/src/Node/Expression/CallExpression.php index da72843ad..11a6b1abc 100644 --- a/app/vendor/twig/twig/src/Node/Expression/CallExpression.php +++ b/app/vendor/twig/twig/src/Node/Expression/CallExpression.php @@ -289,7 +289,13 @@ private function reflectCallable($callable) return $this->reflector = [$r, $callable, $r->class.'::'.$r->name]; } - $r = new \ReflectionFunction(\Closure::fromCallable($callable)); + $checkVisibility = $callable instanceof \Closure; + try { + $closure = \Closure::fromCallable($callable); + } catch (\TypeError $e) { + throw new \LogicException(sprintf('Callback for %s "%s" is not callable in the current scope.', $this->getAttribute('type'), $this->getAttribute('name')), 0, $e); + } + $r = new \ReflectionFunction($closure); if (false !== strpos($r->name, '{closure}')) { return $this->reflector = [$r, $callable, 'Closure']; @@ -298,13 +304,18 @@ private function reflectCallable($callable) if ($object = $r->getClosureThis()) { $callable = [$object, $r->name]; $callableName = (\function_exists('get_debug_type') ? get_debug_type($object) : \get_class($object)).'::'.$r->name; - } elseif ($class = $r->getClosureScopeClass()) { - $callable = [$class, $r->name]; - $callableName = $class.'::'.$r->name; + } elseif (\PHP_VERSION_ID >= 80111 && $class = $r->getClosureCalledClass()) { + $callableName = $class->name.'::'.$r->name; + } elseif (\PHP_VERSION_ID < 80111 && $class = $r->getClosureScopeClass()) { + $callableName = (\is_array($callable) ? $callable[0] : $class->name).'::'.$r->name; } else { $callable = $callableName = $r->name; } + if ($checkVisibility && \is_array($callable) && method_exists(...$callable) && !(new \ReflectionMethod(...$callable))->isPublic()) { + $callable = $r->getClosure(); + } + return $this->reflector = [$r, $callable, $callableName]; } } diff --git a/app/vendor/twig/twig/src/Node/IfNode.php b/app/vendor/twig/twig/src/Node/IfNode.php index 5fa20082a..569ab7950 100644 --- a/app/vendor/twig/twig/src/Node/IfNode.php +++ b/app/vendor/twig/twig/src/Node/IfNode.php @@ -50,8 +50,11 @@ public function compile(Compiler $compiler): void ->subcompile($this->getNode('tests')->getNode($i)) ->raw(") {\n") ->indent() - ->subcompile($this->getNode('tests')->getNode($i + 1)) ; + // The node might not exists if the content is empty + if ($this->getNode('tests')->hasNode($i + 1)) { + $compiler->subcompile($this->getNode('tests')->getNode($i + 1)); + } } if ($this->hasNode('else')) { diff --git a/app/vendor/webmozart/assert/.editorconfig b/app/vendor/webmozart/assert/.editorconfig deleted file mode 100644 index 384453bfb..000000000 --- a/app/vendor/webmozart/assert/.editorconfig +++ /dev/null @@ -1,12 +0,0 @@ -root = true - -[*] -charset=utf-8 -end_of_line=lf -trim_trailing_whitespace=true -insert_final_newline=true -indent_style=space -indent_size=4 - -[*.yml] -indent_size=2 diff --git a/app/vendor/webmozart/assert/.github/workflows/ci.yaml b/app/vendor/webmozart/assert/.github/workflows/ci.yaml deleted file mode 100644 index 636fc5ab5..000000000 --- a/app/vendor/webmozart/assert/.github/workflows/ci.yaml +++ /dev/null @@ -1,120 +0,0 @@ -# https://docs.github.com/en/actions - -name: "CI" - -on: - pull_request: ~ - push: - branches: - - "master" - -env: - COMPOSER_ROOT_VERSION: 1.99 - -jobs: - coding-standards: - name: "Coding Standards" - - runs-on: "ubuntu-latest" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2.3.4" - - - name: "Install PHP" - uses: "shivammathur/setup-php@2.9.0" - with: - coverage: "none" - extensions: "mbstring" - php-version: "7.4" - tools: "composer-normalize" - - - name: "Validate composer.json" - run: "composer validate --strict" - - - name: "Normalize composer.json" - run: "composer-normalize --dry-run" - - - name: "PHP-CS-Fixer" - uses: "docker://oskarstark/php-cs-fixer-ga:2.18.0" - with: - args: "--dry-run --diff-format udiff" - - static-code-analysis: - name: "Static Code Analysis" - - runs-on: "ubuntu-latest" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2.3.4" - - - name: "Install PHP" - uses: "shivammathur/setup-php@2.9.0" - with: - coverage: "none" - extensions: "mbstring" - php-version: "7.4" - - - name: "Install dependencies with composer" - run: "composer update --no-interaction --no-progress && composer i --working-dir=ci" - - - name: "Run vimeo/psalm" - run: "ci/vendor/bin/psalm --threads=4" - - tests: - name: "Tests" - - runs-on: "ubuntu-latest" - - strategy: - matrix: - php-version: - - "7.2" - - "7.3" - - "7.4" - - "8.0" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2.3.4" - - - name: "Install PHP" - uses: "shivammathur/setup-php@2.9.0" - with: - coverage: "none" - extensions: "mbstring" - php-version: "${{ matrix.php-version }}" - - - name: "Install dependencies with composer" - run: "composer update --no-interaction --no-progress" - - - name: "Run unit tests" - run: "vendor/bin/phpunit" - - windows-tests: - name: "Windows tests" - - runs-on: "windows-latest" - - strategy: - matrix: - php-version: - - "7.4" - - steps: - - name: "Checkout" - uses: "actions/checkout@v2.3.4" - - - name: "Install PHP" - uses: "shivammathur/setup-php@2.9.0" - with: - coverage: "none" - extensions: "mbstring" - php-version: "${{ matrix.php-version }}" - - - name: "Install dependencies with composer" - run: "composer update --no-interaction --no-progress" - - - name: "Run unit tests" - run: "vendor/bin/phpunit tests/AssertTest.php" diff --git a/app/vendor/webmozart/assert/.php_cs b/app/vendor/webmozart/assert/.php_cs deleted file mode 100644 index f7afd3ed7..000000000 --- a/app/vendor/webmozart/assert/.php_cs +++ /dev/null @@ -1,24 +0,0 @@ -in(__DIR__.'/src') - ->in(__DIR__.'/tests') -; - -return PhpCsFixer\Config::create() - ->setRiskyAllowed(true) - ->setRules([ - '@PSR2' => true, - '@Symfony' => true, - 'ordered_imports' => true, - 'array_syntax' => ['syntax' => 'long'], - 'no_superfluous_phpdoc_tags' => false, - 'phpdoc_annotation_without_dot' => false, - 'phpdoc_types_order' => false, - 'phpdoc_summary' => false, - 'phpdoc_to_comment' => false, - 'phpdoc_align' => false, - 'yoda_style' => false, - ]) - ->setFinder($finder) -; diff --git a/app/vendor/webmozart/assert/CHANGELOG.md b/app/vendor/webmozart/assert/CHANGELOG.md deleted file mode 100644 index 8629248bb..000000000 --- a/app/vendor/webmozart/assert/CHANGELOG.md +++ /dev/null @@ -1,190 +0,0 @@ -Changelog -========= - -## UNRELEASED - -## 1.10.0 - -### Added - -* On invalid assertion, we throw a `Webmozart\Assert\InvalidArgumentException` -* Added `Assert::positiveInteger()` - -### Changed - -* Using a trait with real implementations of `all*()` and `nullOr*()` methods to improve psalm compatibility. - -### Removed - -* Support for PHP <7.2 - -## 1.9.1 - -## Fixed - -* provisional support for PHP 8.0 - -## 1.9.0 - -* added better Psalm support for `all*` & `nullOr*` methods -* These methods are now understood by Psalm through a mixin. You may need a newer version of Psalm in order to use this -* added `@psalm-pure` annotation to `Assert::notFalse()` -* added more `@psalm-assert` annotations where appropriate - -## Changed - -* the `all*` & `nullOr*` methods are now declared on an interface, instead of `@method` annotations. -This interface is linked to the `Assert` class with a `@mixin` annotation. Most IDE's have supported this -for a long time, and you should not lose any autocompletion capabilities. PHPStan has supported this since -version `0.12.20`. This package is marked incompatible (with a composer conflict) with phpstan version prior to that. -If you do not use PHPStan than this does not matter. - -## 1.8.0 - -### Added - -* added `Assert::notStartsWith()` -* added `Assert::notEndsWith()` -* added `Assert::inArray()` -* added `@psalm-pure` annotations to pure assertions - -### Fixed - -* Exception messages of comparisons between `DateTime(Immutable)` objects now display their date & time. -* Custom Exception messages for `Assert::count()` now use the values to render the exception message. - -## 1.7.0 (2020-02-14) - -### Added - -* added `Assert::notFalse()` -* added `Assert::isAOf()` -* added `Assert::isAnyOf()` -* added `Assert::isNotA()` - -## 1.6.0 (2019-11-24) - -### Added - -* added `Assert::validArrayKey()` -* added `Assert::isNonEmptyList()` -* added `Assert::isNonEmptyMap()` -* added `@throws InvalidArgumentException` annotations to all methods that throw. -* added `@psalm-assert` for the list type to the `isList` assertion. - -### Fixed - -* `ResourceBundle` & `SimpleXMLElement` now pass the `isCountable` assertions. -They are countable, without implementing the `Countable` interface. -* The doc block of `range` now has the proper variables. -* An empty array will now pass `isList` and `isMap`. As it is a valid form of both. -If a non-empty variant is needed, use `isNonEmptyList` or `isNonEmptyMap`. - -### Changed - -* Removed some `@psalm-assert` annotations, that were 'side effect' assertions See: - * [#144](https://github.com/webmozart/assert/pull/144) - * [#145](https://github.com/webmozart/assert/issues/145) - * [#146](https://github.com/webmozart/assert/pull/146) - * [#150](https://github.com/webmozart/assert/pull/150) -* If you use Psalm, the minimum version needed is `3.6.0`. Which is enforced through a composer conflict. -If you don't use Psalm, then this has no impact. - -## 1.5.0 (2019-08-24) - -### Added - -* added `Assert::uniqueValues()` -* added `Assert::unicodeLetters()` -* added: `Assert::email()` -* added support for [Psalm](https://github.com/vimeo/psalm), by adding `@psalm-assert` annotations where appropriate. - -### Fixed - -* `Assert::endsWith()` would not give the correct result when dealing with a multibyte suffix. -* `Assert::length(), minLength, maxLength, lengthBetween` would not give the correct result when dealing with multibyte characters. - -**NOTE**: These 2 changes may break your assertions if you relied on the fact that multibyte characters didn't behave correctly. - -### Changed - -* The names of some variables have been updated to better reflect what they are. -* All function calls are now in their FQN form, slightly increasing performance. -* Tests are now properly ran against HHVM-3.30 and PHP nightly. - -### Deprecation - -* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` - * This was already done in 1.3.0, but it was only done through a silenced `trigger_error`. It is now annotated as well. - -## 1.4.0 (2018-12-25) - -### Added - -* added `Assert::ip()` -* added `Assert::ipv4()` -* added `Assert::ipv6()` -* added `Assert::notRegex()` -* added `Assert::interfaceExists()` -* added `Assert::isList()` -* added `Assert::isMap()` -* added polyfill for ctype - -### Fixed - -* Special case when comparing objects implementing `__toString()` - -## 1.3.0 (2018-01-29) - -### Added - -* added `Assert::minCount()` -* added `Assert::maxCount()` -* added `Assert::countBetween()` -* added `Assert::isCountable()` -* added `Assert::notWhitespaceOnly()` -* added `Assert::natural()` -* added `Assert::notContains()` -* added `Assert::isArrayAccessible()` -* added `Assert::isInstanceOfAny()` -* added `Assert::isIterable()` - -### Fixed - -* `stringNotEmpty` will no longer report "0" is an empty string - -### Deprecation - -* deprecated `Assert::isTraversable()` in favor of `Assert::isIterable()` - -## 1.2.0 (2016-11-23) - - * added `Assert::throws()` - * added `Assert::count()` - * added extension point `Assert::reportInvalidArgument()` for custom subclasses - -## 1.1.0 (2016-08-09) - - * added `Assert::object()` - * added `Assert::propertyExists()` - * added `Assert::propertyNotExists()` - * added `Assert::methodExists()` - * added `Assert::methodNotExists()` - * added `Assert::uuid()` - -## 1.0.2 (2015-08-24) - - * integrated Style CI - * add tests for minimum package dependencies on Travis CI - -## 1.0.1 (2015-05-12) - - * added support for PHP 5.3.3 - -## 1.0.0 (2015-05-12) - - * first stable release - -## 1.0.0-beta (2015-03-19) - - * first beta release diff --git a/app/vendor/webmozart/assert/LICENSE b/app/vendor/webmozart/assert/LICENSE deleted file mode 100644 index 9e2e3075e..000000000 --- a/app/vendor/webmozart/assert/LICENSE +++ /dev/null @@ -1,20 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Bernhard Schussek - -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. diff --git a/app/vendor/webmozart/assert/README.md b/app/vendor/webmozart/assert/README.md deleted file mode 100644 index b85d59817..000000000 --- a/app/vendor/webmozart/assert/README.md +++ /dev/null @@ -1,287 +0,0 @@ -Webmozart Assert -================ - -[![Latest Stable Version](https://poser.pugx.org/webmozart/assert/v/stable.svg)](https://packagist.org/packages/webmozart/assert) -[![Total Downloads](https://poser.pugx.org/webmozart/assert/downloads.svg)](https://packagist.org/packages/webmozart/assert) - -This library contains efficient assertions to test the input and output of -your methods. With these assertions, you can greatly reduce the amount of coding -needed to write a safe implementation. - -All assertions in the [`Assert`] class throw an `Webmozart\Assert\InvalidArgumentException` if -they fail. - -FAQ ---- - -**What's the difference to [beberlei/assert]?** - -This library is heavily inspired by Benjamin Eberlei's wonderful [assert package], -but fixes a usability issue with error messages that can't be fixed there without -breaking backwards compatibility. - -This package features usable error messages by default. However, you can also -easily write custom error messages: - -``` -Assert::string($path, 'The path is expected to be a string. Got: %s'); -``` - -In [beberlei/assert], the ordering of the `%s` placeholders is different for -every assertion. This package, on the contrary, provides consistent placeholder -ordering for all assertions: - -* `%s`: The tested value as string, e.g. `"/foo/bar"`. -* `%2$s`, `%3$s`, ...: Additional assertion-specific values, e.g. the - minimum/maximum length, allowed values, etc. - -Check the source code of the assertions to find out details about the additional -available placeholders. - -Installation ------------- - -Use [Composer] to install the package: - -``` -$ composer require webmozart/assert -``` - -Example -------- - -```php -use Webmozart\Assert\Assert; - -class Employee -{ - public function __construct($id) - { - Assert::integer($id, 'The employee ID must be an integer. Got: %s'); - Assert::greaterThan($id, 0, 'The employee ID must be a positive integer. Got: %s'); - } -} -``` - -If you create an employee with an invalid ID, an exception is thrown: - -```php -new Employee('foobar'); -// => Webmozart\Assert\InvalidArgumentException: -// The employee ID must be an integer. Got: string - -new Employee(-10); -// => Webmozart\Assert\InvalidArgumentException: -// The employee ID must be a positive integer. Got: -10 -``` - -Assertions ----------- - -The [`Assert`] class provides the following assertions: - -### Type Assertions - -Method | Description --------------------------------------------------------- | -------------------------------------------------- -`string($value, $message = '')` | Check that a value is a string -`stringNotEmpty($value, $message = '')` | Check that a value is a non-empty string -`integer($value, $message = '')` | Check that a value is an integer -`integerish($value, $message = '')` | Check that a value casts to an integer -`positiveInteger($value, $message = '')` | Check that a value is a positive (non-zero) integer -`float($value, $message = '')` | Check that a value is a float -`numeric($value, $message = '')` | Check that a value is numeric -`natural($value, $message= ''')` | Check that a value is a non-negative integer -`boolean($value, $message = '')` | Check that a value is a boolean -`scalar($value, $message = '')` | Check that a value is a scalar -`object($value, $message = '')` | Check that a value is an object -`resource($value, $type = null, $message = '')` | Check that a value is a resource -`isCallable($value, $message = '')` | Check that a value is a callable -`isArray($value, $message = '')` | Check that a value is an array -`isTraversable($value, $message = '')` (deprecated) | Check that a value is an array or a `\Traversable` -`isIterable($value, $message = '')` | Check that a value is an array or a `\Traversable` -`isCountable($value, $message = '')` | Check that a value is an array or a `\Countable` -`isInstanceOf($value, $class, $message = '')` | Check that a value is an `instanceof` a class -`isInstanceOfAny($value, array $classes, $message = '')` | Check that a value is an `instanceof` at least one class on the array of classes -`notInstanceOf($value, $class, $message = '')` | Check that a value is not an `instanceof` a class -`isAOf($value, $class, $message = '')` | Check that a value is of the class or has one of its parents -`isAnyOf($value, array $classes, $message = '')` | Check that a value is of at least one of the classes or has one of its parents -`isNotA($value, $class, $message = '')` | Check that a value is not of the class or has not one of its parents -`isArrayAccessible($value, $message = '')` | Check that a value can be accessed as an array -`uniqueValues($values, $message = '')` | Check that the given array contains unique values - -### Comparison Assertions - -Method | Description ------------------------------------------------ | ------------------------------------------------------------------ -`true($value, $message = '')` | Check that a value is `true` -`false($value, $message = '')` | Check that a value is `false` -`notFalse($value, $message = '')` | Check that a value is not `false` -`null($value, $message = '')` | Check that a value is `null` -`notNull($value, $message = '')` | Check that a value is not `null` -`isEmpty($value, $message = '')` | Check that a value is `empty()` -`notEmpty($value, $message = '')` | Check that a value is not `empty()` -`eq($value, $value2, $message = '')` | Check that a value equals another (`==`) -`notEq($value, $value2, $message = '')` | Check that a value does not equal another (`!=`) -`same($value, $value2, $message = '')` | Check that a value is identical to another (`===`) -`notSame($value, $value2, $message = '')` | Check that a value is not identical to another (`!==`) -`greaterThan($value, $value2, $message = '')` | Check that a value is greater than another -`greaterThanEq($value, $value2, $message = '')` | Check that a value is greater than or equal to another -`lessThan($value, $value2, $message = '')` | Check that a value is less than another -`lessThanEq($value, $value2, $message = '')` | Check that a value is less than or equal to another -`range($value, $min, $max, $message = '')` | Check that a value is within a range -`inArray($value, array $values, $message = '')` | Check that a value is one of a list of values -`oneOf($value, array $values, $message = '')` | Check that a value is one of a list of values (alias of `inArray`) - -### String Assertions - -You should check that a value is a string with `Assert::string()` before making -any of the following assertions. - -Method | Description ---------------------------------------------------- | ----------------------------------------------------------------- -`contains($value, $subString, $message = '')` | Check that a string contains a substring -`notContains($value, $subString, $message = '')` | Check that a string does not contain a substring -`startsWith($value, $prefix, $message = '')` | Check that a string has a prefix -`notStartsWith($value, $prefix, $message = '')` | Check that a string does not have a prefix -`startsWithLetter($value, $message = '')` | Check that a string starts with a letter -`endsWith($value, $suffix, $message = '')` | Check that a string has a suffix -`notEndsWith($value, $suffix, $message = '')` | Check that a string does not have a suffix -`regex($value, $pattern, $message = '')` | Check that a string matches a regular expression -`notRegex($value, $pattern, $message = '')` | Check that a string does not match a regular expression -`unicodeLetters($value, $message = '')` | Check that a string contains Unicode letters only -`alpha($value, $message = '')` | Check that a string contains letters only -`digits($value, $message = '')` | Check that a string contains digits only -`alnum($value, $message = '')` | Check that a string contains letters and digits only -`lower($value, $message = '')` | Check that a string contains lowercase characters only -`upper($value, $message = '')` | Check that a string contains uppercase characters only -`length($value, $length, $message = '')` | Check that a string has a certain number of characters -`minLength($value, $min, $message = '')` | Check that a string has at least a certain number of characters -`maxLength($value, $max, $message = '')` | Check that a string has at most a certain number of characters -`lengthBetween($value, $min, $max, $message = '')` | Check that a string has a length in the given range -`uuid($value, $message = '')` | Check that a string is a valid UUID -`ip($value, $message = '')` | Check that a string is a valid IP (either IPv4 or IPv6) -`ipv4($value, $message = '')` | Check that a string is a valid IPv4 -`ipv6($value, $message = '')` | Check that a string is a valid IPv6 -`email($value, $message = '')` | Check that a string is a valid e-mail address -`notWhitespaceOnly($value, $message = '')` | Check that a string contains at least one non-whitespace character - -### File Assertions - -Method | Description ------------------------------------ | -------------------------------------------------- -`fileExists($value, $message = '')` | Check that a value is an existing path -`file($value, $message = '')` | Check that a value is an existing file -`directory($value, $message = '')` | Check that a value is an existing directory -`readable($value, $message = '')` | Check that a value is a readable path -`writable($value, $message = '')` | Check that a value is a writable path - -### Object Assertions - -Method | Description ------------------------------------------------------ | -------------------------------------------------- -`classExists($value, $message = '')` | Check that a value is an existing class name -`subclassOf($value, $class, $message = '')` | Check that a class is a subclass of another -`interfaceExists($value, $message = '')` | Check that a value is an existing interface name -`implementsInterface($value, $class, $message = '')` | Check that a class implements an interface -`propertyExists($value, $property, $message = '')` | Check that a property exists in a class/object -`propertyNotExists($value, $property, $message = '')` | Check that a property does not exist in a class/object -`methodExists($value, $method, $message = '')` | Check that a method exists in a class/object -`methodNotExists($value, $method, $message = '')` | Check that a method does not exist in a class/object - -### Array Assertions - -Method | Description --------------------------------------------------- | ------------------------------------------------------------------ -`keyExists($array, $key, $message = '')` | Check that a key exists in an array -`keyNotExists($array, $key, $message = '')` | Check that a key does not exist in an array -`validArrayKey($key, $message = '')` | Check that a value is a valid array key (int or string) -`count($array, $number, $message = '')` | Check that an array contains a specific number of elements -`minCount($array, $min, $message = '')` | Check that an array contains at least a certain number of elements -`maxCount($array, $max, $message = '')` | Check that an array contains at most a certain number of elements -`countBetween($array, $min, $max, $message = '')` | Check that an array has a count in the given range -`isList($array, $message = '')` | Check that an array is a non-associative list -`isNonEmptyList($array, $message = '')` | Check that an array is a non-associative list, and not empty -`isMap($array, $message = '')` | Check that an array is associative and has strings as keys -`isNonEmptyMap($array, $message = '')` | Check that an array is associative and has strings as keys, and is not empty - -### Function Assertions - -Method | Description -------------------------------------------- | ----------------------------------------------------------------------------------------------------- -`throws($closure, $class, $message = '')` | Check that a function throws a certain exception. Subclasses of the exception class will be accepted. - -### Collection Assertions - -All of the above assertions can be prefixed with `all*()` to test the contents -of an array or a `\Traversable`: - -```php -Assert::allIsInstanceOf($employees, 'Acme\Employee'); -``` - -### Nullable Assertions - -All of the above assertions can be prefixed with `nullOr*()` to run the -assertion only if it the value is not `null`: - -```php -Assert::nullOrString($middleName, 'The middle name must be a string or null. Got: %s'); -``` - -### Extending Assert - -The `Assert` class comes with a few methods, which can be overridden to change the class behaviour. You can also extend it to -add your own assertions. - -#### Overriding methods - -Overriding the following methods in your assertion class allows you to change the behaviour of the assertions: - -* `public static function __callStatic($name, $arguments)` - * This method is used to 'create' the `nullOr` and `all` versions of the assertions. -* `protected static function valueToString($value)` - * This method is used for error messages, to convert the value to a string value for displaying. You could use this for representing a value object with a `__toString` method for example. -* `protected static function typeToString($value)` - * This method is used for error messages, to convert the a value to a string representing its type. -* `protected static function strlen($value)` - * This method is used to calculate string length for relevant methods, using the `mb_strlen` if available and useful. -* `protected static function reportInvalidArgument($message)` - * This method is called when an assertion fails, with the specified error message. Here you can throw your own exception, or log something. - -## Static analysis support - -Where applicable, assertion functions are annotated to support Psalm's -[Assertion syntax](https://psalm.dev/docs/annotating_code/assertion_syntax/). -A dedicated [PHPStan Plugin](https://github.com/phpstan/phpstan-webmozart-assert) is -required for proper type support. - -Authors -------- - -* [Bernhard Schussek] a.k.a. [@webmozart] -* [The Community Contributors] - -Contribute ----------- - -Contributions to the package are always welcome! - -* Report any bugs or issues you find on the [issue tracker]. -* You can grab the source code at the package's [Git repository]. - -License -------- - -All contents of this package are licensed under the [MIT license]. - -[beberlei/assert]: https://github.com/beberlei/assert -[assert package]: https://github.com/beberlei/assert -[Composer]: https://getcomposer.org -[Bernhard Schussek]: https://webmozarts.com -[The Community Contributors]: https://github.com/webmozart/assert/graphs/contributors -[issue tracker]: https://github.com/webmozart/assert/issues -[Git repository]: https://github.com/webmozart/assert -[@webmozart]: https://twitter.com/webmozart -[MIT license]: LICENSE -[`Assert`]: src/Assert.php diff --git a/app/vendor/webmozart/assert/composer.json b/app/vendor/webmozart/assert/composer.json deleted file mode 100644 index cfae60e5c..000000000 --- a/app/vendor/webmozart/assert/composer.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "name": "webmozart/assert", - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "license": "MIT", - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "autoload-dev": { - "psr-4": { - "Webmozart\\Assert\\Tests\\": "tests/", - "Webmozart\\Assert\\Bin\\": "bin/src" - } - } -} diff --git a/app/vendor/webmozart/assert/psalm.xml b/app/vendor/webmozart/assert/psalm.xml deleted file mode 100644 index 9a4300819..000000000 --- a/app/vendor/webmozart/assert/psalm.xml +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - diff --git a/app/vendor/webmozart/assert/src/Assert.php b/app/vendor/webmozart/assert/src/Assert.php deleted file mode 100644 index e0fbabc86..000000000 --- a/app/vendor/webmozart/assert/src/Assert.php +++ /dev/null @@ -1,2066 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Webmozart\Assert; - -use ArrayAccess; -use BadMethodCallException; -use Closure; -use Countable; -use DateTime; -use DateTimeImmutable; -use Exception; -use ResourceBundle; -use SimpleXMLElement; -use Throwable; -use Traversable; - -/** - * Efficient assertions to validate the input/output of your methods. - * - * @since 1.0 - * - * @author Bernhard Schussek - */ -class Assert -{ - use Mixin; - - /** - * @psalm-pure - * @psalm-assert string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function string($value, $message = '') - { - if (!\is_string($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a string. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function stringNotEmpty($value, $message = '') - { - static::string($value, $message); - static::notEq($value, '', $message); - } - - /** - * @psalm-pure - * @psalm-assert int $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function integer($value, $message = '') - { - if (!\is_int($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an integer. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function integerish($value, $message = '') - { - if (!\is_numeric($value) || $value != (int) $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an integerish value. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function positiveInteger($value, $message = '') - { - if (!(\is_int($value) && $value > 0)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a positive integer. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert float $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function float($value, $message = '') - { - if (!\is_float($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a float. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert numeric $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function numeric($value, $message = '') - { - if (!\is_numeric($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a numeric. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert positive-int|0 $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function natural($value, $message = '') - { - if (!\is_int($value) || $value < 0) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-negative integer. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert bool $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function boolean($value, $message = '') - { - if (!\is_bool($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a boolean. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert scalar $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function scalar($value, $message = '') - { - if (!\is_scalar($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a scalar. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert object $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function object($value, $message = '') - { - if (!\is_object($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an object. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert resource $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function resource($value, $type = null, $message = '') - { - if (!\is_resource($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a resource. Got: %s', - static::typeToString($value) - )); - } - - if ($type && $type !== \get_resource_type($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a resource of type %2$s. Got: %s', - static::typeToString($value), - $type - )); - } - } - - /** - * @psalm-pure - * @psalm-assert callable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isCallable($value, $message = '') - { - if (!\is_callable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a callable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert array $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isArray($value, $message = '') - { - if (!\is_array($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isTraversable($value, $message = '') - { - @\trigger_error( - \sprintf( - 'The "%s" assertion is deprecated. You should stop using it, as it will soon be removed in 2.0 version. Use "isIterable" or "isInstanceOf" instead.', - __METHOD__ - ), - \E_USER_DEPRECATED - ); - - if (!\is_array($value) && !($value instanceof Traversable)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a traversable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert array|ArrayAccess $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isArrayAccessible($value, $message = '') - { - if (!\is_array($value) && !($value instanceof ArrayAccess)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array accessible. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert countable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isCountable($value, $message = '') - { - if ( - !\is_array($value) - && !($value instanceof Countable) - && !($value instanceof ResourceBundle) - && !($value instanceof SimpleXMLElement) - ) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a countable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isIterable($value, $message = '') - { - if (!\is_array($value) && !($value instanceof Traversable)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an iterable. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isInstanceOf($value, $class, $message = '') - { - if (!($value instanceof $class)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance of %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert !ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notInstanceOf($value, $class, $message = '') - { - if ($value instanceof $class) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance other than %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isInstanceOfAny($value, array $classes, $message = '') - { - foreach ($classes as $class) { - if ($value instanceof $class) { - return; - } - } - - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an instance of any of %2$s. Got: %s', - static::typeToString($value), - \implode(', ', \array_map(array('static', 'valueToString'), $classes)) - )); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|class-string $value - * - * @param object|string $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isAOf($value, $class, $message = '') - { - static::string($class, 'Expected class as a string. Got: %s'); - - if (!\is_a($value, $class, \is_string($value))) { - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an instance of this class or to this class among his parents %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * @psalm-assert !UnexpectedType $value - * @psalm-assert !class-string $value - * - * @param object|string $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNotA($value, $class, $message = '') - { - static::string($class, 'Expected class as a string. Got: %s'); - - if (\is_a($value, $class, \is_string($value))) { - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an instance of this class or to this class among his parents other than %2$s. Got: %s', - static::typeToString($value), - $class - )); - } - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param object|string $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isAnyOf($value, array $classes, $message = '') - { - foreach ($classes as $class) { - static::string($class, 'Expected class as a string. Got: %s'); - - if (\is_a($value, $class, \is_string($value))) { - return; - } - } - - static::reportInvalidArgument(sprintf( - $message ?: 'Expected an any of instance of this class or to this class among his parents other than %2$s. Got: %s', - static::typeToString($value), - \implode(', ', \array_map(array('static', 'valueToString'), $classes)) - )); - } - - /** - * @psalm-pure - * @psalm-assert empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isEmpty($value, $message = '') - { - if (!empty($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an empty value. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEmpty($value, $message = '') - { - if (empty($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-empty value. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function null($value, $message = '') - { - if (null !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected null. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notNull($value, $message = '') - { - if (null === $value) { - static::reportInvalidArgument( - $message ?: 'Expected a value other than null.' - ); - } - } - - /** - * @psalm-pure - * @psalm-assert true $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function true($value, $message = '') - { - if (true !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be true. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert false $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function false($value, $message = '') - { - if (false !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be false. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !false $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notFalse($value, $message = '') - { - if (false === $value) { - static::reportInvalidArgument( - $message ?: 'Expected a value other than false.' - ); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ip($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IP. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ipv4($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV4)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IPv4. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function ipv6($value, $message = '') - { - if (false === \filter_var($value, \FILTER_VALIDATE_IP, \FILTER_FLAG_IPV6)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be an IPv6. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function email($value, $message = '') - { - if (false === \filter_var($value, FILTER_VALIDATE_EMAIL)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to be a valid e-mail address. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * Does non strict comparisons on the items, so ['3', 3] will not pass the assertion. - * - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function uniqueValues(array $values, $message = '') - { - $allValues = \count($values); - $uniqueValues = \count(\array_unique($values)); - - if ($allValues !== $uniqueValues) { - $difference = $allValues - $uniqueValues; - - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array of unique values, but %s of them %s duplicated', - $difference, - (1 === $difference ? 'is' : 'are') - )); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function eq($value, $expect, $message = '') - { - if ($expect != $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($expect) - )); - } - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEq($value, $expect, $message = '') - { - if ($expect == $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a different value than %s.', - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function same($value, $expect, $message = '') - { - if ($expect !== $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value identical to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notSame($value, $expect, $message = '') - { - if ($expect === $value) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not identical to %s.', - static::valueToString($expect) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function greaterThan($value, $limit, $message = '') - { - if ($value <= $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value greater than %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function greaterThanEq($value, $limit, $message = '') - { - if ($value < $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value greater than or equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lessThan($value, $limit, $message = '') - { - if ($value >= $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value less than %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lessThanEq($value, $limit, $message = '') - { - if ($value > $limit) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value less than or equal to %2$s. Got: %s', - static::valueToString($value), - static::valueToString($limit) - )); - } - } - - /** - * Inclusive range, so Assert::(3, 3, 5) passes. - * - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function range($value, $min, $max, $message = '') - { - if ($value < $min || $value > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value between %2$s and %3$s. Got: %s', - static::valueToString($value), - static::valueToString($min), - static::valueToString($max) - )); - } - } - - /** - * A more human-readable alias of Assert::inArray(). - * - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function oneOf($value, array $values, $message = '') - { - static::inArray($value, $values, $message); - } - - /** - * Does strict comparison, so Assert::inArray(3, ['3']) does not pass the assertion. - * - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function inArray($value, array $values, $message = '') - { - if (!\in_array($value, $values, true)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected one of: %2$s. Got: %s', - static::valueToString($value), - \implode(', ', \array_map(array('static', 'valueToString'), $values)) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function contains($value, $subString, $message = '') - { - if (false === \strpos($value, $subString)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain %2$s. Got: %s', - static::valueToString($value), - static::valueToString($subString) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notContains($value, $subString, $message = '') - { - if (false !== \strpos($value, $subString)) { - static::reportInvalidArgument(\sprintf( - $message ?: '%2$s was not expected to be contained in a value. Got: %s', - static::valueToString($value), - static::valueToString($subString) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notWhitespaceOnly($value, $message = '') - { - if (\preg_match('/^\s*$/', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a non-whitespace string. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function startsWith($value, $prefix, $message = '') - { - if (0 !== \strpos($value, $prefix)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to start with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($prefix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notStartsWith($value, $prefix, $message = '') - { - if (0 === \strpos($value, $prefix)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not to start with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($prefix) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function startsWithLetter($value, $message = '') - { - static::string($value); - - $valid = isset($value[0]); - - if ($valid) { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = \ctype_alpha($value[0]); - \setlocale(LC_CTYPE, $locale); - } - - if (!$valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to start with a letter. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function endsWith($value, $suffix, $message = '') - { - if ($suffix !== \substr($value, -\strlen($suffix))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to end with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($suffix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notEndsWith($value, $suffix, $message = '') - { - if ($suffix === \substr($value, -\strlen($suffix))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value not to end with %2$s. Got: %s', - static::valueToString($value), - static::valueToString($suffix) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function regex($value, $pattern, $message = '') - { - if (!\preg_match($pattern, $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The value %s does not match the expected pattern.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function notRegex($value, $pattern, $message = '') - { - if (\preg_match($pattern, $value, $matches, PREG_OFFSET_CAPTURE)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The value %s matches the pattern %s (at offset %d).', - static::valueToString($value), - static::valueToString($pattern), - $matches[0][1] - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function unicodeLetters($value, $message = '') - { - static::string($value); - - if (!\preg_match('/^\p{L}+$/u', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain only Unicode letters. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function alpha($value, $message = '') - { - static::string($value); - - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_alpha($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain only letters. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function digits($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_digit($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain digits only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function alnum($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_alnum($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain letters and digits only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert lowercase-string $value - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lower($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_lower($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain lowercase characters only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-assert !lowercase-string $value - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function upper($value, $message = '') - { - $locale = \setlocale(LC_CTYPE, 0); - \setlocale(LC_CTYPE, 'C'); - $valid = !\ctype_upper($value); - \setlocale(LC_CTYPE, $locale); - - if ($valid) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain uppercase characters only. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * - * @param string $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function length($value, $length, $message = '') - { - if ($length !== static::strlen($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain %2$s characters. Got: %s', - static::valueToString($value), - $length - )); - } - } - - /** - * Inclusive min. - * - * @psalm-pure - * - * @param string $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function minLength($value, $min, $message = '') - { - if (static::strlen($value) < $min) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain at least %2$s characters. Got: %s', - static::valueToString($value), - $min - )); - } - } - - /** - * Inclusive max. - * - * @psalm-pure - * - * @param string $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function maxLength($value, $max, $message = '') - { - if (static::strlen($value) > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain at most %2$s characters. Got: %s', - static::valueToString($value), - $max - )); - } - } - - /** - * Inclusive , so Assert::lengthBetween('asd', 3, 5); passes the assertion. - * - * @psalm-pure - * - * @param string $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function lengthBetween($value, $min, $max, $message = '') - { - $length = static::strlen($value); - - if ($length < $min || $length > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a value to contain between %2$s and %3$s characters. Got: %s', - static::valueToString($value), - $min, - $max - )); - } - } - - /** - * Will also pass if $value is a directory, use Assert::file() instead if you need to be sure it is a file. - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function fileExists($value, $message = '') - { - static::string($value); - - if (!\file_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The file %s does not exist.', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function file($value, $message = '') - { - static::fileExists($value, $message); - - if (!\is_file($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not a file.', - static::valueToString($value) - )); - } - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function directory($value, $message = '') - { - static::fileExists($value, $message); - - if (!\is_dir($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is no directory.', - static::valueToString($value) - )); - } - } - - /** - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function readable($value, $message = '') - { - if (!\is_readable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not readable.', - static::valueToString($value) - )); - } - } - - /** - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function writable($value, $message = '') - { - if (!\is_writable($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'The path %s is not writable.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-assert class-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function classExists($value, $message = '') - { - if (!\class_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an existing class name. Got: %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert class-string|ExpectedType $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function subclassOf($value, $class, $message = '') - { - if (!\is_subclass_of($value, $class)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected a sub-class of %2$s. Got: %s', - static::valueToString($value), - static::valueToString($class) - )); - } - } - - /** - * @psalm-assert class-string $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function interfaceExists($value, $message = '') - { - if (!\interface_exists($value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an existing interface name. got %s', - static::valueToString($value) - )); - } - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert class-string $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function implementsInterface($value, $interface, $message = '') - { - if (!\in_array($interface, \class_implements($value))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an implementation of %2$s. Got: %s', - static::valueToString($value), - static::valueToString($interface) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function propertyExists($classOrObject, $property, $message = '') - { - if (!\property_exists($classOrObject, $property)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the property %s to exist.', - static::valueToString($property) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function propertyNotExists($classOrObject, $property, $message = '') - { - if (\property_exists($classOrObject, $property)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the property %s to not exist.', - static::valueToString($property) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function methodExists($classOrObject, $method, $message = '') - { - if (!(\is_string($classOrObject) || \is_object($classOrObject)) || !\method_exists($classOrObject, $method)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the method %s to exist.', - static::valueToString($method) - )); - } - } - - /** - * @psalm-pure - * @psalm-param class-string|object $classOrObject - * - * @param string|object $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function methodNotExists($classOrObject, $method, $message = '') - { - if ((\is_string($classOrObject) || \is_object($classOrObject)) && \method_exists($classOrObject, $method)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the method %s to not exist.', - static::valueToString($method) - )); - } - } - - /** - * @psalm-pure - * - * @param array $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function keyExists($array, $key, $message = '') - { - if (!(isset($array[$key]) || \array_key_exists($key, $array))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the key %s to exist.', - static::valueToString($key) - )); - } - } - - /** - * @psalm-pure - * - * @param array $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function keyNotExists($array, $key, $message = '') - { - if (isset($array[$key]) || \array_key_exists($key, $array)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected the key %s to not exist.', - static::valueToString($key) - )); - } - } - - /** - * Checks if a value is a valid array key (int or string). - * - * @psalm-pure - * @psalm-assert array-key $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function validArrayKey($value, $message = '') - { - if (!(\is_int($value) || \is_string($value))) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected string or integer. Got: %s', - static::typeToString($value) - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function count($array, $number, $message = '') - { - static::eq( - \count($array), - $number, - \sprintf( - $message ?: 'Expected an array to contain %d elements. Got: %d.', - $number, - \count($array) - ) - ); - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function minCount($array, $min, $message = '') - { - if (\count($array) < $min) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain at least %2$d elements. Got: %d', - \count($array), - $min - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function maxCount($array, $max, $message = '') - { - if (\count($array) > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain at most %2$d elements. Got: %d', - \count($array), - $max - )); - } - } - - /** - * Does not check if $array is countable, this can generate a warning on php versions after 7.2. - * - * @param Countable|array $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function countBetween($array, $min, $max, $message = '') - { - $count = \count($array); - - if ($count < $min || $count > $max) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Expected an array to contain between %2$d and %3$d elements. Got: %d', - $count, - $min, - $max - )); - } - } - - /** - * @psalm-pure - * @psalm-assert list $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isList($array, $message = '') - { - if (!\is_array($array) || $array !== \array_values($array)) { - static::reportInvalidArgument( - $message ?: 'Expected list - non-associative array.' - ); - } - } - - /** - * @psalm-pure - * @psalm-assert non-empty-list $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNonEmptyList($array, $message = '') - { - static::isList($array, $message); - static::notEmpty($array, $message); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array $array - * @psalm-assert array $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isMap($array, $message = '') - { - if ( - !\is_array($array) || - \array_keys($array) !== \array_filter(\array_keys($array), '\is_string') - ) { - static::reportInvalidArgument( - $message ?: 'Expected map - associative array with string keys.' - ); - } - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array $array - * @psalm-assert array $array - * @psalm-assert !empty $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function isNonEmptyMap($array, $message = '') - { - static::isMap($array, $message); - static::notEmpty($array, $message); - } - - /** - * @psalm-pure - * - * @param string $value - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function uuid($value, $message = '') - { - $value = \str_replace(array('urn:', 'uuid:', '{', '}'), '', $value); - - // The nil UUID is special form of UUID that is specified to have all - // 128 bits set to zero. - if ('00000000-0000-0000-0000-000000000000' === $value) { - return; - } - - if (!\preg_match('/^[0-9A-Fa-f]{8}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{4}-[0-9A-Fa-f]{12}$/', $value)) { - static::reportInvalidArgument(\sprintf( - $message ?: 'Value %s is not a valid UUID.', - static::valueToString($value) - )); - } - } - - /** - * @psalm-param class-string $class - * - * @param Closure $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - */ - public static function throws(Closure $expression, $class = 'Exception', $message = '') - { - static::string($class); - - $actual = 'none'; - - try { - $expression(); - } catch (Exception $e) { - $actual = \get_class($e); - if ($e instanceof $class) { - return; - } - } catch (Throwable $e) { - $actual = \get_class($e); - if ($e instanceof $class) { - return; - } - } - - static::reportInvalidArgument($message ?: \sprintf( - 'Expected to throw "%s", got "%s"', - $class, - $actual - )); - } - - /** - * @throws BadMethodCallException - */ - public static function __callStatic($name, $arguments) - { - if ('nullOr' === \substr($name, 0, 6)) { - if (null !== $arguments[0]) { - $method = \lcfirst(\substr($name, 6)); - \call_user_func_array(array('static', $method), $arguments); - } - - return; - } - - if ('all' === \substr($name, 0, 3)) { - static::isIterable($arguments[0]); - - $method = \lcfirst(\substr($name, 3)); - $args = $arguments; - - foreach ($arguments[0] as $entry) { - $args[0] = $entry; - - \call_user_func_array(array('static', $method), $args); - } - - return; - } - - throw new BadMethodCallException('No such method: '.$name); - } - - /** - * @param mixed $value - * - * @return string - */ - protected static function valueToString($value) - { - if (null === $value) { - return 'null'; - } - - if (true === $value) { - return 'true'; - } - - if (false === $value) { - return 'false'; - } - - if (\is_array($value)) { - return 'array'; - } - - if (\is_object($value)) { - if (\method_exists($value, '__toString')) { - return \get_class($value).': '.self::valueToString($value->__toString()); - } - - if ($value instanceof DateTime || $value instanceof DateTimeImmutable) { - return \get_class($value).': '.self::valueToString($value->format('c')); - } - - return \get_class($value); - } - - if (\is_resource($value)) { - return 'resource'; - } - - if (\is_string($value)) { - return '"'.$value.'"'; - } - - return (string) $value; - } - - /** - * @param mixed $value - * - * @return string - */ - protected static function typeToString($value) - { - return \is_object($value) ? \get_class($value) : \gettype($value); - } - - protected static function strlen($value) - { - if (!\function_exists('mb_detect_encoding')) { - return \strlen($value); - } - - if (false === $encoding = \mb_detect_encoding($value)) { - return \strlen($value); - } - - return \mb_strlen($value, $encoding); - } - - /** - * @param string $message - * - * @throws InvalidArgumentException - * - * @psalm-pure this method is not supposed to perform side-effects - */ - protected static function reportInvalidArgument($message) - { - throw new InvalidArgumentException($message); - } - - private function __construct() - { - } -} diff --git a/app/vendor/webmozart/assert/src/InvalidArgumentException.php b/app/vendor/webmozart/assert/src/InvalidArgumentException.php deleted file mode 100644 index 9d95a58c5..000000000 --- a/app/vendor/webmozart/assert/src/InvalidArgumentException.php +++ /dev/null @@ -1,16 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Webmozart\Assert; - -class InvalidArgumentException extends \InvalidArgumentException -{ -} diff --git a/app/vendor/webmozart/assert/src/Mixin.php b/app/vendor/webmozart/assert/src/Mixin.php deleted file mode 100644 index 5e98823d4..000000000 --- a/app/vendor/webmozart/assert/src/Mixin.php +++ /dev/null @@ -1,2916 +0,0 @@ - $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allString($value, $message = '') - { - static::__callStatic('allString', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert non-empty-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStringNotEmpty($value, $message = '') - { - static::__callStatic('nullOrStringNotEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStringNotEmpty($value, $message = '') - { - static::__callStatic('allStringNotEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert int|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInteger($value, $message = '') - { - static::__callStatic('nullOrInteger', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInteger($value, $message = '') - { - static::__callStatic('allInteger', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert numeric|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIntegerish($value, $message = '') - { - static::__callStatic('nullOrIntegerish', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIntegerish($value, $message = '') - { - static::__callStatic('allIntegerish', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert positive-int|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPositiveInteger($value, $message = '') - { - static::__callStatic('nullOrPositiveInteger', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPositiveInteger($value, $message = '') - { - static::__callStatic('allPositiveInteger', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert float|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFloat($value, $message = '') - { - static::__callStatic('nullOrFloat', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFloat($value, $message = '') - { - static::__callStatic('allFloat', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert numeric|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNumeric($value, $message = '') - { - static::__callStatic('nullOrNumeric', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNumeric($value, $message = '') - { - static::__callStatic('allNumeric', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert positive-int|0|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNatural($value, $message = '') - { - static::__callStatic('nullOrNatural', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNatural($value, $message = '') - { - static::__callStatic('allNatural', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert bool|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrBoolean($value, $message = '') - { - static::__callStatic('nullOrBoolean', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allBoolean($value, $message = '') - { - static::__callStatic('allBoolean', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert scalar|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrScalar($value, $message = '') - { - static::__callStatic('nullOrScalar', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allScalar($value, $message = '') - { - static::__callStatic('allScalar', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert object|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrObject($value, $message = '') - { - static::__callStatic('nullOrObject', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allObject($value, $message = '') - { - static::__callStatic('allObject', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert resource|null $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrResource($value, $type = null, $message = '') - { - static::__callStatic('nullOrResource', array($value, $type, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|null $type type of resource this should be. @see https://www.php.net/manual/en/function.get-resource-type.php - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allResource($value, $type = null, $message = '') - { - static::__callStatic('allResource', array($value, $type, $message)); - } - - /** - * @psalm-pure - * @psalm-assert callable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsCallable($value, $message = '') - { - static::__callStatic('nullOrIsCallable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsCallable($value, $message = '') - { - static::__callStatic('allIsCallable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert array|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsArray($value, $message = '') - { - static::__callStatic('nullOrIsArray', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsArray($value, $message = '') - { - static::__callStatic('allIsArray', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable|null $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsTraversable($value, $message = '') - { - static::__callStatic('nullOrIsTraversable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @deprecated use "isIterable" or "isInstanceOf" instead - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsTraversable($value, $message = '') - { - static::__callStatic('allIsTraversable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert array|ArrayAccess|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsArrayAccessible($value, $message = '') - { - static::__callStatic('nullOrIsArrayAccessible', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsArrayAccessible($value, $message = '') - { - static::__callStatic('allIsArrayAccessible', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert countable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsCountable($value, $message = '') - { - static::__callStatic('nullOrIsCountable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsCountable($value, $message = '') - { - static::__callStatic('allIsCountable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsIterable($value, $message = '') - { - static::__callStatic('nullOrIsIterable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsIterable($value, $message = '') - { - static::__callStatic('allIsIterable', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|null $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsInstanceOf($value, $class, $message = '') - { - static::__callStatic('nullOrIsInstanceOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsInstanceOf($value, $class, $message = '') - { - static::__callStatic('allIsInstanceOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotInstanceOf($value, $class, $message = '') - { - static::__callStatic('nullOrNotInstanceOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotInstanceOf($value, $class, $message = '') - { - static::__callStatic('allNotInstanceOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsInstanceOfAny($value, $classes, $message = '') - { - static::__callStatic('nullOrIsInstanceOfAny', array($value, $classes, $message)); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param mixed $value - * @param array $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsInstanceOfAny($value, $classes, $message = '') - { - static::__callStatic('allIsInstanceOfAny', array($value, $classes, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert ExpectedType|class-string|null $value - * - * @param object|string|null $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsAOf($value, $class, $message = '') - { - static::__callStatic('nullOrIsAOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable> $value - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsAOf($value, $class, $message = '') - { - static::__callStatic('allIsAOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * - * @param object|string|null $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNotA($value, $class, $message = '') - { - static::__callStatic('nullOrIsNotA', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template UnexpectedType of object - * @psalm-param class-string $class - * - * @param iterable $value - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNotA($value, $class, $message = '') - { - static::__callStatic('allIsNotA', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param object|string|null $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsAnyOf($value, $classes, $message = '') - { - static::__callStatic('nullOrIsAnyOf', array($value, $classes, $message)); - } - - /** - * @psalm-pure - * @psalm-param array $classes - * - * @param iterable $value - * @param string[] $classes - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsAnyOf($value, $classes, $message = '') - { - static::__callStatic('allIsAnyOf', array($value, $classes, $message)); - } - - /** - * @psalm-pure - * @psalm-assert empty $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsEmpty($value, $message = '') - { - static::__callStatic('nullOrIsEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsEmpty($value, $message = '') - { - static::__callStatic('allIsEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEmpty($value, $message = '') - { - static::__callStatic('nullOrNotEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEmpty($value, $message = '') - { - static::__callStatic('allNotEmpty', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNull($value, $message = '') - { - static::__callStatic('allNull', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotNull($value, $message = '') - { - static::__callStatic('allNotNull', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert true|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrTrue($value, $message = '') - { - static::__callStatic('nullOrTrue', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allTrue($value, $message = '') - { - static::__callStatic('allTrue', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert false|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFalse($value, $message = '') - { - static::__callStatic('nullOrFalse', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFalse($value, $message = '') - { - static::__callStatic('allFalse', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotFalse($value, $message = '') - { - static::__callStatic('nullOrNotFalse', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotFalse($value, $message = '') - { - static::__callStatic('allNotFalse', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIp($value, $message = '') - { - static::__callStatic('nullOrIp', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIp($value, $message = '') - { - static::__callStatic('allIp', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIpv4($value, $message = '') - { - static::__callStatic('nullOrIpv4', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIpv4($value, $message = '') - { - static::__callStatic('allIpv4', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIpv6($value, $message = '') - { - static::__callStatic('nullOrIpv6', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIpv6($value, $message = '') - { - static::__callStatic('allIpv6', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEmail($value, $message = '') - { - static::__callStatic('nullOrEmail', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEmail($value, $message = '') - { - static::__callStatic('allEmail', array($value, $message)); - } - - /** - * @param array|null $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUniqueValues($values, $message = '') - { - static::__callStatic('nullOrUniqueValues', array($values, $message)); - } - - /** - * @param iterable $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUniqueValues($values, $message = '') - { - static::__callStatic('allUniqueValues', array($values, $message)); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEq($value, $expect, $message = '') - { - static::__callStatic('nullOrEq', array($value, $expect, $message)); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEq($value, $expect, $message = '') - { - static::__callStatic('allEq', array($value, $expect, $message)); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEq($value, $expect, $message = '') - { - static::__callStatic('nullOrNotEq', array($value, $expect, $message)); - } - - /** - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEq($value, $expect, $message = '') - { - static::__callStatic('allNotEq', array($value, $expect, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrSame($value, $expect, $message = '') - { - static::__callStatic('nullOrSame', array($value, $expect, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allSame($value, $expect, $message = '') - { - static::__callStatic('allSame', array($value, $expect, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotSame($value, $expect, $message = '') - { - static::__callStatic('nullOrNotSame', array($value, $expect, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $expect - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotSame($value, $expect, $message = '') - { - static::__callStatic('allNotSame', array($value, $expect, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrGreaterThan($value, $limit, $message = '') - { - static::__callStatic('nullOrGreaterThan', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allGreaterThan($value, $limit, $message = '') - { - static::__callStatic('allGreaterThan', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrGreaterThanEq($value, $limit, $message = '') - { - static::__callStatic('nullOrGreaterThanEq', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allGreaterThanEq($value, $limit, $message = '') - { - static::__callStatic('allGreaterThanEq', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLessThan($value, $limit, $message = '') - { - static::__callStatic('nullOrLessThan', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLessThan($value, $limit, $message = '') - { - static::__callStatic('allLessThan', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLessThanEq($value, $limit, $message = '') - { - static::__callStatic('nullOrLessThanEq', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $limit - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLessThanEq($value, $limit, $message = '') - { - static::__callStatic('allLessThanEq', array($value, $limit, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrRange($value, $min, $max, $message = '') - { - static::__callStatic('nullOrRange', array($value, $min, $max, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param mixed $min - * @param mixed $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allRange($value, $min, $max, $message = '') - { - static::__callStatic('allRange', array($value, $min, $max, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrOneOf($value, $values, $message = '') - { - static::__callStatic('nullOrOneOf', array($value, $values, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allOneOf($value, $values, $message = '') - { - static::__callStatic('allOneOf', array($value, $values, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInArray($value, $values, $message = '') - { - static::__callStatic('nullOrInArray', array($value, $values, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param array $values - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInArray($value, $values, $message = '') - { - static::__callStatic('allInArray', array($value, $values, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrContains($value, $subString, $message = '') - { - static::__callStatic('nullOrContains', array($value, $subString, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allContains($value, $subString, $message = '') - { - static::__callStatic('allContains', array($value, $subString, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotContains($value, $subString, $message = '') - { - static::__callStatic('nullOrNotContains', array($value, $subString, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $subString - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotContains($value, $subString, $message = '') - { - static::__callStatic('allNotContains', array($value, $subString, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotWhitespaceOnly($value, $message = '') - { - static::__callStatic('nullOrNotWhitespaceOnly', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotWhitespaceOnly($value, $message = '') - { - static::__callStatic('allNotWhitespaceOnly', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStartsWith($value, $prefix, $message = '') - { - static::__callStatic('nullOrStartsWith', array($value, $prefix, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStartsWith($value, $prefix, $message = '') - { - static::__callStatic('allStartsWith', array($value, $prefix, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotStartsWith($value, $prefix, $message = '') - { - static::__callStatic('nullOrNotStartsWith', array($value, $prefix, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $prefix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotStartsWith($value, $prefix, $message = '') - { - static::__callStatic('allNotStartsWith', array($value, $prefix, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrStartsWithLetter($value, $message = '') - { - static::__callStatic('nullOrStartsWithLetter', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allStartsWithLetter($value, $message = '') - { - static::__callStatic('allStartsWithLetter', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrEndsWith($value, $suffix, $message = '') - { - static::__callStatic('nullOrEndsWith', array($value, $suffix, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allEndsWith($value, $suffix, $message = '') - { - static::__callStatic('allEndsWith', array($value, $suffix, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotEndsWith($value, $suffix, $message = '') - { - static::__callStatic('nullOrNotEndsWith', array($value, $suffix, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $suffix - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotEndsWith($value, $suffix, $message = '') - { - static::__callStatic('allNotEndsWith', array($value, $suffix, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrRegex($value, $pattern, $message = '') - { - static::__callStatic('nullOrRegex', array($value, $pattern, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allRegex($value, $pattern, $message = '') - { - static::__callStatic('allRegex', array($value, $pattern, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrNotRegex($value, $pattern, $message = '') - { - static::__callStatic('nullOrNotRegex', array($value, $pattern, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $pattern - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allNotRegex($value, $pattern, $message = '') - { - static::__callStatic('allNotRegex', array($value, $pattern, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUnicodeLetters($value, $message = '') - { - static::__callStatic('nullOrUnicodeLetters', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUnicodeLetters($value, $message = '') - { - static::__callStatic('allUnicodeLetters', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrAlpha($value, $message = '') - { - static::__callStatic('nullOrAlpha', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allAlpha($value, $message = '') - { - static::__callStatic('allAlpha', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrDigits($value, $message = '') - { - static::__callStatic('nullOrDigits', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allDigits($value, $message = '') - { - static::__callStatic('allDigits', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrAlnum($value, $message = '') - { - static::__callStatic('nullOrAlnum', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allAlnum($value, $message = '') - { - static::__callStatic('allAlnum', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert lowercase-string|null $value - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLower($value, $message = '') - { - static::__callStatic('nullOrLower', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLower($value, $message = '') - { - static::__callStatic('allLower', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUpper($value, $message = '') - { - static::__callStatic('nullOrUpper', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUpper($value, $message = '') - { - static::__callStatic('allUpper', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLength($value, $length, $message = '') - { - static::__callStatic('nullOrLength', array($value, $length, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int $length - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLength($value, $length, $message = '') - { - static::__callStatic('allLength', array($value, $length, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMinLength($value, $min, $message = '') - { - static::__callStatic('nullOrMinLength', array($value, $min, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMinLength($value, $min, $message = '') - { - static::__callStatic('allMinLength', array($value, $min, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMaxLength($value, $max, $message = '') - { - static::__callStatic('nullOrMaxLength', array($value, $max, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMaxLength($value, $max, $message = '') - { - static::__callStatic('allMaxLength', array($value, $max, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrLengthBetween($value, $min, $max, $message = '') - { - static::__callStatic('nullOrLengthBetween', array($value, $min, $max, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allLengthBetween($value, $min, $max, $message = '') - { - static::__callStatic('allLengthBetween', array($value, $min, $max, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFileExists($value, $message = '') - { - static::__callStatic('nullOrFileExists', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFileExists($value, $message = '') - { - static::__callStatic('allFileExists', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrFile($value, $message = '') - { - static::__callStatic('nullOrFile', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allFile($value, $message = '') - { - static::__callStatic('allFile', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrDirectory($value, $message = '') - { - static::__callStatic('nullOrDirectory', array($value, $message)); - } - - /** - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allDirectory($value, $message = '') - { - static::__callStatic('allDirectory', array($value, $message)); - } - - /** - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrReadable($value, $message = '') - { - static::__callStatic('nullOrReadable', array($value, $message)); - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allReadable($value, $message = '') - { - static::__callStatic('allReadable', array($value, $message)); - } - - /** - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrWritable($value, $message = '') - { - static::__callStatic('nullOrWritable', array($value, $message)); - } - - /** - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allWritable($value, $message = '') - { - static::__callStatic('allWritable', array($value, $message)); - } - - /** - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrClassExists($value, $message = '') - { - static::__callStatic('nullOrClassExists', array($value, $message)); - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allClassExists($value, $message = '') - { - static::__callStatic('allClassExists', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert class-string|ExpectedType|null $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrSubclassOf($value, $class, $message = '') - { - static::__callStatic('nullOrSubclassOf', array($value, $class, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $class - * @psalm-assert iterable|ExpectedType> $value - * - * @param mixed $value - * @param string|object $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allSubclassOf($value, $class, $message = '') - { - static::__callStatic('allSubclassOf', array($value, $class, $message)); - } - - /** - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrInterfaceExists($value, $message = '') - { - static::__callStatic('nullOrInterfaceExists', array($value, $message)); - } - - /** - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allInterfaceExists($value, $message = '') - { - static::__callStatic('allInterfaceExists', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert class-string|null $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrImplementsInterface($value, $interface, $message = '') - { - static::__callStatic('nullOrImplementsInterface', array($value, $interface, $message)); - } - - /** - * @psalm-pure - * @psalm-template ExpectedType of object - * @psalm-param class-string $interface - * @psalm-assert iterable> $value - * - * @param mixed $value - * @param mixed $interface - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allImplementsInterface($value, $interface, $message = '') - { - static::__callStatic('allImplementsInterface', array($value, $interface, $message)); - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPropertyExists($classOrObject, $property, $message = '') - { - static::__callStatic('nullOrPropertyExists', array($classOrObject, $property, $message)); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPropertyExists($classOrObject, $property, $message = '') - { - static::__callStatic('allPropertyExists', array($classOrObject, $property, $message)); - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrPropertyNotExists($classOrObject, $property, $message = '') - { - static::__callStatic('nullOrPropertyNotExists', array($classOrObject, $property, $message)); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $property - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allPropertyNotExists($classOrObject, $property, $message = '') - { - static::__callStatic('allPropertyNotExists', array($classOrObject, $property, $message)); - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMethodExists($classOrObject, $method, $message = '') - { - static::__callStatic('nullOrMethodExists', array($classOrObject, $method, $message)); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMethodExists($classOrObject, $method, $message = '') - { - static::__callStatic('allMethodExists', array($classOrObject, $method, $message)); - } - - /** - * @psalm-pure - * @psalm-param class-string|object|null $classOrObject - * - * @param string|object|null $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMethodNotExists($classOrObject, $method, $message = '') - { - static::__callStatic('nullOrMethodNotExists', array($classOrObject, $method, $message)); - } - - /** - * @psalm-pure - * @psalm-param iterable $classOrObject - * - * @param iterable $classOrObject - * @param mixed $method - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMethodNotExists($classOrObject, $method, $message = '') - { - static::__callStatic('allMethodNotExists', array($classOrObject, $method, $message)); - } - - /** - * @psalm-pure - * - * @param array|null $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrKeyExists($array, $key, $message = '') - { - static::__callStatic('nullOrKeyExists', array($array, $key, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allKeyExists($array, $key, $message = '') - { - static::__callStatic('allKeyExists', array($array, $key, $message)); - } - - /** - * @psalm-pure - * - * @param array|null $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrKeyNotExists($array, $key, $message = '') - { - static::__callStatic('nullOrKeyNotExists', array($array, $key, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $array - * @param string|int $key - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allKeyNotExists($array, $key, $message = '') - { - static::__callStatic('allKeyNotExists', array($array, $key, $message)); - } - - /** - * @psalm-pure - * @psalm-assert array-key|null $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrValidArrayKey($value, $message = '') - { - static::__callStatic('nullOrValidArrayKey', array($value, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $value - * - * @param mixed $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allValidArrayKey($value, $message = '') - { - static::__callStatic('allValidArrayKey', array($value, $message)); - } - - /** - * @param Countable|array|null $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrCount($array, $number, $message = '') - { - static::__callStatic('nullOrCount', array($array, $number, $message)); - } - - /** - * @param iterable $array - * @param int $number - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allCount($array, $number, $message = '') - { - static::__callStatic('allCount', array($array, $number, $message)); - } - - /** - * @param Countable|array|null $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMinCount($array, $min, $message = '') - { - static::__callStatic('nullOrMinCount', array($array, $min, $message)); - } - - /** - * @param iterable $array - * @param int|float $min - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMinCount($array, $min, $message = '') - { - static::__callStatic('allMinCount', array($array, $min, $message)); - } - - /** - * @param Countable|array|null $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrMaxCount($array, $max, $message = '') - { - static::__callStatic('nullOrMaxCount', array($array, $max, $message)); - } - - /** - * @param iterable $array - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allMaxCount($array, $max, $message = '') - { - static::__callStatic('allMaxCount', array($array, $max, $message)); - } - - /** - * @param Countable|array|null $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrCountBetween($array, $min, $max, $message = '') - { - static::__callStatic('nullOrCountBetween', array($array, $min, $max, $message)); - } - - /** - * @param iterable $array - * @param int|float $min - * @param int|float $max - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allCountBetween($array, $min, $max, $message = '') - { - static::__callStatic('allCountBetween', array($array, $min, $max, $message)); - } - - /** - * @psalm-pure - * @psalm-assert list|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsList($array, $message = '') - { - static::__callStatic('nullOrIsList', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsList($array, $message = '') - { - static::__callStatic('allIsList', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-assert non-empty-list|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNonEmptyList($array, $message = '') - { - static::__callStatic('nullOrIsNonEmptyList', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-assert iterable $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNonEmptyList($array, $message = '') - { - static::__callStatic('allIsNonEmptyList', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array|null $array - * @psalm-assert array|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsMap($array, $message = '') - { - static::__callStatic('nullOrIsMap', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable> $array - * @psalm-assert iterable> $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsMap($array, $message = '') - { - static::__callStatic('allIsMap', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param mixed|array|null $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrIsNonEmptyMap($array, $message = '') - { - static::__callStatic('nullOrIsNonEmptyMap', array($array, $message)); - } - - /** - * @psalm-pure - * @psalm-template T - * @psalm-param iterable> $array - * - * @param mixed $array - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allIsNonEmptyMap($array, $message = '') - { - static::__callStatic('allIsNonEmptyMap', array($array, $message)); - } - - /** - * @psalm-pure - * - * @param string|null $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrUuid($value, $message = '') - { - static::__callStatic('nullOrUuid', array($value, $message)); - } - - /** - * @psalm-pure - * - * @param iterable $value - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allUuid($value, $message = '') - { - static::__callStatic('allUuid', array($value, $message)); - } - - /** - * @psalm-param class-string $class - * - * @param Closure|null $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function nullOrThrows($expression, $class = 'Exception', $message = '') - { - static::__callStatic('nullOrThrows', array($expression, $class, $message)); - } - - /** - * @psalm-param class-string $class - * - * @param iterable $expression - * @param string $class - * @param string $message - * - * @throws InvalidArgumentException - * - * @return void - */ - public static function allThrows($expression, $class = 'Exception', $message = '') - { - static::__callStatic('allThrows', array($expression, $class, $message)); - } -}